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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
64 #include "wine/debug.h"
66 #include "ddraw_private.h"
67 #include "mesa_private.h" /* To have the D3D creation function */
68 #include "ddraw/main.h"
69 #include "dclipper/main.h"
70 #include "dpalette/main.h"
71 #include "dsurface/main.h"
72 #include "dsurface/dib.h"
73 #include "dsurface/fakezbuffer.h"
75 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
77 extern ICOM_VTABLE(IDirectDraw) DDRAW_IDirectDraw_VTable;
78 extern ICOM_VTABLE(IDirectDraw2) DDRAW_IDirectDraw2_VTable;
79 extern ICOM_VTABLE(IDirectDraw4) DDRAW_IDirectDraw4_VTable;
81 static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This);
83 static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This);
84 static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This);
85 static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This);
86 static void LosePrimarySurface(IDirectDrawImpl* This);
88 static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) ;
89 static void free_memory(IDirectDrawImpl *This, DWORD mem) ;
92 static const char ddProp[] = "WINE_DDRAW_Property";
94 /* Not called from the vtable. */
95 HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
97 /* NOTE: The creator must use HEAP_ZERO_MEMORY or equivalent. */
101 if (ex) This->local.dwLocalFlags |= DDRAWILCL_DIRECTDRAW7;
102 This->local.dwProcessId = GetCurrentProcessId();
104 This->final_release = Main_DirectDraw_final_release;
106 This->create_palette = Main_DirectDrawPalette_Create;
108 This->create_offscreen = Main_create_offscreen;
109 This->create_texture = Main_create_texture;
110 This->create_zbuffer = Main_create_zbuffer;
111 /* There are no generic versions of create_{primary,backbuffer}. */
113 ICOM_INIT_INTERFACE(This, IDirectDraw, DDRAW_IDirectDraw_VTable);
114 ICOM_INIT_INTERFACE(This, IDirectDraw2, DDRAW_IDirectDraw2_VTable);
115 ICOM_INIT_INTERFACE(This, IDirectDraw4, DDRAW_IDirectDraw4_VTable);
116 /* There is no generic implementation of IDD7 */
118 /* This is for the moment here... */
119 This->free_memory = free_memory;
120 This->allocate_memory = allocate_memory;
121 This->total_vidmem = 16 * 1024 * 1024;
122 This->available_vidmem = This->total_vidmem;
127 void Main_DirectDraw_final_release(IDirectDrawImpl* This)
129 if (IsWindow(This->window))
131 if (GetPropA(This->window, ddProp))
132 DDRAW_UnsubclassWindow(This);
134 FIXME("this shouldn't happen, right?\n");
137 Main_DirectDraw_DeleteSurfaces(This);
138 Main_DirectDraw_DeleteClippers(This);
139 Main_DirectDraw_DeletePalettes(This);
140 if (This->local.lpGbl && This->local.lpGbl->lpExclusiveOwner == &This->local)
142 This->local.lpGbl->lpExclusiveOwner = NULL;
143 if (This->set_exclusive_mode)
144 This->set_exclusive_mode(This, FALSE);
148 /* There is no Main_DirectDraw_Create. */
150 ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface) {
151 ICOM_THIS(IDirectDrawImpl,iface);
152 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
157 ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface) {
159 ICOM_THIS(IDirectDrawImpl,iface);
160 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
166 if (This->final_release != NULL)
167 This->final_release(This);
169 /* We free the private. This is an artifact of the fact that I don't
170 * have the destructors set up correctly. */
171 if (This->private != (This+1))
172 HeapFree(GetProcessHeap(), 0, This->private);
174 HeapFree(GetProcessHeap(), 0, This);
180 HRESULT WINAPI Main_DirectDraw_QueryInterface(
181 LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj
183 ICOM_THIS(IDirectDrawImpl,iface);
184 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
186 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
189 if ( IsEqualGUID( &IID_IUnknown, refiid )
190 || IsEqualGUID( &IID_IDirectDraw7, refiid ) )
192 *obj = ICOM_INTERFACE(This, IDirectDraw7);
194 else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
196 *obj = ICOM_INTERFACE(This, IDirectDraw);
198 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
200 *obj = ICOM_INTERFACE(This, IDirectDraw2);
202 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
204 *obj = ICOM_INTERFACE(This, IDirectDraw4);
207 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
208 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
209 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
210 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
212 if (opengl_initialized) {
215 ret_value = direct3d_create(This);
216 if (FAILED(ret_value)) return ret_value;
218 if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) {
219 *obj = ICOM_INTERFACE(This, IDirect3D);
220 TRACE(" returning Direct3D interface at %p.\n", *obj);
221 } else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) {
222 *obj = ICOM_INTERFACE(This, IDirect3D2);
223 TRACE(" returning Direct3D2 interface at %p.\n", *obj);
224 } else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) {
225 *obj = ICOM_INTERFACE(This, IDirect3D3);
226 TRACE(" returning Direct3D3 interface at %p.\n", *obj);
228 *obj = ICOM_INTERFACE(This, IDirect3D7);
229 TRACE(" returning Direct3D7 interface at %p.\n", *obj);
232 ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n");
233 ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
234 return E_NOINTERFACE;
238 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
239 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
240 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
241 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
243 ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n");
244 ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
245 return E_NOINTERFACE;
250 FIXME("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
251 return E_NOINTERFACE;
254 IDirectDraw7_AddRef(iface);
258 /* MSDN: "not currently implemented". */
259 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
261 TRACE("(%p)\n", iface);
266 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface,
268 LPDIRECTDRAWCLIPPER *ppClipper,
271 ICOM_THIS(IDirectDrawImpl, iface);
274 TRACE("(%p)->(0x%lx, %p, %p)\n", iface, dwFlags, ppClipper, pUnkOuter);
276 hr = DirectDrawCreateClipper(dwFlags, ppClipper, pUnkOuter);
277 if (FAILED(hr)) return hr;
279 /* dwFlags is passed twice, apparently an API wart. */
280 hr = IDirectDrawClipper_Initialize(*ppClipper,
281 ICOM_INTERFACE(This, IDirectDraw),
285 IDirectDrawClipper_Release(*ppClipper);
293 Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
294 LPPALETTEENTRY palent,
295 LPDIRECTDRAWPALETTE* ppPalette,
298 ICOM_THIS(IDirectDrawImpl,iface);
299 LPDIRECTDRAWPALETTE pPalette;
302 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ppPalette,pUnknown);
304 if (ppPalette == NULL) return E_POINTER; /* unchecked */
305 if (pUnknown != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */
307 hr = This->create_palette(This, dwFlags, &pPalette, pUnknown);
308 if (FAILED(hr)) return hr;
310 hr = IDirectDrawPalette_SetEntries(pPalette, 0, 0,
311 Main_DirectDrawPalette_Size(dwFlags),
315 IDirectDrawPalette_Release(pPalette);
320 *ppPalette = pPalette;
326 Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
327 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
329 assert(pOuter == NULL);
331 return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
335 Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
336 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,
339 assert(pOuter == NULL);
341 return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
345 Main_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
346 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
348 assert(pOuter == NULL);
350 return FakeZBuffer_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
353 /* Does the texture surface described in pDDSD have any smaller mipmaps? */
354 static BOOL more_mipmaps(const DDSURFACEDESC2 *pDDSD)
356 return ((pDDSD->dwFlags & DDSD_MIPMAPCOUNT) && pDDSD->u2.dwMipMapCount > 1
357 && (pDDSD->dwWidth > 1 || pDDSD->dwHeight > 1));
360 /* Create a texture surface along with any of its mipmaps. */
362 create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
363 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
366 DWORD mipmap_level = 0;
369 assert(pUnkOuter == NULL);
371 /* is this check right? (pixelformat can be copied from primary) */
372 if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
373 return DDERR_INVALIDPARAMS;
375 ddsd.dwSize = sizeof(ddsd);
376 DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
378 if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
380 ddsd.u4.ddpfPixelFormat = This->pixelformat;
383 /* We do not support for now compressed texture formats... */
384 if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
386 return DDERR_INVALIDPIXELFORMAT;
389 if (!(ddsd.dwFlags & DDSD_PITCH))
391 ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,
395 /* Check also for the MIPMAP / MIPMAPCOUNT flags.
396 As checked on Windows, this is the right behaviour. No mipmaps seem to be generated. */
397 if (((ddsd.dwFlags & DDSD_MIPMAPCOUNT) == 0) &&
398 ((ddsd.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != 0)) {
399 ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
400 ddsd.u2.dwMipMapCount = 1;
403 ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT;
405 hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
406 if (FAILED(hr)) return hr;
408 if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
409 ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
411 /* Create attached mipmaps if required. */
412 if (more_mipmaps(&ddsd))
414 LPDIRECTDRAWSURFACE7 mipmap;
415 LPDIRECTDRAWSURFACE7 prev_mipmap;
416 DDSURFACEDESC2 mipmap_surface_desc;
418 prev_mipmap = *ppSurf;
419 IDirectDrawSurface7_AddRef(prev_mipmap);
420 mipmap_surface_desc = ddsd;
421 mipmap_surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
423 while (more_mipmaps(&mipmap_surface_desc))
425 IDirectDrawSurfaceImpl *mipmap_impl;
428 mipmap_surface_desc.u2.dwMipMapCount--;
430 if (mipmap_surface_desc.dwWidth > 1)
431 mipmap_surface_desc.dwWidth /= 2;
433 if (mipmap_surface_desc.dwHeight > 1)
434 mipmap_surface_desc.dwHeight /= 2;
436 mipmap_surface_desc.u1.lPitch
437 = DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth,
440 hr = This->create_texture(This, &mipmap_surface_desc, &mipmap,
441 pUnkOuter, mipmap_level);
444 IDirectDrawSurface7_Release(prev_mipmap);
445 IDirectDrawSurface7_Release(*ppSurf);
449 /* This is needed for delayed mipmap creation */
450 mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap);
451 mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf);
452 mipmap_impl->mipmap_level = mipmap_level;
454 if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE,
455 ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
457 IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
458 IDirectDrawSurface7_Release(prev_mipmap);
459 prev_mipmap = mipmap;
462 IDirectDrawSurface7_Release(prev_mipmap);
468 /* Creates a primary surface and any indicated backbuffers. */
470 create_primary(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
471 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
476 assert(pUnkOuter == NULL);
478 if (This->primary_surface != NULL)
479 return DDERR_PRIMARYSURFACEALREADYEXISTS;
481 /* as documented (what about pitch?) */
482 if (pDDSD->dwFlags & (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT))
483 return DDERR_INVALIDPARAMS;
485 ddsd.dwSize = sizeof(ddsd);
486 DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
487 ddsd.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
488 ddsd.dwHeight = This->height;
489 ddsd.dwWidth = This->width;
490 ddsd.u1.lPitch = This->pitch;
491 ddsd.u4.ddpfPixelFormat = This->pixelformat;
492 ddsd.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY
493 | DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER;
495 if ((ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) && ddsd.dwBackBufferCount > 0)
496 ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP;
498 hr = This->create_primary(This, &ddsd, ppSurf, pUnkOuter);
499 if (FAILED(hr)) return hr;
501 if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT)
503 IDirectDrawSurfaceImpl* primary;
504 LPDIRECTDRAWSURFACE7 pPrev;
507 ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
508 ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE
509 | DDSCAPS_BACKBUFFER | DDSCAPS_FRONTBUFFER);
511 primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7,
514 IDirectDrawSurface7_AddRef(pPrev);
516 for (i=0; i < ddsd.dwBackBufferCount; i++)
518 LPDIRECTDRAWSURFACE7 pBack;
521 ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
523 ddsd.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
525 hr = This->create_backbuffer(This, &ddsd, &pBack, pUnkOuter,
530 IDirectDraw7_Release(pPrev);
531 IDirectDraw7_Release(*ppSurf);
535 IDirectDrawSurface7_AddAttachedSurface(pPrev, pBack);
536 IDirectDrawSurface7_Release(pPrev);
540 IDirectDrawSurface7_Release(pPrev);
543 This->primary_surface = (IDirectDrawSurfaceImpl *)*ppSurf;
549 create_offscreen(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
550 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
555 /* is this check right? (pixelformat can be copied from primary) */
556 if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
557 return DDERR_INVALIDPARAMS;
559 ddsd.dwSize = sizeof(ddsd);
560 DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
562 if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
564 ddsd.u4.ddpfPixelFormat = This->pixelformat;
567 if (!(ddsd.dwFlags & DDSD_PITCH))
569 ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,
573 ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT;
575 hr = This->create_offscreen(This, &ddsd, ppSurf, pUnkOuter);
576 if (FAILED(hr)) return hr;
582 Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
583 LPDIRECTDRAWSURFACE7 *ppSurf,
587 ICOM_THIS(IDirectDrawImpl, iface);
589 TRACE("(%p)->(%p,%p,%p)\n",This,pDDSD,ppSurf,pUnkOuter);
590 if (TRACE_ON(ddraw)) {
591 TRACE("Requesting surface desc :\n");
592 DDRAW_dump_surface_desc(pDDSD);
595 if (pUnkOuter != NULL) {
596 FIXME("outer != NULL?\n");
597 return CLASS_E_NOAGGREGATION; /* unchecked */
600 if (!(pDDSD->dwFlags & DDSD_CAPS)) {
601 /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
602 pDDSD->dwFlags |= DDSD_CAPS;
604 if (pDDSD->ddsCaps.dwCaps == 0) {
605 /* This has been checked on real Windows */
606 pDDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
609 if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) {
610 /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
611 pDDSD->dwFlags &= ~DDSD_LPSURFACE;
614 if (ppSurf == NULL) {
615 FIXME("You want to get back a surface? Don't give NULL ptrs!\n");
616 return E_POINTER; /* unchecked */
619 if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
621 /* create primary surface & backbuffers */
622 hr = create_primary(This, pDDSD, ppSurf, pUnkOuter);
624 else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
626 /* create backbuffer surface */
627 hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL);
629 else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
632 hr = create_texture(This, pDDSD, ppSurf, pUnkOuter);
634 else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) ||
635 (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */
637 /* create offscreenplain surface */
638 hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
640 else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
642 /* create z-buffer */
643 hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter);
647 /* Otherwise, assume offscreenplain surface */
648 TRACE("App didn't request a valid surface type - assuming offscreenplain\n");
649 hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
653 FIXME("failed surface creation with code 0x%08lx\n",hr);
661 Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
662 LPDIRECTDRAWSURFACE7* dst)
664 ICOM_THIS(IDirectDrawImpl,iface);
666 IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl,
667 IDirectDrawSurface7, src);
669 TRACE("(%p)->(%p,%p)\n",This,src,dst);
671 return pSrc->duplicate_surface(pSrc, dst);
674 /* EnumDisplayModes */
676 BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested,
677 const DDPIXELFORMAT *provided)
679 /* Some flags must be present in both or neither for a match. */
680 static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
681 | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC
682 | DDPF_ZBUFFER | DDPF_STENCILBUFFER;
684 if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
687 if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match))
690 if (requested->dwFlags & DDPF_FOURCC)
691 if (requested->dwFourCC != provided->dwFourCC)
694 if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA
695 |DDPF_LUMINANCE|DDPF_BUMPDUDV))
696 if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount)
699 if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
700 |DDPF_LUMINANCE|DDPF_BUMPDUDV))
701 if (requested->u2.dwRBitMask != provided->u2.dwRBitMask)
704 if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV))
705 if (requested->u3.dwGBitMask != provided->u3.dwGBitMask)
708 /* I could be wrong about the bumpmapping. MSDN docs are vague. */
709 if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
711 if (requested->u4.dwBBitMask != provided->u4.dwBBitMask)
714 if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS))
715 if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask)
721 BOOL Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2* requested,
722 const DDSURFACEDESC2* provided)
731 #define CMP(FLAG, FIELD) \
732 { DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD), \
733 sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) }
735 static const struct compare_info compare[] = {
736 CMP(ALPHABITDEPTH, dwAlphaBitDepth),
737 CMP(BACKBUFFERCOUNT, dwBackBufferCount),
739 CMP(CKDESTBLT, ddckCKDestBlt),
740 CMP(CKDESTOVERLAY, u3.ddckCKDestOverlay),
741 CMP(CKSRCBLT, ddckCKSrcBlt),
742 CMP(CKSRCOVERLAY, ddckCKSrcOverlay),
743 CMP(HEIGHT, dwHeight),
744 CMP(LINEARSIZE, u1.dwLinearSize),
745 CMP(LPSURFACE, lpSurface),
746 CMP(MIPMAPCOUNT, u2.dwMipMapCount),
747 CMP(PITCH, u1.lPitch),
748 /* PIXELFORMAT: manual */
749 CMP(REFRESHRATE, u2.dwRefreshRate),
750 CMP(TEXTURESTAGE, dwTextureStage),
752 /* ZBUFFERBITDEPTH: "obsolete" */
759 if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
762 for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++)
764 if (requested->dwFlags & compare[i].flag
765 && memcmp((const char *)provided + compare[i].offset,
766 (const char *)requested + compare[i].offset,
767 compare[i].size) != 0)
771 if (requested->dwFlags & DDSD_PIXELFORMAT)
773 if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat,
774 &provided->u4.ddpfPixelFormat))
781 #define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
782 #define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
784 /* This should be extended so that it can be used by
785 * IDirectDrawSurface7::EnumAttachedSurfaces. */
787 Main_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
788 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
789 LPDDENUMSURFACESCALLBACK7 callback)
791 IDirectDrawSurfaceImpl *surf;
794 /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */
795 if (lpDDSD2 == NULL && !(dwFlags & DDENUMSURFACES_ALL))
796 return DDERR_INVALIDPARAMS;
798 all = dwFlags & DDENUMSURFACES_ALL;
799 nomatch = dwFlags & DDENUMSURFACES_NOMATCH;
801 for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
804 || (nomatch != Main_DirectDraw_DDSD_Match(lpDDSD2,
805 &surf->surface_desc)))
807 LPDIRECTDRAWSURFACE7 surface = ICOM_INTERFACE(surf,
808 IDirectDrawSurface7);
810 /* BOGUS! Violates COM rules, but MSDN says so. */
811 IDirectDrawSurface7_AddRef(surface);
813 if (callback(surface, &surf->surface_desc, context)
822 /* I really don't understand how this is supposed to work.
823 * We only consider dwHeight, dwWidth and ddpfPixelFormat.dwFlags. */
825 Main_DirectDraw_EnumCreateableSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
826 LPDDSURFACEDESC2 lpDDSD2,
828 LPDDENUMSURFACESCALLBACK7 callback)
830 FIXME("This isn't going to work.\n");
832 if ((dwFlags & DDENUMSURFACES_MATCHTYPE) != DDENUMSURFACES_MATCH)
833 return DDERR_INVALIDPARAMS;
835 /* TODO: implement this.
836 * Does this work before SCL is called?
837 * Does it only consider off-screen surfaces?
843 /* For unsigned x. 0 is not a power of 2. */
844 #define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
847 Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
848 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
849 LPDDENUMSURFACESCALLBACK7 callback)
851 ICOM_THIS(IDirectDrawImpl, iface);
852 TRACE("(%p)->(0x%lx, %p, %p, %p)\n", iface, dwFlags, lpDDSD2, context,
855 if (callback == NULL)
856 return DDERR_INVALIDPARAMS;
858 if (dwFlags & ~(DDENUMSURFACES_SEARCHTYPE|DDENUMSURFACES_MATCHTYPE))
859 return DDERR_INVALIDPARAMS;
861 if (!IS_POW_2(dwFlags & DDENUMSURFACES_SEARCHTYPE)
862 || !IS_POW_2(dwFlags & DDENUMSURFACES_MATCHTYPE))
863 return DDERR_INVALIDPARAMS;
865 if (dwFlags & DDENUMSURFACES_DOESEXIST)
867 return Main_DirectDraw_EnumExistingSurfaces(This, dwFlags, lpDDSD2,
872 return Main_DirectDraw_EnumCreateableSurfaces(This, dwFlags, lpDDSD2,
878 Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
880 ICOM_THIS(IDirectDrawImpl,iface);
881 FIXME("(%p)->() stub\n", This);
887 Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
889 ICOM_THIS(IDirectDrawImpl,iface);
890 TRACE("(%p)->()\n",This);
895 Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
898 ICOM_THIS(IDirectDrawImpl,iface);
899 TRACE("(%p,%p,%p)\n",This,pDriverCaps,pHELCaps);
900 if (pDriverCaps != NULL) {
901 DD_STRUCT_COPY_BYSIZE(pDriverCaps,&This->caps);
902 if (TRACE_ON(ddraw)) {
903 TRACE("Driver Caps : \n");
904 DDRAW_dump_DDCAPS(pDriverCaps);
907 if (pHELCaps != NULL) {
908 DD_STRUCT_COPY_BYSIZE(pHELCaps,&This->caps);
909 if (TRACE_ON(ddraw)) {
910 TRACE("HEL Caps : \n");
911 DDRAW_dump_DDCAPS(pHELCaps);
918 /* GetDeviceIdentifier */
922 Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
925 ICOM_THIS(IDirectDrawImpl,iface);
929 FIXME("(%p,%p,%p), stub\n",This,pNumCodes,pCodes);
934 Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
935 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
937 ICOM_THIS(IDirectDrawImpl,iface);
938 TRACE("(%p)->(%p)\n", This, lplpGDIDDSSurface);
939 TRACE("returning primary (%p)\n", This->primary_surface);
940 *lplpGDIDDSSurface = ICOM_INTERFACE(This->primary_surface, IDirectDrawSurface7);
941 if (*lplpGDIDDSSurface)
942 IDirectDrawSurface7_AddRef(*lplpGDIDDSSurface);
947 Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
949 ICOM_THIS(IDirectDrawImpl,iface);
950 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
951 *freq = 60*100; /* 60 Hz */
956 Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
958 ICOM_THIS(IDirectDrawImpl,iface);
959 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
967 Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
968 LPDIRECTDRAWSURFACE7 *lpDDS)
970 ICOM_THIS(IDirectDrawImpl,iface);
971 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
977 Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
979 ICOM_THIS(IDirectDrawImpl,iface);
980 TRACE("(%p)->(%p)\n",This,status);
985 /* If we were not initialised then Uninit_Main_IDirectDraw7_Initialize would
986 * have been called instead. */
988 Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid)
990 TRACE("(%p)->(%s)\n", iface, debugstr_guid(lpGuid));
992 return DDERR_ALREADYINITIALIZED;
996 Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
998 ICOM_THIS(IDirectDrawImpl,iface);
999 IDirectDrawSurfaceImpl* surf;
1001 TRACE("(%p)->()\n", This);
1003 for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
1004 IDirectDrawSurface7_Restore(ICOM_INTERFACE(surf, IDirectDrawSurface7));
1009 static void DDRAW_SubclassWindow(IDirectDrawImpl* This)
1011 /* Well we don't actually subclass the window yet. */
1012 SetPropA(This->window, ddProp, This);
1015 static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This)
1017 RemovePropA(This->window, ddProp);
1021 Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
1024 ICOM_THIS(IDirectDrawImpl,iface);
1026 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
1027 DDRAW_dump_cooperativelevel(cooplevel);
1029 /* Makes realMYST test happy. */
1030 if (This->cooperative_level == cooplevel
1031 && This->window == hwnd)
1034 /* XXX "It cannot be reset while the process has surfaces or palettes
1035 * created." Otherwise the window can be changed???
1037 * This appears to be wrong - comment it out for now.
1039 return DDERR_HWNDALREADYSET;
1042 if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL)))
1043 return DDERR_INVALIDPARAMS;
1045 This->window = hwnd;
1046 This->cooperative_level = cooplevel;
1048 This->local.hWnd = (ULONG_PTR)hwnd;
1049 This->local.dwLocalFlags |= DDRAWILCL_SETCOOPCALLED;
1050 /* not entirely sure about these */
1051 if (cooplevel & DDSCL_EXCLUSIVE) This->local.dwLocalFlags |= DDRAWILCL_HASEXCLUSIVEMODE;
1052 if (cooplevel & DDSCL_FULLSCREEN) This->local.dwLocalFlags |= DDRAWILCL_ISFULLSCREEN;
1053 if (cooplevel & DDSCL_ALLOWMODEX) This->local.dwLocalFlags |= DDRAWILCL_ALLOWMODEX;
1054 if (cooplevel & DDSCL_MULTITHREADED) This->local.dwLocalFlags |= DDRAWILCL_MULTITHREADED;
1055 if (cooplevel & DDSCL_FPUSETUP) This->local.dwLocalFlags |= DDRAWILCL_FPUSETUP;
1056 if (cooplevel & DDSCL_FPUPRESERVE) This->local.dwLocalFlags |= DDRAWILCL_FPUPRESERVE;
1058 if (This->local.lpGbl) {
1059 /* assume that this app is the active app (in wine, there's
1060 * probably only one app per global ddraw object anyway) */
1061 if (cooplevel & DDSCL_EXCLUSIVE) This->local.lpGbl->lpExclusiveOwner = &This->local;
1062 else if (This->local.lpGbl->lpExclusiveOwner == &This->local)
1063 This->local.lpGbl->lpExclusiveOwner = NULL;
1064 if (This->set_exclusive_mode)
1065 This->set_exclusive_mode(This, (cooplevel & DDSCL_EXCLUSIVE) != 0);
1068 ShowWindow(hwnd, SW_SHOW);
1070 DDRAW_SubclassWindow(This);
1072 /* TODO Does it also get resized to the current screen size? */
1078 Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
1079 DWORD dwHeight, LONG lPitch,
1080 DWORD dwRefreshRate, DWORD dwFlags,
1081 const DDPIXELFORMAT* pixelformat)
1086 ICOM_THIS(IDirectDrawImpl,iface);
1088 TRACE("(%p)->SetDisplayMode(%ld,%ld)\n",This,dwWidth,dwHeight);
1090 if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
1091 return DDERR_NOEXCLUSIVEMODE;
1093 if (!IsWindow(This->window))
1094 return DDERR_GENERIC; /* unchecked */
1096 LosePrimarySurface(This);
1098 screenX = GetSystemMetrics(SM_CXSCREEN);
1099 screenY = GetSystemMetrics(SM_CYSCREEN);
1101 This->width = dwWidth;
1102 This->height = dwHeight;
1103 This->pitch = lPitch;
1104 This->pixelformat = *pixelformat;
1106 /* Position the window in the center of the screen - don't center for now */
1107 /* MoveWindow(This->window, (screenX-dwWidth)/2, (screenY-dwHeight)/2,
1108 dwWidth, dwHeight, TRUE);*/
1109 MoveWindow(This->window, 0, 0, dwWidth, dwHeight, TRUE);
1111 SetFocus(This->window);
1117 Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
1119 ICOM_THIS(IDirectDrawImpl,iface);
1121 TRACE("(%p)\n",This);
1122 if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
1123 return DDERR_NOEXCLUSIVEMODE;
1125 /* Lose the primary surface if the resolution changes. */
1126 if (This->orig_width != This->width || This->orig_height != This->height
1127 || This->orig_pitch != This->pitch
1128 || This->orig_pixelformat.dwFlags != This->pixelformat.dwFlags
1129 || !Main_DirectDraw_DDPIXELFORMAT_Match(&This->pixelformat,
1130 &This->orig_pixelformat))
1132 LosePrimarySurface(This);
1135 /* TODO Move the window back where it belongs. */
1141 Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
1144 ICOM_THIS(IDirectDrawImpl,iface);
1145 FIXME("(%p)->(flags=0x%08lx,handle=%p)\n",This,dwFlags,h);
1150 Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
1152 ICOM_THIS(IDirectDrawImpl,iface);
1153 TRACE("(%p)->GetDisplayMode(%p)\n",This,pDDSD);
1155 pDDSD->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_REFRESHRATE;
1156 pDDSD->dwHeight = This->height;
1157 pDDSD->dwWidth = This->width;
1158 pDDSD->u1.lPitch = This->pitch;
1159 pDDSD->u2.dwRefreshRate = 60;
1160 pDDSD->u4.ddpfPixelFormat = This->pixelformat;
1161 pDDSD->ddsCaps.dwCaps = 0;
1166 static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem)
1168 if (mem > This->available_vidmem) return -1;
1169 This->available_vidmem -= mem;
1170 return This->available_vidmem;
1173 static void free_memory(IDirectDrawImpl *This, DWORD mem)
1175 This->available_vidmem += mem;
1179 Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
1180 LPDWORD total, LPDWORD free)
1182 ICOM_THIS(IDirectDrawImpl,iface);
1183 TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
1185 if (TRACE_ON(ddraw)) {
1186 TRACE(" Asking for memory of type : ");
1187 DDRAW_dump_DDSCAPS2(ddscaps); TRACE("\n");
1190 /* We have 16 MB videomemory */
1191 if (total) *total= This->total_vidmem;
1192 if (free) *free = This->available_vidmem;
1194 TRACE(" returning (total) %ld / (free) %ld\n",
1195 total != NULL ? *total : 0,
1196 free != NULL ? *free : 0);
1201 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) {
1202 ICOM_THIS(IDirectDrawImpl,iface);
1203 TRACE("(%p)->(): stub\n", This);
1209 Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
1210 DWORD dwNumModes, DWORD dwFlags)
1212 ICOM_THIS(IDirectDrawImpl,iface);
1213 FIXME("(%p)->() stub\n", This);
1218 /*** Owned object management. */
1220 void Main_DirectDraw_AddSurface(IDirectDrawImpl* This,
1221 IDirectDrawSurfaceImpl* surface)
1223 assert(surface->ddraw_owner == NULL || surface->ddraw_owner == This);
1225 surface->ddraw_owner = This;
1227 /* where should it go? */
1228 surface->next_ddraw = This->surfaces;
1229 surface->prev_ddraw = NULL;
1231 This->surfaces->prev_ddraw = surface;
1232 This->surfaces = surface;
1235 void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This,
1236 IDirectDrawSurfaceImpl* surface)
1238 assert(surface->ddraw_owner == This);
1240 if (This->surfaces == surface)
1241 This->surfaces = surface->next_ddraw;
1243 if (This->primary_surface == surface)
1244 This->primary_surface = NULL;
1246 if (surface->next_ddraw)
1247 surface->next_ddraw->prev_ddraw = surface->prev_ddraw;
1248 if (surface->prev_ddraw)
1249 surface->prev_ddraw->next_ddraw = surface->next_ddraw;
1252 static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This)
1254 while (This->surfaces != NULL)
1255 Main_DirectDrawSurface_ForceDestroy(This->surfaces);
1258 void Main_DirectDraw_AddClipper(IDirectDrawImpl* This,
1259 IDirectDrawClipperImpl* clipper)
1261 assert(clipper->ddraw_owner == NULL || clipper->ddraw_owner == This);
1263 clipper->ddraw_owner = This;
1265 clipper->next_ddraw = This->clippers;
1266 clipper->prev_ddraw = NULL;
1268 This->clippers->prev_ddraw = clipper;
1269 This->clippers = clipper;
1272 void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This,
1273 IDirectDrawClipperImpl* clipper)
1275 assert(clipper->ddraw_owner == This);
1277 if (This->clippers == clipper)
1278 This->clippers = clipper->next_ddraw;
1280 if (clipper->next_ddraw)
1281 clipper->next_ddraw->prev_ddraw = clipper->prev_ddraw;
1282 if (clipper->prev_ddraw)
1283 clipper->prev_ddraw->next_ddraw = clipper->next_ddraw;
1286 static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This)
1288 while (This->clippers != NULL)
1289 Main_DirectDrawClipper_ForceDestroy(This->clippers);
1292 void Main_DirectDraw_AddPalette(IDirectDrawImpl* This,
1293 IDirectDrawPaletteImpl* palette)
1295 assert(palette->ddraw_owner == NULL || palette->ddraw_owner == This);
1297 palette->ddraw_owner = This;
1299 /* where should it go? */
1300 palette->next_ddraw = This->palettes;
1301 palette->prev_ddraw = NULL;
1303 This->palettes->prev_ddraw = palette;
1304 This->palettes = palette;
1307 void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This,
1308 IDirectDrawPaletteImpl* palette)
1310 IDirectDrawSurfaceImpl *surf;
1312 assert(palette->ddraw_owner == This);
1314 if (This->palettes == palette)
1315 This->palettes = palette->next_ddraw;
1317 if (palette->next_ddraw)
1318 palette->next_ddraw->prev_ddraw = palette->prev_ddraw;
1319 if (palette->prev_ddraw)
1320 palette->prev_ddraw->next_ddraw = palette->next_ddraw;
1322 /* Here we need also to remove tha palette from any surface which has it as the
1323 * current palette (checked on Windows)
1325 for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) {
1326 if (surf->palette == palette) {
1327 TRACE("Palette %p attached to surface %p.\n", palette, surf);
1328 surf->palette = NULL;
1329 surf->set_palette(surf, NULL);
1334 static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This)
1336 while (This->palettes != NULL)
1337 Main_DirectDrawPalette_ForceDestroy(This->palettes);
1343 LoseSurface(IDirectDrawSurfaceImpl *surface)
1345 if (surface != NULL) surface->lose_surface(surface);
1349 LosePrimarySurface(IDirectDrawImpl *This)
1351 /* MSDN: "If another application changes the display mode, the primary
1352 * surface is lost, and the method returns DDERR_SURFACELOST until the
1353 * primary surface is recreated to match the new display mode."
1355 * We mark all the primary surfaces as lost as soon as the display
1356 * mode is changed (by any application). */
1358 LoseSurface(This->primary_surface);
1361 /******************************************************************************
1362 * Uninitialised DirectDraw functions
1364 * This vtable is used when a DirectDraw object is created with
1365 * CoCreateInstance. The only usable method is Initialize.
1368 void Uninit_DirectDraw_final_release(IDirectDrawImpl *This)
1370 Main_DirectDraw_final_release(This);
1373 static ICOM_VTABLE(IDirectDraw7) Uninit_DirectDraw_VTable;
1375 /* Not called from the vtable. */
1376 HRESULT Uninit_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
1380 hr = Main_DirectDraw_Construct(This, ex);
1381 if (FAILED(hr)) return hr;
1383 This->final_release = Uninit_DirectDraw_final_release;
1384 ICOM_INIT_INTERFACE(This, IDirectDraw7, Uninit_DirectDraw_VTable);
1389 HRESULT Uninit_DirectDraw_Create(const GUID* pGUID,
1390 LPDIRECTDRAW7* pIface,
1391 IUnknown* pUnkOuter, BOOL ex)
1394 IDirectDrawImpl* This;
1396 assert(pUnkOuter == NULL); /* XXX no: we must check this */
1398 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1399 sizeof(IDirectDrawImpl));
1400 if (This == NULL) return E_OUTOFMEMORY;
1402 hr = Uninit_DirectDraw_Construct(This, ex);
1404 HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This);
1406 *pIface = ICOM_INTERFACE(This, IDirectDraw7);
1411 static HRESULT WINAPI
1412 Uninit_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID pDeviceGuid)
1414 const ddraw_driver* driver;
1415 ICOM_THIS(IDirectDrawImpl, iface);
1417 TRACE("(%p)->(%p)\n", iface, pDeviceGuid);
1419 driver = DDRAW_FindDriver(pDeviceGuid);
1420 /* XXX This return value is not documented. (Not checked.) */
1421 if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID;
1423 return driver->init(This, pDeviceGuid);
1426 static HRESULT WINAPI
1427 Uninit_DirectDraw_Compact(LPDIRECTDRAW7 iface)
1429 return DDERR_NOTINITIALIZED;
1432 static HRESULT WINAPI
1433 Uninit_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
1434 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1435 IUnknown *pUnkOuter)
1438 return DDERR_NOTINITIALIZED;
1441 static HRESULT WINAPI
1442 Uninit_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
1443 LPPALETTEENTRY lpColorTable,
1444 LPDIRECTDRAWPALETTE *lplpDDPalette,
1445 IUnknown *pUnkOuter)
1447 return DDERR_NOTINITIALIZED;
1450 static HRESULT WINAPI
1451 Uninit_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface,
1452 LPDDSURFACEDESC2 lpDDSurfaceDesc,
1453 LPDIRECTDRAWSURFACE7 *lplpDDSurface,
1454 IUnknown *pUnkOuter)
1456 return DDERR_NOTINITIALIZED;
1459 static HRESULT WINAPI
1460 Uninit_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface,
1461 LPDIRECTDRAWSURFACE7 pSurf,
1462 LPDIRECTDRAWSURFACE7 *pDupSurf)
1465 return DDERR_NOTINITIALIZED;
1468 static HRESULT WINAPI
1469 Uninit_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
1470 LPDDSURFACEDESC2 lpDDSD,
1472 LPDDENUMMODESCALLBACK2 cb)
1474 return DDERR_NOTINITIALIZED;
1477 static HRESULT WINAPI
1478 Uninit_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
1479 LPDDSURFACEDESC2 pDDSD, LPVOID context,
1480 LPDDENUMSURFACESCALLBACK7 cb)
1482 return DDERR_NOTINITIALIZED;
1485 static HRESULT WINAPI
1486 Uninit_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
1488 return DDERR_NOTINITIALIZED;
1491 static HRESULT WINAPI
1492 Uninit_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
1495 return DDERR_NOTINITIALIZED;
1498 static HRESULT WINAPI
1499 Uninit_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface,
1500 LPDDSURFACEDESC2 pDDSD)
1502 return DDERR_NOTINITIALIZED;
1505 static HRESULT WINAPI
1506 Uninit_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
1509 return DDERR_NOTINITIALIZED;
1512 static HRESULT WINAPI
1513 Uninit_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
1514 LPDIRECTDRAWSURFACE7 *pGDISurf)
1516 return DDERR_NOTINITIALIZED;
1519 static HRESULT WINAPI
1520 Uninit_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface, LPDWORD pdwFreq)
1522 return DDERR_NOTINITIALIZED;
1525 static HRESULT WINAPI
1526 Uninit_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD pdwScanLine)
1528 return DDERR_NOTINITIALIZED;
1531 static HRESULT WINAPI
1532 Uninit_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, PBOOL pbIsInVB)
1534 return DDERR_NOTINITIALIZED;
1537 static HRESULT WINAPI
1538 Uninit_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
1540 return DDERR_NOTINITIALIZED;
1543 static HRESULT WINAPI
1544 Uninit_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hWnd,
1547 return DDERR_NOTINITIALIZED;
1550 static HRESULT WINAPI
1551 Uninit_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
1552 DWORD dwHeight, DWORD dwBPP,
1553 DWORD dwRefreshRate, DWORD dwFlags)
1555 return DDERR_NOTINITIALIZED;
1558 static HRESULT WINAPI
1559 Uninit_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
1562 return DDERR_NOTINITIALIZED;
1565 static HRESULT WINAPI
1566 Uninit_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 pDDCaps,
1567 LPDWORD pdwTotal, LPDWORD pdwFree)
1569 return DDERR_NOTINITIALIZED;
1572 static HRESULT WINAPI
1573 Uninit_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hDC,
1574 LPDIRECTDRAWSURFACE7 *pSurf)
1576 return DDERR_NOTINITIALIZED;
1579 static HRESULT WINAPI
1580 Uninit_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
1582 return DDERR_NOTINITIALIZED;
1585 static HRESULT WINAPI
1586 Uninit_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
1588 return DDERR_NOTINITIALIZED;
1591 static HRESULT WINAPI
1592 Uninit_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
1593 LPDDDEVICEIDENTIFIER2 pDDDI,
1596 return DDERR_NOTINITIALIZED;
1599 static HRESULT WINAPI
1600 Uninit_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pszModes,
1601 DWORD cModes, DWORD dwFlags)
1603 return DDERR_NOTINITIALIZED;
1606 static HRESULT WINAPI
1607 Uninit_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface, DWORD dwFlags,
1610 return DDERR_NOTINITIALIZED;
1613 static ICOM_VTABLE(IDirectDraw7) Uninit_DirectDraw_VTable =
1615 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1616 Main_DirectDraw_QueryInterface,
1617 Main_DirectDraw_AddRef,
1618 Main_DirectDraw_Release,
1619 Uninit_DirectDraw_Compact,
1620 Uninit_DirectDraw_CreateClipper,
1621 Uninit_DirectDraw_CreatePalette,
1622 Uninit_DirectDraw_CreateSurface,
1623 Uninit_DirectDraw_DuplicateSurface,
1624 Uninit_DirectDraw_EnumDisplayModes,
1625 Uninit_DirectDraw_EnumSurfaces,
1626 Uninit_DirectDraw_FlipToGDISurface,
1627 Uninit_DirectDraw_GetCaps,
1628 Uninit_DirectDraw_GetDisplayMode,
1629 Uninit_DirectDraw_GetFourCCCodes,
1630 Uninit_DirectDraw_GetGDISurface,
1631 Uninit_DirectDraw_GetMonitorFrequency,
1632 Uninit_DirectDraw_GetScanLine,
1633 Uninit_DirectDraw_GetVerticalBlankStatus,
1634 Uninit_DirectDraw_Initialize,
1635 Uninit_DirectDraw_RestoreDisplayMode,
1636 Uninit_DirectDraw_SetCooperativeLevel,
1637 Uninit_DirectDraw_SetDisplayMode,
1638 Uninit_DirectDraw_WaitForVerticalBlank,
1639 Uninit_DirectDraw_GetAvailableVidMem,
1640 Uninit_DirectDraw_GetSurfaceFromDC,
1641 Uninit_DirectDraw_RestoreAllSurfaces,
1642 Uninit_DirectDraw_TestCooperativeLevel,
1643 Uninit_DirectDraw_GetDeviceIdentifier,
1644 Uninit_DirectDraw_StartModeTest,
1645 Uninit_DirectDraw_EvaluateMode