1 /* DirectDraw IDirectDraw interface (generic)
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
5 * Copyright 2000-2001 TransGaming Technologies Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * WINE currently implements a very basic set of the DirectDraw functionality
24 * in graphics/ddraw.c. This implementation uses either the XFree86-DGA extension
25 * to get very fast access to the graphics card framebuffer and doublebuffering
26 * features or Xlib, which is slower.
27 * The implementation using XFree86-DGA is as fast as the MS equivalent for the
28 * stuff that is implemented.
30 * Several applications already work, see below.
31 * Problems of the implementation using XFree86-DGA:
33 * - XFree86 cannot switch depth on the fly.
34 * This is a problem with X and unavoidable.
35 * Current solution is to pop up a MessageBox with an error for
36 * mismatched parameters and advice the user to restart the X server
37 * with the specified depth.
38 * - The rest of the functionality that has to be implemented will have
39 * to be done in software and will be very slow.
40 * - This requires WINE to be run as root user so XF86DGA can mmap the
41 * framebuffer into the addressspace of the process.
42 * - Blocks all other X windowed applications.
44 * This file contains all the interface functions that are shared between
45 * all interfaces. Or better, it is a "common stub" library for the
46 * IDirectDraw* objects
50 #include "wine/port.h"
56 #define NONAMELESSUNION
57 #define NONAMELESSSTRUCT
65 #include "wine/debug.h"
67 #include "ddraw_private.h"
68 #include "opengl_private.h" /* To have the D3D creation function */
70 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
72 extern const IDirectDrawVtbl DDRAW_IDirectDraw_VTable
;
73 extern const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable
;
74 extern const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable
;
76 static void DDRAW_UnsubclassWindow(IDirectDrawImpl
* This
);
78 static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl
* This
);
79 static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl
* This
);
80 static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl
* This
);
81 static void LosePrimarySurface(IDirectDrawImpl
* This
);
83 static INT32
allocate_memory(IDirectDrawImpl
*This
, DWORD mem
) ;
84 static void free_memory(IDirectDrawImpl
*This
, DWORD mem
) ;
87 static const char ddProp
[] = "WINE_DDRAW_Property";
89 /* Not called from the vtable. */
90 HRESULT
Main_DirectDraw_Construct(IDirectDrawImpl
*This
, BOOL ex
)
92 /* NOTE: The creator must use HEAP_ZERO_MEMORY or equivalent. */
96 if (ex
) This
->local
.dwLocalFlags
|= DDRAWILCL_DIRECTDRAW7
;
97 This
->local
.dwProcessId
= GetCurrentProcessId();
99 This
->final_release
= Main_DirectDraw_final_release
;
101 This
->create_palette
= Main_DirectDrawPalette_Create
;
103 This
->create_offscreen
= Main_create_offscreen
;
104 This
->create_texture
= Main_create_texture
;
105 This
->create_zbuffer
= Main_create_zbuffer
;
106 /* There are no generic versions of create_{primary,backbuffer}. */
108 ICOM_INIT_INTERFACE(This
, IDirectDraw
, DDRAW_IDirectDraw_VTable
);
109 ICOM_INIT_INTERFACE(This
, IDirectDraw2
, DDRAW_IDirectDraw2_VTable
);
110 ICOM_INIT_INTERFACE(This
, IDirectDraw4
, DDRAW_IDirectDraw4_VTable
);
111 /* There is no generic implementation of IDD7 */
113 /* This is for the moment here... */
114 This
->free_memory
= free_memory
;
115 This
->allocate_memory
= allocate_memory
;
116 This
->total_vidmem
= 64 * 1024 * 1024;
117 This
->available_vidmem
= This
->total_vidmem
;
122 void Main_DirectDraw_final_release(IDirectDrawImpl
* This
)
124 if (IsWindow(This
->window
))
126 if (GetPropA(This
->window
, ddProp
))
127 DDRAW_UnsubclassWindow(This
);
129 FIXME("this shouldn't happen, right?\n");
132 Main_DirectDraw_DeleteSurfaces(This
);
133 Main_DirectDraw_DeleteClippers(This
);
134 Main_DirectDraw_DeletePalettes(This
);
135 if (This
->local
.lpGbl
&& This
->local
.lpGbl
->lpExclusiveOwner
== &This
->local
)
137 This
->local
.lpGbl
->lpExclusiveOwner
= NULL
;
138 if (This
->set_exclusive_mode
)
139 This
->set_exclusive_mode(This
, FALSE
);
143 /* There is no Main_DirectDraw_Create. */
145 ULONG WINAPI
Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface
) {
146 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
147 ULONG ref
= InterlockedIncrement(&This
->ref
);
149 TRACE("(%p)->() incrementing from %lu.\n", This
, ref
-1);
154 ULONG WINAPI
Main_DirectDraw_Release(LPDIRECTDRAW7 iface
) {
155 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
156 ULONG ref
= InterlockedDecrement(&This
->ref
);
158 TRACE("(%p)->() decrementing from %lu.\n", This
, ref
+1);
162 if (This
->final_release
!= NULL
)
163 This
->final_release(This
);
165 /* We free the private. This is an artifact of the fact that I don't
166 * have the destructors set up correctly. */
167 if (This
->private != (This
+1))
168 HeapFree(GetProcessHeap(), 0, This
->private);
170 HeapFree(GetProcessHeap(), 0, This
);
176 HRESULT WINAPI
Main_DirectDraw_QueryInterface(
177 LPDIRECTDRAW7 iface
,REFIID refiid
,LPVOID
*obj
179 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
180 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(refiid
), obj
);
182 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
185 if ( IsEqualGUID( &IID_IUnknown
, refiid
)
186 || IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
188 *obj
= ICOM_INTERFACE(This
, IDirectDraw7
);
190 else if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
192 *obj
= ICOM_INTERFACE(This
, IDirectDraw
);
194 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
196 *obj
= ICOM_INTERFACE(This
, IDirectDraw2
);
198 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
200 *obj
= ICOM_INTERFACE(This
, IDirectDraw4
);
203 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ||
204 IsEqualGUID( &IID_IDirect3D2
, refiid
) ||
205 IsEqualGUID( &IID_IDirect3D3
, refiid
) ||
206 IsEqualGUID( &IID_IDirect3D7
, refiid
) )
208 if (opengl_initialized
) {
211 ret_value
= direct3d_create(This
);
212 if (FAILED(ret_value
)) return ret_value
;
214 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
215 *obj
= ICOM_INTERFACE(This
, IDirect3D
);
216 TRACE(" returning Direct3D interface at %p.\n", *obj
);
217 } else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
218 *obj
= ICOM_INTERFACE(This
, IDirect3D2
);
219 TRACE(" returning Direct3D2 interface at %p.\n", *obj
);
220 } else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) ) {
221 *obj
= ICOM_INTERFACE(This
, IDirect3D3
);
222 TRACE(" returning Direct3D3 interface at %p.\n", *obj
);
224 *obj
= ICOM_INTERFACE(This
, IDirect3D7
);
225 TRACE(" returning Direct3D7 interface at %p.\n", *obj
);
228 ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n");
229 ERR("(%p)->(%s,%p): no interface\n",This
,debugstr_guid(refiid
),obj
);
230 return E_NOINTERFACE
;
234 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ||
235 IsEqualGUID( &IID_IDirect3D2
, refiid
) ||
236 IsEqualGUID( &IID_IDirect3D3
, refiid
) ||
237 IsEqualGUID( &IID_IDirect3D7
, refiid
) )
239 ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n");
240 ERR("(%p)->(%s,%p): no interface\n",This
,debugstr_guid(refiid
),obj
);
241 return E_NOINTERFACE
;
246 FIXME("(%p)->(%s,%p): no interface\n",This
,debugstr_guid(refiid
),obj
);
247 return E_NOINTERFACE
;
250 IDirectDraw7_AddRef(iface
);
254 /* MSDN: "not currently implemented". */
255 HRESULT WINAPI
Main_DirectDraw_Compact(LPDIRECTDRAW7 iface
)
257 TRACE("(%p)\n", iface
);
262 HRESULT WINAPI
Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface
,
264 LPDIRECTDRAWCLIPPER
*ppClipper
,
267 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
270 TRACE("(%p)->(0x%lx, %p, %p)\n", iface
, dwFlags
, ppClipper
, pUnkOuter
);
272 hr
= DirectDrawCreateClipper(dwFlags
, ppClipper
, pUnkOuter
);
273 if (FAILED(hr
)) return hr
;
275 /* dwFlags is passed twice, apparently an API wart. */
276 hr
= IDirectDrawClipper_Initialize(*ppClipper
,
277 ICOM_INTERFACE(This
, IDirectDraw
),
281 IDirectDrawClipper_Release(*ppClipper
);
289 Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
290 LPPALETTEENTRY palent
,
291 LPDIRECTDRAWPALETTE
* ppPalette
,
294 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
295 LPDIRECTDRAWPALETTE pPalette
;
298 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ppPalette
,pUnknown
);
300 if (ppPalette
== NULL
) return E_POINTER
; /* unchecked */
301 if (pUnknown
!= NULL
) return CLASS_E_NOAGGREGATION
; /* unchecked */
303 hr
= This
->create_palette(This
, dwFlags
, &pPalette
, pUnknown
);
304 if (FAILED(hr
)) return hr
;
306 hr
= IDirectDrawPalette_SetEntries(pPalette
, 0, 0,
307 Main_DirectDrawPalette_Size(dwFlags
),
311 IDirectDrawPalette_Release(pPalette
);
316 *ppPalette
= pPalette
;
322 Main_create_offscreen(IDirectDrawImpl
* This
, const DDSURFACEDESC2
* pDDSD
,
323 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pOuter
)
325 assert(pOuter
== NULL
);
327 return DIB_DirectDrawSurface_Create(This
, pDDSD
, ppSurf
, pOuter
);
331 Main_create_texture(IDirectDrawImpl
* This
, const DDSURFACEDESC2
* pDDSD
,
332 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pOuter
,
335 assert(pOuter
== NULL
);
337 return DIB_DirectDrawSurface_Create(This
, pDDSD
, ppSurf
, pOuter
);
341 Main_create_zbuffer(IDirectDrawImpl
* This
, const DDSURFACEDESC2
* pDDSD
,
342 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pOuter
)
344 assert(pOuter
== NULL
);
346 return FakeZBuffer_DirectDrawSurface_Create(This
, pDDSD
, ppSurf
, pOuter
);
349 /* Does the texture surface described in pDDSD have any smaller mipmaps? */
350 static BOOL
more_mipmaps(const DDSURFACEDESC2
*pDDSD
)
352 return ((pDDSD
->dwFlags
& DDSD_MIPMAPCOUNT
) && pDDSD
->u2
.dwMipMapCount
> 1
353 && (pDDSD
->dwWidth
> 1 || pDDSD
->dwHeight
> 1));
356 /* Create a texture surface along with any of its mipmaps. */
358 create_texture(IDirectDrawImpl
* This
, const DDSURFACEDESC2
*pDDSD
,
359 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pUnkOuter
)
362 DWORD mipmap_level
= 0;
365 assert(pUnkOuter
== NULL
);
367 /* is this check right? (pixelformat can be copied from primary) */
368 if ((pDDSD
->dwFlags
&(DDSD_HEIGHT
|DDSD_WIDTH
)) != (DDSD_HEIGHT
|DDSD_WIDTH
))
369 return DDERR_INVALIDPARAMS
;
371 ddsd
.dwSize
= sizeof(ddsd
);
372 DD_STRUCT_COPY_BYSIZE((&ddsd
),pDDSD
);
374 if (!(ddsd
.dwFlags
& DDSD_PIXELFORMAT
))
376 ddsd
.u4
.ddpfPixelFormat
= This
->pixelformat
;
380 /* We support for now only DXT1, DXT3 & DXT5 compressed texture formats... */
381 if ((ddsd
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) &&
382 (ddsd
.u4
.ddpfPixelFormat
.dwFourCC
!= MAKE_FOURCC('D','X','T','1')) &&
383 (ddsd
.u4
.ddpfPixelFormat
.dwFourCC
!= MAKE_FOURCC('D','X','T','3')) &&
384 (ddsd
.u4
.ddpfPixelFormat
.dwFourCC
!= MAKE_FOURCC('D','X','T','5')) )
386 return DDERR_INVALIDPIXELFORMAT
;
389 /* Check if we can really support DXT1, DXT3 & DXT5 */
390 if ((ddsd
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) &&
391 !GL_extensions
.s3tc_compressed_texture
&& !s3tc_initialized
) {
392 static BOOLEAN user_warned
= 0;
393 if (user_warned
== 0) {
394 ERR("Trying to create DXT1, DXT3 or DXT5 texture which is not supported by the video card!!!\n");
395 ERR("However there is a library libtxc_dxtn.so that can be used to do the software decompression...\n");
398 return DDERR_INVALIDPIXELFORMAT
;
401 if (ddsd
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
)
403 return DDERR_INVALIDPIXELFORMAT
;
407 if ((ddsd
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) && !(ddsd
.dwFlags
& DDSD_LINEARSIZE
))
410 int width
= ddsd
.dwWidth
;
411 int height
= ddsd
.dwHeight
;
412 switch(ddsd
.u4
.ddpfPixelFormat
.dwFourCC
) {
413 case MAKE_FOURCC('D','X','T','1'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 8; break;
414 case MAKE_FOURCC('D','X','T','3'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 16; break;
415 case MAKE_FOURCC('D','X','T','5'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 16; break;
416 default: FIXME("FOURCC not supported\n"); break;
418 ddsd
.u1
.dwLinearSize
= size
;
419 ddsd
.dwFlags
|= DDSD_LINEARSIZE
;
420 } else if (!(ddsd
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) && !(ddsd
.dwFlags
& DDSD_PITCH
)) {
421 ddsd
.u1
.lPitch
= DDRAW_width_bpp_to_pitch(ddsd
.dwWidth
, GET_BPP(ddsd
)*8);
422 ddsd
.dwFlags
|= DDSD_PITCH
;
425 if((ddsd
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
) &&
426 !(ddsd
.dwFlags
& DDSD_MIPMAPCOUNT
))
428 if(ddsd
.ddsCaps
.dwCaps
& DDSCAPS_COMPLEX
)
430 /* Undocumented feature: if DDSCAPS_MIPMAP and DDSCAPS_COMPLEX are
431 * both set, but mipmap count isn't given, as many mipmap levels
432 * as necessary are created to get down to a size where either
433 * the width or the height of the texture is 1.
435 * This is needed by Anarchy Online. */
436 DWORD min
= ddsd
.dwWidth
< ddsd
.dwHeight
?
437 ddsd
.dwWidth
: ddsd
.dwHeight
;
438 ddsd
.u2
.dwMipMapCount
= 0;
441 ddsd
.u2
.dwMipMapCount
++;
446 /* Create a single mipmap. */
447 ddsd
.u2
.dwMipMapCount
= 1;
449 ddsd
.dwFlags
|= DDSD_MIPMAPCOUNT
;
452 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
454 hr
= This
->create_texture(This
, &ddsd
, ppSurf
, pUnkOuter
, mipmap_level
);
455 if (FAILED(hr
)) return hr
;
457 if (This
->d3d_private
) This
->d3d_create_texture(This
, ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, *ppSurf
), TRUE
,
458 ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, *ppSurf
));
460 /* Create attached mipmaps if required. */
461 if (more_mipmaps(&ddsd
))
463 LPDIRECTDRAWSURFACE7 mipmap
;
464 LPDIRECTDRAWSURFACE7 prev_mipmap
;
465 DDSURFACEDESC2 mipmap_surface_desc
;
467 prev_mipmap
= *ppSurf
;
468 IDirectDrawSurface7_AddRef(prev_mipmap
);
469 mipmap_surface_desc
= ddsd
;
470 mipmap_surface_desc
.ddsCaps
.dwCaps2
|= DDSCAPS2_MIPMAPSUBLEVEL
;
472 while (more_mipmaps(&mipmap_surface_desc
))
474 IDirectDrawSurfaceImpl
*mipmap_impl
;
477 mipmap_surface_desc
.u2
.dwMipMapCount
--;
479 if (mipmap_surface_desc
.dwWidth
> 1)
480 mipmap_surface_desc
.dwWidth
/= 2;
482 if (mipmap_surface_desc
.dwHeight
> 1)
483 mipmap_surface_desc
.dwHeight
/= 2;
485 if (mipmap_surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) {
487 int width
= mipmap_surface_desc
.dwWidth
;
488 int height
= mipmap_surface_desc
.dwHeight
;
489 switch(mipmap_surface_desc
.u4
.ddpfPixelFormat
.dwFourCC
) {
490 case MAKE_FOURCC('D','X','T','1'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 8; break;
491 case MAKE_FOURCC('D','X','T','3'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 16; break;
492 case MAKE_FOURCC('D','X','T','5'): size
= ((width
+3)&~3) * ((height
+3)&~3) / 16 * 16; break;
493 default: FIXME("FOURCC not supported\n"); break;
495 mipmap_surface_desc
.u1
.dwLinearSize
= size
;
497 ddsd
.u1
.lPitch
= DDRAW_width_bpp_to_pitch(ddsd
.dwWidth
, GET_BPP(ddsd
)*8);
498 mipmap_surface_desc
.u1
.lPitch
499 = DDRAW_width_bpp_to_pitch(mipmap_surface_desc
.dwWidth
,
503 hr
= This
->create_texture(This
, &mipmap_surface_desc
, &mipmap
,
504 pUnkOuter
, mipmap_level
);
507 IDirectDrawSurface7_Release(prev_mipmap
);
508 IDirectDrawSurface7_Release(*ppSurf
);
512 /* This is needed for delayed mipmap creation */
513 mipmap_impl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, mipmap
);
514 mipmap_impl
->mip_main
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, *ppSurf
);
515 mipmap_impl
->mipmap_level
= mipmap_level
;
517 if (This
->d3d_private
) This
->d3d_create_texture(This
, ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, mipmap
), TRUE
,
518 ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, *ppSurf
));
520 IDirectDrawSurface7_AddAttachedSurface(prev_mipmap
, mipmap
);
521 IDirectDrawSurface7_Release(prev_mipmap
);
522 prev_mipmap
= mipmap
;
525 IDirectDrawSurface7_Release(prev_mipmap
);
531 /* Creates a primary surface and any indicated backbuffers. */
533 create_primary(IDirectDrawImpl
* This
, LPDDSURFACEDESC2 pDDSD
,
534 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pUnkOuter
)
539 assert(pUnkOuter
== NULL
);
541 if (This
->primary_surface
!= NULL
)
542 return DDERR_PRIMARYSURFACEALREADYEXISTS
;
544 /* as documented (what about pitch?) */
545 if (pDDSD
->dwFlags
& (DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
))
546 return DDERR_INVALIDPARAMS
;
548 ddsd
.dwSize
= sizeof(ddsd
);
549 DD_STRUCT_COPY_BYSIZE((&ddsd
),pDDSD
);
550 ddsd
.dwFlags
|= DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
551 ddsd
.dwHeight
= This
->height
;
552 ddsd
.dwWidth
= This
->width
;
553 ddsd
.u1
.lPitch
= This
->pitch
;
554 ddsd
.u4
.ddpfPixelFormat
= This
->pixelformat
;
555 ddsd
.ddsCaps
.dwCaps
|= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
556 | DDSCAPS_VISIBLE
| DDSCAPS_FRONTBUFFER
;
558 if ((ddsd
.dwFlags
& DDSD_BACKBUFFERCOUNT
) && ddsd
.dwBackBufferCount
> 0)
559 ddsd
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
561 hr
= This
->create_primary(This
, &ddsd
, ppSurf
, pUnkOuter
);
562 if (FAILED(hr
)) return hr
;
564 if (ddsd
.dwFlags
& DDSD_BACKBUFFERCOUNT
)
566 IDirectDrawSurfaceImpl
* primary
;
567 LPDIRECTDRAWSURFACE7 pPrev
;
570 ddsd
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
571 ddsd
.ddsCaps
.dwCaps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
572 | DDSCAPS_BACKBUFFER
| DDSCAPS_FRONTBUFFER
);
574 primary
= ICOM_OBJECT(IDirectDrawSurfaceImpl
,IDirectDrawSurface7
,
577 IDirectDrawSurface7_AddRef(pPrev
);
579 for (i
=0; i
< ddsd
.dwBackBufferCount
; i
++)
581 LPDIRECTDRAWSURFACE7 pBack
;
584 ddsd
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
586 ddsd
.ddsCaps
.dwCaps
&= ~DDSCAPS_BACKBUFFER
;
588 hr
= This
->create_backbuffer(This
, &ddsd
, &pBack
, pUnkOuter
,
593 IDirectDraw7_Release(pPrev
);
594 IDirectDraw7_Release(*ppSurf
);
598 IDirectDrawSurface7_AddAttachedSurface(pPrev
, pBack
);
599 IDirectDrawSurface7_Release(pPrev
);
603 IDirectDrawSurface7_Release(pPrev
);
606 This
->primary_surface
= (IDirectDrawSurfaceImpl
*)*ppSurf
;
612 create_offscreen(IDirectDrawImpl
* This
, LPDDSURFACEDESC2 pDDSD
,
613 LPDIRECTDRAWSURFACE7
* ppSurf
, LPUNKNOWN pUnkOuter
)
618 /* is this check right? (pixelformat can be copied from primary) */
619 if ((pDDSD
->dwFlags
&(DDSD_HEIGHT
|DDSD_WIDTH
)) != (DDSD_HEIGHT
|DDSD_WIDTH
))
620 return DDERR_INVALIDPARAMS
;
622 ddsd
.dwSize
= sizeof(ddsd
);
623 DD_STRUCT_COPY_BYSIZE((&ddsd
),pDDSD
);
625 if (!(ddsd
.dwFlags
& DDSD_PIXELFORMAT
))
627 ddsd
.u4
.ddpfPixelFormat
= This
->pixelformat
;
630 if (!(ddsd
.dwFlags
& DDSD_PITCH
))
632 ddsd
.u1
.lPitch
= DDRAW_width_bpp_to_pitch(ddsd
.dwWidth
,
636 ddsd
.dwFlags
|= DDSD_PITCH
| DDSD_PIXELFORMAT
;
638 hr
= This
->create_offscreen(This
, &ddsd
, ppSurf
, pUnkOuter
);
639 if (FAILED(hr
)) return hr
;
645 Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface
, LPDDSURFACEDESC2 pDDSD
,
646 LPDIRECTDRAWSURFACE7
*ppSurf
,
650 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
652 TRACE("(%p)->(%p,%p,%p)\n",This
,pDDSD
,ppSurf
,pUnkOuter
);
653 if (TRACE_ON(ddraw
)) {
654 TRACE("Requesting surface desc :\n");
655 DDRAW_dump_surface_desc(pDDSD
);
658 if (pUnkOuter
!= NULL
) {
659 FIXME("outer != NULL?\n");
660 return CLASS_E_NOAGGREGATION
; /* unchecked */
663 if (!(pDDSD
->dwFlags
& DDSD_CAPS
)) {
664 /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
665 pDDSD
->dwFlags
|= DDSD_CAPS
;
667 if (pDDSD
->ddsCaps
.dwCaps
== 0) {
668 /* This has been checked on real Windows */
669 pDDSD
->ddsCaps
.dwCaps
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
;
672 if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_ALLOCONLOAD
) {
673 /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
674 pDDSD
->dwFlags
&= ~DDSD_LPSURFACE
;
677 if ((pDDSD
->dwFlags
& DDSD_LPSURFACE
) && (pDDSD
->lpSurface
== NULL
)) {
678 /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */
679 WARN("Null surface pointer specified, ignore it!\n");
680 pDDSD
->dwFlags
&= ~DDSD_LPSURFACE
;
683 if (ppSurf
== NULL
) {
684 FIXME("You want to get back a surface? Don't give NULL ptrs!\n");
685 return E_POINTER
; /* unchecked */
688 if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
690 /* create primary surface & backbuffers */
691 hr
= create_primary(This
, pDDSD
, ppSurf
, pUnkOuter
);
693 else if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_BACKBUFFER
)
695 /* create backbuffer surface */
696 hr
= This
->create_backbuffer(This
, pDDSD
, ppSurf
, pUnkOuter
, NULL
);
698 else if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
)
701 hr
= create_texture(This
, pDDSD
, ppSurf
, pUnkOuter
);
703 else if ( (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
) &&
704 !(pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_OFFSCREENPLAIN
)) /* Support DDSCAPS_SYSTEMMEMORY */
706 /* create z-buffer */
707 hr
= This
->create_zbuffer(This
, pDDSD
, ppSurf
, pUnkOuter
);
709 else if ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_OFFSCREENPLAIN
) ||
710 (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)) /* No difference in Wine right now */
712 /* create offscreenplain surface */
713 hr
= create_offscreen(This
, pDDSD
, ppSurf
, pUnkOuter
);
717 /* Otherwise, assume offscreenplain surface */
718 TRACE("App didn't request a valid surface type - assuming offscreenplain\n");
719 hr
= create_offscreen(This
, pDDSD
, ppSurf
, pUnkOuter
);
723 FIXME("failed surface creation with code 0x%08lx\n",hr
);
731 Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface
, LPDIRECTDRAWSURFACE7 src
,
732 LPDIRECTDRAWSURFACE7
* dst
)
734 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
736 IDirectDrawSurfaceImpl
*pSrc
= ICOM_OBJECT(IDirectDrawSurfaceImpl
,
737 IDirectDrawSurface7
, src
);
739 TRACE("(%p)->(%p,%p)\n",This
,src
,dst
);
741 return pSrc
->duplicate_surface(pSrc
, dst
);
744 /* EnumDisplayModes */
746 BOOL
Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT
*requested
,
747 const DDPIXELFORMAT
*provided
)
749 /* Some flags must be present in both or neither for a match. */
750 static const DWORD must_match
= DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
751 | DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_FOURCC
752 | DDPF_ZBUFFER
| DDPF_STENCILBUFFER
;
754 if ((requested
->dwFlags
& provided
->dwFlags
) != requested
->dwFlags
)
757 if ((requested
->dwFlags
& must_match
) != (provided
->dwFlags
& must_match
))
760 if (requested
->dwFlags
& DDPF_FOURCC
)
761 if (requested
->dwFourCC
!= provided
->dwFourCC
)
764 if (requested
->dwFlags
& (DDPF_RGB
|DDPF_YUV
|DDPF_ZBUFFER
|DDPF_ALPHA
765 |DDPF_LUMINANCE
|DDPF_BUMPDUDV
))
766 if (requested
->u1
.dwRGBBitCount
!= provided
->u1
.dwRGBBitCount
)
769 if (requested
->dwFlags
& (DDPF_RGB
|DDPF_YUV
|DDPF_STENCILBUFFER
770 |DDPF_LUMINANCE
|DDPF_BUMPDUDV
))
771 if (requested
->u2
.dwRBitMask
!= provided
->u2
.dwRBitMask
)
774 if (requested
->dwFlags
& (DDPF_RGB
|DDPF_YUV
|DDPF_ZBUFFER
|DDPF_BUMPDUDV
))
775 if (requested
->u3
.dwGBitMask
!= provided
->u3
.dwGBitMask
)
778 /* I could be wrong about the bumpmapping. MSDN docs are vague. */
779 if (requested
->dwFlags
& (DDPF_RGB
|DDPF_YUV
|DDPF_STENCILBUFFER
781 if (requested
->u4
.dwBBitMask
!= provided
->u4
.dwBBitMask
)
784 if (requested
->dwFlags
& (DDPF_ALPHAPIXELS
|DDPF_ZPIXELS
))
785 if (requested
->u5
.dwRGBAlphaBitMask
!= provided
->u5
.dwRGBAlphaBitMask
)
791 BOOL
Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2
* requested
,
792 const DDSURFACEDESC2
* provided
)
801 #define CMP(FLAG, FIELD) \
802 { DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD), \
803 sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) }
805 static const struct compare_info compare
[] = {
806 CMP(ALPHABITDEPTH
, dwAlphaBitDepth
),
807 CMP(BACKBUFFERCOUNT
, dwBackBufferCount
),
809 CMP(CKDESTBLT
, ddckCKDestBlt
),
810 CMP(CKDESTOVERLAY
, u3
.ddckCKDestOverlay
),
811 CMP(CKSRCBLT
, ddckCKSrcBlt
),
812 CMP(CKSRCOVERLAY
, ddckCKSrcOverlay
),
813 CMP(HEIGHT
, dwHeight
),
814 CMP(LINEARSIZE
, u1
.dwLinearSize
),
815 CMP(LPSURFACE
, lpSurface
),
816 CMP(MIPMAPCOUNT
, u2
.dwMipMapCount
),
817 CMP(PITCH
, u1
.lPitch
),
818 /* PIXELFORMAT: manual */
819 CMP(REFRESHRATE
, u2
.dwRefreshRate
),
820 CMP(TEXTURESTAGE
, dwTextureStage
),
822 /* ZBUFFERBITDEPTH: "obsolete" */
829 if ((requested
->dwFlags
& provided
->dwFlags
) != requested
->dwFlags
)
832 for (i
=0; i
< sizeof(compare
)/sizeof(compare
[0]); i
++)
834 if (requested
->dwFlags
& compare
[i
].flag
835 && memcmp((const char *)provided
+ compare
[i
].offset
,
836 (const char *)requested
+ compare
[i
].offset
,
837 compare
[i
].size
) != 0)
841 if (requested
->dwFlags
& DDSD_PIXELFORMAT
)
843 if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested
->u4
.ddpfPixelFormat
,
844 &provided
->u4
.ddpfPixelFormat
))
851 #define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
852 #define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
854 /* This should be extended so that it can be used by
855 * IDirectDrawSurface7::EnumAttachedSurfaces. */
857 Main_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl
*This
, DWORD dwFlags
,
858 LPDDSURFACEDESC2 lpDDSD2
, LPVOID context
,
859 LPDDENUMSURFACESCALLBACK7 callback
)
861 IDirectDrawSurfaceImpl
*surf
;
864 /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */
865 if (lpDDSD2
== NULL
&& !(dwFlags
& DDENUMSURFACES_ALL
))
866 return DDERR_INVALIDPARAMS
;
868 all
= dwFlags
& DDENUMSURFACES_ALL
;
869 nomatch
= dwFlags
& DDENUMSURFACES_NOMATCH
;
871 for (surf
= This
->surfaces
; surf
!= NULL
; surf
= surf
->next_ddraw
)
874 || (nomatch
!= Main_DirectDraw_DDSD_Match(lpDDSD2
,
875 &surf
->surface_desc
)))
877 LPDIRECTDRAWSURFACE7 isurf
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
880 if (TRACE_ON(ddraw
)) {
881 TRACE(" => enumerating surface %p (priv. %p) with description:\n", isurf
, surf
);
882 DDRAW_dump_surface_desc(&surf
->surface_desc
);
885 IDirectDrawSurface7_AddRef(isurf
);
887 desc
= surf
->surface_desc
;
888 if (callback(isurf
, &desc
, context
) == DDENUMRET_CANCEL
)
892 TRACE(" end of enumeration.\n");
897 /* I really don't understand how this is supposed to work.
898 * We only consider dwHeight, dwWidth and ddpfPixelFormat.dwFlags. */
900 Main_DirectDraw_EnumCreateableSurfaces(IDirectDrawImpl
*This
, DWORD dwFlags
,
901 LPDDSURFACEDESC2 lpDDSD2
,
903 LPDDENUMSURFACESCALLBACK7 callback
)
905 FIXME("This isn't going to work.\n");
907 if ((dwFlags
& DDENUMSURFACES_MATCHTYPE
) != DDENUMSURFACES_MATCH
)
908 return DDERR_INVALIDPARAMS
;
910 /* TODO: implement this.
911 * Does this work before SCL is called?
912 * Does it only consider off-screen surfaces?
918 /* For unsigned x. 0 is not a power of 2. */
919 #define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
922 Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
923 LPDDSURFACEDESC2 lpDDSD2
, LPVOID context
,
924 LPDDENUMSURFACESCALLBACK7 callback
)
926 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
927 TRACE("(%p)->(0x%lx, %p, %p, %p)\n", iface
, dwFlags
, lpDDSD2
, context
,
929 if (TRACE_ON(ddraw
)) {
930 TRACE(" flags: "); DDRAW_dump_DDENUMSURFACES(dwFlags
);
933 if (callback
== NULL
)
934 return DDERR_INVALIDPARAMS
;
936 if (dwFlags
& ~(DDENUMSURFACES_SEARCHTYPE
|DDENUMSURFACES_MATCHTYPE
))
937 return DDERR_INVALIDPARAMS
;
939 if (!IS_POW_2(dwFlags
& DDENUMSURFACES_SEARCHTYPE
)
940 || !IS_POW_2(dwFlags
& DDENUMSURFACES_MATCHTYPE
))
941 return DDERR_INVALIDPARAMS
;
943 if (dwFlags
& DDENUMSURFACES_DOESEXIST
)
945 return Main_DirectDraw_EnumExistingSurfaces(This
, dwFlags
, lpDDSD2
,
950 return Main_DirectDraw_EnumCreateableSurfaces(This
, dwFlags
, lpDDSD2
,
956 Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface
,DWORD a
,DWORD
* b
)
958 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
959 FIXME("(%p)->() stub\n", This
);
965 Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface
)
967 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
968 TRACE("(%p)->()\n",This
);
973 Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface
, LPDDCAPS pDriverCaps
,
976 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
977 TRACE("(%p,%p,%p)\n",This
,pDriverCaps
,pHELCaps
);
978 if (pDriverCaps
!= NULL
) {
979 DD_STRUCT_COPY_BYSIZE(pDriverCaps
,&This
->caps
);
980 if (TRACE_ON(ddraw
)) {
981 TRACE("Driver Caps :\n");
982 DDRAW_dump_DDCAPS(pDriverCaps
);
985 if (pHELCaps
!= NULL
) {
986 DD_STRUCT_COPY_BYSIZE(pHELCaps
,&This
->caps
);
987 if (TRACE_ON(ddraw
)) {
988 TRACE("HEL Caps :\n");
989 DDRAW_dump_DDCAPS(pHELCaps
);
996 /* GetDeviceIdentifier */
1000 Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface
, LPDWORD pNumCodes
,
1003 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1007 FIXME("(%p,%p,%p), stub\n",This
,pNumCodes
,pCodes
);
1012 Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface
,
1013 LPDIRECTDRAWSURFACE7
*lplpGDIDDSSurface
)
1015 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1016 TRACE("(%p)->(%p)\n", This
, lplpGDIDDSSurface
);
1017 TRACE("returning primary (%p)\n", This
->primary_surface
);
1018 *lplpGDIDDSSurface
= ICOM_INTERFACE(This
->primary_surface
, IDirectDrawSurface7
);
1019 if (*lplpGDIDDSSurface
)
1020 IDirectDrawSurface7_AddRef(*lplpGDIDDSSurface
);
1025 Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface
,LPDWORD freq
)
1027 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1028 FIXME("(%p)->(%p) returns 60 Hz always\n",This
,freq
);
1029 *freq
= 60*100; /* 60 Hz */
1034 Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface
, LPDWORD lpdwScanLine
)
1036 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1039 /* Since this method is called often, show the fixme only once */
1041 FIXME("(%p)->(%p) semi-stub\n", This
, lpdwScanLine
);
1045 /* Fake the line sweeping of the monitor */
1046 /* FIXME: We should synchronize with a source to keep the refresh rate */
1047 *lpdwScanLine
= This
->cur_scanline
++;
1048 /* Assume 20 scan lines in the vertical blank */
1049 if (This
->cur_scanline
>= This
->height
+ 20)
1050 This
->cur_scanline
= 0;
1056 Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface
, HDC hdc
,
1057 LPDIRECTDRAWSURFACE7
*lpDDS
)
1059 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1060 FIXME("(%p)->(%p,%p)\n", This
, hdc
, lpDDS
);
1066 Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface
, LPBOOL status
)
1068 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1069 TRACE("(%p)->(%p)\n",This
,status
);
1070 *status
= This
->fake_vblank
;
1071 This
->fake_vblank
= !This
->fake_vblank
;
1075 /* If we were not initialised then Uninit_Main_IDirectDraw7_Initialize would
1076 * have been called instead. */
1078 Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface
, LPGUID lpGuid
)
1080 TRACE("(%p)->(%s)\n", iface
, debugstr_guid(lpGuid
));
1082 return DDERR_ALREADYINITIALIZED
;
1086 Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface
)
1088 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1089 IDirectDrawSurfaceImpl
* surf
;
1091 TRACE("(%p)->()\n", This
);
1093 for (surf
= This
->surfaces
; surf
!= NULL
; surf
= surf
->next_ddraw
)
1094 IDirectDrawSurface7_Restore(ICOM_INTERFACE(surf
, IDirectDrawSurface7
));
1099 static void DDRAW_SubclassWindow(IDirectDrawImpl
* This
)
1101 /* Well we don't actually subclass the window yet. */
1102 SetPropA(This
->window
, ddProp
, This
);
1105 static void DDRAW_UnsubclassWindow(IDirectDrawImpl
* This
)
1107 RemovePropA(This
->window
, ddProp
);
1111 Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface
, HWND hwnd
,
1114 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1116 FIXME("(%p)->(%p,%08lx)\n",This
,hwnd
,cooplevel
);
1117 DDRAW_dump_cooperativelevel(cooplevel
);
1119 /* Makes realMYST test happy. */
1120 if (This
->cooperative_level
== cooplevel
1121 && This
->window
== hwnd
)
1124 /* XXX "It cannot be reset while the process has surfaces or palettes
1125 * created." Otherwise the window can be changed???
1127 * This appears to be wrong - comment it out for now.
1128 * This seems to be true at least for DDSCL_SETFOCUSWINDOW
1129 * It looks like Windows doesn't store the HWND in all cases,
1130 * probably if DDSCL_NORMAL is specified, but that's not sure
1132 return DDERR_HWNDALREADYSET;
1135 /* DDSCL_EXCLUSIVE or DDSCL_NORMAL or DDSCL_SETFOCUSWINDOW must be given */
1136 if (!(cooplevel
& (DDSCL_EXCLUSIVE
|DDSCL_NORMAL
|DDSCL_SETFOCUSWINDOW
)))
1138 ERR("(%p) : Call to SetCooperativeLevel failed: cooplevel != DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This
);
1139 return DDERR_INVALIDPARAMS
;
1141 /* Device window and focus Window. They only really matter in a
1142 * Multi-Monitor application, but some games specify them and we
1143 * have to react correctly. */
1144 if(cooplevel
& DDSCL_SETFOCUSWINDOW
)
1146 /* This flag is a biest: It is only valid when DDSCL_NORMAL has been set
1147 * or no hwnd is set and no other flags are allowed, except DDSCL_NOWINDOWCHANGES
1150 if(!(This
->cooperative_level
& DDSCL_NORMAL
))
1152 ERR("(%p) : Call to SetCooperativeLevel failed: DDSCL_SETFOCUSWINDOW may not be used in Cooplevel %08lx, returning DDERR_HWNDALREADYSET\n",
1153 This
, This
->cooperative_level
);
1154 return DDERR_HWNDALREADYSET
;
1156 if((cooplevel
!= DDSCL_SETFOCUSWINDOW
))
1157 if(cooplevel
!= (DDSCL_SETFOCUSWINDOW
| DDSCL_NOWINDOWCHANGES
) )
1159 ERR("(%p) : Call to SetCooperativeLevel failed: Invalid use of DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This
);
1160 return DDERR_INVALIDPARAMS
;
1163 /* Don't know what exactly to do, but it's perfectly valid
1164 * to pass DDSCL_SETFOCUSWINDOW only */
1165 FIXME("(%p) : Poorly handled flag DDSCL_SETFOCUSWINDOW\n", This
);
1167 /* Store the flag in the cooperative level. I don't think that all other
1168 * flags should be overwritten, so just add it
1169 * (In the most cases this will be DDSCL_SETFOCUSWINDOW | DDSCL_NORMAL) */
1170 cooplevel
|= DDSCL_SETFOCUSWINDOW
;
1175 /* DDSCL_EXCLUSE mode requires DDSCL_FULLSCREEN and vice versa */
1176 if((cooplevel
& DDSCL_EXCLUSIVE
) && !(cooplevel
& DDSCL_FULLSCREEN
))
1177 return DDERR_INVALIDPARAMS
;
1178 /* The other case is checked above */
1180 /* Unhandled flags. Give a warning */
1181 if(cooplevel
& DDSCL_SETDEVICEWINDOW
)
1182 FIXME("(%p) : Unhandled flag DDSCL_SETDEVICEWINDOW.\n", This
);
1183 if(cooplevel
& DDSCL_CREATEDEVICEWINDOW
)
1184 FIXME("(%p) : Unhandled flag DDSCL_CREATEDEVICEWINDOW.\n", This
);
1186 /* Perhaps the hwnd is only set in DDSCL_EXLUSIVE and DDSCL_FULLSCREEN mode. Not sure */
1187 This
->window
= hwnd
;
1188 This
->cooperative_level
= cooplevel
;
1190 This
->local
.hWnd
= (ULONG_PTR
)hwnd
;
1191 This
->local
.dwLocalFlags
|= DDRAWILCL_SETCOOPCALLED
;
1192 /* not entirely sure about these */
1193 if (cooplevel
& DDSCL_EXCLUSIVE
) This
->local
.dwLocalFlags
|= DDRAWILCL_HASEXCLUSIVEMODE
;
1194 if (cooplevel
& DDSCL_FULLSCREEN
) This
->local
.dwLocalFlags
|= DDRAWILCL_ISFULLSCREEN
;
1195 if (cooplevel
& DDSCL_ALLOWMODEX
) This
->local
.dwLocalFlags
|= DDRAWILCL_ALLOWMODEX
;
1196 if (cooplevel
& DDSCL_MULTITHREADED
) This
->local
.dwLocalFlags
|= DDRAWILCL_MULTITHREADED
;
1197 if (cooplevel
& DDSCL_FPUSETUP
) This
->local
.dwLocalFlags
|= DDRAWILCL_FPUSETUP
;
1198 if (cooplevel
& DDSCL_FPUPRESERVE
) This
->local
.dwLocalFlags
|= DDRAWILCL_FPUPRESERVE
;
1200 if (This
->local
.lpGbl
) {
1201 /* assume that this app is the active app (in wine, there's
1202 * probably only one app per global ddraw object anyway) */
1203 if (cooplevel
& DDSCL_EXCLUSIVE
) This
->local
.lpGbl
->lpExclusiveOwner
= &This
->local
;
1204 else if (This
->local
.lpGbl
->lpExclusiveOwner
== &This
->local
)
1205 This
->local
.lpGbl
->lpExclusiveOwner
= NULL
;
1206 if (This
->set_exclusive_mode
)
1207 This
->set_exclusive_mode(This
, (cooplevel
& DDSCL_EXCLUSIVE
) != 0);
1210 ShowWindow(hwnd
, SW_SHOW
);
1212 DDRAW_SubclassWindow(This
);
1214 /* TODO Does it also get resized to the current screen size? */
1220 Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface
, DWORD dwWidth
,
1221 DWORD dwHeight
, LONG lPitch
,
1222 DWORD dwRefreshRate
, DWORD dwFlags
,
1223 const DDPIXELFORMAT
* pixelformat
)
1228 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1230 TRACE("(%p)->SetDisplayMode(%ld,%ld)\n",This
,dwWidth
,dwHeight
);
1232 if (!(This
->cooperative_level
& DDSCL_EXCLUSIVE
))
1233 return DDERR_NOEXCLUSIVEMODE
;
1235 if (!IsWindow(This
->window
))
1236 return DDERR_GENERIC
; /* unchecked */
1238 LosePrimarySurface(This
);
1240 screenX
= GetSystemMetrics(SM_CXSCREEN
);
1241 screenY
= GetSystemMetrics(SM_CYSCREEN
);
1243 This
->width
= dwWidth
;
1244 This
->height
= dwHeight
;
1245 This
->pitch
= lPitch
;
1246 This
->pixelformat
= *pixelformat
;
1248 /* Position the window in the center of the screen - don't center for now */
1249 /* MoveWindow(This->window, (screenX-dwWidth)/2, (screenY-dwHeight)/2,
1250 dwWidth, dwHeight, TRUE);*/
1251 MoveWindow(This
->window
, 0, 0, dwWidth
, dwHeight
, TRUE
);
1253 SetFocus(This
->window
);
1259 Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface
)
1261 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1263 TRACE("(%p)\n",This
);
1264 if (!(This
->cooperative_level
& DDSCL_EXCLUSIVE
))
1265 return DDERR_NOEXCLUSIVEMODE
;
1267 /* Lose the primary surface if the resolution changes. */
1268 if (This
->orig_width
!= This
->width
|| This
->orig_height
!= This
->height
1269 || This
->orig_pitch
!= This
->pitch
1270 || This
->orig_pixelformat
.dwFlags
!= This
->pixelformat
.dwFlags
1271 || !Main_DirectDraw_DDPIXELFORMAT_Match(&This
->pixelformat
,
1272 &This
->orig_pixelformat
))
1274 LosePrimarySurface(This
);
1277 /* TODO Move the window back where it belongs. */
1283 Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1286 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1287 FIXME("(%p)->(flags=0x%08lx,handle=%p)\n",This
,dwFlags
,h
);
1292 Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface
, LPDDSURFACEDESC2 pDDSD
)
1294 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1295 TRACE("(%p)->GetDisplayMode(%p)\n",This
,pDDSD
);
1297 pDDSD
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_PIXELFORMAT
|DDSD_REFRESHRATE
;
1298 pDDSD
->dwHeight
= This
->height
;
1299 pDDSD
->dwWidth
= This
->width
;
1300 pDDSD
->u1
.lPitch
= This
->pitch
;
1301 pDDSD
->u2
.dwRefreshRate
= 60;
1302 pDDSD
->u4
.ddpfPixelFormat
= This
->pixelformat
;
1303 pDDSD
->ddsCaps
.dwCaps
= 0;
1308 static INT32
allocate_memory(IDirectDrawImpl
*This
, DWORD mem
)
1310 if (mem
> This
->available_vidmem
) return -1;
1311 This
->available_vidmem
-= mem
;
1312 return This
->available_vidmem
;
1315 static void free_memory(IDirectDrawImpl
*This
, DWORD mem
)
1317 This
->available_vidmem
+= mem
;
1321 Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface
, LPDDSCAPS2 ddscaps
,
1322 LPDWORD total
, LPDWORD free
)
1324 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1325 TRACE("(%p)->(%p,%p,%p)\n", This
,ddscaps
,total
,free
);
1327 if (TRACE_ON(ddraw
)) {
1328 TRACE(" Asking for memory of type : ");
1329 DDRAW_dump_DDSCAPS2(ddscaps
); TRACE("\n");
1332 /* We have 16 MB videomemory */
1333 if (total
) *total
= This
->total_vidmem
;
1334 if (free
) *free
= This
->available_vidmem
;
1336 TRACE(" returning (total) %ld / (free) %ld\n",
1337 total
!= NULL
? *total
: 0,
1338 free
!= NULL
? *free
: 0);
1343 HRESULT WINAPI
Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface
) {
1344 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1345 TRACE("(%p)->(): stub\n", This
);
1351 Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface
, LPSIZE pModes
,
1352 DWORD dwNumModes
, DWORD dwFlags
)
1354 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1355 FIXME("(%p)->() stub\n", This
);
1360 /*** Owned object management. */
1362 void Main_DirectDraw_AddSurface(IDirectDrawImpl
* This
,
1363 IDirectDrawSurfaceImpl
* surface
)
1365 assert(surface
->ddraw_owner
== NULL
|| surface
->ddraw_owner
== This
);
1367 surface
->ddraw_owner
= This
;
1369 /* where should it go? */
1370 surface
->next_ddraw
= This
->surfaces
;
1371 surface
->prev_ddraw
= NULL
;
1373 This
->surfaces
->prev_ddraw
= surface
;
1374 This
->surfaces
= surface
;
1377 void Main_DirectDraw_RemoveSurface(IDirectDrawImpl
* This
,
1378 IDirectDrawSurfaceImpl
* surface
)
1380 assert(surface
->ddraw_owner
== This
);
1382 if (This
->surfaces
== surface
)
1383 This
->surfaces
= surface
->next_ddraw
;
1385 if (This
->primary_surface
== surface
)
1386 This
->primary_surface
= NULL
;
1388 if (surface
->next_ddraw
)
1389 surface
->next_ddraw
->prev_ddraw
= surface
->prev_ddraw
;
1390 if (surface
->prev_ddraw
)
1391 surface
->prev_ddraw
->next_ddraw
= surface
->next_ddraw
;
1394 static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl
* This
)
1396 while (This
->surfaces
!= NULL
)
1397 Main_DirectDrawSurface_ForceDestroy(This
->surfaces
);
1400 void Main_DirectDraw_AddClipper(IDirectDrawImpl
* This
,
1401 IDirectDrawClipperImpl
* clipper
)
1403 assert(clipper
->ddraw_owner
== NULL
|| clipper
->ddraw_owner
== This
);
1405 clipper
->ddraw_owner
= This
;
1407 clipper
->next_ddraw
= This
->clippers
;
1408 clipper
->prev_ddraw
= NULL
;
1410 This
->clippers
->prev_ddraw
= clipper
;
1411 This
->clippers
= clipper
;
1414 void Main_DirectDraw_RemoveClipper(IDirectDrawImpl
* This
,
1415 IDirectDrawClipperImpl
* clipper
)
1417 assert(clipper
->ddraw_owner
== This
);
1419 if (This
->clippers
== clipper
)
1420 This
->clippers
= clipper
->next_ddraw
;
1422 if (clipper
->next_ddraw
)
1423 clipper
->next_ddraw
->prev_ddraw
= clipper
->prev_ddraw
;
1424 if (clipper
->prev_ddraw
)
1425 clipper
->prev_ddraw
->next_ddraw
= clipper
->next_ddraw
;
1428 static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl
* This
)
1430 while (This
->clippers
!= NULL
)
1431 Main_DirectDrawClipper_ForceDestroy(This
->clippers
);
1434 void Main_DirectDraw_AddPalette(IDirectDrawImpl
* This
,
1435 IDirectDrawPaletteImpl
* palette
)
1437 assert(palette
->ddraw_owner
== NULL
|| palette
->ddraw_owner
== This
);
1439 palette
->ddraw_owner
= This
;
1441 /* where should it go? */
1442 palette
->next_ddraw
= This
->palettes
;
1443 palette
->prev_ddraw
= NULL
;
1445 This
->palettes
->prev_ddraw
= palette
;
1446 This
->palettes
= palette
;
1449 void Main_DirectDraw_RemovePalette(IDirectDrawImpl
* This
,
1450 IDirectDrawPaletteImpl
* palette
)
1452 IDirectDrawSurfaceImpl
*surf
;
1454 assert(palette
->ddraw_owner
== This
);
1456 if (This
->palettes
== palette
)
1457 This
->palettes
= palette
->next_ddraw
;
1459 if (palette
->next_ddraw
)
1460 palette
->next_ddraw
->prev_ddraw
= palette
->prev_ddraw
;
1461 if (palette
->prev_ddraw
)
1462 palette
->prev_ddraw
->next_ddraw
= palette
->next_ddraw
;
1464 /* Here we need also to remove tha palette from any surface which has it as the
1465 * current palette (checked on Windows)
1467 for (surf
= This
->surfaces
; surf
!= NULL
; surf
= surf
->next_ddraw
) {
1468 if (surf
->palette
== palette
) {
1469 TRACE("Palette %p attached to surface %p.\n", palette
, surf
);
1470 surf
->palette
= NULL
;
1471 surf
->set_palette(surf
, NULL
);
1476 static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl
* This
)
1478 while (This
->palettes
!= NULL
)
1479 Main_DirectDrawPalette_ForceDestroy(This
->palettes
);
1485 LoseSurface(IDirectDrawSurfaceImpl
*surface
)
1487 if (surface
!= NULL
) surface
->lose_surface(surface
);
1491 LosePrimarySurface(IDirectDrawImpl
*This
)
1493 /* MSDN: "If another application changes the display mode, the primary
1494 * surface is lost, and the method returns DDERR_SURFACELOST until the
1495 * primary surface is recreated to match the new display mode."
1497 * We mark all the primary surfaces as lost as soon as the display
1498 * mode is changed (by any application). */
1500 LoseSurface(This
->primary_surface
);
1503 /******************************************************************************
1504 * Uninitialised DirectDraw functions
1506 * This vtable is used when a DirectDraw object is created with
1507 * CoCreateInstance. The only usable method is Initialize.
1510 void Uninit_DirectDraw_final_release(IDirectDrawImpl
*This
)
1512 Main_DirectDraw_final_release(This
);
1515 static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable
;
1517 /* Not called from the vtable. */
1518 HRESULT
Uninit_DirectDraw_Construct(IDirectDrawImpl
*This
, BOOL ex
)
1522 hr
= Main_DirectDraw_Construct(This
, ex
);
1523 if (FAILED(hr
)) return hr
;
1525 This
->final_release
= Uninit_DirectDraw_final_release
;
1526 ICOM_INIT_INTERFACE(This
, IDirectDraw7
, Uninit_DirectDraw_VTable
);
1531 HRESULT
Uninit_DirectDraw_Create(const GUID
* pGUID
,
1532 LPDIRECTDRAW7
* pIface
,
1533 IUnknown
* pUnkOuter
, BOOL ex
)
1536 IDirectDrawImpl
* This
;
1538 assert(pUnkOuter
== NULL
); /* XXX no: we must check this */
1540 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1541 sizeof(IDirectDrawImpl
));
1542 if (This
== NULL
) return E_OUTOFMEMORY
;
1544 hr
= Uninit_DirectDraw_Construct(This
, ex
);
1546 HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
);
1548 *pIface
= ICOM_INTERFACE(This
, IDirectDraw7
);
1553 static HRESULT WINAPI
1554 Uninit_DirectDraw_Initialize(LPDIRECTDRAW7 iface
, LPGUID pDeviceGuid
)
1556 const ddraw_driver
* driver
;
1557 IDirectDrawImpl
*This
= (IDirectDrawImpl
*)iface
;
1559 TRACE("(%p)->(%p)\n", iface
, pDeviceGuid
);
1561 driver
= DDRAW_FindDriver(pDeviceGuid
);
1562 /* XXX This return value is not documented. (Not checked.) */
1563 if (driver
== NULL
) return DDERR_INVALIDDIRECTDRAWGUID
;
1565 return driver
->init(This
, pDeviceGuid
);
1568 static HRESULT WINAPI
1569 Uninit_DirectDraw_Compact(LPDIRECTDRAW7 iface
)
1571 return DDERR_NOTINITIALIZED
;
1574 static HRESULT WINAPI
1575 Uninit_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1576 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1577 IUnknown
*pUnkOuter
)
1580 return DDERR_NOTINITIALIZED
;
1583 static HRESULT WINAPI
1584 Uninit_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1585 LPPALETTEENTRY lpColorTable
,
1586 LPDIRECTDRAWPALETTE
*lplpDDPalette
,
1587 IUnknown
*pUnkOuter
)
1589 return DDERR_NOTINITIALIZED
;
1592 static HRESULT WINAPI
1593 Uninit_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface
,
1594 LPDDSURFACEDESC2 lpDDSurfaceDesc
,
1595 LPDIRECTDRAWSURFACE7
*lplpDDSurface
,
1596 IUnknown
*pUnkOuter
)
1598 return DDERR_NOTINITIALIZED
;
1601 static HRESULT WINAPI
1602 Uninit_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface
,
1603 LPDIRECTDRAWSURFACE7 pSurf
,
1604 LPDIRECTDRAWSURFACE7
*pDupSurf
)
1607 return DDERR_NOTINITIALIZED
;
1610 static HRESULT WINAPI
1611 Uninit_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1612 LPDDSURFACEDESC2 lpDDSD
,
1614 LPDDENUMMODESCALLBACK2 cb
)
1616 return DDERR_NOTINITIALIZED
;
1619 static HRESULT WINAPI
1620 Uninit_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1621 LPDDSURFACEDESC2 pDDSD
, LPVOID context
,
1622 LPDDENUMSURFACESCALLBACK7 cb
)
1624 return DDERR_NOTINITIALIZED
;
1627 static HRESULT WINAPI
1628 Uninit_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface
)
1630 return DDERR_NOTINITIALIZED
;
1633 static HRESULT WINAPI
1634 Uninit_DirectDraw_GetCaps(LPDIRECTDRAW7 iface
, LPDDCAPS pDriverCaps
,
1637 return DDERR_NOTINITIALIZED
;
1640 static HRESULT WINAPI
1641 Uninit_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface
,
1642 LPDDSURFACEDESC2 pDDSD
)
1644 return DDERR_NOTINITIALIZED
;
1647 static HRESULT WINAPI
1648 Uninit_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface
, LPDWORD pNumCodes
,
1651 return DDERR_NOTINITIALIZED
;
1654 static HRESULT WINAPI
1655 Uninit_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface
,
1656 LPDIRECTDRAWSURFACE7
*pGDISurf
)
1658 return DDERR_NOTINITIALIZED
;
1661 static HRESULT WINAPI
1662 Uninit_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface
, LPDWORD pdwFreq
)
1664 return DDERR_NOTINITIALIZED
;
1667 static HRESULT WINAPI
1668 Uninit_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface
, LPDWORD pdwScanLine
)
1670 return DDERR_NOTINITIALIZED
;
1673 static HRESULT WINAPI
1674 Uninit_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface
, PBOOL pbIsInVB
)
1676 return DDERR_NOTINITIALIZED
;
1679 static HRESULT WINAPI
1680 Uninit_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface
)
1682 return DDERR_NOTINITIALIZED
;
1685 static HRESULT WINAPI
1686 Uninit_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface
, HWND hWnd
,
1689 return DDERR_NOTINITIALIZED
;
1692 static HRESULT WINAPI
1693 Uninit_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface
, DWORD dwWidth
,
1694 DWORD dwHeight
, DWORD dwBPP
,
1695 DWORD dwRefreshRate
, DWORD dwFlags
)
1697 return DDERR_NOTINITIALIZED
;
1700 static HRESULT WINAPI
1701 Uninit_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1704 return DDERR_NOTINITIALIZED
;
1707 static HRESULT WINAPI
1708 Uninit_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface
, LPDDSCAPS2 pDDCaps
,
1709 LPDWORD pdwTotal
, LPDWORD pdwFree
)
1711 return DDERR_NOTINITIALIZED
;
1714 static HRESULT WINAPI
1715 Uninit_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface
, HDC hDC
,
1716 LPDIRECTDRAWSURFACE7
*pSurf
)
1718 return DDERR_NOTINITIALIZED
;
1721 static HRESULT WINAPI
1722 Uninit_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface
)
1724 return DDERR_NOTINITIALIZED
;
1727 static HRESULT WINAPI
1728 Uninit_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface
)
1730 return DDERR_NOTINITIALIZED
;
1733 static HRESULT WINAPI
1734 Uninit_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface
,
1735 LPDDDEVICEIDENTIFIER2 pDDDI
,
1738 return DDERR_NOTINITIALIZED
;
1741 static HRESULT WINAPI
1742 Uninit_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface
, LPSIZE pszModes
,
1743 DWORD cModes
, DWORD dwFlags
)
1745 return DDERR_NOTINITIALIZED
;
1748 static HRESULT WINAPI
1749 Uninit_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface
, DWORD dwFlags
,
1752 return DDERR_NOTINITIALIZED
;
1755 static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable
=
1757 Main_DirectDraw_QueryInterface
,
1758 Main_DirectDraw_AddRef
,
1759 Main_DirectDraw_Release
,
1760 Uninit_DirectDraw_Compact
,
1761 Uninit_DirectDraw_CreateClipper
,
1762 Uninit_DirectDraw_CreatePalette
,
1763 Uninit_DirectDraw_CreateSurface
,
1764 Uninit_DirectDraw_DuplicateSurface
,
1765 Uninit_DirectDraw_EnumDisplayModes
,
1766 Uninit_DirectDraw_EnumSurfaces
,
1767 Uninit_DirectDraw_FlipToGDISurface
,
1768 Uninit_DirectDraw_GetCaps
,
1769 Uninit_DirectDraw_GetDisplayMode
,
1770 Uninit_DirectDraw_GetFourCCCodes
,
1771 Uninit_DirectDraw_GetGDISurface
,
1772 Uninit_DirectDraw_GetMonitorFrequency
,
1773 Uninit_DirectDraw_GetScanLine
,
1774 Uninit_DirectDraw_GetVerticalBlankStatus
,
1775 Uninit_DirectDraw_Initialize
,
1776 Uninit_DirectDraw_RestoreDisplayMode
,
1777 Uninit_DirectDraw_SetCooperativeLevel
,
1778 Uninit_DirectDraw_SetDisplayMode
,
1779 Uninit_DirectDraw_WaitForVerticalBlank
,
1780 Uninit_DirectDraw_GetAvailableVidMem
,
1781 Uninit_DirectDraw_GetSurfaceFromDC
,
1782 Uninit_DirectDraw_RestoreAllSurfaces
,
1783 Uninit_DirectDraw_TestCooperativeLevel
,
1784 Uninit_DirectDraw_GetDeviceIdentifier
,
1785 Uninit_DirectDraw_StartModeTest
,
1786 Uninit_DirectDraw_EvaluateMode