1 /* DirectDraw Surface Implementation
3 * Copyright (c) 1997-2000 Marcus Meissner
4 * Copyright (c) 1998-2000 Lionel Ulmer
5 * Copyright (c) 2000-2001 TransGaming Technologies Inc.
6 * Copyright (c) 2006 Stefan Dösinger
8 * This file contains the (internal) driver registration functions,
9 * driver enumeration APIs and DirectDraw creation functions.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/port.h"
35 #define NONAMELESSUNION
42 #include "wine/exception.h"
48 #include "ddraw_private.h"
49 #include "wine/debug.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
53 /*****************************************************************************
54 * IUnknown parts follow
55 *****************************************************************************/
57 /*****************************************************************************
58 * IDirectDrawSurface7::QueryInterface
60 * A normal QueryInterface implementation. For QueryInterface rules
61 * see ddraw.c, IDirectDraw7::QueryInterface. This method
62 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
63 * in all versions, the IDirectDrawGammaControl interface and it can
64 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
67 * riid: The interface id queried for
68 * obj: Address to write the pointer to
72 * E_NOINTERFACE if the requested interface wasn't found
74 *****************************************************************************/
76 IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7
*iface
,
80 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
82 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
86 return DDERR_INVALIDPARAMS
;
88 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),obj
);
89 if (IsEqualGUID(riid
, &IID_IUnknown
)
90 || IsEqualGUID(riid
, &IID_IDirectDrawSurface7
)
91 || IsEqualGUID(riid
, &IID_IDirectDrawSurface4
) )
93 IUnknown_AddRef(iface
);
94 *obj
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
95 TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This
, *obj
);
98 else if( IsEqualGUID(riid
, &IID_IDirectDrawSurface3
)
99 || IsEqualGUID(riid
, &IID_IDirectDrawSurface2
)
100 || IsEqualGUID(riid
, &IID_IDirectDrawSurface
) )
102 IUnknown_AddRef(iface
);
103 *obj
= ICOM_INTERFACE(This
, IDirectDrawSurface3
);
104 TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This
, *obj
);
107 else if( IsEqualGUID(riid
, &IID_IDirectDrawGammaControl
) )
109 IUnknown_AddRef(iface
);
110 *obj
= ICOM_INTERFACE(This
, IDirectDrawGammaControl
);
111 TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This
, *obj
);
114 else if( IsEqualGUID(riid
, &IID_D3DDEVICE_WineD3D
) ||
115 IsEqualGUID(riid
, &IID_IDirect3DHALDevice
) )
117 IDirect3DDevice7
*d3d
;
119 /* Call into IDirect3D7 for creation */
120 IDirect3D7_CreateDevice(ICOM_INTERFACE(This
->ddraw
, IDirect3D7
),
122 ICOM_INTERFACE(This
, IDirectDrawSurface7
),
125 *obj
= COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice7
, IDirect3DDevice
, d3d
);
126 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
130 else if (IsEqualGUID( &IID_IDirect3DTexture
, riid
) ||
131 IsEqualGUID( &IID_IDirect3DTexture2
, riid
))
133 if (IsEqualGUID( &IID_IDirect3DTexture
, riid
))
135 *obj
= ICOM_INTERFACE(This
, IDirect3DTexture
);
136 TRACE(" returning Direct3DTexture interface at %p.\n", *obj
);
140 *obj
= ICOM_INTERFACE(This
, IDirect3DTexture2
);
141 TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj
);
143 IUnknown_AddRef( (IUnknown
*) *obj
);
147 ERR("No interface\n");
148 return E_NOINTERFACE
;
151 /*****************************************************************************
152 * IDirectDrawSurface7::AddRef
154 * A normal addref implementation
159 *****************************************************************************/
161 IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7
*iface
)
163 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
164 ULONG refCount
= InterlockedIncrement(&This
->ref
);
166 TRACE("(%p) : AddRef increasing from %d\n", This
, refCount
- 1);
170 /*****************************************************************************
171 * IDirectDrawSurfaceImpl_Destroy
173 * A helper function for IDirectDrawSurface7::Release
175 * Frees the surface, regardless of its refcount.
176 * See IDirectDrawSurface7::Release for more information
179 * This: Surface to free
181 *****************************************************************************/
182 static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl
*This
)
184 TRACE("(%p)\n", This
);
186 /* Check the refcount and give a warning */
189 /* This can happen when a complex surface is destroyed,
190 * because the 2nd surface was addref()ed when the app
191 * called GetAttachedSurface
193 WARN("(%p): Destroying surface with refount %d\n", This
, This
->ref
);
196 /* Check for attached surfaces and detach them */
197 if(This
->first_attached
!= This
)
199 /* Well, this shouldn't happen: The surface being attached is addref()ed
200 * in AddAttachedSurface, so it shouldn't be released until DeleteAttachedSurface
201 * is called, because the refcount is held. It looks like the app released()
202 * it often enough to force this
204 IDirectDrawSurface7
*root
= ICOM_INTERFACE(This
->first_attached
, IDirectDrawSurface7
);
205 IDirectDrawSurface7
*detach
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
207 FIXME("(%p) Freeing a surface that is attached to surface %p\n", This
, This
->first_attached
);
209 /* The refcount will drop to -1 here */
210 if(IDirectDrawSurface7_DeleteAttachedSurface(root
, 0, detach
) != DD_OK
)
212 ERR("(%p) DeleteAttachedSurface failed!\n", This
);
216 while(This
->next_attached
!= NULL
)
218 IDirectDrawSurface7
*root
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
219 IDirectDrawSurface7
*detach
= ICOM_INTERFACE(This
->next_attached
, IDirectDrawSurface7
);
221 if(IDirectDrawSurface7_DeleteAttachedSurface(root
, 0, detach
) != DD_OK
)
223 ERR("(%p) DeleteAttachedSurface failed!\n", This
);
228 /* Now destroy the surface. Wait: It could have been released if we are a texture */
229 if(This
->WineD3DSurface
)
230 IWineD3DSurface_Release(This
->WineD3DSurface
);
232 /* Having a texture handle set implies that the device still exists */
235 This
->ddraw
->d3ddevice
->Handles
[This
->Handle
- 1].ptr
= NULL
;
236 This
->ddraw
->d3ddevice
->Handles
[This
->Handle
- 1].type
= DDrawHandle_Unknown
;
239 /* Reduce the ddraw surface count */
240 InterlockedDecrement(&This
->ddraw
->surfaces
);
241 list_remove(&This
->surface_list_entry
);
243 HeapFree(GetProcessHeap(), 0, This
);
246 /*****************************************************************************
247 * IDirectDrawSurface7::Release
249 * Reduces the surface's refcount by 1. If the refcount falls to 0, the
250 * surface is destroyed.
252 * Destroying the surface is a bit tricky. For the connection between
253 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
254 * It has a nice graph explaining the connection.
256 * What happens here is basically this:
257 * When a surface is destroyed, its WineD3DSurface is released,
258 * and the refcount of the DirectDraw interface is reduced by 1. If it has
259 * complex surfaces attached to it, then these surfaces are destroyed too,
260 * regardless of their refcount. If any surface being destroyed has another
261 * surface attached to it (with a "soft" attachment, not complex), then
262 * this surface is detached with DeleteAttachedSurface.
264 * When the surface is a texture, the WineD3DTexture is released.
265 * If the surface is the Direct3D render target, then the D3D
266 * capabilities of the WineD3DDevice are uninitialized, which causes the
267 * swapchain to be released.
272 *****************************************************************************/
274 IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7
*iface
)
276 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
278 TRACE("(%p) : Releasing from %d\n", This
, This
->ref
);
279 ref
= InterlockedDecrement(&This
->ref
);
284 IDirectDrawSurfaceImpl
*surf
;
285 IDirectDrawImpl
*ddraw
;
286 IUnknown
*ifaceToRelease
= This
->ifaceToRelease
;
288 /* Complex attached surfaces are destroyed implicitely when the root is released */
289 if(This
->first_complex
!= This
)
291 WARN("(%p) Attempt to destroy a surface that is attached to a complex root %p\n", This
, This
->first_complex
);
296 /* If it's a texture, destroy the WineD3DTexture.
297 * WineD3D will destroy the IParent interfaces
298 * of the sublevels, which destroys the WineD3DSurfaces.
299 * Set the surfaces to NULL to avoid destroying them again later
301 if(This
->wineD3DTexture
)
303 IWineD3DTexture_Release(This
->wineD3DTexture
);
305 /* If it's the RenderTarget, destroy the d3ddevice */
306 else if( (ddraw
->d3d_initialized
) && (This
== ddraw
->d3d_target
))
308 TRACE("(%p) Destroying the render target, uninitializing D3D\n", This
);
310 /* Unset any index buffer, just to be sure */
311 IWineD3DDevice_SetIndices(ddraw
->wineD3DDevice
, NULL
, 0);
312 IWineD3DDevice_SetDepthStencilSurface(ddraw
->wineD3DDevice
, NULL
);
314 if(IWineD3DDevice_Uninit3D(ddraw
->wineD3DDevice
, D3D7CB_DestroyDepthStencilSurface
, D3D7CB_DestroySwapChain
) != D3D_OK
)
317 ERR("(%p) Failed to uninit 3D\n", This
);
321 /* Free the d3d window if one was created */
322 if(ddraw
->d3d_window
!= 0)
324 TRACE(" (%p) Destroying the hidden render window %p\n", This
, ddraw
->d3d_window
);
325 DestroyWindow(ddraw
->d3d_window
);
326 ddraw
->d3d_window
= 0;
328 /* Unset the pointers */
331 ddraw
->d3d_initialized
= FALSE
;
332 ddraw
->d3d_target
= NULL
;
334 /* Write a trace because D3D unloading was the reason for many
335 * crashes during development.
337 TRACE("(%p) D3D unloaded\n", This
);
339 else if(This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
|
343 /* It's a render target, but no swapchain was created.
344 * The IParent interfaces have to be released manually.
345 * The same applies for textures without an
346 * IWineD3DTexture object attached
353 IWineD3DSurface_GetParent(surf
->WineD3DSurface
,
354 (IUnknown
**) &Parent
);
355 IParent_Release(Parent
); /* For the getParent */
356 IParent_Release(Parent
); /* To release it */
357 surf
= surf
->next_complex
;
361 /* The refcount test shows that the palette is detached when the surface is destroyed */
362 IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(This
, IDirectDrawSurface7
),
365 /* Loop through all complex attached surfaces,
368 while( (surf
= This
->next_complex
) )
370 This
->next_complex
= surf
->next_complex
; /* Unchain it from the complex listing */
371 IDirectDrawSurfaceImpl_Destroy(surf
); /* Destroy it */
374 /* Destroy the surface.
376 IDirectDrawSurfaceImpl_Destroy(This
);
378 /* Reduce the ddraw refcount */
379 if(ifaceToRelease
) IUnknown_Release(ifaceToRelease
);
385 /*****************************************************************************
386 * IDirectDrawSurface7::GetAttachedSurface
388 * Returns an attached surface with the requested caps. Surface attachment
389 * and complex surfaces are not clearly described by the MSDN or sdk,
390 * so this method is tricky and likely to contain problems.
391 * This implementation searches the complex chain first, then the
392 * attachment chain, and then it checks if the caps match to itself.
394 * The chains are searched from This down to the last surface in the chain,
395 * not from the first element in the chain. The first surface found is
396 * returned. The MSDN says that this method fails if more than one surface
397 * matches the caps, but apparently this is incorrect.
399 * The found surface is AddRef-ed before it is returned.
402 * Caps: Pointer to a DDCAPS2 structure describing the caps asked for
403 * Surface: Address to store the found surface
407 * DDERR_INVALIDPARAMS if Caps or Surface is NULL
408 * DDERR_NOTFOUND if no surface was found
410 *****************************************************************************/
411 static HRESULT WINAPI
412 IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7
*iface
,
414 IDirectDrawSurface7
**Surface
)
416 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
417 IDirectDrawSurfaceImpl
*surf
;
420 TRACE("(%p)->(%p,%p)\n", This
, Caps
, Surface
);
424 if(This
->version
< 7)
426 /* Earlier dx apps put garbage into these members, clear them */
427 our_caps
.dwCaps2
= 0;
428 our_caps
.dwCaps3
= 0;
429 our_caps
.dwCaps4
= 0;
432 TRACE("(%p): Looking for caps: %x,%x,%x,%x\n", This
, our_caps
.dwCaps
, our_caps
.dwCaps2
, our_caps
.dwCaps3
, our_caps
.dwCaps4
); /* FIXME: Better debugging */
434 /* First, look at the complex chain */
437 while( (surf
= surf
->next_complex
) )
441 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf
,
442 surf
->surface_desc
.ddsCaps
.dwCaps
,
443 surf
->surface_desc
.ddsCaps
.dwCaps2
,
444 surf
->surface_desc
.ddsCaps
.dwCaps3
,
445 surf
->surface_desc
.ddsCaps
.dwCaps4
);
448 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
449 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
451 /* MSDN: "This method fails if more than one surface is attached
452 * that matches the capabilities requested."
454 * The mipmap demo of the DirectX7 sdk shows what to do here:
455 * apparently apps expect the first found surface to be returned.
458 TRACE("(%p): Returning surface %p\n", This
, surf
);
459 TRACE("(%p): mipmapcount=%d\n", This
, surf
->mipmap_level
);
460 *Surface
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
461 IDirectDrawSurface7_AddRef(*Surface
);
466 /* Next, look at the attachment chain */
469 while( (surf
= surf
->next_attached
) )
473 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf
,
474 surf
->surface_desc
.ddsCaps
.dwCaps
,
475 surf
->surface_desc
.ddsCaps
.dwCaps2
,
476 surf
->surface_desc
.ddsCaps
.dwCaps3
,
477 surf
->surface_desc
.ddsCaps
.dwCaps4
);
480 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
481 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
483 /* MSDN: "This method fails if more than one surface is attached
484 * that matches the capabilities requested."
486 * The mipmap demo of the DirectX7 sdk shows what to do here:
487 * apparently apps expect the first found surface to be returned.
490 TRACE("(%p): Returning surface %p\n", This
, surf
);
491 *Surface
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
492 IDirectDrawSurface7_AddRef(*Surface
);
499 if (((This
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
500 ((This
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
) &&
501 This
== This
->first_complex
)
504 TRACE("(%p): Returning surface %p\n", This
, This
);
505 *Surface
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
506 IDirectDrawSurface7_AddRef(*Surface
);
511 /* What to do here? Continue with the surface root?? */
513 TRACE("(%p) Didn't find a valid surface\n", This
);
514 return DDERR_NOTFOUND
;
517 /*****************************************************************************
518 * IDirectDrawSurface7::Lock
520 * Locks the surface and returns a pointer to the surface's memory
523 * Rect: Rectangle to lock. If NULL, the whole surface is locked
524 * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
525 * Flags: Locking flags, e.g Read only or write only
526 * h: An event handle that's not used and must be NULL
530 * DDERR_INVALIDPARAMS if DDSD is NULL
531 * For more details, see IWineD3DSurface::LockRect
533 *****************************************************************************/
534 static HRESULT WINAPI
535 IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7
*iface
,
537 DDSURFACEDESC2
*DDSD
,
541 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
542 WINED3DLOCKED_RECT LockedRect
;
544 TRACE("(%p)->(%p,%p,%x,%p)\n", This
, Rect
, DDSD
, Flags
, h
);
547 return DDERR_INVALIDPARAMS
;
549 /* Should I check for the handle to be NULL?
551 * The DDLOCK flags and the D3DLOCK flags are equal
552 * for the supported values. The others are ignored by WineD3D
555 /* Hmm. Anarchy online passes an uninitialized surface descriptor,
556 * that means it doesn't have dwSize set. Init it to some sane
559 if(DDSD
->dwSize
<= sizeof(DDSURFACEDESC
))
561 DDSD
->dwSize
= sizeof(DDSURFACEDESC
);
565 DDSD
->dwSize
= sizeof(DDSURFACEDESC2
);
568 DD_STRUCT_COPY_BYSIZE(DDSD
,&(This
->surface_desc
));
569 hr
= IWineD3DSurface_LockRect(This
->WineD3DSurface
,
573 if(hr
!= D3D_OK
) return hr
;
575 /* Override the memory area and the pitch */
576 DDSD
->dwFlags
|= DDSD_LPSURFACE
;
577 DDSD
->lpSurface
= LockedRect
.pBits
;
578 DDSD
->dwFlags
|= DDSD_PITCH
;
579 DDSD
->u1
.lPitch
= LockedRect
.Pitch
;
581 TRACE("locked surface returning description :\n");
582 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(DDSD
);
587 /*****************************************************************************
588 * IDirectDrawSurface7::Unlock
590 * Unlocks an locked surface
593 * Rect: Not used by this implementation
597 * For more details, see IWineD3DSurface::UnlockRect
599 *****************************************************************************/
600 static HRESULT WINAPI
601 IDirectDrawSurfaceImpl_Unlock(IDirectDrawSurface7
*iface
,
604 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
605 TRACE("(%p)->(%p)\n", This
, pRect
);
607 return IWineD3DSurface_UnlockRect(This
->WineD3DSurface
);
610 /*****************************************************************************
611 * IDirectDrawSurface7::Flip
613 * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
614 * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
615 * the flip target is passed to WineD3D, even if the app didn't specify one
618 * DestOverride: Specifies the surface that will become the new front
619 * buffer. If NULL, the current back buffer is used
620 * Flags: some DirectDraw flags, see include/ddraw.h
624 * DDERR_NOTFLIPPABLE if no flip target could be found
625 * DDERR_INVALIDOBJECT if the surface isn't a front buffer
626 * For more details, see IWineD3DSurface::Flip
628 *****************************************************************************/
629 static HRESULT WINAPI
630 IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7
*iface
,
631 IDirectDrawSurface7
*DestOverride
,
634 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
635 IDirectDrawSurfaceImpl
*Override
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DestOverride
);
636 IDirectDrawSurface7
*Override7
;
638 TRACE("(%p)->(%p,%x)\n", This
, DestOverride
, Flags
);
640 /* Flip has to be called from a front buffer
641 * What about overlay surfaces, AFAIK they can flip too?
643 if( !(This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_FRONTBUFFER
) )
644 return DDERR_INVALIDOBJECT
; /* Unckecked */
646 /* WineD3D doesn't keep track of attached surface, so find the target */
651 memset(&Caps
, 0, sizeof(Caps
));
652 Caps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
653 hr
= IDirectDrawSurface7_GetAttachedSurface(iface
, &Caps
, &Override7
);
656 ERR("Can't find a flip target\n");
657 return DDERR_NOTFLIPPABLE
; /* Unchecked */
659 Override
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Override7
);
661 /* For the GetAttachedSurface */
662 IDirectDrawSurface7_Release(Override7
);
665 return IWineD3DSurface_Flip(This
->WineD3DSurface
,
666 Override
->WineD3DSurface
,
670 /*****************************************************************************
671 * IDirectDrawSurface7::Blt
673 * Performs a blit on the surface
676 * DestRect: Destination rectangle, can be NULL
677 * SrcSurface: Source surface, can be NULL
678 * SrcRect: Source rectange, can be NULL
680 * DDBltFx: Some extended blt parameters, connected to the flags
684 * See IWineD3DSurface::Blt for more details
686 *****************************************************************************/
687 static HRESULT WINAPI
688 IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7
*iface
,
690 IDirectDrawSurface7
*SrcSurface
,
695 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
697 IDirectDrawSurfaceImpl
*Src
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, SrcSurface
);
698 TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This
, DestRect
, Src
, SrcRect
, Flags
, DDBltFx
);
700 /* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have
701 * to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-)
703 if((Flags
& DDBLT_KEYSRCOVERRIDE
) && (!DDBltFx
|| Flags
& DDBLT_KEYSRC
)) {
704 WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
705 return DDERR_INVALIDPARAMS
;
708 if((Flags
& DDBLT_KEYDESTOVERRIDE
) && (!DDBltFx
|| Flags
& DDBLT_KEYDEST
)) {
709 WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
710 return DDERR_INVALIDPARAMS
;
713 if(Flags
& DDBLT_KEYSRC
&& (!Src
|| !(Src
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
))) {
714 WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
715 return DDERR_INVALIDPARAMS
;
718 /* TODO: Check if the DDBltFx contains any ddraw surface pointers. If it does, copy the struct,
719 * and replace the ddraw surfaces with the wined3d surfaces
720 * So far no blitting operations using surfaces in the bltfx struct are supported anyway.
722 hr
= IWineD3DSurface_Blt(This
->WineD3DSurface
,
724 Src
? Src
->WineD3DSurface
: NULL
,
727 (WINEDDBLTFX
*) DDBltFx
,
731 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
732 case WINED3DERR_WRONGTEXTUREFORMAT
: return DDERR_INVALIDPIXELFORMAT
;
737 /*****************************************************************************
738 * IDirectDrawSurface7::AddAttachedSurface
740 * Attaches a surface to another surface. Surface attachments are
741 * incorrectly described in the SDK and the MSDN, and this method
742 * is prone to bugs. The surface that is attached is AddRef-ed.
744 * The attachment list consists of a first surface (first_attached) and
745 * for each surface a pointer to the next attached surface (next_attached).
746 * For the first surface, and a surface that has no attachments
747 * first_attached points to the surface itself. A surface that has
748 * no successors in the chain has next_attached set to NULL.
750 * Newly attached surfaces are attached right after the root surface. The
751 * complex chains are handled separately in a similar chain, with
752 * first_complex and next_complex. If a surface is attached to a complex
753 * surface compound, it's attached to the surface that the app requested,
754 * not the complex root. See GetAttachedSurface for a description
755 * how surfaces are found.
757 * This is how the current implementation works, and it was coded by looking
758 * at the needs of the applications.
760 * So far only Z-Buffer attachments are tested, but there's no code yet
761 * to activate them. Mipmaps could be tricky to activate in WineD3D.
762 * Back buffers should work in 2D mode, but they are not tested.
763 * Rendering to the primary surface and switching between that and
764 * double buffering is not yet implemented in WineD3D, so for 3D it might
765 * have unexpected results.
768 * Attach: Surface to attach to iface
772 * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
774 *****************************************************************************/
775 static HRESULT WINAPI
776 IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7
*iface
,
777 IDirectDrawSurface7
*Attach
)
779 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
780 IDirectDrawSurfaceImpl
*Surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Attach
);
781 TRACE("(%p)->(%p)\n", This
, Surf
);
783 /* Should I make sure to add it to the first complex surface? */
786 return DDERR_CANNOTATTACHSURFACE
; /* unchecked */
788 /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
789 * But apparently backbuffers and mipmaps can be attached too. */
791 /* Set MIPMAPSUBLEVEL if this seems to be one */
792 if (This
->surface_desc
.ddsCaps
.dwCaps
&
793 Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
795 Surf
->surface_desc
.ddsCaps
.dwCaps2
|= DDSCAPS2_MIPMAPSUBLEVEL
;
796 /* FIXME: we should probably also add to dwMipMapCount of this
797 * and all parent surfaces (update create_texture if you do) */
800 /* Check if the surface is already attached somewhere */
801 if( (Surf
->next_attached
!= NULL
) ||
802 (Surf
->first_attached
!= Surf
) )
804 ERR("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This
, Surf
, Surf
->next_attached
, Surf
->first_attached
);
805 return DDERR_CANNOTATTACHSURFACE
;
808 /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
809 Surf
->next_attached
= This
->next_attached
;
810 Surf
->first_attached
= This
->first_attached
;
811 This
->next_attached
= Surf
;
813 /* Check if we attach a back buffer to the primary */
814 if(Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
&&
815 This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
817 IWineD3DDevice_SetDepthStencilSurface(This
->ddraw
->wineD3DDevice
,
818 Surf
->WineD3DSurface
);
822 * "This method increments the reference count of the surface being attached."
824 IDirectDrawSurface7_AddRef(Attach
);
828 /*****************************************************************************
829 * IDirectDrawSurface7::DeleteAttachedSurface
831 * Removes a surface from the attachment chain. The surface's refcount
832 * is decreased by one after it has been removed
835 * Flags: Some flags, not used by this implementation
836 * Attach: Surface to detach
840 * DDERR_SURFACENOTATTACHED if the surface isn't attached to
842 *****************************************************************************/
843 static HRESULT WINAPI
844 IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7
*iface
,
846 IDirectDrawSurface7
*Attach
)
848 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
849 IDirectDrawSurfaceImpl
*Surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Attach
);
850 IDirectDrawSurfaceImpl
*Prev
= This
;
851 TRACE("(%p)->(%08x,%p)\n", This
, Flags
, Surf
);
853 if (!Surf
|| (Surf
->first_attached
!= This
) || (Surf
== This
) )
854 return DDERR_SURFACENOTATTACHED
; /* unchecked */
856 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
857 if (This
->surface_desc
.ddsCaps
.dwCaps
&
858 Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
860 Surf
->surface_desc
.ddsCaps
.dwCaps2
&= ~DDSCAPS2_MIPMAPSUBLEVEL
;
861 /* FIXME: we should probably also subtract from dwMipMapCount of this
862 * and all parent surfaces */
865 /* Find the predecessor of the detached surface */
868 if(Prev
->next_attached
== Surf
) break;
869 Prev
= Prev
->next_attached
;
872 /* There must be a surface, otherwise there's a bug */
873 assert(Prev
!= NULL
);
875 /* Unchain the surface */
876 Prev
->next_attached
= Surf
->next_attached
;
877 Surf
->next_attached
= NULL
;
878 Surf
->first_attached
= Surf
;
880 /* Check if we attach a back buffer to the primary */
881 if(Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
&&
882 This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
884 IWineD3DDevice_SetDepthStencilSurface(This
->ddraw
->wineD3DDevice
,
888 IDirectDrawSurface7_Release(Attach
);
892 /*****************************************************************************
893 * IDirectDrawSurface7::AddOverlayDirtyRect
895 * "This method is not currently implemented"
903 *****************************************************************************/
904 static HRESULT WINAPI
905 IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7
*iface
,
908 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
909 TRACE("(%p)->(%p)\n",This
,Rect
);
911 /* MSDN says it's not implemented. I could forward it to WineD3D,
912 * then we'd implement it, but I don't think that's a good idea
916 return IWineD3DSurface_AddOverlayDirtyRect(This
->WineD3DSurface
, pRect
);
918 return DDERR_UNSUPPORTED
; /* unchecked */
921 /*****************************************************************************
922 * IDirectDrawSurface7::GetDC
924 * Returns a GDI device context for the surface
927 * hdc: Address of a HDC variable to store the dc to
931 * DDERR_INVALIDPARAMS if hdc is NULL
932 * For details, see IWineD3DSurface::GetDC
934 *****************************************************************************/
935 static HRESULT WINAPI
936 IDirectDrawSurfaceImpl_GetDC(IDirectDrawSurface7
*iface
,
939 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
940 TRACE("(%p)->(%p): Relay\n", This
, hdc
);
943 return DDERR_INVALIDPARAMS
;
945 return IWineD3DSurface_GetDC(This
->WineD3DSurface
,
949 /*****************************************************************************
950 * IDirectDrawSurface7::ReleaseDC
952 * Releases the DC that was constructed with GetDC
955 * hdc: HDC to release
959 * For more details, see IWineD3DSurface::ReleaseDC
961 *****************************************************************************/
962 static HRESULT WINAPI
963 IDirectDrawSurfaceImpl_ReleaseDC(IDirectDrawSurface7
*iface
,
966 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
967 TRACE("(%p)->(%p): Relay\n", This
, hdc
);
969 return IWineD3DSurface_ReleaseDC(This
->WineD3DSurface
, hdc
);
972 /*****************************************************************************
973 * IDirectDrawSurface7::GetCaps
975 * Returns the surface's caps
978 * Caps: Address to write the caps to
982 * DDERR_INVALIDPARAMS if Caps is NULL
984 *****************************************************************************/
985 static HRESULT WINAPI
986 IDirectDrawSurfaceImpl_GetCaps(IDirectDrawSurface7
*iface
,
989 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
990 TRACE("(%p)->(%p)\n",This
,Caps
);
993 return DDERR_INVALIDPARAMS
;
995 *Caps
= This
->surface_desc
.ddsCaps
;
999 /*****************************************************************************
1000 * IDirectDrawSurface7::SetPriority
1002 * Sets a texture priority for managed textures.
1005 * Priority: The new priority
1009 * For more details, see IWineD3DSurface::SetPriority
1011 *****************************************************************************/
1012 static HRESULT WINAPI
1013 IDirectDrawSurfaceImpl_SetPriority(IDirectDrawSurface7
*iface
, DWORD Priority
)
1015 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1016 TRACE("(%p)->(%d): Relay!\n",This
,Priority
);
1018 return IWineD3DSurface_SetPriority(This
->WineD3DSurface
, Priority
);
1021 /*****************************************************************************
1022 * IDirectDrawSurface7::GetPriority
1024 * Returns the surface's priority
1027 * Priority: Address of a variable to write the priority to
1031 * DDERR_INVALIDPARAMS if Priority == NULL
1032 * For more details, see IWineD3DSurface::GetPriority
1034 *****************************************************************************/
1035 static HRESULT WINAPI
1036 IDirectDrawSurfaceImpl_GetPriority(IDirectDrawSurface7
*iface
,
1039 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1040 TRACE("(%p)->(%p): Relay\n",This
,Priority
);
1043 return DDERR_INVALIDPARAMS
;
1045 *Priority
= IWineD3DSurface_GetPriority(This
->WineD3DSurface
);
1049 /*****************************************************************************
1050 * IDirectDrawSurface7::SetPrivateData
1052 * Stores some data in the surface that is intended for the application's
1056 * tag: GUID that identifies the data
1057 * Data: Pointer to the private data
1058 * Size: Size of the private data
1063 * For more details, see IWineD3DSurface::SetPrivateData
1065 *****************************************************************************/
1066 static HRESULT WINAPI
1067 IDirectDrawSurfaceImpl_SetPrivateData(IDirectDrawSurface7
*iface
,
1073 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1074 TRACE("(%p)->(%s,%p,%d,%x): Relay\n", This
, debugstr_guid(tag
), Data
, Size
, Flags
);
1076 return IWineD3DSurface_SetPrivateData(This
->WineD3DSurface
,
1083 /*****************************************************************************
1084 * IDirectDrawSurface7::GetPrivateData
1086 * Returns the private data set with IDirectDrawSurface7::SetPrivateData
1089 * tag: GUID of the data to return
1090 * Data: Address where to write the data to
1091 * Size: Size of the buffer at Data
1095 * DDERR_INVALIDPARAMS if Data is NULL
1096 * For more details, see IWineD3DSurface::GetPrivateData
1098 *****************************************************************************/
1099 static HRESULT WINAPI
1100 IDirectDrawSurfaceImpl_GetPrivateData(IDirectDrawSurface7
*iface
,
1105 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1106 TRACE("(%p)->(%s,%p,%p): Relay\n", This
, debugstr_guid(tag
), Data
, Size
);
1109 return DDERR_INVALIDPARAMS
;
1111 return IWineD3DSurface_GetPrivateData(This
->WineD3DSurface
,
1117 /*****************************************************************************
1118 * IDirectDrawSurface7::FreePrivateData
1120 * Frees private data stored in the surface
1123 * tag: Tag of the data to free
1127 * For more details, see IWineD3DSurface::FreePrivateData
1129 *****************************************************************************/
1130 static HRESULT WINAPI
1131 IDirectDrawSurfaceImpl_FreePrivateData(IDirectDrawSurface7
*iface
,
1134 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1135 TRACE("(%p)->(%s): Relay\n", This
, debugstr_guid(tag
));
1137 return IWineD3DSurface_FreePrivateData(This
->WineD3DSurface
, tag
);
1140 /*****************************************************************************
1141 * IDirectDrawSurface7::PageLock
1143 * Prevents a sysmem surface from being paged out
1146 * Flags: Not used, must be 0(unchecked)
1149 * DD_OK, because it's a stub
1151 *****************************************************************************/
1152 static HRESULT WINAPI
1153 IDirectDrawSurfaceImpl_PageLock(IDirectDrawSurface7
*iface
,
1156 TRACE("(%p)->(%x)\n", iface
, Flags
);
1158 /* This is Windows memory management related - we don't need this */
1162 /*****************************************************************************
1163 * IDirectDrawSurface7::PageUnlock
1165 * Allows a sysmem surface to be paged out
1168 * Flags: Not used, must be 0(unckeched)
1171 * DD_OK, because it's a stub
1173 *****************************************************************************/
1174 static HRESULT WINAPI
1175 IDirectDrawSurfaceImpl_PageUnlock(IDirectDrawSurface7
*iface
,
1178 TRACE("(%p)->(%x)\n", iface
, Flags
);
1183 /*****************************************************************************
1184 * IDirectDrawSurface7::BltBatch
1186 * An unimplemented function
1194 *****************************************************************************/
1195 static HRESULT WINAPI
IDirectDrawSurfaceImpl_BltBatch(IDirectDrawSurface7
*iface
, DDBLTBATCH
*Batch
, DWORD Count
, DWORD Flags
)
1197 TRACE("(%p)->(%p,%d,%08x)\n",iface
,Batch
,Count
,Flags
);
1199 /* MSDN: "not currently implemented" */
1200 return DDERR_UNSUPPORTED
;
1203 /*****************************************************************************
1204 * IDirectDrawSurface7::EnumAttachedSurfaces
1206 * Enumerates all surfaces attached to this surface
1209 * context: Pointer to pass unmodified to the callback
1210 * cb: Callback function to call for each surface
1214 * DDERR_INVALIDPARAMS if cb is NULL
1216 *****************************************************************************/
1217 static HRESULT WINAPI
1218 IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7
*iface
,
1220 LPDDENUMSURFACESCALLBACK7 cb
)
1222 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1223 IDirectDrawSurfaceImpl
*surf
;
1224 DDSURFACEDESC2 desc
;
1226 /* Attached surfaces aren't handled in WineD3D */
1227 TRACE("(%p)->(%p,%p)\n",This
,context
,cb
);
1230 return DDERR_INVALIDPARAMS
;
1232 for (surf
= This
->next_complex
; surf
!= NULL
; surf
= surf
->next_complex
)
1234 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf
, IDirectDrawSurface7
));
1235 desc
= surf
->surface_desc
;
1236 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
1237 if (cb(ICOM_INTERFACE(surf
, IDirectDrawSurface7
), &desc
, context
) == DDENUMRET_CANCEL
)
1241 for (surf
= This
->next_attached
; surf
!= NULL
; surf
= surf
->next_attached
)
1243 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf
, IDirectDrawSurface7
));
1244 desc
= surf
->surface_desc
;
1245 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
1246 if (cb( ICOM_INTERFACE(surf
, IDirectDrawSurface7
), &desc
, context
) == DDENUMRET_CANCEL
)
1250 TRACE(" end of enumeration.\n");
1255 /*****************************************************************************
1256 * IDirectDrawSurface7::EnumOverlayZOrders
1258 * "Enumerates the overlay surfaces on the specified destination"
1261 * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK
1262 * context: context to pass back to the callback
1263 * cb: callback function to call for each enumerated surface
1266 * DD_OK, because it's a stub
1268 *****************************************************************************/
1269 static HRESULT WINAPI
1270 IDirectDrawSurfaceImpl_EnumOverlayZOrders(IDirectDrawSurface7
*iface
,
1273 LPDDENUMSURFACESCALLBACK7 cb
)
1275 FIXME("(%p)->(%x,%p,%p): Stub!\n", iface
, Flags
, context
, cb
);
1280 /*****************************************************************************
1281 * IDirectDrawSurface7::GetBltStatus
1283 * Returns the blitting status
1286 * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
1289 * See IWineD3DSurface::Blt
1291 *****************************************************************************/
1292 static HRESULT WINAPI
1293 IDirectDrawSurfaceImpl_GetBltStatus(IDirectDrawSurface7
*iface
,
1296 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1298 TRACE("(%p)->(%x): Relay\n", This
, Flags
);
1300 hr
= IWineD3DSurface_GetBltStatus(This
->WineD3DSurface
, Flags
);
1303 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
1308 /*****************************************************************************
1309 * IDirectDrawSurface7::GetColorKey
1311 * Returns the color key assigned to the surface
1315 * CKey: Address to store the key to
1319 * DDERR_INVALIDPARAMS if CKey is NULL
1321 *****************************************************************************/
1322 static HRESULT WINAPI
1323 IDirectDrawSurfaceImpl_GetColorKey(IDirectDrawSurface7
*iface
,
1327 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
1328 * isn't there? That's like saying that an int isn't there. (Which MS
1329 * has done in other docs.) */
1330 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1331 TRACE("(%p)->(%08x,%p)\n", This
, Flags
, CKey
);
1334 return DDERR_INVALIDPARAMS
;
1338 case DDCKEY_DESTBLT
:
1339 *CKey
= This
->surface_desc
.ddckCKDestBlt
;
1342 case DDCKEY_DESTOVERLAY
:
1343 *CKey
= This
->surface_desc
.u3
.ddckCKDestOverlay
;
1347 *CKey
= This
->surface_desc
.ddckCKSrcBlt
;
1350 case DDCKEY_SRCOVERLAY
:
1351 *CKey
= This
->surface_desc
.ddckCKSrcOverlay
;
1355 return DDERR_INVALIDPARAMS
;
1361 /*****************************************************************************
1362 * IDirectDrawSurface7::GetFlipStatus
1364 * Returns the flipping status of the surface
1367 * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
1370 * See IWineD3DSurface::GetFlipStatus
1372 *****************************************************************************/
1373 static HRESULT WINAPI
1374 IDirectDrawSurfaceImpl_GetFlipStatus(IDirectDrawSurface7
*iface
,
1377 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1379 TRACE("(%p)->(%x): Relay\n", This
, Flags
);
1381 hr
= IWineD3DSurface_GetFlipStatus(This
->WineD3DSurface
, Flags
);
1384 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
1389 /*****************************************************************************
1390 * IDirectDrawSurface7::GetOverlayPosition
1392 * Returns the display coordinates of a visible and active overlay surface
1399 * DDERR_NOTAOVERLAYSURFACE, because it's a stub
1400 *****************************************************************************/
1401 static HRESULT WINAPI
1402 IDirectDrawSurfaceImpl_GetOverlayPosition(IDirectDrawSurface7
*iface
,
1405 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1406 TRACE("(%p)->(%p,%p): Relay\n", This
, X
, Y
);
1408 return IWineD3DSurface_GetOverlayPosition(This
->WineD3DSurface
,
1413 /*****************************************************************************
1414 * IDirectDrawSurface7::GetPixelFormat
1416 * Returns the pixel format of the Surface
1419 * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
1420 * format should be written
1424 * DDERR_INVALIDPARAMS if PixelFormat is NULL
1426 *****************************************************************************/
1427 static HRESULT WINAPI
1428 IDirectDrawSurfaceImpl_GetPixelFormat(IDirectDrawSurface7
*iface
,
1429 DDPIXELFORMAT
*PixelFormat
)
1431 /* What is DDERR_INVALIDSURFACETYPE for here? */
1432 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1433 TRACE("(%p)->(%p)\n",This
,PixelFormat
);
1436 return DDERR_INVALIDPARAMS
;
1438 DD_STRUCT_COPY_BYSIZE(PixelFormat
,&This
->surface_desc
.u4
.ddpfPixelFormat
);
1444 /*****************************************************************************
1445 * IDirectDrawSurface7::GetSurfaceDesc
1447 * Returns the description of this surface
1450 * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
1455 * DDERR_INVALIDPARAMS if DDSD is NULL
1457 *****************************************************************************/
1458 static HRESULT WINAPI
1459 IDirectDrawSurfaceImpl_GetSurfaceDesc(IDirectDrawSurface7
*iface
,
1460 DDSURFACEDESC2
*DDSD
)
1462 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1464 TRACE("(%p)->(%p)\n",This
,DDSD
);
1467 return DDERR_INVALIDPARAMS
;
1469 if ((DDSD
->dwSize
< sizeof(DDSURFACEDESC
)) ||
1470 (DDSD
->dwSize
> sizeof(DDSURFACEDESC2
)))
1472 ERR("Impossible/Strange struct size %d.\n",DDSD
->dwSize
);
1473 return DDERR_GENERIC
;
1476 DD_STRUCT_COPY_BYSIZE(DDSD
,&This
->surface_desc
);
1477 TRACE("Returning surface desc:\n");
1478 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(DDSD
);
1483 /*****************************************************************************
1484 * IDirectDrawSurface7::Initialize
1486 * Initializes the surface. This is a no-op in Wine
1489 * DD: Pointer to an DirectDraw interface
1490 * DDSD: Surface description for initialization
1493 * DDERR_ALREADYINITIALIZED
1495 *****************************************************************************/
1496 static HRESULT WINAPI
1497 IDirectDrawSurfaceImpl_Initialize(IDirectDrawSurface7
*iface
,
1499 DDSURFACEDESC2
*DDSD
)
1501 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1502 IDirectDrawImpl
*ddimpl
= ICOM_OBJECT(IDirectDrawImpl
, IDirectDraw
, DD
);
1503 TRACE("(%p)->(%p,%p)\n",This
,ddimpl
,DDSD
);
1505 return DDERR_ALREADYINITIALIZED
;
1508 /*****************************************************************************
1509 * IDirectDrawSurface7::IsLost
1511 * Checks if the surface is lost
1514 * DD_OK, if the surface is useable
1515 * DDERR_ISLOST if the surface is lost
1516 * See IWineD3DSurface::IsLost for more details
1518 *****************************************************************************/
1519 static HRESULT WINAPI
1520 IDirectDrawSurfaceImpl_IsLost(IDirectDrawSurface7
*iface
)
1522 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1524 TRACE("(%p)\n", This
);
1526 /* We lose the surface if the implementation was changed */
1527 if(This
->ImplType
!= This
->ddraw
->ImplType
)
1529 /* But this shouldn't happen. When we change the implementation,
1530 * all surfaces are re-created automatically, and their content
1533 ERR(" (%p) Implementation was changed from %d to %d\n", This
, This
->ImplType
, This
->ddraw
->ImplType
);
1534 return DDERR_SURFACELOST
;
1537 hr
= IWineD3DSurface_IsLost(This
->WineD3DSurface
);
1540 /* D3D8 and 9 loose full devices, thus there's only a DEVICELOST error.
1541 * WineD3D uses the same error for surfaces
1543 case WINED3DERR_DEVICELOST
: return DDERR_SURFACELOST
;
1548 /*****************************************************************************
1549 * IDirectDrawSurface7::Restore
1551 * Restores a lost surface. This makes the surface usable again, but
1552 * doesn't reload its old contents
1556 * See IWineD3DSurface::Restore for more details
1558 *****************************************************************************/
1559 static HRESULT WINAPI
1560 IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7
*iface
)
1562 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1563 TRACE("(%p)\n", This
);
1565 if(This
->ImplType
!= This
->ddraw
->ImplType
)
1567 /* Call the recreation callback. Make sure to AddRef first */
1568 IDirectDrawSurface_AddRef(iface
);
1569 IDirectDrawImpl_RecreateSurfacesCallback(iface
,
1570 &This
->surface_desc
,
1571 NULL
/* Not needed */);
1573 return IWineD3DSurface_Restore(This
->WineD3DSurface
);
1576 /*****************************************************************************
1577 * IDirectDrawSurface7::SetOverlayPosition
1579 * Changes the display coordinates of an overlay surface
1586 * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
1587 *****************************************************************************/
1588 static HRESULT WINAPI
1589 IDirectDrawSurfaceImpl_SetOverlayPosition(IDirectDrawSurface7
*iface
,
1593 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1594 TRACE("(%p)->(%d,%d): Relay\n", This
, X
, Y
);
1596 return IWineD3DSurface_SetOverlayPosition(This
->WineD3DSurface
,
1601 /*****************************************************************************
1602 * IDirectDrawSurface7::UpdateOverlay
1604 * Modifies the attributes of an overlay surface.
1607 * SrcRect: The section of the source being used for the overlay
1608 * DstSurface: Address of the surface that is overlaid
1609 * DstRect: Place of the overlay
1610 * Flags: some DDOVER_* flags
1613 * DDERR_UNSUPPORTED, because we don't support overlays
1615 *****************************************************************************/
1616 static HRESULT WINAPI
1617 IDirectDrawSurfaceImpl_UpdateOverlay(IDirectDrawSurface7
*iface
,
1619 IDirectDrawSurface7
*DstSurface
,
1624 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1625 IDirectDrawSurfaceImpl
*Dst
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DstSurface
);
1626 TRACE("(%p)->(%p,%p,%p,%x,%p): Relay\n", This
, SrcRect
, Dst
, DstRect
, Flags
, FX
);
1628 return IWineD3DSurface_UpdateOverlay(This
->WineD3DSurface
,
1630 Dst
? Dst
->WineD3DSurface
: NULL
,
1633 (WINEDDOVERLAYFX
*) FX
);
1636 /*****************************************************************************
1637 * IDirectDrawSurface7::UpdateOverlayDisplay
1639 * The DX7 sdk says that it's not implemented
1644 * Returns: DDERR_UNSUPPORTED, because we don't support overlays
1646 *****************************************************************************/
1647 static HRESULT WINAPI
1648 IDirectDrawSurfaceImpl_UpdateOverlayDisplay(IDirectDrawSurface7
*iface
,
1651 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1652 TRACE("(%p)->(%x)\n", This
, Flags
);
1653 return DDERR_UNSUPPORTED
;
1656 /*****************************************************************************
1657 * IDirectDrawSurface7::UpdateOverlayZOrder
1659 * Sets an overlay's Z order
1662 * Flags: DDOVERZ_* flags
1663 * DDSRef: Defines the relative position in the overlay chain
1666 * DDERR_NOTOVERLAYSURFACE, because we don't support overlays
1668 *****************************************************************************/
1669 static HRESULT WINAPI
1670 IDirectDrawSurfaceImpl_UpdateOverlayZOrder(IDirectDrawSurface7
*iface
,
1672 IDirectDrawSurface7
*DDSRef
)
1674 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1675 IDirectDrawSurfaceImpl
*Ref
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DDSRef
);
1677 TRACE("(%p)->(%x,%p): Relay\n", This
, Flags
, Ref
);
1678 return IWineD3DSurface_UpdateOverlayZOrder(This
->WineD3DSurface
,
1680 Ref
? Ref
->WineD3DSurface
: NULL
);
1683 /*****************************************************************************
1684 * IDirectDrawSurface7::GetDDInterface
1686 * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
1687 * surface belongs to
1690 * DD: Address to write the interface pointer to
1694 * DDERR_INVALIDPARAMS if DD is NULL
1696 *****************************************************************************/
1697 static HRESULT WINAPI
1698 IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7
*iface
,
1701 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1703 TRACE("(%p)->(%p)\n",This
,DD
);
1706 return DDERR_INVALIDPARAMS
;
1708 switch(This
->version
)
1711 *((IDirectDraw7
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw7
);
1712 IDirectDraw7_AddRef(*(IDirectDraw7
**) DD
);
1716 *((IDirectDraw4
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw4
);
1717 IDirectDraw4_AddRef(*(IDirectDraw4
**) DD
);
1721 *((IDirectDraw2
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw2
);
1722 IDirectDraw_AddRef( *(IDirectDraw2
**) DD
);
1726 *((IDirectDraw
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw
);
1727 IDirectDraw_AddRef( *(IDirectDraw
**) DD
);
1735 /* This seems also windows implementation specific - I don't think WineD3D needs this */
1736 static HRESULT WINAPI
IDirectDrawSurfaceImpl_ChangeUniquenessValue(IDirectDrawSurface7
*iface
)
1738 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1739 volatile IDirectDrawSurfaceImpl
* vThis
= This
;
1741 TRACE("(%p)\n",This
);
1742 /* A uniqueness value of 0 is apparently special.
1743 * This needs to be checked. */
1745 DWORD old_uniqueness_value
= vThis
->uniqueness_value
;
1746 DWORD new_uniqueness_value
= old_uniqueness_value
+1;
1748 if (old_uniqueness_value
== 0) break;
1749 if (new_uniqueness_value
== 0) new_uniqueness_value
= 1;
1751 if (InterlockedCompareExchange((LONG
*)&vThis
->uniqueness_value
,
1752 old_uniqueness_value
,
1753 new_uniqueness_value
)
1754 == old_uniqueness_value
)
1761 static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetUniquenessValue(IDirectDrawSurface7
*iface
, LPDWORD pValue
)
1763 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1765 TRACE("(%p)->(%p)\n",This
,pValue
);
1766 *pValue
= This
->uniqueness_value
;
1770 /*****************************************************************************
1771 * IDirectDrawSurface7::SetLOD
1773 * Sets the level of detail of a texture
1776 * MaxLOD: LOD to set
1780 * DDERR_INVALIDOBJECT if the surface is invalid for this method
1782 *****************************************************************************/
1783 static HRESULT WINAPI
1784 IDirectDrawSurfaceImpl_SetLOD(IDirectDrawSurface7
*iface
,
1787 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1788 TRACE("(%p)->(%d)\n", This
, MaxLOD
);
1790 if (!(This
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
1791 return DDERR_INVALIDOBJECT
;
1793 if(!This
->wineD3DTexture
)
1795 ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This
);
1796 return DDERR_INVALIDOBJECT
;
1799 return IWineD3DTexture_SetLOD(This
->wineD3DTexture
,
1803 /*****************************************************************************
1804 * IDirectDrawSurface7::GetLOD
1806 * Returns the level of detail of a Direct3D texture
1809 * MaxLOD: Address to write the LOD to
1813 * DDERR_INVALIDPARAMS if MaxLOD is NULL
1814 * DDERR_INVALIDOBJECT if the surface is invalid for this method
1816 *****************************************************************************/
1817 static HRESULT WINAPI
1818 IDirectDrawSurfaceImpl_GetLOD(IDirectDrawSurface7
*iface
,
1821 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1822 TRACE("(%p)->(%p)\n", This
, MaxLOD
);
1825 return DDERR_INVALIDPARAMS
;
1827 if (!(This
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
1828 return DDERR_INVALIDOBJECT
;
1830 *MaxLOD
= IWineD3DTexture_GetLOD(This
->wineD3DTexture
);
1834 /*****************************************************************************
1835 * IDirectDrawSurface7::BltFast
1837 * Performs a fast Blit.
1840 * dstx: The x coordinate to blit to on the destination
1841 * dsty: The y coordinate to blit to on the destination
1842 * Source: The source surface
1843 * rsrc: The source rectangle
1844 * trans: Type of transfer. Some DDBLTFAST_* flags
1848 * For more details, see IWineD3DSurface::BltFast
1850 *****************************************************************************/
1851 static HRESULT WINAPI
1852 IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7
*iface
,
1855 IDirectDrawSurface7
*Source
,
1859 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1861 IDirectDrawSurfaceImpl
*src
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Source
);
1862 TRACE("(%p)->(%d,%d,%p,%p,%d): Relay\n", This
, dstx
, dsty
, Source
, rsrc
, trans
);
1864 hr
= IWineD3DSurface_BltFast(This
->WineD3DSurface
,
1866 src
? src
->WineD3DSurface
: NULL
,
1871 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
1872 case WINED3DERR_WRONGTEXTUREFORMAT
: return DDERR_INVALIDPIXELFORMAT
;
1877 /*****************************************************************************
1878 * IDirectDrawSurface7::GetClipper
1880 * Returns the IDirectDrawClipper interface of the clipper assigned to this
1884 * Clipper: Address to store the interface pointer at
1888 * DDERR_INVALIDPARAMS if Clipper is NULL
1889 * DDERR_NOCLIPPERATTACHED if there's no clipper attached
1891 *****************************************************************************/
1892 static HRESULT WINAPI
1893 IDirectDrawSurfaceImpl_GetClipper(IDirectDrawSurface7
*iface
,
1894 IDirectDrawClipper
**Clipper
)
1896 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1897 TRACE("(%p)->(%p)\n", This
, Clipper
);
1900 return DDERR_INVALIDPARAMS
;
1902 if(This
->clipper
== NULL
)
1903 return DDERR_NOCLIPPERATTACHED
;
1905 *Clipper
= ICOM_INTERFACE(This
->clipper
, IDirectDrawClipper
);
1906 IDirectDrawClipper_AddRef(*Clipper
);
1910 /*****************************************************************************
1911 * IDirectDrawSurface7::SetClipper
1913 * Sets a clipper for the surface
1916 * Clipper: IDirectDrawClipper interface of the clipper to set
1921 *****************************************************************************/
1922 static HRESULT WINAPI
1923 IDirectDrawSurfaceImpl_SetClipper(IDirectDrawSurface7
*iface
,
1924 IDirectDrawClipper
*Clipper
)
1926 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1927 IDirectDrawClipperImpl
*oldClipper
= This
->clipper
;
1929 TRACE("(%p)->(%p)\n",This
,Clipper
);
1930 if (ICOM_OBJECT(IDirectDrawClipperImpl
, IDirectDrawClipper
, Clipper
) == This
->clipper
)
1933 This
->clipper
= ICOM_OBJECT(IDirectDrawClipperImpl
, IDirectDrawClipper
, Clipper
);
1935 if (Clipper
!= NULL
)
1936 IDirectDrawClipper_AddRef(Clipper
);
1938 IDirectDrawClipper_Release(ICOM_INTERFACE(oldClipper
, IDirectDrawClipper
));
1943 /*****************************************************************************
1944 * IDirectDrawSurface7::SetSurfaceDesc
1946 * Sets the surface description. It can override the pixel format, the surface
1948 * It's not really tested.
1951 * DDSD: Pointer to the new surface description to set
1956 * DDERR_INVALIDPARAMS if DDSD is NULL
1958 *****************************************************************************/
1959 static HRESULT WINAPI
1960 IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7
*iface
,
1961 DDSURFACEDESC2
*DDSD
,
1964 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1965 WINED3DFORMAT newFormat
= WINED3DFMT_UNKNOWN
;
1967 TRACE("(%p)->(%p,%x)\n", This
, DDSD
, Flags
);
1970 return DDERR_INVALIDPARAMS
;
1972 if (DDSD
->dwFlags
& DDSD_LPSURFACE
&& DDSD
->lpSurface
)
1974 ERR("Setting the surface memory isn't supported yet\n");
1975 return DDERR_INVALIDPARAMS
;
1978 if (DDSD
->dwFlags
& DDSD_PIXELFORMAT
)
1980 newFormat
= PixelFormat_DD2WineD3D(&DDSD
->u4
.ddpfPixelFormat
);
1982 if(newFormat
== WINED3DFMT_UNKNOWN
)
1984 ERR("Requested to set an unknown pixelformat\n");
1985 return DDERR_INVALIDPARAMS
;
1987 if(newFormat
!= PixelFormat_DD2WineD3D(&This
->surface_desc
.u4
.ddpfPixelFormat
) )
1989 hr
= IWineD3DSurface_SetFormat(This
->WineD3DSurface
,
1991 if(hr
!= DD_OK
) return hr
;
1994 if (DDSD
->dwFlags
& DDSD_CKDESTOVERLAY
)
1996 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
1998 (WINEDDCOLORKEY
*) &DDSD
->u3
.ddckCKDestOverlay
);
2000 if (DDSD
->dwFlags
& DDSD_CKDESTBLT
)
2002 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2004 (WINEDDCOLORKEY
*) &DDSD
->ddckCKDestBlt
);
2006 if (DDSD
->dwFlags
& DDSD_CKSRCOVERLAY
)
2008 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2010 (WINEDDCOLORKEY
*) &DDSD
->ddckCKSrcOverlay
);
2012 if (DDSD
->dwFlags
& DDSD_CKSRCBLT
)
2014 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2016 (WINEDDCOLORKEY
*) &DDSD
->ddckCKSrcBlt
);
2018 if (DDSD
->dwFlags
& DDSD_LPSURFACE
)
2020 hr
= IWineD3DSurface_SetMem(This
->WineD3DSurface
, DDSD
->lpSurface
);
2021 if(hr
!= WINED3D_OK
)
2023 /* No need for a trace here, wined3d does that for us */
2028 This
->surface_desc
= *DDSD
;
2033 /*****************************************************************************
2034 * IDirectDrawSurface7::GetPalette
2036 * Returns the IDirectDrawPalette interface of the palette currently assigned
2040 * Pal: Address to write the interface pointer to
2044 * DDERR_INVALIDPARAMS if Pal is NULL
2046 *****************************************************************************/
2047 static HRESULT WINAPI
2048 IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7
*iface
,
2049 IDirectDrawPalette
**Pal
)
2051 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2052 IWineD3DPalette
*wPal
;
2054 TRACE("(%p)->(%p): Relay\n", This
, Pal
);
2057 return DDERR_INVALIDPARAMS
;
2059 hr
= IWineD3DSurface_GetPalette(This
->WineD3DSurface
, &wPal
);
2060 if(hr
!= DD_OK
) return hr
;
2064 hr
= IWineD3DPalette_GetParent(wPal
, (IUnknown
**) Pal
);
2069 hr
= DDERR_NOPALETTEATTACHED
;
2075 /*****************************************************************************
2078 * EnumAttachedSurface callback for SetColorKey. Used to set color keys
2079 * recursively in the surface tree
2081 *****************************************************************************/
2085 WINEDDCOLORKEY
*CKey
;
2089 static HRESULT WINAPI
2090 SetColorKeyEnum(IDirectDrawSurface7
*surface
,
2091 DDSURFACEDESC2
*desc
,
2094 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, surface
);
2095 struct SCKContext
*ctx
= context
;
2098 hr
= IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2103 WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr
);
2107 IDirectDrawSurface7_EnumAttachedSurfaces(surface
,
2110 IDirectDrawSurface7_Release(surface
);
2111 return DDENUMRET_OK
;
2114 /*****************************************************************************
2115 * IDirectDrawSurface7::SetColorKey
2117 * Sets the color keying options for the surface. Observations showed that
2118 * in case of complex surfaces the color key has to be assigned to all
2123 * CKey: The new color key
2127 * See IWineD3DSurface::SetColorKey for details
2129 *****************************************************************************/
2130 static HRESULT WINAPI
2131 IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7
*iface
,
2135 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2136 struct SCKContext ctx
= { DD_OK
, (WINEDDCOLORKEY
*) CKey
, Flags
};
2137 TRACE("(%p)->(%x,%p)\n", This
, Flags
, CKey
);
2141 switch (Flags
& ~DDCKEY_COLORSPACE
)
2143 case DDCKEY_DESTBLT
:
2144 This
->surface_desc
.ddckCKDestBlt
= *CKey
;
2145 This
->surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
2148 case DDCKEY_DESTOVERLAY
:
2149 This
->surface_desc
.u3
.ddckCKDestOverlay
= *CKey
;
2150 This
->surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
2153 case DDCKEY_SRCOVERLAY
:
2154 This
->surface_desc
.ddckCKSrcOverlay
= *CKey
;
2155 This
->surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
2159 This
->surface_desc
.ddckCKSrcBlt
= *CKey
;
2160 This
->surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
2164 return DDERR_INVALIDPARAMS
;
2169 switch (Flags
& ~DDCKEY_COLORSPACE
)
2171 case DDCKEY_DESTBLT
:
2172 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTBLT
;
2175 case DDCKEY_DESTOVERLAY
:
2176 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTOVERLAY
;
2179 case DDCKEY_SRCOVERLAY
:
2180 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCOVERLAY
;
2184 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCBLT
;
2188 return DDERR_INVALIDPARAMS
;
2191 ctx
.ret
= IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2194 IDirectDrawSurface7_EnumAttachedSurfaces(iface
,
2199 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
2200 default: return ctx
.ret
;
2204 /*****************************************************************************
2205 * IDirectDrawSurface7::SetPalette
2207 * Assigns a DirectDrawPalette object to the surface
2210 * Pal: Interface to the palette to set
2215 *****************************************************************************/
2216 static HRESULT WINAPI
2217 IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7
*iface
,
2218 IDirectDrawPalette
*Pal
)
2220 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2221 IDirectDrawPalette
*oldPal
;
2222 IDirectDrawSurfaceImpl
*surf
;
2223 IDirectDrawPaletteImpl
*PalImpl
= ICOM_OBJECT(IDirectDrawPaletteImpl
, IDirectDrawPalette
, Pal
);
2225 TRACE("(%p)->(%p)\n", This
, Pal
);
2227 /* Find the old palette */
2228 hr
= IDirectDrawSurface_GetPalette(iface
, &oldPal
);
2229 if(hr
!= DD_OK
&& hr
!= DDERR_NOPALETTEATTACHED
) return hr
;
2230 if(oldPal
) IDirectDrawPalette_Release(oldPal
); /* For the GetPalette */
2232 /* Set the new Palette */
2233 IWineD3DSurface_SetPalette(This
->WineD3DSurface
,
2234 PalImpl
? PalImpl
->wineD3DPalette
: NULL
);
2235 /* AddRef the Palette */
2236 if(Pal
) IDirectDrawPalette_AddRef(Pal
);
2238 /* Release the old palette */
2239 if(oldPal
) IDirectDrawPalette_Release(oldPal
);
2241 /* If this is a front buffer, also update the back buffers
2242 * TODO: How do things work for palettized cube textures?
2244 if(This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_FRONTBUFFER
)
2246 /* For primary surfaces the tree is just a list, so the simpler scheme fits too */
2247 DDSCAPS2 caps2
= { DDSCAPS_PRIMARYSURFACE
, 0, 0, 0 };
2252 IDirectDrawSurface7
*attach
;
2254 hr
= IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(surf
, IDirectDrawSurface7
),
2261 IDirectDrawSurface7_SetPalette(attach
,
2263 surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, attach
);
2264 IDirectDrawSurface7_Release(attach
);
2271 /*****************************************************************************
2273 *****************************************************************************/
2275 const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl
=
2278 IDirectDrawSurfaceImpl_QueryInterface
,
2279 IDirectDrawSurfaceImpl_AddRef
,
2280 IDirectDrawSurfaceImpl_Release
,
2281 /*** IDirectDrawSurface ***/
2282 IDirectDrawSurfaceImpl_AddAttachedSurface
,
2283 IDirectDrawSurfaceImpl_AddOverlayDirtyRect
,
2284 IDirectDrawSurfaceImpl_Blt
,
2285 IDirectDrawSurfaceImpl_BltBatch
,
2286 IDirectDrawSurfaceImpl_BltFast
,
2287 IDirectDrawSurfaceImpl_DeleteAttachedSurface
,
2288 IDirectDrawSurfaceImpl_EnumAttachedSurfaces
,
2289 IDirectDrawSurfaceImpl_EnumOverlayZOrders
,
2290 IDirectDrawSurfaceImpl_Flip
,
2291 IDirectDrawSurfaceImpl_GetAttachedSurface
,
2292 IDirectDrawSurfaceImpl_GetBltStatus
,
2293 IDirectDrawSurfaceImpl_GetCaps
,
2294 IDirectDrawSurfaceImpl_GetClipper
,
2295 IDirectDrawSurfaceImpl_GetColorKey
,
2296 IDirectDrawSurfaceImpl_GetDC
,
2297 IDirectDrawSurfaceImpl_GetFlipStatus
,
2298 IDirectDrawSurfaceImpl_GetOverlayPosition
,
2299 IDirectDrawSurfaceImpl_GetPalette
,
2300 IDirectDrawSurfaceImpl_GetPixelFormat
,
2301 IDirectDrawSurfaceImpl_GetSurfaceDesc
,
2302 IDirectDrawSurfaceImpl_Initialize
,
2303 IDirectDrawSurfaceImpl_IsLost
,
2304 IDirectDrawSurfaceImpl_Lock
,
2305 IDirectDrawSurfaceImpl_ReleaseDC
,
2306 IDirectDrawSurfaceImpl_Restore
,
2307 IDirectDrawSurfaceImpl_SetClipper
,
2308 IDirectDrawSurfaceImpl_SetColorKey
,
2309 IDirectDrawSurfaceImpl_SetOverlayPosition
,
2310 IDirectDrawSurfaceImpl_SetPalette
,
2311 IDirectDrawSurfaceImpl_Unlock
,
2312 IDirectDrawSurfaceImpl_UpdateOverlay
,
2313 IDirectDrawSurfaceImpl_UpdateOverlayDisplay
,
2314 IDirectDrawSurfaceImpl_UpdateOverlayZOrder
,
2315 /*** IDirectDrawSurface2 ***/
2316 IDirectDrawSurfaceImpl_GetDDInterface
,
2317 IDirectDrawSurfaceImpl_PageLock
,
2318 IDirectDrawSurfaceImpl_PageUnlock
,
2319 /*** IDirectDrawSurface3 ***/
2320 IDirectDrawSurfaceImpl_SetSurfaceDesc
,
2321 /*** IDirectDrawSurface4 ***/
2322 IDirectDrawSurfaceImpl_SetPrivateData
,
2323 IDirectDrawSurfaceImpl_GetPrivateData
,
2324 IDirectDrawSurfaceImpl_FreePrivateData
,
2325 IDirectDrawSurfaceImpl_GetUniquenessValue
,
2326 IDirectDrawSurfaceImpl_ChangeUniquenessValue
,
2327 /*** IDirectDrawSurface7 ***/
2328 IDirectDrawSurfaceImpl_SetPriority
,
2329 IDirectDrawSurfaceImpl_GetPriority
,
2330 IDirectDrawSurfaceImpl_SetLOD
,
2331 IDirectDrawSurfaceImpl_GetLOD