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