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
41 #include "wine/exception.h"
46 #include "ddraw_private.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
51 /*****************************************************************************
52 * IUnknown parts follow
53 *****************************************************************************/
55 /*****************************************************************************
56 * IDirectDrawSurface7::QueryInterface
58 * A normal QueryInterface implementation. For QueryInterface rules
59 * see ddraw.c, IDirectDraw7::QueryInterface. This method
60 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
61 * in all versions, the IDirectDrawGammaControl interface and it can
62 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
65 * riid: The interface id queried for
66 * obj: Address to write the pointer to
70 * E_NOINTERFACE if the requested interface wasn't found
72 *****************************************************************************/
74 IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7
*iface
,
78 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
80 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
84 return DDERR_INVALIDPARAMS
;
86 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),obj
);
87 if (IsEqualGUID(riid
, &IID_IUnknown
)
88 || IsEqualGUID(riid
, &IID_IDirectDrawSurface7
)
89 || IsEqualGUID(riid
, &IID_IDirectDrawSurface4
) )
91 IUnknown_AddRef(iface
);
92 *obj
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
93 TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This
, *obj
);
96 else if( IsEqualGUID(riid
, &IID_IDirectDrawSurface3
)
97 || IsEqualGUID(riid
, &IID_IDirectDrawSurface2
)
98 || IsEqualGUID(riid
, &IID_IDirectDrawSurface
) )
100 IUnknown_AddRef(iface
);
101 *obj
= ICOM_INTERFACE(This
, IDirectDrawSurface3
);
102 TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This
, *obj
);
105 else if( IsEqualGUID(riid
, &IID_IDirectDrawGammaControl
) )
107 IUnknown_AddRef(iface
);
108 *obj
= ICOM_INTERFACE(This
, IDirectDrawGammaControl
);
109 TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This
, *obj
);
112 else if( IsEqualGUID(riid
, &IID_D3DDEVICE_WineD3D
) ||
113 IsEqualGUID(riid
, &IID_IDirect3DHALDevice
) )
115 IDirect3DDevice7
*d3d
;
117 /* Call into IDirect3D7 for creation */
118 IDirect3D7_CreateDevice(ICOM_INTERFACE(This
->ddraw
, IDirect3D7
),
120 ICOM_INTERFACE(This
, IDirectDrawSurface7
),
123 *obj
= COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice7
, IDirect3DDevice
, d3d
);
124 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
128 else if (IsEqualGUID( &IID_IDirect3DTexture
, riid
) ||
129 IsEqualGUID( &IID_IDirect3DTexture2
, riid
))
131 if (IsEqualGUID( &IID_IDirect3DTexture
, riid
))
133 *obj
= ICOM_INTERFACE(This
, IDirect3DTexture
);
134 TRACE(" returning Direct3DTexture interface at %p.\n", *obj
);
138 *obj
= ICOM_INTERFACE(This
, IDirect3DTexture2
);
139 TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj
);
141 IUnknown_AddRef( (IUnknown
*) *obj
);
145 ERR("No interface\n");
146 return E_NOINTERFACE
;
149 /*****************************************************************************
150 * IDirectDrawSurface7::AddRef
152 * A normal addref implementation
157 *****************************************************************************/
159 IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7
*iface
)
161 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
162 ULONG refCount
= InterlockedIncrement(&This
->ref
);
164 TRACE("(%p) : AddRef increasing from %d\n", This
, refCount
- 1);
168 /*****************************************************************************
169 * IDirectDrawSurfaceImpl_Destroy
171 * A helper function for IDirectDrawSurface7::Release
173 * Frees the surface, regardless of its refcount.
174 * See IDirectDrawSurface7::Release for more information
177 * This: Surface to free
179 *****************************************************************************/
180 static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl
*This
)
182 TRACE("(%p)\n", This
);
184 /* Check the refcount and give a warning */
187 /* This can happen when a complex surface is destroyed,
188 * because the 2nd surface was addref()ed when the app
189 * called GetAttachedSurface
191 WARN("(%p): Destroying surface with refount %d\n", This
, This
->ref
);
194 /* Check for attached surfaces and detach them */
195 if(This
->first_attached
!= This
)
197 /* Well, this shouldn't happen: The surface being attached is addref()ed
198 * in AddAttachedSurface, so it shouldn't be released until DeleteAttachedSurface
199 * is called, because the refcount is held. It looks like the app released()
200 * it often enough to force this
202 IDirectDrawSurface7
*root
= ICOM_INTERFACE(This
->first_attached
, IDirectDrawSurface7
);
203 IDirectDrawSurface7
*detach
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
205 FIXME("(%p) Freeing a surface that is attached to surface %p\n", This
, This
->first_attached
);
207 /* The refcount will drop to -1 here */
208 if(IDirectDrawSurface7_DeleteAttachedSurface(root
, 0, detach
) != DD_OK
)
210 ERR("(%p) DeleteAttachedSurface failed!\n", This
);
214 while(This
->next_attached
!= NULL
)
216 IDirectDrawSurface7
*root
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
217 IDirectDrawSurface7
*detach
= ICOM_INTERFACE(This
->next_attached
, IDirectDrawSurface7
);
219 if(IDirectDrawSurface7_DeleteAttachedSurface(root
, 0, detach
) != DD_OK
)
221 ERR("(%p) DeleteAttachedSurface failed!\n", This
);
226 /* Now destroy the surface. Wait: It could have been released if we are a texture */
227 if(This
->WineD3DSurface
)
228 IWineD3DSurface_Release(This
->WineD3DSurface
);
230 /* Having a texture handle set implies that the device still exists */
233 This
->ddraw
->d3ddevice
->Handles
[This
->Handle
- 1].ptr
= NULL
;
234 This
->ddraw
->d3ddevice
->Handles
[This
->Handle
- 1].type
= DDrawHandle_Unknown
;
237 /* Reduce the ddraw surface count */
238 InterlockedDecrement(&This
->ddraw
->surfaces
);
239 list_remove(&This
->surface_list_entry
);
241 HeapFree(GetProcessHeap(), 0, This
);
244 /*****************************************************************************
245 * IDirectDrawSurface7::Release
247 * Reduces the surface's refcount by 1. If the refcount falls to 0, the
248 * surface is destroyed.
250 * Destroying the surface is a bit tricky. For the connection between
251 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
252 * It has a nice graph explaining the connection.
254 * What happens here is basically this:
255 * When a surface is destroyed, its WineD3DSurface is released,
256 * and the refcount of the DirectDraw interface is reduced by 1. If it has
257 * complex surfaces attached to it, then these surfaces are destroyed too,
258 * regardless of their refcount. If any surface being destroyed has another
259 * surface attached to it (with a "soft" attachment, not complex), then
260 * this surface is detached with DeleteAttachedSurface.
262 * When the surface is a texture, the WineD3DTexture is released.
263 * If the surface is the Direct3D render target, then the D3D
264 * capabilities of the WineD3DDevice are uninitialized, which causes the
265 * swapchain to be released.
267 * When a complex sublevel falls to ref zero, then this is ignored.
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
;
289 /* Complex attached surfaces are destroyed implicitely when the root is released */
290 if(!This
->is_complex_root
)
292 WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This
);
297 /* If it's a texture, destroy the WineD3DTexture.
298 * WineD3D will destroy the IParent interfaces
299 * of the sublevels, which destroys the WineD3DSurfaces.
300 * Set the surfaces to NULL to avoid destroying them again later
302 if(This
->wineD3DTexture
)
304 IWineD3DBaseTexture_Release(This
->wineD3DTexture
);
306 /* If it's the RenderTarget, destroy the d3ddevice */
307 else if( (ddraw
->d3d_initialized
) && (This
== ddraw
->d3d_target
))
309 TRACE("(%p) Destroying the render target, uninitializing D3D\n", This
);
311 /* Unset any index buffer, just to be sure */
312 IWineD3DDevice_SetIndices(ddraw
->wineD3DDevice
, NULL
, 0);
313 IWineD3DDevice_SetDepthStencilSurface(ddraw
->wineD3DDevice
, NULL
);
315 if(IWineD3DDevice_Uninit3D(ddraw
->wineD3DDevice
, D3D7CB_DestroyDepthStencilSurface
, D3D7CB_DestroySwapChain
) != D3D_OK
)
318 ERR("(%p) Failed to uninit 3D\n", This
);
322 /* Free the d3d window if one was created */
323 if(ddraw
->d3d_window
!= 0)
325 TRACE(" (%p) Destroying the hidden render window %p\n", This
, ddraw
->d3d_window
);
326 DestroyWindow(ddraw
->d3d_window
);
327 ddraw
->d3d_window
= 0;
329 /* Unset the pointers */
332 ddraw
->d3d_initialized
= FALSE
;
333 ddraw
->d3d_target
= NULL
;
335 /* Write a trace because D3D unloading was the reason for many
336 * crashes during development.
338 TRACE("(%p) D3D unloaded\n", This
);
340 else if(This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
|
344 /* It's a render target, but no swapchain was created.
345 * The IParent interfaces have to be released manually.
346 * The same applies for textures without an
347 * IWineD3DTexture object attached
351 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
353 if(This
->complex_array
[i
])
355 /* Only the topmost level can have more than 1 surfaces in the complex
356 * attachment array(Cube texture roots), for all others there is only
359 surf
= This
->complex_array
[i
];
362 IWineD3DSurface_GetParent(surf
->WineD3DSurface
,
363 (IUnknown
**) &Parent
);
364 IParent_Release(Parent
); /* For the getParent */
365 IParent_Release(Parent
); /* To release it */
366 surf
= surf
->complex_array
[0];
371 /* Now the top-level surface */
372 IWineD3DSurface_GetParent(This
->WineD3DSurface
,
373 (IUnknown
**) &Parent
);
374 IParent_Release(Parent
); /* For the getParent */
375 IParent_Release(Parent
); /* To release it */
378 /* The refcount test shows that the palette is detached when the surface is destroyed */
379 IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(This
, IDirectDrawSurface7
),
382 /* Loop through all complex attached surfaces,
385 * Yet again, only the root can have more than one complexly attached surface, all the others
386 * have a total of one;
388 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
390 if(!This
->complex_array
[i
]) break;
392 surf
= This
->complex_array
[i
];
393 This
->complex_array
[i
] = NULL
;
396 IDirectDrawSurfaceImpl
*destroy
= surf
;
397 surf
= surf
->complex_array
[0]; /* Iterate through the "tree" */
398 IDirectDrawSurfaceImpl_Destroy(destroy
); /* Destroy it */
402 /* Destroy the root surface.
404 IDirectDrawSurfaceImpl_Destroy(This
);
406 /* Reduce the ddraw refcount */
407 if(ifaceToRelease
) IUnknown_Release(ifaceToRelease
);
413 /*****************************************************************************
414 * IDirectDrawSurface7::GetAttachedSurface
416 * Returns an attached surface with the requested caps. Surface attachment
417 * and complex surfaces are not clearly described by the MSDN or sdk,
418 * so this method is tricky and likely to contain problems.
419 * This implementation searches the complex list first, then the
422 * The chains are searched from This down to the last surface in the chain,
423 * not from the first element in the chain. The first surface found is
424 * returned. The MSDN says that this method fails if more than one surface
425 * matches the caps, but it is not sure if that is right. The attachment
426 * structure may not even allow two matching surfaces.
428 * The found surface is AddRef-ed before it is returned.
431 * Caps: Pointer to a DDCAPS2 structure describing the caps asked for
432 * Surface: Address to store the found surface
436 * DDERR_INVALIDPARAMS if Caps or Surface is NULL
437 * DDERR_NOTFOUND if no surface was found
439 *****************************************************************************/
440 static HRESULT WINAPI
441 IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7
*iface
,
443 IDirectDrawSurface7
**Surface
)
445 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
446 IDirectDrawSurfaceImpl
*surf
;
450 TRACE("(%p)->(%p,%p)\n", This
, Caps
, Surface
);
454 if(This
->version
< 7)
456 /* Earlier dx apps put garbage into these members, clear them */
457 our_caps
.dwCaps2
= 0;
458 our_caps
.dwCaps3
= 0;
459 our_caps
.dwCaps4
= 0;
462 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 */
464 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
466 surf
= This
->complex_array
[i
];
471 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf
,
472 surf
->surface_desc
.ddsCaps
.dwCaps
,
473 surf
->surface_desc
.ddsCaps
.dwCaps2
,
474 surf
->surface_desc
.ddsCaps
.dwCaps3
,
475 surf
->surface_desc
.ddsCaps
.dwCaps4
);
478 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
479 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
481 /* MSDN: "This method fails if more than one surface is attached
482 * that matches the capabilities requested."
484 * Not sure how to test this.
487 TRACE("(%p): Returning surface %p\n", This
, surf
);
488 TRACE("(%p): mipmapcount=%d\n", This
, surf
->mipmap_level
);
489 *Surface
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
490 IDirectDrawSurface7_AddRef(*Surface
);
495 /* Next, look at the attachment chain */
498 while( (surf
= surf
->next_attached
) )
502 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf
,
503 surf
->surface_desc
.ddsCaps
.dwCaps
,
504 surf
->surface_desc
.ddsCaps
.dwCaps2
,
505 surf
->surface_desc
.ddsCaps
.dwCaps3
,
506 surf
->surface_desc
.ddsCaps
.dwCaps4
);
509 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
510 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
512 TRACE("(%p): Returning surface %p\n", This
, surf
);
513 *Surface
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
514 IDirectDrawSurface7_AddRef(*Surface
);
519 TRACE("(%p) Didn't find a valid surface\n", This
);
520 return DDERR_NOTFOUND
;
523 /*****************************************************************************
524 * IDirectDrawSurface7::Lock
526 * Locks the surface and returns a pointer to the surface's memory
529 * Rect: Rectangle to lock. If NULL, the whole surface is locked
530 * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
531 * Flags: Locking flags, e.g Read only or write only
532 * h: An event handle that's not used and must be NULL
536 * DDERR_INVALIDPARAMS if DDSD is NULL
537 * For more details, see IWineD3DSurface::LockRect
539 *****************************************************************************/
540 static HRESULT WINAPI
541 IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7
*iface
,
543 DDSURFACEDESC2
*DDSD
,
547 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
548 WINED3DLOCKED_RECT LockedRect
;
550 TRACE("(%p)->(%p,%p,%x,%p)\n", This
, Rect
, DDSD
, Flags
, h
);
556 || (Rect
->left
> Rect
->right
)
557 || (Rect
->top
> Rect
->bottom
)
558 || (Rect
->right
> This
->surface_desc
.dwWidth
)
559 || (Rect
->bottom
> This
->surface_desc
.dwHeight
))
561 WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
562 return DDERR_INVALIDPARAMS
;
567 return DDERR_INVALIDPARAMS
;
569 /* Should I check for the handle to be NULL?
571 * The DDLOCK flags and the D3DLOCK flags are equal
572 * for the supported values. The others are ignored by WineD3D
575 /* Hmm. Anarchy online passes an uninitialized surface descriptor,
576 * that means it doesn't have dwSize set. Init it to some sane
579 if(DDSD
->dwSize
<= sizeof(DDSURFACEDESC
))
581 DDSD
->dwSize
= sizeof(DDSURFACEDESC
);
585 DDSD
->dwSize
= sizeof(DDSURFACEDESC2
);
588 hr
= IWineD3DSurface_LockRect(This
->WineD3DSurface
,
592 if(hr
!= D3D_OK
) return hr
;
594 /* Override the memory area. The pitch should be set already. Strangely windows
595 * does not set the LPSURFACE flag on locked surfaces !?!.
596 * DDSD->dwFlags |= DDSD_LPSURFACE;
598 This
->surface_desc
.lpSurface
= LockedRect
.pBits
;
599 DD_STRUCT_COPY_BYSIZE(DDSD
,&(This
->surface_desc
));
601 TRACE("locked surface returning description :\n");
602 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(DDSD
);
607 /*****************************************************************************
608 * IDirectDrawSurface7::Unlock
610 * Unlocks an locked surface
613 * Rect: Not used by this implementation
617 * For more details, see IWineD3DSurface::UnlockRect
619 *****************************************************************************/
620 static HRESULT WINAPI
621 IDirectDrawSurfaceImpl_Unlock(IDirectDrawSurface7
*iface
,
624 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
626 TRACE("(%p)->(%p)\n", This
, pRect
);
628 hr
= IWineD3DSurface_UnlockRect(This
->WineD3DSurface
);
631 This
->surface_desc
.lpSurface
= NULL
;
636 /*****************************************************************************
637 * IDirectDrawSurface7::Flip
639 * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
640 * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
641 * the flip target is passed to WineD3D, even if the app didn't specify one
644 * DestOverride: Specifies the surface that will become the new front
645 * buffer. If NULL, the current back buffer is used
646 * Flags: some DirectDraw flags, see include/ddraw.h
650 * DDERR_NOTFLIPPABLE if no flip target could be found
651 * DDERR_INVALIDOBJECT if the surface isn't a front buffer
652 * For more details, see IWineD3DSurface::Flip
654 *****************************************************************************/
655 static HRESULT WINAPI
656 IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7
*iface
,
657 IDirectDrawSurface7
*DestOverride
,
660 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
661 IDirectDrawSurfaceImpl
*Override
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DestOverride
);
662 IDirectDrawSurface7
*Override7
;
664 TRACE("(%p)->(%p,%x)\n", This
, DestOverride
, Flags
);
666 /* Flip has to be called from a front buffer
667 * What about overlay surfaces, AFAIK they can flip too?
669 if( !(This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_FRONTBUFFER
) )
670 return DDERR_INVALIDOBJECT
; /* Unckecked */
672 /* WineD3D doesn't keep track of attached surface, so find the target */
677 memset(&Caps
, 0, sizeof(Caps
));
678 Caps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
679 hr
= IDirectDrawSurface7_GetAttachedSurface(iface
, &Caps
, &Override7
);
682 ERR("Can't find a flip target\n");
683 return DDERR_NOTFLIPPABLE
; /* Unchecked */
685 Override
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Override7
);
687 /* For the GetAttachedSurface */
688 IDirectDrawSurface7_Release(Override7
);
691 return IWineD3DSurface_Flip(This
->WineD3DSurface
,
692 Override
->WineD3DSurface
,
696 /*****************************************************************************
697 * IDirectDrawSurface7::Blt
699 * Performs a blit on the surface
702 * DestRect: Destination rectangle, can be NULL
703 * SrcSurface: Source surface, can be NULL
704 * SrcRect: Source rectange, can be NULL
706 * DDBltFx: Some extended blt parameters, connected to the flags
710 * See IWineD3DSurface::Blt for more details
712 *****************************************************************************/
713 static HRESULT WINAPI
714 IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7
*iface
,
716 IDirectDrawSurface7
*SrcSurface
,
721 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
723 IDirectDrawSurfaceImpl
*Src
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, SrcSurface
);
724 TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This
, DestRect
, Src
, SrcRect
, Flags
, DDBltFx
);
726 /* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have
727 * to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-)
729 if((Flags
& DDBLT_KEYSRCOVERRIDE
) && (!DDBltFx
|| Flags
& DDBLT_KEYSRC
)) {
730 WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
731 return DDERR_INVALIDPARAMS
;
734 if((Flags
& DDBLT_KEYDESTOVERRIDE
) && (!DDBltFx
|| Flags
& DDBLT_KEYDEST
)) {
735 WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
736 return DDERR_INVALIDPARAMS
;
739 if(Flags
& DDBLT_KEYSRC
&& (!Src
|| !(Src
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
))) {
740 WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
741 return DDERR_INVALIDPARAMS
;
744 /* TODO: Check if the DDBltFx contains any ddraw surface pointers. If it does, copy the struct,
745 * and replace the ddraw surfaces with the wined3d surfaces
746 * So far no blitting operations using surfaces in the bltfx struct are supported anyway.
748 hr
= IWineD3DSurface_Blt(This
->WineD3DSurface
,
750 Src
? Src
->WineD3DSurface
: NULL
,
753 (WINEDDBLTFX
*) DDBltFx
,
757 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
758 case WINED3DERR_WRONGTEXTUREFORMAT
: return DDERR_INVALIDPIXELFORMAT
;
763 /*****************************************************************************
764 * IDirectDrawSurface7::AddAttachedSurface
766 * Attaches a surface to another surface. How the surface attachments work
767 * is not totally understood yet, and this method is prone to problems.
768 * he surface that is attached is AddRef-ed.
770 * Tests with complex surfaces suggest that the surface attachments form a
771 * tree, but no method to test this has been found yet.
773 * The attachment list consists of a first surface (first_attached) and
774 * for each surface a pointer to the next attached surface (next_attached).
775 * For the first surface, and a surface that has no attachments
776 * first_attached points to the surface itself. A surface that has
777 * no successors in the chain has next_attached set to NULL.
779 * Newly attached surfaces are attached right after the root surface.
780 * If a surface is attached to a complex surface compound, it's attached to
781 * the surface that the app requested, not the complex root. See
782 * GetAttachedSurface for a description how surfaces are found.
784 * This is how the current implementation works, and it was coded by looking
785 * at the needs of the applications.
787 * So far only Z-Buffer attachments are tested, and they are activated in
788 * WineD3D. Mipmaps could be tricky to activate in WineD3D.
789 * Back buffers should work in 2D mode, but they are not tested(They can be
790 * attached in older iface versions). Rendering to the front buffer and
791 * switching between that and double buffering is not yet implemented in
792 * WineD3D, so for 3D it might have unexpected results.
794 * IDirectDrawSurfaceImpl_AddAttachedSurface is the real thing,
795 * IDirectDrawSurface7Impl_AddAttachedSurface is a wrapper around it that
796 * performs additional checks. Version 7 of this interface is much more restrictive
797 * than its predecessors.
800 * Attach: Surface to attach to iface
804 * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
806 *****************************************************************************/
808 IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl
*This
,
809 IDirectDrawSurfaceImpl
*Surf
)
811 TRACE("(%p)->(%p)\n", This
, Surf
);
814 return DDERR_CANNOTATTACHSURFACE
; /* unchecked */
816 /* Check if the surface is already attached somewhere */
817 if( (Surf
->next_attached
!= NULL
) ||
818 (Surf
->first_attached
!= Surf
) )
820 /* TODO: Test for the structure of the manual attachment. Is it a chain or a list?
821 * What happens if one surface is attached to 2 different surfaces?
823 FIXME("(%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
);
824 return DDERR_SURFACEALREADYATTACHED
;
827 /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
828 Surf
->next_attached
= This
->next_attached
;
829 Surf
->first_attached
= This
->first_attached
;
830 This
->next_attached
= Surf
;
832 /* Check if the WineD3D depth stencil needs updating */
833 if(This
->ddraw
->d3ddevice
)
835 IDirect3DDeviceImpl_UpdateDepthStencil(This
->ddraw
->d3ddevice
);
839 * "This method increments the reference count of the surface being attached."
841 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(Surf
, IDirectDrawSurface7
));
845 static HRESULT WINAPI
846 IDirectDrawSurface7Impl_AddAttachedSurface(IDirectDrawSurface7
*iface
,
847 IDirectDrawSurface7
*Attach
)
849 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
850 IDirectDrawSurfaceImpl
*Surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Attach
);
852 /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
853 if(!(Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
856 WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
857 Surf
->surface_desc
.ddsCaps
.dwCaps
);
858 return DDERR_CANNOTATTACHSURFACE
;
861 return IDirectDrawSurfaceImpl_AddAttachedSurface(This
,
864 /*****************************************************************************
865 * IDirectDrawSurface7::DeleteAttachedSurface
867 * Removes a surface from the attachment chain. The surface's refcount
868 * is decreased by one after it has been removed
871 * Flags: Some flags, not used by this implementation
872 * Attach: Surface to detach
876 * DDERR_SURFACENOTATTACHED if the surface isn't attached to
878 *****************************************************************************/
879 static HRESULT WINAPI
880 IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7
*iface
,
882 IDirectDrawSurface7
*Attach
)
884 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
885 IDirectDrawSurfaceImpl
*Surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Attach
);
886 IDirectDrawSurfaceImpl
*Prev
= This
;
887 TRACE("(%p)->(%08x,%p)\n", This
, Flags
, Surf
);
889 if (!Surf
|| (Surf
->first_attached
!= This
) || (Surf
== This
) )
890 return DDERR_CANNOTDETACHSURFACE
;
892 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
893 if (This
->surface_desc
.ddsCaps
.dwCaps
&
894 Surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
896 Surf
->surface_desc
.ddsCaps
.dwCaps2
&= ~DDSCAPS2_MIPMAPSUBLEVEL
;
897 /* FIXME: we should probably also subtract from dwMipMapCount of this
898 * and all parent surfaces */
901 /* Find the predecessor of the detached surface */
904 if(Prev
->next_attached
== Surf
) break;
905 Prev
= Prev
->next_attached
;
908 /* There must be a surface, otherwise there's a bug */
909 assert(Prev
!= NULL
);
911 /* Unchain the surface */
912 Prev
->next_attached
= Surf
->next_attached
;
913 Surf
->next_attached
= NULL
;
914 Surf
->first_attached
= Surf
;
916 /* Check if the WineD3D depth stencil needs updating */
917 if(This
->ddraw
->d3ddevice
)
919 IDirect3DDeviceImpl_UpdateDepthStencil(This
->ddraw
->d3ddevice
);
922 IDirectDrawSurface7_Release(Attach
);
926 /*****************************************************************************
927 * IDirectDrawSurface7::AddOverlayDirtyRect
929 * "This method is not currently implemented"
937 *****************************************************************************/
938 static HRESULT WINAPI
939 IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7
*iface
,
942 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
943 TRACE("(%p)->(%p)\n",This
,Rect
);
945 /* MSDN says it's not implemented. I could forward it to WineD3D,
946 * then we'd implement it, but I don't think that's a good idea
950 return IWineD3DSurface_AddOverlayDirtyRect(This
->WineD3DSurface
, pRect
);
952 return DDERR_UNSUPPORTED
; /* unchecked */
955 /*****************************************************************************
956 * IDirectDrawSurface7::GetDC
958 * Returns a GDI device context for the surface
961 * hdc: Address of a HDC variable to store the dc to
965 * DDERR_INVALIDPARAMS if hdc is NULL
966 * For details, see IWineD3DSurface::GetDC
968 *****************************************************************************/
969 static HRESULT WINAPI
970 IDirectDrawSurfaceImpl_GetDC(IDirectDrawSurface7
*iface
,
973 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
974 TRACE("(%p)->(%p): Relay\n", This
, hdc
);
977 return DDERR_INVALIDPARAMS
;
979 return IWineD3DSurface_GetDC(This
->WineD3DSurface
,
983 /*****************************************************************************
984 * IDirectDrawSurface7::ReleaseDC
986 * Releases the DC that was constructed with GetDC
989 * hdc: HDC to release
993 * For more details, see IWineD3DSurface::ReleaseDC
995 *****************************************************************************/
996 static HRESULT WINAPI
997 IDirectDrawSurfaceImpl_ReleaseDC(IDirectDrawSurface7
*iface
,
1000 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1001 TRACE("(%p)->(%p): Relay\n", This
, hdc
);
1003 return IWineD3DSurface_ReleaseDC(This
->WineD3DSurface
, hdc
);
1006 /*****************************************************************************
1007 * IDirectDrawSurface7::GetCaps
1009 * Returns the surface's caps
1012 * Caps: Address to write the caps to
1016 * DDERR_INVALIDPARAMS if Caps is NULL
1018 *****************************************************************************/
1019 static HRESULT WINAPI
1020 IDirectDrawSurfaceImpl_GetCaps(IDirectDrawSurface7
*iface
,
1023 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1024 TRACE("(%p)->(%p)\n",This
,Caps
);
1027 return DDERR_INVALIDPARAMS
;
1029 *Caps
= This
->surface_desc
.ddsCaps
;
1033 /*****************************************************************************
1034 * IDirectDrawSurface7::SetPriority
1036 * Sets a texture priority for managed textures.
1039 * Priority: The new priority
1043 * For more details, see IWineD3DSurface::SetPriority
1045 *****************************************************************************/
1046 static HRESULT WINAPI
1047 IDirectDrawSurfaceImpl_SetPriority(IDirectDrawSurface7
*iface
, DWORD Priority
)
1049 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1050 TRACE("(%p)->(%d): Relay!\n",This
,Priority
);
1052 return IWineD3DSurface_SetPriority(This
->WineD3DSurface
, Priority
);
1055 /*****************************************************************************
1056 * IDirectDrawSurface7::GetPriority
1058 * Returns the surface's priority
1061 * Priority: Address of a variable to write the priority to
1065 * DDERR_INVALIDPARAMS if Priority == NULL
1066 * For more details, see IWineD3DSurface::GetPriority
1068 *****************************************************************************/
1069 static HRESULT WINAPI
1070 IDirectDrawSurfaceImpl_GetPriority(IDirectDrawSurface7
*iface
,
1073 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1074 TRACE("(%p)->(%p): Relay\n",This
,Priority
);
1077 return DDERR_INVALIDPARAMS
;
1079 *Priority
= IWineD3DSurface_GetPriority(This
->WineD3DSurface
);
1083 /*****************************************************************************
1084 * IDirectDrawSurface7::SetPrivateData
1086 * Stores some data in the surface that is intended for the application's
1090 * tag: GUID that identifies the data
1091 * Data: Pointer to the private data
1092 * Size: Size of the private data
1097 * For more details, see IWineD3DSurface::SetPrivateData
1099 *****************************************************************************/
1100 static HRESULT WINAPI
1101 IDirectDrawSurfaceImpl_SetPrivateData(IDirectDrawSurface7
*iface
,
1107 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1109 TRACE("(%p)->(%s,%p,%d,%x): Relay\n", This
, debugstr_guid(tag
), Data
, Size
, Flags
);
1111 hr
= IWineD3DSurface_SetPrivateData(This
->WineD3DSurface
,
1118 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
1123 /*****************************************************************************
1124 * IDirectDrawSurface7::GetPrivateData
1126 * Returns the private data set with IDirectDrawSurface7::SetPrivateData
1129 * tag: GUID of the data to return
1130 * Data: Address where to write the data to
1131 * Size: Size of the buffer at Data
1135 * DDERR_INVALIDPARAMS if Data is NULL
1136 * For more details, see IWineD3DSurface::GetPrivateData
1138 *****************************************************************************/
1139 static HRESULT WINAPI
1140 IDirectDrawSurfaceImpl_GetPrivateData(IDirectDrawSurface7
*iface
,
1145 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1146 TRACE("(%p)->(%s,%p,%p): Relay\n", This
, debugstr_guid(tag
), Data
, Size
);
1149 return DDERR_INVALIDPARAMS
;
1151 return IWineD3DSurface_GetPrivateData(This
->WineD3DSurface
,
1157 /*****************************************************************************
1158 * IDirectDrawSurface7::FreePrivateData
1160 * Frees private data stored in the surface
1163 * tag: Tag of the data to free
1167 * For more details, see IWineD3DSurface::FreePrivateData
1169 *****************************************************************************/
1170 static HRESULT WINAPI
1171 IDirectDrawSurfaceImpl_FreePrivateData(IDirectDrawSurface7
*iface
,
1174 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1175 TRACE("(%p)->(%s): Relay\n", This
, debugstr_guid(tag
));
1177 return IWineD3DSurface_FreePrivateData(This
->WineD3DSurface
, tag
);
1180 /*****************************************************************************
1181 * IDirectDrawSurface7::PageLock
1183 * Prevents a sysmem surface from being paged out
1186 * Flags: Not used, must be 0(unchecked)
1189 * DD_OK, because it's a stub
1191 *****************************************************************************/
1192 static HRESULT WINAPI
1193 IDirectDrawSurfaceImpl_PageLock(IDirectDrawSurface7
*iface
,
1196 TRACE("(%p)->(%x)\n", iface
, Flags
);
1198 /* This is Windows memory management related - we don't need this */
1202 /*****************************************************************************
1203 * IDirectDrawSurface7::PageUnlock
1205 * Allows a sysmem surface to be paged out
1208 * Flags: Not used, must be 0(unckeched)
1211 * DD_OK, because it's a stub
1213 *****************************************************************************/
1214 static HRESULT WINAPI
1215 IDirectDrawSurfaceImpl_PageUnlock(IDirectDrawSurface7
*iface
,
1218 TRACE("(%p)->(%x)\n", iface
, Flags
);
1223 /*****************************************************************************
1224 * IDirectDrawSurface7::BltBatch
1226 * An unimplemented function
1234 *****************************************************************************/
1235 static HRESULT WINAPI
IDirectDrawSurfaceImpl_BltBatch(IDirectDrawSurface7
*iface
, DDBLTBATCH
*Batch
, DWORD Count
, DWORD Flags
)
1237 TRACE("(%p)->(%p,%d,%08x)\n",iface
,Batch
,Count
,Flags
);
1239 /* MSDN: "not currently implemented" */
1240 return DDERR_UNSUPPORTED
;
1243 /*****************************************************************************
1244 * IDirectDrawSurface7::EnumAttachedSurfaces
1246 * Enumerates all surfaces attached to this surface
1249 * context: Pointer to pass unmodified to the callback
1250 * cb: Callback function to call for each surface
1254 * DDERR_INVALIDPARAMS if cb is NULL
1256 *****************************************************************************/
1257 static HRESULT WINAPI
1258 IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7
*iface
,
1260 LPDDENUMSURFACESCALLBACK7 cb
)
1262 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1263 IDirectDrawSurfaceImpl
*surf
;
1264 DDSURFACEDESC2 desc
;
1267 /* Attached surfaces aren't handled in WineD3D */
1268 TRACE("(%p)->(%p,%p)\n",This
,context
,cb
);
1271 return DDERR_INVALIDPARAMS
;
1273 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
1275 surf
= This
->complex_array
[i
];
1278 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf
, IDirectDrawSurface7
));
1279 desc
= surf
->surface_desc
;
1280 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
1281 if (cb(ICOM_INTERFACE(surf
, IDirectDrawSurface7
), &desc
, context
) == DDENUMRET_CANCEL
)
1285 for (surf
= This
->next_attached
; surf
!= NULL
; surf
= surf
->next_attached
)
1287 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf
, IDirectDrawSurface7
));
1288 desc
= surf
->surface_desc
;
1289 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
1290 if (cb( ICOM_INTERFACE(surf
, IDirectDrawSurface7
), &desc
, context
) == DDENUMRET_CANCEL
)
1294 TRACE(" end of enumeration.\n");
1299 /*****************************************************************************
1300 * IDirectDrawSurface7::EnumOverlayZOrders
1302 * "Enumerates the overlay surfaces on the specified destination"
1305 * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK
1306 * context: context to pass back to the callback
1307 * cb: callback function to call for each enumerated surface
1310 * DD_OK, because it's a stub
1312 *****************************************************************************/
1313 static HRESULT WINAPI
1314 IDirectDrawSurfaceImpl_EnumOverlayZOrders(IDirectDrawSurface7
*iface
,
1317 LPDDENUMSURFACESCALLBACK7 cb
)
1319 FIXME("(%p)->(%x,%p,%p): Stub!\n", iface
, Flags
, context
, cb
);
1324 /*****************************************************************************
1325 * IDirectDrawSurface7::GetBltStatus
1327 * Returns the blitting status
1330 * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
1333 * See IWineD3DSurface::Blt
1335 *****************************************************************************/
1336 static HRESULT WINAPI
1337 IDirectDrawSurfaceImpl_GetBltStatus(IDirectDrawSurface7
*iface
,
1340 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1342 TRACE("(%p)->(%x): Relay\n", This
, Flags
);
1344 hr
= IWineD3DSurface_GetBltStatus(This
->WineD3DSurface
, Flags
);
1347 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
1352 /*****************************************************************************
1353 * IDirectDrawSurface7::GetColorKey
1355 * Returns the color key assigned to the surface
1359 * CKey: Address to store the key to
1363 * DDERR_INVALIDPARAMS if CKey is NULL
1365 *****************************************************************************/
1366 static HRESULT WINAPI
1367 IDirectDrawSurfaceImpl_GetColorKey(IDirectDrawSurface7
*iface
,
1371 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
1372 * isn't there? That's like saying that an int isn't there. (Which MS
1373 * has done in other docs.) */
1374 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1375 TRACE("(%p)->(%08x,%p)\n", This
, Flags
, CKey
);
1378 return DDERR_INVALIDPARAMS
;
1382 case DDCKEY_DESTBLT
:
1383 *CKey
= This
->surface_desc
.ddckCKDestBlt
;
1386 case DDCKEY_DESTOVERLAY
:
1387 *CKey
= This
->surface_desc
.u3
.ddckCKDestOverlay
;
1391 *CKey
= This
->surface_desc
.ddckCKSrcBlt
;
1394 case DDCKEY_SRCOVERLAY
:
1395 *CKey
= This
->surface_desc
.ddckCKSrcOverlay
;
1399 return DDERR_INVALIDPARAMS
;
1405 /*****************************************************************************
1406 * IDirectDrawSurface7::GetFlipStatus
1408 * Returns the flipping status of the surface
1411 * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
1414 * See IWineD3DSurface::GetFlipStatus
1416 *****************************************************************************/
1417 static HRESULT WINAPI
1418 IDirectDrawSurfaceImpl_GetFlipStatus(IDirectDrawSurface7
*iface
,
1421 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1423 TRACE("(%p)->(%x): Relay\n", This
, Flags
);
1425 hr
= IWineD3DSurface_GetFlipStatus(This
->WineD3DSurface
, Flags
);
1428 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
1433 /*****************************************************************************
1434 * IDirectDrawSurface7::GetOverlayPosition
1436 * Returns the display coordinates of a visible and active overlay surface
1443 * DDERR_NOTAOVERLAYSURFACE, because it's a stub
1444 *****************************************************************************/
1445 static HRESULT WINAPI
1446 IDirectDrawSurfaceImpl_GetOverlayPosition(IDirectDrawSurface7
*iface
,
1449 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1450 TRACE("(%p)->(%p,%p): Relay\n", This
, X
, Y
);
1452 return IWineD3DSurface_GetOverlayPosition(This
->WineD3DSurface
,
1457 /*****************************************************************************
1458 * IDirectDrawSurface7::GetPixelFormat
1460 * Returns the pixel format of the Surface
1463 * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
1464 * format should be written
1468 * DDERR_INVALIDPARAMS if PixelFormat is NULL
1470 *****************************************************************************/
1471 static HRESULT WINAPI
1472 IDirectDrawSurfaceImpl_GetPixelFormat(IDirectDrawSurface7
*iface
,
1473 DDPIXELFORMAT
*PixelFormat
)
1475 /* What is DDERR_INVALIDSURFACETYPE for here? */
1476 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1477 TRACE("(%p)->(%p)\n",This
,PixelFormat
);
1480 return DDERR_INVALIDPARAMS
;
1482 DD_STRUCT_COPY_BYSIZE(PixelFormat
,&This
->surface_desc
.u4
.ddpfPixelFormat
);
1488 /*****************************************************************************
1489 * IDirectDrawSurface7::GetSurfaceDesc
1491 * Returns the description of this surface
1494 * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
1499 * DDERR_INVALIDPARAMS if DDSD is NULL
1501 *****************************************************************************/
1502 static HRESULT WINAPI
1503 IDirectDrawSurfaceImpl_GetSurfaceDesc(IDirectDrawSurface7
*iface
,
1504 DDSURFACEDESC2
*DDSD
)
1506 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1508 TRACE("(%p)->(%p)\n",This
,DDSD
);
1511 return DDERR_INVALIDPARAMS
;
1513 if ((DDSD
->dwSize
< sizeof(DDSURFACEDESC
)) ||
1514 (DDSD
->dwSize
> sizeof(DDSURFACEDESC2
)))
1516 ERR("Impossible/Strange struct size %d.\n",DDSD
->dwSize
);
1517 return DDERR_GENERIC
;
1520 DD_STRUCT_COPY_BYSIZE(DDSD
,&This
->surface_desc
);
1521 TRACE("Returning surface desc:\n");
1522 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(DDSD
);
1527 /*****************************************************************************
1528 * IDirectDrawSurface7::Initialize
1530 * Initializes the surface. This is a no-op in Wine
1533 * DD: Pointer to an DirectDraw interface
1534 * DDSD: Surface description for initialization
1537 * DDERR_ALREADYINITIALIZED
1539 *****************************************************************************/
1540 static HRESULT WINAPI
1541 IDirectDrawSurfaceImpl_Initialize(IDirectDrawSurface7
*iface
,
1543 DDSURFACEDESC2
*DDSD
)
1545 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1546 IDirectDrawImpl
*ddimpl
= ICOM_OBJECT(IDirectDrawImpl
, IDirectDraw
, DD
);
1547 TRACE("(%p)->(%p,%p)\n",This
,ddimpl
,DDSD
);
1549 return DDERR_ALREADYINITIALIZED
;
1552 /*****************************************************************************
1553 * IDirectDrawSurface7::IsLost
1555 * Checks if the surface is lost
1558 * DD_OK, if the surface is useable
1559 * DDERR_ISLOST if the surface is lost
1560 * See IWineD3DSurface::IsLost for more details
1562 *****************************************************************************/
1563 static HRESULT WINAPI
1564 IDirectDrawSurfaceImpl_IsLost(IDirectDrawSurface7
*iface
)
1566 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1568 TRACE("(%p)\n", This
);
1570 /* We lose the surface if the implementation was changed */
1571 if(This
->ImplType
!= This
->ddraw
->ImplType
)
1573 /* But this shouldn't happen. When we change the implementation,
1574 * all surfaces are re-created automatically, and their content
1577 ERR(" (%p) Implementation was changed from %d to %d\n", This
, This
->ImplType
, This
->ddraw
->ImplType
);
1578 return DDERR_SURFACELOST
;
1581 hr
= IWineD3DSurface_IsLost(This
->WineD3DSurface
);
1584 /* D3D8 and 9 loose full devices, thus there's only a DEVICELOST error.
1585 * WineD3D uses the same error for surfaces
1587 case WINED3DERR_DEVICELOST
: return DDERR_SURFACELOST
;
1592 /*****************************************************************************
1593 * IDirectDrawSurface7::Restore
1595 * Restores a lost surface. This makes the surface usable again, but
1596 * doesn't reload its old contents
1600 * See IWineD3DSurface::Restore for more details
1602 *****************************************************************************/
1603 static HRESULT WINAPI
1604 IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7
*iface
)
1606 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1607 TRACE("(%p)\n", This
);
1609 if(This
->ImplType
!= This
->ddraw
->ImplType
)
1611 /* Call the recreation callback. Make sure to AddRef first */
1612 IDirectDrawSurface_AddRef(iface
);
1613 IDirectDrawImpl_RecreateSurfacesCallback(iface
,
1614 &This
->surface_desc
,
1615 NULL
/* Not needed */);
1617 return IWineD3DSurface_Restore(This
->WineD3DSurface
);
1620 /*****************************************************************************
1621 * IDirectDrawSurface7::SetOverlayPosition
1623 * Changes the display coordinates of an overlay surface
1630 * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
1631 *****************************************************************************/
1632 static HRESULT WINAPI
1633 IDirectDrawSurfaceImpl_SetOverlayPosition(IDirectDrawSurface7
*iface
,
1637 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1638 TRACE("(%p)->(%d,%d): Relay\n", This
, X
, Y
);
1640 return IWineD3DSurface_SetOverlayPosition(This
->WineD3DSurface
,
1645 /*****************************************************************************
1646 * IDirectDrawSurface7::UpdateOverlay
1648 * Modifies the attributes of an overlay surface.
1651 * SrcRect: The section of the source being used for the overlay
1652 * DstSurface: Address of the surface that is overlaid
1653 * DstRect: Place of the overlay
1654 * Flags: some DDOVER_* flags
1657 * DDERR_UNSUPPORTED, because we don't support overlays
1659 *****************************************************************************/
1660 static HRESULT WINAPI
1661 IDirectDrawSurfaceImpl_UpdateOverlay(IDirectDrawSurface7
*iface
,
1663 IDirectDrawSurface7
*DstSurface
,
1668 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1669 IDirectDrawSurfaceImpl
*Dst
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DstSurface
);
1670 TRACE("(%p)->(%p,%p,%p,%x,%p): Relay\n", This
, SrcRect
, Dst
, DstRect
, Flags
, FX
);
1672 return IWineD3DSurface_UpdateOverlay(This
->WineD3DSurface
,
1674 Dst
? Dst
->WineD3DSurface
: NULL
,
1677 (WINEDDOVERLAYFX
*) FX
);
1680 /*****************************************************************************
1681 * IDirectDrawSurface7::UpdateOverlayDisplay
1683 * The DX7 sdk says that it's not implemented
1688 * Returns: DDERR_UNSUPPORTED, because we don't support overlays
1690 *****************************************************************************/
1691 static HRESULT WINAPI
1692 IDirectDrawSurfaceImpl_UpdateOverlayDisplay(IDirectDrawSurface7
*iface
,
1695 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1696 TRACE("(%p)->(%x)\n", This
, Flags
);
1697 return DDERR_UNSUPPORTED
;
1700 /*****************************************************************************
1701 * IDirectDrawSurface7::UpdateOverlayZOrder
1703 * Sets an overlay's Z order
1706 * Flags: DDOVERZ_* flags
1707 * DDSRef: Defines the relative position in the overlay chain
1710 * DDERR_NOTOVERLAYSURFACE, because we don't support overlays
1712 *****************************************************************************/
1713 static HRESULT WINAPI
1714 IDirectDrawSurfaceImpl_UpdateOverlayZOrder(IDirectDrawSurface7
*iface
,
1716 IDirectDrawSurface7
*DDSRef
)
1718 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1719 IDirectDrawSurfaceImpl
*Ref
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DDSRef
);
1721 TRACE("(%p)->(%x,%p): Relay\n", This
, Flags
, Ref
);
1722 return IWineD3DSurface_UpdateOverlayZOrder(This
->WineD3DSurface
,
1724 Ref
? Ref
->WineD3DSurface
: NULL
);
1727 /*****************************************************************************
1728 * IDirectDrawSurface7::GetDDInterface
1730 * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
1731 * surface belongs to
1734 * DD: Address to write the interface pointer to
1738 * DDERR_INVALIDPARAMS if DD is NULL
1740 *****************************************************************************/
1741 static HRESULT WINAPI
1742 IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7
*iface
,
1745 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1747 TRACE("(%p)->(%p)\n",This
,DD
);
1750 return DDERR_INVALIDPARAMS
;
1752 switch(This
->version
)
1755 *((IDirectDraw7
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw7
);
1756 IDirectDraw7_AddRef(*(IDirectDraw7
**) DD
);
1760 *((IDirectDraw4
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw4
);
1761 IDirectDraw4_AddRef(*(IDirectDraw4
**) DD
);
1765 *((IDirectDraw2
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw2
);
1766 IDirectDraw_AddRef( *(IDirectDraw2
**) DD
);
1770 *((IDirectDraw
**) DD
) = ICOM_INTERFACE(This
->ddraw
, IDirectDraw
);
1771 IDirectDraw_AddRef( *(IDirectDraw
**) DD
);
1779 /* This seems also windows implementation specific - I don't think WineD3D needs this */
1780 static HRESULT WINAPI
IDirectDrawSurfaceImpl_ChangeUniquenessValue(IDirectDrawSurface7
*iface
)
1782 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1783 volatile IDirectDrawSurfaceImpl
* vThis
= This
;
1785 TRACE("(%p)\n",This
);
1786 /* A uniqueness value of 0 is apparently special.
1787 * This needs to be checked. */
1789 DWORD old_uniqueness_value
= vThis
->uniqueness_value
;
1790 DWORD new_uniqueness_value
= old_uniqueness_value
+1;
1792 if (old_uniqueness_value
== 0) break;
1793 if (new_uniqueness_value
== 0) new_uniqueness_value
= 1;
1795 if (InterlockedCompareExchange((LONG
*)&vThis
->uniqueness_value
,
1796 old_uniqueness_value
,
1797 new_uniqueness_value
)
1798 == old_uniqueness_value
)
1805 static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetUniquenessValue(IDirectDrawSurface7
*iface
, LPDWORD pValue
)
1807 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1809 TRACE("(%p)->(%p)\n",This
,pValue
);
1810 *pValue
= This
->uniqueness_value
;
1814 /*****************************************************************************
1815 * IDirectDrawSurface7::SetLOD
1817 * Sets the level of detail of a texture
1820 * MaxLOD: LOD to set
1824 * DDERR_INVALIDOBJECT if the surface is invalid for this method
1826 *****************************************************************************/
1827 static HRESULT WINAPI
1828 IDirectDrawSurfaceImpl_SetLOD(IDirectDrawSurface7
*iface
,
1831 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1832 TRACE("(%p)->(%d)\n", This
, MaxLOD
);
1834 if (!(This
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
1835 return DDERR_INVALIDOBJECT
;
1837 if(!This
->wineD3DTexture
)
1839 ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This
);
1840 return DDERR_INVALIDOBJECT
;
1843 return IWineD3DBaseTexture_SetLOD(This
->wineD3DTexture
,
1847 /*****************************************************************************
1848 * IDirectDrawSurface7::GetLOD
1850 * Returns the level of detail of a Direct3D texture
1853 * MaxLOD: Address to write the LOD to
1857 * DDERR_INVALIDPARAMS if MaxLOD is NULL
1858 * DDERR_INVALIDOBJECT if the surface is invalid for this method
1860 *****************************************************************************/
1861 static HRESULT WINAPI
1862 IDirectDrawSurfaceImpl_GetLOD(IDirectDrawSurface7
*iface
,
1865 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1866 TRACE("(%p)->(%p)\n", This
, MaxLOD
);
1869 return DDERR_INVALIDPARAMS
;
1871 if (!(This
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
1872 return DDERR_INVALIDOBJECT
;
1874 *MaxLOD
= IWineD3DBaseTexture_GetLOD(This
->wineD3DTexture
);
1878 /*****************************************************************************
1879 * IDirectDrawSurface7::BltFast
1881 * Performs a fast Blit.
1884 * dstx: The x coordinate to blit to on the destination
1885 * dsty: The y coordinate to blit to on the destination
1886 * Source: The source surface
1887 * rsrc: The source rectangle
1888 * trans: Type of transfer. Some DDBLTFAST_* flags
1892 * For more details, see IWineD3DSurface::BltFast
1894 *****************************************************************************/
1895 static HRESULT WINAPI
1896 IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7
*iface
,
1899 IDirectDrawSurface7
*Source
,
1903 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1905 IDirectDrawSurfaceImpl
*src
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Source
);
1906 TRACE("(%p)->(%d,%d,%p,%p,%d): Relay\n", This
, dstx
, dsty
, Source
, rsrc
, trans
);
1908 hr
= IWineD3DSurface_BltFast(This
->WineD3DSurface
,
1910 src
? src
->WineD3DSurface
: NULL
,
1915 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
1916 case WINED3DERR_WRONGTEXTUREFORMAT
: return DDERR_INVALIDPIXELFORMAT
;
1921 /*****************************************************************************
1922 * IDirectDrawSurface7::GetClipper
1924 * Returns the IDirectDrawClipper interface of the clipper assigned to this
1928 * Clipper: Address to store the interface pointer at
1932 * DDERR_INVALIDPARAMS if Clipper is NULL
1933 * DDERR_NOCLIPPERATTACHED if there's no clipper attached
1935 *****************************************************************************/
1936 static HRESULT WINAPI
1937 IDirectDrawSurfaceImpl_GetClipper(IDirectDrawSurface7
*iface
,
1938 IDirectDrawClipper
**Clipper
)
1940 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1941 TRACE("(%p)->(%p)\n", This
, Clipper
);
1944 return DDERR_INVALIDPARAMS
;
1946 if(This
->clipper
== NULL
)
1947 return DDERR_NOCLIPPERATTACHED
;
1949 *Clipper
= ICOM_INTERFACE(This
->clipper
, IDirectDrawClipper
);
1950 IDirectDrawClipper_AddRef(*Clipper
);
1954 /*****************************************************************************
1955 * IDirectDrawSurface7::SetClipper
1957 * Sets a clipper for the surface
1960 * Clipper: IDirectDrawClipper interface of the clipper to set
1965 *****************************************************************************/
1966 static HRESULT WINAPI
1967 IDirectDrawSurfaceImpl_SetClipper(IDirectDrawSurface7
*iface
,
1968 IDirectDrawClipper
*Clipper
)
1970 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
1971 IDirectDrawClipperImpl
*oldClipper
= This
->clipper
;
1973 TRACE("(%p)->(%p)\n",This
,Clipper
);
1974 if (ICOM_OBJECT(IDirectDrawClipperImpl
, IDirectDrawClipper
, Clipper
) == This
->clipper
)
1977 This
->clipper
= ICOM_OBJECT(IDirectDrawClipperImpl
, IDirectDrawClipper
, Clipper
);
1979 if (Clipper
!= NULL
)
1980 IDirectDrawClipper_AddRef(Clipper
);
1982 IDirectDrawClipper_Release(ICOM_INTERFACE(oldClipper
, IDirectDrawClipper
));
1984 return IWineD3DSurface_SetClipper(This
->WineD3DSurface
, This
->clipper
->wineD3DClipper
);
1987 /*****************************************************************************
1988 * IDirectDrawSurface7::SetSurfaceDesc
1990 * Sets the surface description. It can override the pixel format, the surface
1992 * It's not really tested.
1995 * DDSD: Pointer to the new surface description to set
2000 * DDERR_INVALIDPARAMS if DDSD is NULL
2002 *****************************************************************************/
2003 static HRESULT WINAPI
2004 IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7
*iface
,
2005 DDSURFACEDESC2
*DDSD
,
2008 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2009 WINED3DFORMAT newFormat
= WINED3DFMT_UNKNOWN
;
2011 TRACE("(%p)->(%p,%x)\n", This
, DDSD
, Flags
);
2014 return DDERR_INVALIDPARAMS
;
2016 if (DDSD
->dwFlags
& DDSD_PIXELFORMAT
)
2018 newFormat
= PixelFormat_DD2WineD3D(&DDSD
->u4
.ddpfPixelFormat
);
2020 if(newFormat
== WINED3DFMT_UNKNOWN
)
2022 ERR("Requested to set an unknown pixelformat\n");
2023 return DDERR_INVALIDPARAMS
;
2025 if(newFormat
!= PixelFormat_DD2WineD3D(&This
->surface_desc
.u4
.ddpfPixelFormat
) )
2027 hr
= IWineD3DSurface_SetFormat(This
->WineD3DSurface
,
2029 if(hr
!= DD_OK
) return hr
;
2032 if (DDSD
->dwFlags
& DDSD_CKDESTOVERLAY
)
2034 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2036 (WINEDDCOLORKEY
*) &DDSD
->u3
.ddckCKDestOverlay
);
2038 if (DDSD
->dwFlags
& DDSD_CKDESTBLT
)
2040 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2042 (WINEDDCOLORKEY
*) &DDSD
->ddckCKDestBlt
);
2044 if (DDSD
->dwFlags
& DDSD_CKSRCOVERLAY
)
2046 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2048 (WINEDDCOLORKEY
*) &DDSD
->ddckCKSrcOverlay
);
2050 if (DDSD
->dwFlags
& DDSD_CKSRCBLT
)
2052 IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2054 (WINEDDCOLORKEY
*) &DDSD
->ddckCKSrcBlt
);
2056 if (DDSD
->dwFlags
& DDSD_LPSURFACE
&& DDSD
->lpSurface
)
2058 hr
= IWineD3DSurface_SetMem(This
->WineD3DSurface
, DDSD
->lpSurface
);
2059 if(hr
!= WINED3D_OK
)
2061 /* No need for a trace here, wined3d does that for us */
2064 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
2065 default: break; /* Go on */
2071 This
->surface_desc
= *DDSD
;
2076 /*****************************************************************************
2077 * IDirectDrawSurface7::GetPalette
2079 * Returns the IDirectDrawPalette interface of the palette currently assigned
2083 * Pal: Address to write the interface pointer to
2087 * DDERR_INVALIDPARAMS if Pal is NULL
2089 *****************************************************************************/
2090 static HRESULT WINAPI
2091 IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7
*iface
,
2092 IDirectDrawPalette
**Pal
)
2094 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2095 IWineD3DPalette
*wPal
;
2097 TRACE("(%p)->(%p): Relay\n", This
, Pal
);
2100 return DDERR_INVALIDPARAMS
;
2102 hr
= IWineD3DSurface_GetPalette(This
->WineD3DSurface
, &wPal
);
2103 if(hr
!= DD_OK
) return hr
;
2107 hr
= IWineD3DPalette_GetParent(wPal
, (IUnknown
**) Pal
);
2112 hr
= DDERR_NOPALETTEATTACHED
;
2118 /*****************************************************************************
2121 * EnumAttachedSurface callback for SetColorKey. Used to set color keys
2122 * recursively in the surface tree
2124 *****************************************************************************/
2128 WINEDDCOLORKEY
*CKey
;
2132 static HRESULT WINAPI
2133 SetColorKeyEnum(IDirectDrawSurface7
*surface
,
2134 DDSURFACEDESC2
*desc
,
2137 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, surface
);
2138 struct SCKContext
*ctx
= context
;
2141 hr
= IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2146 WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr
);
2150 IDirectDrawSurface7_EnumAttachedSurfaces(surface
,
2153 IDirectDrawSurface7_Release(surface
);
2154 return DDENUMRET_OK
;
2157 /*****************************************************************************
2158 * IDirectDrawSurface7::SetColorKey
2160 * Sets the color keying options for the surface. Observations showed that
2161 * in case of complex surfaces the color key has to be assigned to all
2166 * CKey: The new color key
2170 * See IWineD3DSurface::SetColorKey for details
2172 *****************************************************************************/
2173 static HRESULT WINAPI
2174 IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7
*iface
,
2178 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2179 struct SCKContext ctx
= { DD_OK
, (WINEDDCOLORKEY
*) CKey
, Flags
};
2180 TRACE("(%p)->(%x,%p)\n", This
, Flags
, CKey
);
2184 switch (Flags
& ~DDCKEY_COLORSPACE
)
2186 case DDCKEY_DESTBLT
:
2187 This
->surface_desc
.ddckCKDestBlt
= *CKey
;
2188 This
->surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
2191 case DDCKEY_DESTOVERLAY
:
2192 This
->surface_desc
.u3
.ddckCKDestOverlay
= *CKey
;
2193 This
->surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
2196 case DDCKEY_SRCOVERLAY
:
2197 This
->surface_desc
.ddckCKSrcOverlay
= *CKey
;
2198 This
->surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
2202 This
->surface_desc
.ddckCKSrcBlt
= *CKey
;
2203 This
->surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
2207 return DDERR_INVALIDPARAMS
;
2212 switch (Flags
& ~DDCKEY_COLORSPACE
)
2214 case DDCKEY_DESTBLT
:
2215 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTBLT
;
2218 case DDCKEY_DESTOVERLAY
:
2219 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTOVERLAY
;
2222 case DDCKEY_SRCOVERLAY
:
2223 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCOVERLAY
;
2227 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCBLT
;
2231 return DDERR_INVALIDPARAMS
;
2234 ctx
.ret
= IWineD3DSurface_SetColorKey(This
->WineD3DSurface
,
2237 IDirectDrawSurface7_EnumAttachedSurfaces(iface
,
2242 case WINED3DERR_INVALIDCALL
: return DDERR_INVALIDPARAMS
;
2243 default: return ctx
.ret
;
2247 /*****************************************************************************
2248 * IDirectDrawSurface7::SetPalette
2250 * Assigns a DirectDrawPalette object to the surface
2253 * Pal: Interface to the palette to set
2258 *****************************************************************************/
2259 static HRESULT WINAPI
2260 IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7
*iface
,
2261 IDirectDrawPalette
*Pal
)
2263 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, iface
);
2264 IDirectDrawPalette
*oldPal
;
2265 IDirectDrawSurfaceImpl
*surf
;
2266 IDirectDrawPaletteImpl
*PalImpl
= ICOM_OBJECT(IDirectDrawPaletteImpl
, IDirectDrawPalette
, Pal
);
2268 TRACE("(%p)->(%p)\n", This
, Pal
);
2270 /* Find the old palette */
2271 hr
= IDirectDrawSurface_GetPalette(iface
, &oldPal
);
2272 if(hr
!= DD_OK
&& hr
!= DDERR_NOPALETTEATTACHED
) return hr
;
2273 if(oldPal
) IDirectDrawPalette_Release(oldPal
); /* For the GetPalette */
2275 /* Set the new Palette */
2276 IWineD3DSurface_SetPalette(This
->WineD3DSurface
,
2277 PalImpl
? PalImpl
->wineD3DPalette
: NULL
);
2278 /* AddRef the Palette */
2279 if(Pal
) IDirectDrawPalette_AddRef(Pal
);
2281 /* Release the old palette */
2282 if(oldPal
) IDirectDrawPalette_Release(oldPal
);
2284 /* If this is a front buffer, also update the back buffers
2285 * TODO: How do things work for palettized cube textures?
2287 if(This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_FRONTBUFFER
)
2289 /* For primary surfaces the tree is just a list, so the simpler scheme fits too */
2290 DDSCAPS2 caps2
= { DDSCAPS_PRIMARYSURFACE
, 0, 0, 0 };
2295 IDirectDrawSurface7
*attach
;
2297 hr
= IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(surf
, IDirectDrawSurface7
),
2304 TRACE("Setting palette on %p\n", attach
);
2305 IDirectDrawSurface7_SetPalette(attach
,
2307 surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, attach
);
2308 IDirectDrawSurface7_Release(attach
);
2315 /*****************************************************************************
2317 *****************************************************************************/
2319 const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl
=
2322 IDirectDrawSurfaceImpl_QueryInterface
,
2323 IDirectDrawSurfaceImpl_AddRef
,
2324 IDirectDrawSurfaceImpl_Release
,
2325 /*** IDirectDrawSurface ***/
2326 IDirectDrawSurface7Impl_AddAttachedSurface
,
2327 IDirectDrawSurfaceImpl_AddOverlayDirtyRect
,
2328 IDirectDrawSurfaceImpl_Blt
,
2329 IDirectDrawSurfaceImpl_BltBatch
,
2330 IDirectDrawSurfaceImpl_BltFast
,
2331 IDirectDrawSurfaceImpl_DeleteAttachedSurface
,
2332 IDirectDrawSurfaceImpl_EnumAttachedSurfaces
,
2333 IDirectDrawSurfaceImpl_EnumOverlayZOrders
,
2334 IDirectDrawSurfaceImpl_Flip
,
2335 IDirectDrawSurfaceImpl_GetAttachedSurface
,
2336 IDirectDrawSurfaceImpl_GetBltStatus
,
2337 IDirectDrawSurfaceImpl_GetCaps
,
2338 IDirectDrawSurfaceImpl_GetClipper
,
2339 IDirectDrawSurfaceImpl_GetColorKey
,
2340 IDirectDrawSurfaceImpl_GetDC
,
2341 IDirectDrawSurfaceImpl_GetFlipStatus
,
2342 IDirectDrawSurfaceImpl_GetOverlayPosition
,
2343 IDirectDrawSurfaceImpl_GetPalette
,
2344 IDirectDrawSurfaceImpl_GetPixelFormat
,
2345 IDirectDrawSurfaceImpl_GetSurfaceDesc
,
2346 IDirectDrawSurfaceImpl_Initialize
,
2347 IDirectDrawSurfaceImpl_IsLost
,
2348 IDirectDrawSurfaceImpl_Lock
,
2349 IDirectDrawSurfaceImpl_ReleaseDC
,
2350 IDirectDrawSurfaceImpl_Restore
,
2351 IDirectDrawSurfaceImpl_SetClipper
,
2352 IDirectDrawSurfaceImpl_SetColorKey
,
2353 IDirectDrawSurfaceImpl_SetOverlayPosition
,
2354 IDirectDrawSurfaceImpl_SetPalette
,
2355 IDirectDrawSurfaceImpl_Unlock
,
2356 IDirectDrawSurfaceImpl_UpdateOverlay
,
2357 IDirectDrawSurfaceImpl_UpdateOverlayDisplay
,
2358 IDirectDrawSurfaceImpl_UpdateOverlayZOrder
,
2359 /*** IDirectDrawSurface2 ***/
2360 IDirectDrawSurfaceImpl_GetDDInterface
,
2361 IDirectDrawSurfaceImpl_PageLock
,
2362 IDirectDrawSurfaceImpl_PageUnlock
,
2363 /*** IDirectDrawSurface3 ***/
2364 IDirectDrawSurfaceImpl_SetSurfaceDesc
,
2365 /*** IDirectDrawSurface4 ***/
2366 IDirectDrawSurfaceImpl_SetPrivateData
,
2367 IDirectDrawSurfaceImpl_GetPrivateData
,
2368 IDirectDrawSurfaceImpl_FreePrivateData
,
2369 IDirectDrawSurfaceImpl_GetUniquenessValue
,
2370 IDirectDrawSurfaceImpl_ChangeUniquenessValue
,
2371 /*** IDirectDrawSurface7 ***/
2372 IDirectDrawSurfaceImpl_SetPriority
,
2373 IDirectDrawSurfaceImpl_GetPriority
,
2374 IDirectDrawSurfaceImpl_SetLOD
,
2375 IDirectDrawSurfaceImpl_GetLOD