crypt32/tests: Don't crash on Win9x.
[wine] / dlls / ddraw / ddraw_thunks.c
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((IDirectDraw7 *)ddraw_from_ddraw1(This), iid, ppObj);
49 }
50
51 static HRESULT WINAPI
52 IDirectDraw2Impl_QueryInterface(LPDIRECTDRAW2 This, REFIID iid, LPVOID *ppObj)
53 {
54     return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw2(This), iid, ppObj);
55 }
56
57 static HRESULT WINAPI
58 IDirectDraw3Impl_QueryInterface(LPDIRECTDRAW3 This, REFIID iid, LPVOID *ppObj)
59 {
60     return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw3(This), iid, ppObj);
61 }
62
63 static HRESULT WINAPI
64 IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
65 {
66     return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw4(This), iid, ppObj);
67 }
68
69 static ULONG WINAPI
70 IDirectDrawImpl_AddRef(LPDIRECTDRAW iface)
71 {
72     IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
73     ULONG ref = InterlockedIncrement(&This->ref1);
74
75     TRACE("(%p) : incrementing IDirectDraw refcount from %u.\n", This, ref -1);
76
77     if(ref == 1) InterlockedIncrement(&This->numIfaces);
78
79     return ref;
80 }
81
82 static ULONG WINAPI
83 IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface)
84 {
85     IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
86     ULONG ref = InterlockedIncrement(&This->ref2);
87
88     TRACE("(%p) : incrementing IDirectDraw2 refcount from %u.\n", This, ref -1);
89
90     if(ref == 1) InterlockedIncrement(&This->numIfaces);
91
92     return ref;
93 }
94
95 static ULONG WINAPI
96 IDirectDraw3Impl_AddRef(LPDIRECTDRAW3 iface)
97 {
98     IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
99     ULONG ref = InterlockedIncrement(&This->ref3);
100
101     TRACE("(%p) : incrementing IDirectDraw3 refcount from %u.\n", This, ref -1);
102
103     if(ref == 1) InterlockedIncrement(&This->numIfaces);
104
105     return ref;
106 }
107
108 static ULONG WINAPI
109 IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 iface)
110 {
111     IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
112     ULONG ref = InterlockedIncrement(&This->ref4);
113
114     TRACE("(%p) : incrementing IDirectDraw4 refcount from %u.\n", This, ref -1);
115
116     if(ref == 1) InterlockedIncrement(&This->numIfaces);
117
118     return ref;
119 }
120
121 static ULONG WINAPI
122 IDirectDrawImpl_Release(LPDIRECTDRAW iface)
123 {
124     IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
125     ULONG ref = InterlockedDecrement(&This->ref1);
126
127     TRACE_(ddraw)("(%p)->() decrementing IDirectDraw refcount from %u.\n", This, ref +1);
128
129     if(ref == 0)
130     {
131         ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
132         if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
133     }
134
135     return ref;
136 }
137
138 static ULONG WINAPI
139 IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface)
140 {
141     IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
142     ULONG ref = InterlockedDecrement(&This->ref2);
143
144     TRACE_(ddraw)("(%p)->() decrementing IDirectDraw2 refcount from %u.\n", This, ref +1);
145
146     if(ref == 0)
147     {
148         ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
149         if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
150     }
151
152     return ref;
153 }
154
155 static ULONG WINAPI
156 IDirectDraw3Impl_Release(LPDIRECTDRAW3 iface)
157 {
158     IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
159     ULONG ref = InterlockedDecrement(&This->ref3);
160
161     TRACE_(ddraw)("(%p)->() decrementing IDirectDraw3 refcount from %u.\n", This, ref +1);
162
163     if(ref == 0)
164     {
165         ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
166         if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
167     }
168
169     return ref;
170 }
171
172 static ULONG WINAPI
173 IDirectDraw4Impl_Release(LPDIRECTDRAW4 iface)
174 {
175     IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
176     ULONG ref = InterlockedDecrement(&This->ref4);
177
178     TRACE_(ddraw)("(%p)->() decrementing IDirectDraw4 refcount from %u.\n", This, ref +1);
179
180     if(ref == 0)
181     {
182         ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
183         if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
184     }
185
186     return ref;
187 }
188
189 static HRESULT WINAPI
190 IDirectDrawImpl_Compact(LPDIRECTDRAW This)
191 {
192     return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw1(This));
193 }
194
195 static HRESULT WINAPI
196 IDirectDraw2Impl_Compact(LPDIRECTDRAW2 This)
197 {
198     return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw2(This));
199 }
200
201     static HRESULT WINAPI
202 IDirectDraw3Impl_Compact(LPDIRECTDRAW3 This)
203 {
204     return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw3(This));
205 }
206
207 static HRESULT WINAPI
208 IDirectDraw4Impl_Compact(LPDIRECTDRAW4 This)
209 {
210     return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw4(This));
211 }
212
213 static HRESULT WINAPI
214 IDirectDrawImpl_CreateClipper(LPDIRECTDRAW This, DWORD dwFlags,
215                               LPDIRECTDRAWCLIPPER *ppClipper,
216                               IUnknown *pUnkOuter)
217 {
218     return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, ppClipper, pUnkOuter);
219 }
220
221 static HRESULT WINAPI
222 IDirectDraw2Impl_CreateClipper(LPDIRECTDRAW2 This, DWORD dwFlags,
223                                LPDIRECTDRAWCLIPPER *ppClipper,
224                                IUnknown *pUnkOuter)
225 {
226     return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, ppClipper, pUnkOuter);
227 }
228
229 static HRESULT WINAPI
230 IDirectDraw3Impl_CreateClipper(LPDIRECTDRAW3 This, DWORD dwFlags,
231                                LPDIRECTDRAWCLIPPER *ppClipper,
232                                IUnknown *pUnkOuter)
233 {
234     return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, ppClipper, pUnkOuter);
235 }
236
237 static HRESULT WINAPI
238 IDirectDraw4Impl_CreateClipper(LPDIRECTDRAW4 This, DWORD dwFlags,
239                                LPDIRECTDRAWCLIPPER *ppClipper,
240                                IUnknown *pUnkOuter)
241 {
242     return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, ppClipper, pUnkOuter);
243 }
244
245 static HRESULT WINAPI
246 IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
247                               LPPALETTEENTRY pEntries,
248                               LPDIRECTDRAWPALETTE *ppPalette,
249                               IUnknown *pUnkOuter)
250 {
251     HRESULT hr;
252     hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, pEntries, ppPalette, pUnkOuter);
253     if(SUCCEEDED(hr) && *ppPalette)
254     {
255         IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
256         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
257         impl->ifaceToRelease = NULL;
258
259     }
260     return hr;
261 }
262
263 static HRESULT WINAPI
264 IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
265                                LPPALETTEENTRY pEntries,
266                                LPDIRECTDRAWPALETTE *ppPalette,
267                                IUnknown *pUnkOuter)
268 {
269     HRESULT hr;
270     hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, pEntries, ppPalette, pUnkOuter);
271     if(SUCCEEDED(hr) && *ppPalette)
272     {
273         IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
274         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
275         impl->ifaceToRelease = NULL;
276     }
277     return hr;
278 }
279
280 static HRESULT WINAPI
281 IDirectDraw3Impl_CreatePalette(LPDIRECTDRAW3 This, DWORD dwFlags,
282                                LPPALETTEENTRY pEntries,
283                                LPDIRECTDRAWPALETTE *ppPalette,
284                                IUnknown *pUnkOuter)
285 {
286     HRESULT hr;
287     hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, pEntries, ppPalette, pUnkOuter);
288     if(SUCCEEDED(hr) && *ppPalette)
289     {
290         IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
291         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw3(This));
292         IDirectDraw4_AddRef(This);
293         impl->ifaceToRelease = (IUnknown *) This;
294     }
295     return hr;
296 }
297
298 static HRESULT WINAPI
299 IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
300                                LPPALETTEENTRY pEntries,
301                                LPDIRECTDRAWPALETTE *ppPalette,
302                                IUnknown *pUnkOuter)
303 {
304     HRESULT hr;
305     hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, pEntries, ppPalette, pUnkOuter);
306     if(SUCCEEDED(hr) && *ppPalette)
307     {
308         IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
309         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
310         IDirectDraw4_AddRef(This);
311         impl->ifaceToRelease = (IUnknown *) This;
312     }
313     return hr;
314 }
315
316 /* Must set all attached surfaces (e.g. mipmaps) versions as well */
317 static void set_surf_version(IDirectDrawSurfaceImpl *surf, int version)
318 {
319     int i;
320     TRACE("%p->version(%d) = %d\n", surf, surf->version, version);
321     surf->version = version;
322     for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
323     {
324         if(!surf->complex_array[i]) break;
325         set_surf_version(surf->complex_array[i], version);
326     }
327     while( (surf = surf->next_attached) )
328     {
329         set_surf_version(surf, version);
330     }
331 }
332
333 static HRESULT WINAPI
334 IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
335                               LPDIRECTDRAWSURFACE *ppSurface,
336                               IUnknown *pUnkOuter)
337 {
338     LPDIRECTDRAWSURFACE7 pSurface7;
339     IDirectDrawSurfaceImpl *impl;
340     HRESULT hr;
341
342     /* Remove front buffer flag, this causes failure in v7, and its added to normal
343      * primaries anyway
344      */
345     pSDesc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
346     /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
347      * since the data layout is the same */
348     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw1(This),
349             (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
350
351     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
352      * IDirectDrawSurface vtable layout at the beginning  */
353     *ppSurface = pSurface7 ?
354             (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurface7)->IDirectDrawSurface3_vtbl : NULL;
355
356     impl = (IDirectDrawSurfaceImpl *)pSurface7;
357     if(SUCCEEDED(hr) && impl)
358     {
359         set_surf_version(impl, 1);
360         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
361         impl->ifaceToRelease = NULL;
362     }
363
364     return hr;
365 }
366
367 static HRESULT WINAPI
368 IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
369                                LPDIRECTDRAWSURFACE *ppSurface,
370                                IUnknown *pUnkOuter)
371 {
372     LPDIRECTDRAWSURFACE7 pSurface7;
373     IDirectDrawSurfaceImpl *impl;
374     HRESULT hr;
375
376     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
377             (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
378
379     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
380      * IDirectDrawSurface vtable layout at the beginning  */
381     *ppSurface = pSurface7 ?
382             (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurface7)->IDirectDrawSurface3_vtbl : NULL;
383
384     impl = (IDirectDrawSurfaceImpl *)pSurface7;
385     if(SUCCEEDED(hr) && impl)
386     {
387         set_surf_version(impl, 2);
388         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
389         impl->ifaceToRelease = NULL;
390     }
391
392     return hr;
393 }
394
395 static HRESULT WINAPI
396 IDirectDraw3Impl_CreateSurface(LPDIRECTDRAW3 This, LPDDSURFACEDESC pSDesc,
397                                LPDIRECTDRAWSURFACE *ppSurface,
398                                IUnknown *pUnkOuter)
399 {
400     LPDIRECTDRAWSURFACE7 pSurface7;
401     IDirectDrawSurfaceImpl *impl;
402     HRESULT hr;
403
404     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw3(This),
405             (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
406
407     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
408      * IDirectDrawSurface vtable layout at the beginning  */
409     *ppSurface = pSurface7 ?
410             (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurface7)->IDirectDrawSurface3_vtbl : NULL;
411
412     impl = (IDirectDrawSurfaceImpl *)pSurface7;
413     if(SUCCEEDED(hr) && impl)
414     {
415         set_surf_version(impl, 3);
416         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw3(This));
417         IDirectDraw3_AddRef(This);
418         impl->ifaceToRelease = (IUnknown *) This;
419     }
420
421     return hr;
422 }
423
424 static HRESULT WINAPI
425 IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
426                                LPDIRECTDRAWSURFACE4 *ppSurface,
427                                IUnknown *pUnkOuter)
428 {
429     HRESULT hr;
430     IDirectDrawSurfaceImpl *impl;
431
432     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
433             pSDesc, (LPDIRECTDRAWSURFACE7 *)ppSurface, pUnkOuter);
434     impl = (IDirectDrawSurfaceImpl *)*ppSurface;
435     if(SUCCEEDED(hr) && impl)
436     {
437         set_surf_version(impl, 4);
438         IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
439         IDirectDraw4_AddRef(This);
440         impl->ifaceToRelease = (IUnknown *) This;
441     }
442     return hr;
443 }
444
445 static HRESULT WINAPI
446 IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
447                                  LPDIRECTDRAWSURFACE *ppDst)
448 {
449     LPDIRECTDRAWSURFACE7 pDst7;
450     HRESULT hr;
451
452     hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw1(This),
453             pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
454
455     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
456      * IDirectDrawSurface vtable layout at the beginning  */
457     *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
458
459     return hr;
460 }
461
462 static HRESULT WINAPI
463 IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
464                                   LPDIRECTDRAWSURFACE *ppDst)
465 {
466     LPDIRECTDRAWSURFACE7 pDst7;
467     HRESULT hr;
468
469     hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
470             pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
471
472     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
473      * IDirectDrawSurface vtable layout at the beginning  */
474     *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
475
476     return hr;
477 }
478
479 static HRESULT WINAPI
480 IDirectDraw3Impl_DuplicateSurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE pSrc,
481                                   LPDIRECTDRAWSURFACE *ppDst)
482 {
483     LPDIRECTDRAWSURFACE7 pDst7;
484     HRESULT hr;
485
486     hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw3(This),
487             pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
488
489     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
490      * IDirectDrawSurface vtable layout at the beginning  */
491     *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
492
493     return hr;
494 }
495
496 static HRESULT WINAPI
497 IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
498                                   LPDIRECTDRAWSURFACE4 pSrc,
499                                   LPDIRECTDRAWSURFACE4 *ppDst)
500 {
501     return IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
502             (LPDIRECTDRAWSURFACE7)pSrc, (LPDIRECTDRAWSURFACE7 *)ppDst);
503 }
504
505 struct displaymodescallback_context
506 {
507     LPDDENUMMODESCALLBACK func;
508     LPVOID context;
509 };
510
511 static HRESULT CALLBACK
512 EnumDisplayModesCallbackThunk(LPDDSURFACEDESC2 pDDSD2, LPVOID context)
513 {
514     DDSURFACEDESC DDSD;
515     struct displaymodescallback_context *cbcontext = context;
516
517     memcpy(&DDSD,pDDSD2,sizeof(DDSD));
518     DDSD.dwSize = sizeof(DDSD);
519
520     return cbcontext->func(&DDSD, cbcontext->context);
521 }
522
523 static HRESULT WINAPI
524 IDirectDrawImpl_EnumDisplayModes(LPDIRECTDRAW This, DWORD dwFlags,
525                                  LPDDSURFACEDESC pDDSD, LPVOID context,
526                                  LPDDENUMMODESCALLBACK cb)
527 {
528     struct displaymodescallback_context cbcontext;
529
530     cbcontext.func    = cb;
531     cbcontext.context = context;
532
533     return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw1(This),
534             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
535 }
536
537 static HRESULT WINAPI
538 IDirectDraw2Impl_EnumDisplayModes(LPDIRECTDRAW2 This, DWORD dwFlags,
539                                   LPDDSURFACEDESC pDDSD, LPVOID context,
540                                   LPDDENUMMODESCALLBACK cb)
541 {
542     struct displaymodescallback_context cbcontext;
543
544     cbcontext.func    = cb;
545     cbcontext.context = context;
546
547     return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw2(This),
548             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
549 }
550
551 static HRESULT WINAPI
552 IDirectDraw3Impl_EnumDisplayModes(LPDIRECTDRAW3 This, DWORD dwFlags,
553                                   LPDDSURFACEDESC pDDSD, LPVOID context,
554                                   LPDDENUMMODESCALLBACK cb)
555 {
556     struct displaymodescallback_context cbcontext;
557
558     cbcontext.func    = cb;
559     cbcontext.context = context;
560
561     return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw3(This),
562             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
563 }
564
565 static HRESULT WINAPI
566 IDirectDraw4Impl_EnumDisplayModes(LPDIRECTDRAW4 This, DWORD dwFlags,
567                                   LPDDSURFACEDESC2 pDDSD, LPVOID context,
568                                   LPDDENUMMODESCALLBACK2 cb)
569 {
570     return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, pDDSD, context, cb);
571 }
572
573 struct surfacescallback_context
574 {
575     LPDDENUMSURFACESCALLBACK func;
576     LPVOID context;
577 };
578
579 static HRESULT CALLBACK
580 EnumSurfacesCallbackThunk(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
581                           LPVOID context)
582 {
583     struct surfacescallback_context *cbcontext = context;
584
585     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
586      * IDirectDrawSurface vtable layout at the beginning  */
587     return cbcontext->func(
588             pSurf ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf)->IDirectDrawSurface3_vtbl : NULL,
589             (LPDDSURFACEDESC)pDDSD, cbcontext->context);
590 }
591
592 static HRESULT WINAPI
593 IDirectDrawImpl_EnumSurfaces(LPDIRECTDRAW This, DWORD dwFlags,
594                              LPDDSURFACEDESC pDDSD, LPVOID context,
595                              LPDDENUMSURFACESCALLBACK cb)
596 {
597     struct surfacescallback_context cbcontext;
598
599     cbcontext.func    = cb;
600     cbcontext.context = context;
601
602     return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw1(This),
603             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
604 }
605
606 static HRESULT WINAPI
607 IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
608                               LPDDSURFACEDESC pDDSD, LPVOID context,
609                               LPDDENUMSURFACESCALLBACK cb)
610 {
611     struct surfacescallback_context cbcontext;
612
613     cbcontext.func    = cb;
614     cbcontext.context = context;
615
616     return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw2(This),
617             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
618 }
619
620 static HRESULT WINAPI
621 IDirectDraw3Impl_EnumSurfaces(LPDIRECTDRAW3 This, DWORD dwFlags,
622                               LPDDSURFACEDESC pDDSD, LPVOID context,
623                               LPDDENUMSURFACESCALLBACK cb)
624 {
625     struct surfacescallback_context cbcontext;
626
627     cbcontext.func    = cb;
628     cbcontext.context = context;
629
630     return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw3(This),
631             dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
632 }
633
634 static HRESULT WINAPI
635 IDirectDraw4Impl_EnumSurfaces(LPDIRECTDRAW4 This, DWORD dwFlags,
636                               LPDDSURFACEDESC2 pDDSD, LPVOID context,
637                               LPDDENUMSURFACESCALLBACK2 cb)
638 {
639     return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(This),
640             dwFlags, pDDSD, context, (LPDDENUMSURFACESCALLBACK7)cb);
641 }
642
643 static HRESULT WINAPI
644 IDirectDrawImpl_FlipToGDISurface(LPDIRECTDRAW This)
645 {
646     return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(This));
647 }
648
649 static HRESULT WINAPI
650 IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 This)
651 {
652     return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(This));
653 }
654
655 static HRESULT WINAPI
656 IDirectDraw3Impl_FlipToGDISurface(LPDIRECTDRAW3 This)
657 {
658     return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(This));
659 }
660
661 static HRESULT WINAPI
662 IDirectDraw4Impl_FlipToGDISurface(LPDIRECTDRAW4 This)
663 {
664     return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(This));
665 }
666
667 static HRESULT WINAPI
668 IDirectDrawImpl_GetCaps(LPDIRECTDRAW This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
669 {
670     return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw1(This), pDDC1, pDDC2);
671 }
672
673 static HRESULT WINAPI
674 IDirectDraw2Impl_GetCaps(LPDIRECTDRAW2 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
675 {
676     return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw2(This), pDDC1, pDDC2);
677 }
678
679 static HRESULT WINAPI
680 IDirectDraw3Impl_GetCaps(LPDIRECTDRAW3 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
681 {
682     return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw3(This), pDDC1, pDDC2);
683 }
684
685 static HRESULT WINAPI
686 IDirectDraw4Impl_GetCaps(LPDIRECTDRAW4 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
687 {
688     return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw4(This), pDDC1, pDDC2);
689 }
690
691 static HRESULT WINAPI
692 IDirectDrawImpl_GetDisplayMode(LPDIRECTDRAW This, LPDDSURFACEDESC pDDSD)
693 {
694     return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This), (LPDDSURFACEDESC2)pDDSD);
695 }
696
697 static HRESULT WINAPI
698 IDirectDraw2Impl_GetDisplayMode(LPDIRECTDRAW2 This, LPDDSURFACEDESC pDDSD)
699 {
700     return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This), (LPDDSURFACEDESC2)pDDSD);
701 }
702
703 static HRESULT WINAPI
704 IDirectDraw3Impl_GetDisplayMode(LPDIRECTDRAW3 This, LPDDSURFACEDESC pDDSD)
705 {
706     return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This), (LPDDSURFACEDESC2)pDDSD);
707 }
708
709 static HRESULT WINAPI
710 IDirectDraw4Impl_GetDisplayMode(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pDDSD)
711 {
712     return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This), (LPDDSURFACEDESC2)pDDSD);
713 }
714
715 static HRESULT WINAPI
716 IDirectDrawImpl_GetFourCCCodes(LPDIRECTDRAW This, LPDWORD lpNumCodes,
717                                LPDWORD lpCodes)
718 {
719     return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw1(This), lpNumCodes, lpCodes);
720 }
721
722 static HRESULT WINAPI
723 IDirectDraw2Impl_GetFourCCCodes(LPDIRECTDRAW2 This, LPDWORD lpNumCodes,
724                                 LPDWORD lpCodes)
725 {
726     return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw2(This), lpNumCodes, lpCodes);
727 }
728
729 static HRESULT WINAPI
730 IDirectDraw3Impl_GetFourCCCodes(LPDIRECTDRAW3 This, LPDWORD lpNumCodes,
731                                 LPDWORD lpCodes)
732 {
733     return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw3(This), lpNumCodes, lpCodes);
734 }
735
736 static HRESULT WINAPI
737 IDirectDraw4Impl_GetFourCCCodes(LPDIRECTDRAW4 This, LPDWORD lpNumCodes,
738                                 LPDWORD lpCodes)
739 {
740     return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw4(This), lpNumCodes, lpCodes);
741 }
742
743 static HRESULT WINAPI
744 IDirectDrawImpl_GetGDISurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE *ppSurf)
745 {
746     LPDIRECTDRAWSURFACE7 pSurf7;
747     HRESULT hr;
748
749     hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(This), &pSurf7);
750
751     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
752      * IDirectDrawSurface vtable layout at the beginning  */
753     *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
754
755     return hr;
756 }
757
758 static HRESULT WINAPI
759 IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE *ppSurf)
760 {
761     LPDIRECTDRAWSURFACE7 pSurf7;
762     HRESULT hr;
763
764     hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(This), &pSurf7);
765
766     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
767      * IDirectDrawSurface vtable layout at the beginning  */
768     *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
769
770     return hr;
771 }
772
773 static HRESULT WINAPI
774 IDirectDraw3Impl_GetGDISurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE *ppSurf)
775 {
776     LPDIRECTDRAWSURFACE7 pSurf7;
777     HRESULT hr;
778
779     hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(This), &pSurf7);
780
781     /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
782      * IDirectDrawSurface vtable layout at the beginning  */
783     *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
784
785     return hr;
786 }
787
788 static HRESULT WINAPI
789 IDirectDraw4Impl_GetGDISurface(LPDIRECTDRAW4 This,
790                                LPDIRECTDRAWSURFACE4 *ppSurf)
791 {
792     return IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(This), (LPDIRECTDRAWSURFACE7 *)ppSurf);
793 }
794
795 static HRESULT WINAPI
796 IDirectDrawImpl_GetMonitorFrequency(LPDIRECTDRAW This, LPDWORD pdwFreq)
797 {
798     return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw1(This), pdwFreq);
799 }
800
801 static HRESULT WINAPI
802 IDirectDraw2Impl_GetMonitorFrequency(LPDIRECTDRAW2 This, LPDWORD pdwFreq)
803 {
804     return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw2(This), pdwFreq);
805 }
806
807 static HRESULT WINAPI
808 IDirectDraw3Impl_GetMonitorFrequency(LPDIRECTDRAW3 This, LPDWORD pdwFreq)
809 {
810     return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw3(This), pdwFreq);
811 }
812
813 static HRESULT WINAPI
814 IDirectDraw4Impl_GetMonitorFrequency(LPDIRECTDRAW4 This, LPDWORD pdwFreq)
815 {
816     return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw4(This), pdwFreq);
817 }
818
819 static HRESULT WINAPI
820 IDirectDrawImpl_GetScanLine(LPDIRECTDRAW This, LPDWORD pdwLine)
821 {
822     return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw1(This), pdwLine);
823 }
824
825 static HRESULT WINAPI
826 IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 This, LPDWORD pdwLine)
827 {
828     return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw2(This), pdwLine);
829 }
830
831 static HRESULT WINAPI
832 IDirectDraw3Impl_GetScanLine(LPDIRECTDRAW3 This, LPDWORD pdwLine)
833 {
834     return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw3(This), pdwLine);
835 }
836
837 static HRESULT WINAPI
838 IDirectDraw4Impl_GetScanLine(LPDIRECTDRAW4 This, LPDWORD pdwLine)
839 {
840     return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw4(This), pdwLine);
841 }
842
843 static HRESULT WINAPI
844 IDirectDrawImpl_GetVerticalBlankStatus(LPDIRECTDRAW This, LPBOOL lpbIsInVB)
845 {
846     return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw1(This), lpbIsInVB);
847 }
848
849 static HRESULT WINAPI
850 IDirectDraw2Impl_GetVerticalBlankStatus(LPDIRECTDRAW2 This, LPBOOL lpbIsInVB)
851 {
852     return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw2(This), lpbIsInVB);
853 }
854
855 static HRESULT WINAPI
856 IDirectDraw3Impl_GetVerticalBlankStatus(LPDIRECTDRAW3 This, LPBOOL lpbIsInVB)
857 {
858     return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw3(This), lpbIsInVB);
859 }
860
861 static HRESULT WINAPI
862 IDirectDraw4Impl_GetVerticalBlankStatus(LPDIRECTDRAW4 This, LPBOOL lpbIsInVB)
863 {
864     return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw4(This), lpbIsInVB);
865 }
866
867 static HRESULT WINAPI
868 IDirectDrawImpl_Initialize(LPDIRECTDRAW iface, LPGUID pGUID)
869 {
870     IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
871     HRESULT ret_value;
872
873     ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
874
875     return ret_value;
876 }
877
878 static HRESULT WINAPI
879 IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, LPGUID pGUID)
880 {
881     IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
882     HRESULT ret_value;
883
884     ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
885
886     return ret_value;
887 }
888
889 static HRESULT WINAPI
890 IDirectDraw3Impl_Initialize(LPDIRECTDRAW3 iface, LPGUID pGUID)
891 {
892     IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
893     HRESULT ret_value;
894
895     ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
896
897     return ret_value;
898 }
899
900 static HRESULT WINAPI
901 IDirectDraw4Impl_Initialize(LPDIRECTDRAW4 iface, LPGUID pGUID)
902 {
903     IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
904     HRESULT ret_value;
905
906     ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
907
908     return ret_value;
909 }
910
911
912 static HRESULT WINAPI
913 IDirectDrawImpl_RestoreDisplayMode(LPDIRECTDRAW This)
914 {
915     return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This));
916 }
917
918 static HRESULT WINAPI
919 IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 This)
920 {
921     return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This));
922 }
923
924 static HRESULT WINAPI
925 IDirectDraw3Impl_RestoreDisplayMode(LPDIRECTDRAW3 This)
926 {
927     return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This));
928 }
929
930 static HRESULT WINAPI
931 IDirectDraw4Impl_RestoreDisplayMode(LPDIRECTDRAW4 This)
932 {
933     return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This));
934 }
935
936 static HRESULT WINAPI
937 IDirectDrawImpl_SetCooperativeLevel(LPDIRECTDRAW This, HWND hWnd,
938                                     DWORD dwFlags)
939 {
940     return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw1(This), hWnd, dwFlags);
941 }
942
943 static HRESULT WINAPI
944 IDirectDraw2Impl_SetCooperativeLevel(LPDIRECTDRAW2 This, HWND hWnd,
945                                      DWORD dwFlags)
946 {
947     return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw2(This), hWnd, dwFlags);
948 }
949
950 static HRESULT WINAPI
951 IDirectDraw3Impl_SetCooperativeLevel(LPDIRECTDRAW3 This, HWND hWnd,
952                                      DWORD dwFlags)
953 {
954     return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw3(This), hWnd, dwFlags);
955 }
956
957 static HRESULT WINAPI
958 IDirectDraw4Impl_SetCooperativeLevel(LPDIRECTDRAW4 This, HWND hWnd,
959                                      DWORD dwFlags)
960 {
961     return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(This), hWnd, dwFlags);
962 }
963
964 static HRESULT WINAPI
965 IDirectDrawImpl_SetDisplayMode(LPDIRECTDRAW This, DWORD a, DWORD b, DWORD c)
966 {
967     return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This), a, b, c, 0, 0);
968 }
969
970 static HRESULT WINAPI
971 IDirectDraw2Impl_SetDisplayMode(LPDIRECTDRAW2 This, DWORD a, DWORD b, DWORD c,
972                                 DWORD d, DWORD e)
973 {
974     return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This), a, b, c, d, e);
975 }
976
977 static HRESULT WINAPI
978 IDirectDraw3Impl_SetDisplayMode(LPDIRECTDRAW3 This, DWORD a, DWORD b, DWORD c,
979                                 DWORD d, DWORD e)
980 {
981     return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This), a, b, c, d, e);
982 }
983
984 static HRESULT WINAPI
985 IDirectDraw4Impl_SetDisplayMode(LPDIRECTDRAW4 This, DWORD a, DWORD b, DWORD c,
986                                 DWORD d, DWORD e)
987 {
988     return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This), a, b, c, d, e);
989 }
990
991 static HRESULT WINAPI
992 IDirectDrawImpl_WaitForVerticalBlank(LPDIRECTDRAW This, DWORD dwFlags,
993                                      HANDLE hEvent)
994 {
995     return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, hEvent);
996 }
997
998 static HRESULT WINAPI
999 IDirectDraw2Impl_WaitForVerticalBlank(LPDIRECTDRAW2 This, DWORD dwFlags,
1000                                       HANDLE hEvent)
1001 {
1002     return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, hEvent);
1003 }
1004
1005 static HRESULT WINAPI
1006 IDirectDraw3Impl_WaitForVerticalBlank(LPDIRECTDRAW3 This, DWORD dwFlags,
1007                                       HANDLE hEvent)
1008 {
1009     return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, hEvent);
1010 }
1011
1012 static HRESULT WINAPI
1013 IDirectDraw4Impl_WaitForVerticalBlank(LPDIRECTDRAW4 This, DWORD dwFlags,
1014                                       HANDLE hEvent)
1015 {
1016     return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, hEvent);
1017 }
1018
1019 static HRESULT WINAPI
1020 IDirectDraw2Impl_GetAvailableVidMem(LPDIRECTDRAW2 This, LPDDSCAPS pCaps,
1021                                     LPDWORD pdwTotal, LPDWORD pdwFree)
1022 {
1023     DDSCAPS2 Caps2;
1024     DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
1025
1026     return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw2(This), &Caps2, pdwTotal, pdwFree);
1027 }
1028
1029 static HRESULT WINAPI
1030 IDirectDraw3Impl_GetAvailableVidMem(LPDIRECTDRAW3 This, LPDDSCAPS pCaps,
1031                                     LPDWORD pdwTotal, LPDWORD pdwFree)
1032 {
1033     DDSCAPS2 Caps2;
1034     DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
1035
1036     return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw3(This), &Caps2, pdwTotal, pdwFree);
1037 }
1038
1039 static HRESULT WINAPI
1040 IDirectDraw4Impl_GetAvailableVidMem(LPDIRECTDRAW4 This, LPDDSCAPS2 pCaps,
1041                                     LPDWORD pdwTotal, LPDWORD pdwFree)
1042 {
1043     return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw4(This), pCaps, pdwTotal, pdwFree);
1044 }
1045
1046 static HRESULT WINAPI
1047 IDirectDraw3Impl_GetSurfaceFromDC(LPDIRECTDRAW3 This, HDC hDC,
1048                                   LPDIRECTDRAWSURFACE *pSurf)
1049 {
1050     return IDirectDraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw3(This), hDC, (LPDIRECTDRAWSURFACE7 *)pSurf);
1051 }
1052
1053 static HRESULT WINAPI
1054 IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 This, HDC hDC,
1055                                   LPDIRECTDRAWSURFACE4 *pSurf)
1056 {
1057     return IDirectDraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw4(This), hDC, (LPDIRECTDRAWSURFACE7 *)pSurf);
1058 }
1059
1060 static HRESULT WINAPI
1061 IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 This)
1062 {
1063     return IDirectDraw7_RestoreAllSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(This));
1064 }
1065
1066 static HRESULT WINAPI
1067 IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 This)
1068 {
1069     return IDirectDraw7_TestCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(This));
1070 }
1071
1072 static HRESULT WINAPI
1073 IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 This,
1074                                      LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags)
1075 {
1076     DDDEVICEIDENTIFIER2 DDDI2;
1077     HRESULT hr;
1078
1079     hr = IDirectDraw7_GetDeviceIdentifier((IDirectDraw7 *)ddraw_from_ddraw4(This), &DDDI2, dwFlags);
1080
1081     DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(&DDDI2, pDDDI);
1082
1083     return hr;
1084 }
1085
1086 const IDirectDrawVtbl IDirectDraw1_Vtbl =
1087 {
1088     IDirectDrawImpl_QueryInterface,
1089     IDirectDrawImpl_AddRef,
1090     IDirectDrawImpl_Release,
1091     IDirectDrawImpl_Compact,
1092     IDirectDrawImpl_CreateClipper,
1093     IDirectDrawImpl_CreatePalette,
1094     IDirectDrawImpl_CreateSurface,
1095     IDirectDrawImpl_DuplicateSurface,
1096     IDirectDrawImpl_EnumDisplayModes,
1097     IDirectDrawImpl_EnumSurfaces,
1098     IDirectDrawImpl_FlipToGDISurface,
1099     IDirectDrawImpl_GetCaps,
1100     IDirectDrawImpl_GetDisplayMode,
1101     IDirectDrawImpl_GetFourCCCodes,
1102     IDirectDrawImpl_GetGDISurface,
1103     IDirectDrawImpl_GetMonitorFrequency,
1104     IDirectDrawImpl_GetScanLine,
1105     IDirectDrawImpl_GetVerticalBlankStatus,
1106     IDirectDrawImpl_Initialize,
1107     IDirectDrawImpl_RestoreDisplayMode,
1108     IDirectDrawImpl_SetCooperativeLevel,
1109     IDirectDrawImpl_SetDisplayMode,
1110     IDirectDrawImpl_WaitForVerticalBlank,
1111 };
1112
1113 const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
1114 {
1115     IDirectDraw2Impl_QueryInterface,
1116     IDirectDraw2Impl_AddRef,
1117     IDirectDraw2Impl_Release,
1118     IDirectDraw2Impl_Compact,
1119     IDirectDraw2Impl_CreateClipper,
1120     IDirectDraw2Impl_CreatePalette,
1121     IDirectDraw2Impl_CreateSurface,
1122     IDirectDraw2Impl_DuplicateSurface,
1123     IDirectDraw2Impl_EnumDisplayModes,
1124     IDirectDraw2Impl_EnumSurfaces,
1125     IDirectDraw2Impl_FlipToGDISurface,
1126     IDirectDraw2Impl_GetCaps,
1127     IDirectDraw2Impl_GetDisplayMode,
1128     IDirectDraw2Impl_GetFourCCCodes,
1129     IDirectDraw2Impl_GetGDISurface,
1130     IDirectDraw2Impl_GetMonitorFrequency,
1131     IDirectDraw2Impl_GetScanLine,
1132     IDirectDraw2Impl_GetVerticalBlankStatus,
1133     IDirectDraw2Impl_Initialize,
1134     IDirectDraw2Impl_RestoreDisplayMode,
1135     IDirectDraw2Impl_SetCooperativeLevel,
1136     IDirectDraw2Impl_SetDisplayMode,
1137     IDirectDraw2Impl_WaitForVerticalBlank,
1138     IDirectDraw2Impl_GetAvailableVidMem
1139 };
1140
1141 const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
1142 {
1143     IDirectDraw3Impl_QueryInterface,
1144     IDirectDraw3Impl_AddRef,
1145     IDirectDraw3Impl_Release,
1146     IDirectDraw3Impl_Compact,
1147     IDirectDraw3Impl_CreateClipper,
1148     IDirectDraw3Impl_CreatePalette,
1149     IDirectDraw3Impl_CreateSurface,
1150     IDirectDraw3Impl_DuplicateSurface,
1151     IDirectDraw3Impl_EnumDisplayModes,
1152     IDirectDraw3Impl_EnumSurfaces,
1153     IDirectDraw3Impl_FlipToGDISurface,
1154     IDirectDraw3Impl_GetCaps,
1155     IDirectDraw3Impl_GetDisplayMode,
1156     IDirectDraw3Impl_GetFourCCCodes,
1157     IDirectDraw3Impl_GetGDISurface,
1158     IDirectDraw3Impl_GetMonitorFrequency,
1159     IDirectDraw3Impl_GetScanLine,
1160     IDirectDraw3Impl_GetVerticalBlankStatus,
1161     IDirectDraw3Impl_Initialize,
1162     IDirectDraw3Impl_RestoreDisplayMode,
1163     IDirectDraw3Impl_SetCooperativeLevel,
1164     IDirectDraw3Impl_SetDisplayMode,
1165     IDirectDraw3Impl_WaitForVerticalBlank,
1166     IDirectDraw3Impl_GetAvailableVidMem,
1167     IDirectDraw3Impl_GetSurfaceFromDC,
1168 };
1169
1170 const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
1171 {
1172     IDirectDraw4Impl_QueryInterface,
1173     IDirectDraw4Impl_AddRef,
1174     IDirectDraw4Impl_Release,
1175     IDirectDraw4Impl_Compact,
1176     IDirectDraw4Impl_CreateClipper,
1177     IDirectDraw4Impl_CreatePalette,
1178     IDirectDraw4Impl_CreateSurface,
1179     IDirectDraw4Impl_DuplicateSurface,
1180     IDirectDraw4Impl_EnumDisplayModes,
1181     IDirectDraw4Impl_EnumSurfaces,
1182     IDirectDraw4Impl_FlipToGDISurface,
1183     IDirectDraw4Impl_GetCaps,
1184     IDirectDraw4Impl_GetDisplayMode,
1185     IDirectDraw4Impl_GetFourCCCodes,
1186     IDirectDraw4Impl_GetGDISurface,
1187     IDirectDraw4Impl_GetMonitorFrequency,
1188     IDirectDraw4Impl_GetScanLine,
1189     IDirectDraw4Impl_GetVerticalBlankStatus,
1190     IDirectDraw4Impl_Initialize,
1191     IDirectDraw4Impl_RestoreDisplayMode,
1192     IDirectDraw4Impl_SetCooperativeLevel,
1193     IDirectDraw4Impl_SetDisplayMode,
1194     IDirectDraw4Impl_WaitForVerticalBlank,
1195     IDirectDraw4Impl_GetAvailableVidMem,
1196     IDirectDraw4Impl_GetSurfaceFromDC,
1197     IDirectDraw4Impl_RestoreAllSurfaces,
1198     IDirectDraw4Impl_TestCooperativeLevel,
1199     IDirectDraw4Impl_GetDeviceIdentifier
1200 };