1 /* Direct Draw Thunks and old vtables
2 * Copyright 2000 TransGaming Technologies Inc.
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 #include "config.h"
20 #include "wine/port.h"
21
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27 #define COBJMACROS
28 #define NONAMELESSUNION
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "wingdi.h"
34 #include "wine/exception.h"
35
36 #include "ddraw.h"
37 #include "d3d.h"
38
39 #include "ddraw_private.h"
40 #include "wine/debug.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
43 WINE_DECLARE_DEBUG_CHANNEL(ddraw);
44
45 static HRESULT WINAPI
46 IDirectDrawImpl_QueryInterface(LPDIRECTDRAW This, REFIID iid, LPVOID *ppObj)
47 {
48 return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
49 IDirectDraw,
50 IDirectDraw7, This),
51 iid, ppObj);
52 }
53
54 static HRESULT WINAPI
55 IDirectDraw2Impl_QueryInterface(LPDIRECTDRAW2 This, REFIID iid, LPVOID *ppObj)
56 {
57 return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
58 IDirectDraw2,
59 IDirectDraw7, This),
60 iid, ppObj);
61 }
62
63 static HRESULT WINAPI
64 IDirectDraw3Impl_QueryInterface(LPDIRECTDRAW3 This, REFIID iid, LPVOID *ppObj)
65 {
66 return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
67 IDirectDraw3,
68 IDirectDraw7, This),
69 iid, ppObj);
70 }
71
72 static HRESULT WINAPI
73 IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
74 {
75 return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
76 IDirectDraw4,
77 IDirectDraw7, This),
78 iid, ppObj);
79 }
80
81 static ULONG WINAPI
82 IDirectDrawImpl_AddRef(LPDIRECTDRAW iface)
83 {
84 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
85 ULONG ref = InterlockedIncrement(&This->ref1);
86
87 TRACE("(%p) : incrementing IDirectDraw refcount from %u.\n", This, ref -1);
88
89 if(ref == 1) InterlockedIncrement(&This->numIfaces);
90
91 return ref;
92 }
93
94 static ULONG WINAPI
95 IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface)
96 {
97 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
98 ULONG ref = InterlockedIncrement(&This->ref2);
99
100 TRACE("(%p) : incrementing IDirectDraw2 refcount from %u.\n", This, ref -1);
101
102 if(ref == 1) InterlockedIncrement(&This->numIfaces);
103
104 return ref;
105 }
106
107 static ULONG WINAPI
108 IDirectDraw3Impl_AddRef(LPDIRECTDRAW3 iface)
109 {
110 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw3, iface);
111 ULONG ref = InterlockedIncrement(&This->ref3);
112
113 TRACE("(%p) : incrementing IDirectDraw3 refcount from %u.\n", This, ref -1);
114
115 if(ref == 1) InterlockedIncrement(&This->numIfaces);
116
117 return ref;
118 }
119
120 static ULONG WINAPI
121 IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 iface)
122 {
123 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
124 ULONG ref = InterlockedIncrement(&This->ref4);
125
126 TRACE("(%p) : incrementing IDirectDraw4 refcount from %u.\n", This, ref -1);
127
128 if(ref == 1) InterlockedIncrement(&This->numIfaces);
129
130 return ref;
131 }
132
133 static ULONG WINAPI
134 IDirectDrawImpl_Release(LPDIRECTDRAW iface)
135 {
136 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
137 ULONG ref = InterlockedDecrement(&This->ref1);
138
139 TRACE_(ddraw)("(%p)->() decrementing IDirectDraw refcount from %u.\n", This, ref +1);
140
141 if(ref == 0)
142 {
143 ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
144 if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
145 }
146
147 return ref;
148 }
149
150 static ULONG WINAPI
151 IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface)
152 {
153 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
154 ULONG ref = InterlockedDecrement(&This->ref2);
155
156 TRACE_(ddraw)("(%p)->() decrementing IDirectDraw2 refcount from %u.\n", This, ref +1);
157
158 if(ref == 0)
159 {
160 ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
161 if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
162 }
163
164 return ref;
165 }
166
167 static ULONG WINAPI
168 IDirectDraw3Impl_Release(LPDIRECTDRAW3 iface)
169 {
170 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw3, iface);
171 ULONG ref = InterlockedDecrement(&This->ref3);
172
173 TRACE_(ddraw)("(%p)->() decrementing IDirectDraw3 refcount from %u.\n", This, ref +1);
174
175 if(ref == 0)
176 {
177 ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
178 if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
179 }
180
181 return ref;
182 }
183
184 static ULONG WINAPI
185 IDirectDraw4Impl_Release(LPDIRECTDRAW4 iface)
186 {
187 ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
188 ULONG ref = InterlockedDecrement(&This->ref4);
189
190 TRACE_(ddraw)("(%p)->() decrementing IDirectDraw4 refcount from %u.\n", This, ref +1);
191
192 if(ref == 0)
193 {
194 ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
195 if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
196 }
197
198 return ref;
199 }
200
201 static HRESULT WINAPI
202 IDirectDrawImpl_Compact(LPDIRECTDRAW This)
203 {
204 return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
205 IDirectDraw, IDirectDraw7,
206 This));
207 }
208
209 static HRESULT WINAPI
210 IDirectDraw2Impl_Compact(LPDIRECTDRAW2 This)
211 {
212 return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
213 IDirectDraw2, IDirectDraw7,
214 This));
215 }
216
217 static HRESULT WINAPI
218 IDirectDraw3Impl_Compact(LPDIRECTDRAW3 This)
219 {
220 return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
221 IDirectDraw3, IDirectDraw7,
222 This));
223 }
224
225 static HRESULT WINAPI
226 IDirectDraw4Impl_Compact(LPDIRECTDRAW4 This)
227 {
228 return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
229 IDirectDraw4, IDirectDraw7,
230 This));
231 }
232
233 static HRESULT WINAPI
234 IDirectDrawImpl_CreateClipper(LPDIRECTDRAW This, DWORD dwFlags,
235 LPDIRECTDRAWCLIPPER *ppClipper,
236 IUnknown *pUnkOuter)
237 {
238 return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
239 IDirectDraw,
240 IDirectDraw7,
241 This),
242 dwFlags, ppClipper, pUnkOuter);
243 }
244
245 static HRESULT WINAPI
246 IDirectDraw2Impl_CreateClipper(LPDIRECTDRAW2 This, DWORD dwFlags,
247 LPDIRECTDRAWCLIPPER *ppClipper,
248 IUnknown *pUnkOuter)
249 {
250 return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
251 IDirectDraw2,
252 IDirectDraw7,
253 This),
254 dwFlags, ppClipper, pUnkOuter);
255 }
256
257 static HRESULT WINAPI
258 IDirectDraw3Impl_CreateClipper(LPDIRECTDRAW3 This, DWORD dwFlags,
259 LPDIRECTDRAWCLIPPER *ppClipper,
260 IUnknown *pUnkOuter)
261 {
262 return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
263 IDirectDraw3,
264 IDirectDraw7,
265 This),
266 dwFlags, ppClipper, pUnkOuter);
267 }
268
269 static HRESULT WINAPI
270 IDirectDraw4Impl_CreateClipper(LPDIRECTDRAW4 This, DWORD dwFlags,
271 LPDIRECTDRAWCLIPPER *ppClipper,
272 IUnknown *pUnkOuter)
273 {
274 return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
275 IDirectDraw4,
276 IDirectDraw7,
277 This),
278 dwFlags, ppClipper, pUnkOuter);
279 }
280
281 static HRESULT WINAPI
282 IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
283 LPPALETTEENTRY pEntries,
284 LPDIRECTDRAWPALETTE *ppPalette,
285 IUnknown *pUnkOuter)
286 {
287 HRESULT hr;
288 hr = IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
289 IDirectDraw,
290 IDirectDraw7,
291 This),
292 dwFlags, pEntries, ppPalette, pUnkOuter);
293 if(SUCCEEDED(hr) && *ppPalette)
294 {
295 IDirectDrawPaletteImpl *impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, *ppPalette);
296 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
297 IDirectDraw,
298 IDirectDraw7,
299 This));
300 impl->ifaceToRelease = NULL;
301
302 }
303 return hr;
304 }
305
306 static HRESULT WINAPI
307 IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
308 LPPALETTEENTRY pEntries,
309 LPDIRECTDRAWPALETTE *ppPalette,
310 IUnknown *pUnkOuter)
311 {
312 HRESULT hr;
313 hr = IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
314 IDirectDraw2,
315 IDirectDraw7,
316 This),
317 dwFlags, pEntries, ppPalette, pUnkOuter);
318 if(SUCCEEDED(hr) && *ppPalette)
319 {
320 IDirectDrawPaletteImpl *impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, *ppPalette);
321 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
322 IDirectDraw2,
323 IDirectDraw7,
324 This));
325 impl->ifaceToRelease = NULL;
326 }
327 return hr;
328 }
329
330 static HRESULT WINAPI
331 IDirectDraw3Impl_CreatePalette(LPDIRECTDRAW3 This, DWORD dwFlags,
332 LPPALETTEENTRY pEntries,
333 LPDIRECTDRAWPALETTE *ppPalette,
334 IUnknown *pUnkOuter)
335 {
336 HRESULT hr;
337 hr = IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
338 IDirectDraw3,
339 IDirectDraw7,
340 This),
341 dwFlags, pEntries, ppPalette, pUnkOuter);
342 if(SUCCEEDED(hr) && *ppPalette)
343 {
344 IDirectDrawPaletteImpl *impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, *ppPalette);
345 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
346 IDirectDraw3,
347 IDirectDraw7,
348 This));
349 IDirectDraw4_AddRef(This);
350 impl->ifaceToRelease = (IUnknown *) This;
351 }
352 return hr;
353 }
354
355 static HRESULT WINAPI
356 IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
357 LPPALETTEENTRY pEntries,
358 LPDIRECTDRAWPALETTE *ppPalette,
359 IUnknown *pUnkOuter)
360 {
361 HRESULT hr;
362 hr = IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
363 IDirectDraw4,
364 IDirectDraw7,
365 This),
366 dwFlags, pEntries, ppPalette, pUnkOuter);
367 if(SUCCEEDED(hr) && *ppPalette)
368 {
369 IDirectDrawPaletteImpl *impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, *ppPalette);
370 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
371 IDirectDraw4,
372 IDirectDraw7,
373 This));
374 IDirectDraw4_AddRef(This);
375 impl->ifaceToRelease = (IUnknown *) This;
376 }
377 return hr;
378 }
379
380 static HRESULT WINAPI
381 IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
382 LPDIRECTDRAWSURFACE *ppSurface,
383 IUnknown *pUnkOuter)
384 {
385 LPDIRECTDRAWSURFACE7 pSurface7;
386 IDirectDrawSurfaceImpl *impl;
387 HRESULT hr;
388
389 /* Remove front buffer flag, this causes failure in v7, and its added to normal
390 * primaries anyway
391 */
392 pSDesc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
393 /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
394 * since the data layout is the same */
395 hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
396 IDirectDraw,
397 IDirectDraw7,
398 This),
399 (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
400
401 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
402 * IDirectDrawSurface vtable layout at the beginning */
403 *ppSurface = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
404 IDirectDrawSurface7, IDirectDrawSurface3,
405 pSurface7);
406
407 impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
408 if(SUCCEEDED(hr) && impl)
409 {
410 impl->version = 1;
411 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
412 IDirectDraw,
413 IDirectDraw7,
414 This));
415 impl->ifaceToRelease = NULL;
416 }
417
418 return hr;
419 }
420
421 static HRESULT WINAPI
422 IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
423 LPDIRECTDRAWSURFACE *ppSurface,
424 IUnknown *pUnkOuter)
425 {
426 LPDIRECTDRAWSURFACE7 pSurface7;
427 IDirectDrawSurfaceImpl *impl;
428 HRESULT hr;
429
430 hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
431 IDirectDraw2,
432 IDirectDraw7,
433 This),
434 (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
435
436 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
437 * IDirectDrawSurface vtable layout at the beginning */
438 *ppSurface = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
439 IDirectDrawSurface7, IDirectDrawSurface3,
440 pSurface7);
441
442 impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
443 if(SUCCEEDED(hr) && impl)
444 {
445 impl->version = 2;
446 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
447 IDirectDraw2,
448 IDirectDraw7,
449 This));
450 impl->ifaceToRelease = NULL;
451 }
452
453 return hr;
454 }
455
456 static HRESULT WINAPI
457 IDirectDraw3Impl_CreateSurface(LPDIRECTDRAW3 This, LPDDSURFACEDESC pSDesc,
458 LPDIRECTDRAWSURFACE *ppSurface,
459 IUnknown *pUnkOuter)
460 {
461 LPDIRECTDRAWSURFACE7 pSurface7;
462 IDirectDrawSurfaceImpl *impl;
463 HRESULT hr;
464
465 hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
466 IDirectDraw3,
467 IDirectDraw7,
468 This),
469 (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
470
471 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
472 * IDirectDrawSurface vtable layout at the beginning */
473 *ppSurface = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
474 IDirectDrawSurface7, IDirectDrawSurface3,
475 pSurface7);
476
477 impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
478 if(SUCCEEDED(hr) && impl)
479 {
480 impl->version = 3;
481 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
482 IDirectDraw3,
483 IDirectDraw7,
484 This));
485 IDirectDraw3_AddRef(This);
486 impl->ifaceToRelease = (IUnknown *) This;
487 }
488
489 return hr;
490 }
491
492 static HRESULT WINAPI
493 IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
494 LPDIRECTDRAWSURFACE4 *ppSurface,
495 IUnknown *pUnkOuter)
496 {
497 HRESULT hr;
498 IDirectDrawSurfaceImpl *impl;
499
500 hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
501 IDirectDraw4,
502 IDirectDraw7,
503 This),
504 pSDesc,
505 (LPDIRECTDRAWSURFACE7 *)ppSurface,
506 pUnkOuter);
507 impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurface);
508 if(SUCCEEDED(hr) && impl)
509 {
510 impl->version = 4;
511 IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
512 IDirectDraw4,
513 IDirectDraw7,
514 This));
515 IDirectDraw4_AddRef(This);
516 impl->ifaceToRelease = (IUnknown *) This;
517 }
518 return hr;
519 }
520
521 static HRESULT WINAPI
522 IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
523 LPDIRECTDRAWSURFACE *ppDst)
524 {
525 LPDIRECTDRAWSURFACE7 pDst7;
526 HRESULT hr;
527
528 hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
529 IDirectDraw,
530 IDirectDraw7, This),
531 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
532 IDirectDrawSurface3,
533 IDirectDrawSurface7,
534 pSrc),
535 &pDst7);
536
537 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
538 * IDirectDrawSurface vtable layout at the beginning */
539 *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
540 IDirectDrawSurface3, pDst7);
541
542 return hr;
543 }
544
545 static HRESULT WINAPI
546 IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
547 LPDIRECTDRAWSURFACE *ppDst)
548 {
549 LPDIRECTDRAWSURFACE7 pDst7;
550 HRESULT hr;
551
552 hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
553 IDirectDraw2,
554 IDirectDraw7, This),
555 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
556 IDirectDrawSurface3,
557 IDirectDrawSurface7,
558 pSrc),
559 &pDst7);
560
561 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
562 * IDirectDrawSurface vtable layout at the beginning */
563 *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
564 IDirectDrawSurface3, pDst7);
565
566 return hr;
567 }
568
569 static HRESULT WINAPI
570 IDirectDraw3Impl_DuplicateSurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE pSrc,
571 LPDIRECTDRAWSURFACE *ppDst)
572 {
573 LPDIRECTDRAWSURFACE7 pDst7;
574 HRESULT hr;
575
576 hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
577 IDirectDraw3,
578 IDirectDraw7, This),
579 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
580 IDirectDrawSurface3,
581 IDirectDrawSurface7,
582 pSrc),
583 &pDst7);
584
585 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
586 * IDirectDrawSurface vtable layout at the beginning */
587 *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
588 IDirectDrawSurface3, pDst7);
589
590 return hr;
591 }
592
593 static HRESULT WINAPI
594 IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
595 LPDIRECTDRAWSURFACE4 pSrc,
596 LPDIRECTDRAWSURFACE4 *ppDst)
597 {
598 return IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
599 IDirectDraw4,
600 IDirectDraw7,
601 This),
602 (LPDIRECTDRAWSURFACE7)pSrc,
603 (LPDIRECTDRAWSURFACE7 *)ppDst);
604 }
605
606 struct displaymodescallback_context
607 {
608 LPDDENUMMODESCALLBACK func;
609 LPVOID context;
610 };
611
612 static HRESULT CALLBACK
613 EnumDisplayModesCallbackThunk(LPDDSURFACEDESC2 pDDSD2, LPVOID context)
614 {
615 DDSURFACEDESC DDSD;
616 struct displaymodescallback_context *cbcontext = context;
617
618 memcpy(&DDSD,pDDSD2,sizeof(DDSD));
619 DDSD.dwSize = sizeof(DDSD);
620
621 return cbcontext->func(&DDSD, cbcontext->context);
622 }
623
624 static HRESULT WINAPI
625 IDirectDrawImpl_EnumDisplayModes(LPDIRECTDRAW This, DWORD dwFlags,
626 LPDDSURFACEDESC pDDSD, LPVOID context,
627 LPDDENUMMODESCALLBACK cb)
628 {
629 struct displaymodescallback_context cbcontext;
630
631 cbcontext.func = cb;
632 cbcontext.context = context;
633
634 return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
635 IDirectDraw,
636 IDirectDraw7,
637 This),
638 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
639 EnumDisplayModesCallbackThunk);
640 }
641
642 static HRESULT WINAPI
643 IDirectDraw2Impl_EnumDisplayModes(LPDIRECTDRAW2 This, DWORD dwFlags,
644 LPDDSURFACEDESC pDDSD, LPVOID context,
645 LPDDENUMMODESCALLBACK cb)
646 {
647 struct displaymodescallback_context cbcontext;
648
649 cbcontext.func = cb;
650 cbcontext.context = context;
651
652 return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
653 IDirectDraw2,
654 IDirectDraw7,
655 This),
656 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
657 EnumDisplayModesCallbackThunk);
658 }
659
660 static HRESULT WINAPI
661 IDirectDraw3Impl_EnumDisplayModes(LPDIRECTDRAW3 This, DWORD dwFlags,
662 LPDDSURFACEDESC pDDSD, LPVOID context,
663 LPDDENUMMODESCALLBACK cb)
664 {
665 struct displaymodescallback_context cbcontext;
666
667 cbcontext.func = cb;
668 cbcontext.context = context;
669
670 return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
671 IDirectDraw3,
672 IDirectDraw7,
673 This),
674 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
675 EnumDisplayModesCallbackThunk);
676 }
677
678 static HRESULT WINAPI
679 IDirectDraw4Impl_EnumDisplayModes(LPDIRECTDRAW4 This, DWORD dwFlags,
680 LPDDSURFACEDESC2 pDDSD, LPVOID context,
681 LPDDENUMMODESCALLBACK2 cb)
682 {
683 return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
684 IDirectDraw4,
685 IDirectDraw7,
686 This),
687 dwFlags, pDDSD, context, cb);
688 }
689
690 struct surfacescallback_context
691 {
692 LPDDENUMSURFACESCALLBACK func;
693 LPVOID context;
694 };
695
696 static HRESULT CALLBACK
697 EnumSurfacesCallbackThunk(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
698 LPVOID context)
699 {
700 struct surfacescallback_context *cbcontext = context;
701
702 /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
703 * IDirectDrawSurface vtable layout at the beginning */
704 return cbcontext->func((LPDIRECTDRAWSURFACE)
705 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
706 IDirectDrawSurface7,
707 IDirectDrawSurface3, pSurf),
708 (LPDDSURFACEDESC)pDDSD, cbcontext->context);
709 }
710
711 static HRESULT WINAPI
712 IDirectDrawImpl_EnumSurfaces(LPDIRECTDRAW This, DWORD dwFlags,
713 LPDDSURFACEDESC pDDSD, LPVOID context,
714 LPDDENUMSURFACESCALLBACK cb)
715 {
716 struct surfacescallback_context cbcontext;
717
718 cbcontext.func = cb;
719 cbcontext.context = context;
720
721 return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
722 IDirectDraw,
723 IDirectDraw7, This),
724 dwFlags, (LPDDSURFACEDESC2)pDDSD,
725 &cbcontext, EnumSurfacesCallbackThunk);
726 }
727
728 static HRESULT WINAPI
729 IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
730 LPDDSURFACEDESC pDDSD, LPVOID context,
731 LPDDENUMSURFACESCALLBACK cb)
732 {
733 struct surfacescallback_context cbcontext;
734
735 cbcontext.func = cb;
736 cbcontext.context = context;
737
738 return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
739 IDirectDraw2,
740 IDirectDraw7, This),
741 dwFlags, (LPDDSURFACEDESC2)pDDSD,
742 &cbcontext, EnumSurfacesCallbackThunk);
743 }
744
745 static HRESULT WINAPI
746 IDirectDraw3Impl_EnumSurfaces(LPDIRECTDRAW3 This, DWORD dwFlags,
747 LPDDSURFACEDESC pDDSD, LPVOID context,
748 LPDDENUMSURFACESCALLBACK cb)
749 {
750 struct surfacescallback_context cbcontext;
751
752 cbcontext.func = cb;
753 cbcontext.context = context;
754
755 return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
756 IDirectDraw3,
757 IDirectDraw7, This),
758 dwFlags, (LPDDSURFACEDESC2)pDDSD,
759 &cbcontext, EnumSurfacesCallbackThunk);
760 }
761
762 static HRESULT WINAPI
763 IDirectDraw4Impl_EnumSurfaces(LPDIRECTDRAW4 This, DWORD dwFlags,
764 LPDDSURFACEDESC2 pDDSD, LPVOID context,
765 LPDDENUMSURFACESCALLBACK2 cb)
766 {
767 return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
768 IDirectDraw4,
769 IDirectDraw7, This),
770 dwFlags, pDDSD, context,
771 (LPDDENUMSURFACESCALLBACK7)cb);
772 }
773
774 static HRESULT WINAPI
775 IDirectDrawImpl_FlipToGDISurface(LPDIRECTDRAW This)
776 {
777 return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
778 IDirectDraw,
779 IDirectDraw7,
780 This));
781 }
782
783 static HRESULT WINAPI
784 IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 This)
785 {
786 return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
787 IDirectDraw2,
788 IDirectDraw7,
789 This));
790 }
791
792 static HRESULT WINAPI
793 IDirectDraw3Impl_FlipToGDISurface(LPDIRECTDRAW3 This)
794 {
795 return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
796 IDirectDraw3,
797 IDirectDraw7,
798 This));
799 }
800
801 static HRESULT WINAPI
802 IDirectDraw4Impl_FlipToGDISurface(LPDIRECTDRAW4 This)
803 {
804 return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
805 IDirectDraw4,
806 IDirectDraw7,
807 This));
808 }
809
810 static HRESULT WINAPI
811 IDirectDrawImpl_GetCaps(LPDIRECTDRAW This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
812 {
813 return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
814 IDirectDraw, IDirectDraw7,
815 This), pDDC1, pDDC2);
816 }
817
818 static HRESULT WINAPI
819 IDirectDraw2Impl_GetCaps(LPDIRECTDRAW2 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
820 {
821 return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
822 IDirectDraw2, IDirectDraw7,
823 This), pDDC1, pDDC2);
824 }
825
826 static HRESULT WINAPI
827 IDirectDraw3Impl_GetCaps(LPDIRECTDRAW3 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
828 {
829 return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
830 IDirectDraw3, IDirectDraw7,
831 This), pDDC1, pDDC2);
832 }
833
834 static HRESULT WINAPI
835 IDirectDraw4Impl_GetCaps(LPDIRECTDRAW4 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
836 {
837 return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
838 IDirectDra