1 /* DirectDrawSurface base implementation
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
5 * Copyright 2000-2001 TransGaming Technologies Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
32 #include "wine/debug.h"
33 #include "ddraw_private.h"
34 #include "opengl_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
37 WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip
);
38 WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps
);
40 /** Creation/Destruction functions */
43 Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl
*This
,
45 const DDSURFACEDESC2
*pDDSD
)
47 TRACE("(%p)->(%p,%p)\n", This
, pDD
, pDDSD
);
49 if (pDDSD
!= &This
->surface_desc
) {
50 This
->surface_desc
.dwSize
= sizeof(This
->surface_desc
);
51 DD_STRUCT_COPY_BYSIZE(&(This
->surface_desc
),pDDSD
);
53 This
->uniqueness_value
= 1; /* unchecked */
56 This
->local
.lpSurfMore
= &This
->more
;
57 This
->local
.lpGbl
= &This
->global
;
58 This
->local
.dwProcessId
= GetCurrentProcessId();
59 This
->local
.dwFlags
= 0; /* FIXME */
60 This
->local
.ddsCaps
.dwCaps
= This
->surface_desc
.ddsCaps
.dwCaps
;
61 /* FIXME: more local stuff */
62 This
->more
.lpDD_lcl
= &pDD
->local
;
63 This
->more
.ddsCapsEx
.dwCaps2
= This
->surface_desc
.ddsCaps
.dwCaps2
;
64 This
->more
.ddsCapsEx
.dwCaps3
= This
->surface_desc
.ddsCaps
.dwCaps3
;
65 This
->more
.ddsCapsEx
.dwCaps4
= This
->surface_desc
.ddsCaps
.dwCaps4
;
66 /* FIXME: more more stuff */
67 This
->gmore
= &This
->global_more
;
68 This
->global
.u3
.lpDD
= pDD
->local
.lpGbl
;
69 /* FIXME: more global stuff */
71 This
->final_release
= Main_DirectDrawSurface_final_release
;
72 This
->late_allocate
= Main_DirectDrawSurface_late_allocate
;
73 This
->attach
= Main_DirectDrawSurface_attach
;
74 This
->detach
= Main_DirectDrawSurface_detach
;
75 This
->lock_update
= Main_DirectDrawSurface_lock_update
;
76 This
->unlock_update
= Main_DirectDrawSurface_unlock_update
;
77 This
->lose_surface
= Main_DirectDrawSurface_lose_surface
;
78 This
->set_palette
= Main_DirectDrawSurface_set_palette
;
79 This
->update_palette
= Main_DirectDrawSurface_update_palette
;
80 This
->get_display_window
= Main_DirectDrawSurface_get_display_window
;
81 This
->get_gamma_ramp
= Main_DirectDrawSurface_get_gamma_ramp
;
82 This
->set_gamma_ramp
= Main_DirectDrawSurface_set_gamma_ramp
;
84 ICOM_INIT_INTERFACE(This
, IDirectDrawSurface3
,
85 DDRAW_IDDS3_Thunk_VTable
);
86 ICOM_INIT_INTERFACE(This
, IDirectDrawGammaControl
,
89 /* There is no generic implementation of IDDS7 or texture */
91 Main_DirectDraw_AddSurface(pDD
, This
);
95 void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl
* This
)
97 Main_DirectDraw_RemoveSurface(This
->ddraw_owner
, This
);
100 HRESULT
Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl
* This
)
105 static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl
* This
)
108 IDirectDrawPalette_Release(ICOM_INTERFACE(This
->palette
, IDirectDrawPalette
));
109 This
->palette
= NULL
;
111 This
->final_release(This
);
112 if (This
->private != This
+1) HeapFree(GetProcessHeap(), 0, This
->private);
113 if (This
->tex_private
) HeapFree(GetProcessHeap(), 0, This
->tex_private
);
114 HeapFree(GetProcessHeap(), 0, This
);
117 void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl
* This
)
119 WARN("destroying surface %p with refcnt %lu\n", This
, This
->ref
);
120 Main_DirectDrawSurface_Destroy(This
);
123 ULONG WINAPI
Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface
)
125 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
126 ULONG ref
= InterlockedDecrement(&This
->ref
);
128 TRACE("(%p)->(): decreasing from %ld\n", This
, ref
+ 1);
132 if (This
->aux_release
)
133 This
->aux_release(This
->aux_ctx
, This
->aux_data
);
134 Main_DirectDrawSurface_Destroy(This
);
136 TRACE("released surface %p\n", This
);
144 ULONG WINAPI
Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface
)
146 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
147 ULONG ref
= InterlockedIncrement(&This
->ref
);
149 TRACE("(%p)->(): increasing from %ld\n", This
, ref
- 1);
155 Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface
, REFIID riid
,
158 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
159 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(riid
), ppObj
);
163 if (IsEqualGUID(&IID_IUnknown
, riid
)
164 || IsEqualGUID(&IID_IDirectDrawSurface7
, riid
)
165 || IsEqualGUID(&IID_IDirectDrawSurface4
, riid
))
167 InterlockedIncrement(&This
->ref
);
168 *ppObj
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
171 else if (IsEqualGUID(&IID_IDirectDrawSurface
, riid
)
172 || IsEqualGUID(&IID_IDirectDrawSurface2
, riid
)
173 || IsEqualGUID(&IID_IDirectDrawSurface3
, riid
))
175 InterlockedIncrement(&This
->ref
);
176 *ppObj
= ICOM_INTERFACE(This
, IDirectDrawSurface3
);
179 else if (IsEqualGUID(&IID_IDirectDrawGammaControl
, riid
))
181 InterlockedIncrement(&This
->ref
);
182 *ppObj
= ICOM_INTERFACE(This
, IDirectDrawGammaControl
);
186 /* interfaces following here require OpenGL */
187 if( !opengl_initialized
)
188 return E_NOINTERFACE
;
190 if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL
, riid
) ||
191 IsEqualGUID( &IID_IDirect3DHALDevice
, riid
) )
193 IDirect3DDeviceImpl
*d3ddevimpl
;
196 ret_value
= d3ddevice_create(&d3ddevimpl
, This
->ddraw_owner
, This
, 1);
197 if (FAILED(ret_value
)) return ret_value
;
199 *ppObj
= ICOM_INTERFACE(d3ddevimpl
, IDirect3DDevice
);
200 TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj
);
202 InterlockedIncrement(&This
->ref
); /* No idea if this is correct.. Need to check using real Windows */
205 else if (IsEqualGUID( &IID_IDirect3DTexture
, riid
) ||
206 IsEqualGUID( &IID_IDirect3DTexture2
, riid
))
208 HRESULT ret_value
= S_OK
;
210 /* Note: this is not exactly how Windows does it... But this seems not to hurt the only
211 application I know creating a texture without this flag set and it will prevent
212 bugs in other parts of Wine.
214 This
->surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_TEXTURE
;
216 /* In case the texture surface was created before the D3D creation */
217 if (This
->tex_private
== NULL
) {
218 if (This
->ddraw_owner
->d3d_private
== NULL
) {
219 ERR("Texture created with no D3D object yet.. Not supported !\n");
220 return E_NOINTERFACE
;
223 ret_value
= This
->ddraw_owner
->d3d_create_texture(This
->ddraw_owner
, This
, FALSE
, This
->mip_main
);
224 if (FAILED(ret_value
)) return ret_value
;
226 if (IsEqualGUID( &IID_IDirect3DTexture
, riid
)) {
227 *ppObj
= ICOM_INTERFACE(This
, IDirect3DTexture
);
228 TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj
);
230 *ppObj
= ICOM_INTERFACE(This
, IDirect3DTexture2
);
231 TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj
);
233 InterlockedIncrement(&This
->ref
);
238 return E_NOINTERFACE
;
244 Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl
*This
,
245 IDirectDrawSurfaceImpl
*to
)
250 BOOL
Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl
*This
)
256 Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
,
262 Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl
* This
,
268 Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl
* This
)
273 Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl
* This
,
274 IDirectDrawPaletteImpl
* pal
)
279 Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl
* This
,
280 IDirectDrawPaletteImpl
* pal
,
281 DWORD dwStart
, DWORD dwCount
,
282 LPPALETTEENTRY palent
)
287 Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl
* This
)
293 Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl
* This
,
295 LPDDGAMMARAMP lpGammaRamp
)
299 hr
= This
->get_dc(This
, &hDC
);
300 if (FAILED(hr
)) return hr
;
301 hr
= GetDeviceGammaRamp(hDC
, lpGammaRamp
) ? DD_OK
: DDERR_UNSUPPORTED
;
302 This
->release_dc(This
, hDC
);
307 Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl
* This
,
309 LPDDGAMMARAMP lpGammaRamp
)
313 hr
= This
->get_dc(This
, &hDC
);
314 if (FAILED(hr
)) return hr
;
315 hr
= SetDeviceGammaRamp(hDC
, lpGammaRamp
) ? DD_OK
: DDERR_UNSUPPORTED
;
316 This
->release_dc(This
, hDC
);
321 /*** Interface functions */
324 Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface
,
325 LPDIRECTDRAWSURFACE7 pAttach
)
327 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
328 IDirectDrawSurfaceImpl
* surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
,
329 IDirectDrawSurface7
, pAttach
);
331 TRACE("(%p)->(%p)\n",This
,pAttach
);
333 /* Does windows check this? */
335 return DDERR_CANNOTATTACHSURFACE
; /* unchecked */
337 /* Does windows check this? */
338 if (surf
->ddraw_owner
!= This
->ddraw_owner
)
339 return DDERR_CANNOTATTACHSURFACE
; /* unchecked */
341 if (surf
->surface_owner
!= NULL
)
342 return DDERR_SURFACEALREADYATTACHED
; /* unchecked */
344 /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
345 * But apparently backbuffers and mipmaps can be attached too. */
347 /* Set MIPMAPSUBLEVEL if this seems to be one */
348 if (This
->surface_desc
.ddsCaps
.dwCaps
&
349 surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
) {
350 surf
->surface_desc
.ddsCaps
.dwCaps2
|= DDSCAPS2_MIPMAPSUBLEVEL
;
351 /* FIXME: we should probably also add to dwMipMapCount of this
352 * and all parent surfaces (update create_texture if you do) */
355 /* Callback to allow the surface to do something special now that it is
356 * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
357 if (!surf
->attach(surf
, This
))
358 return DDERR_CANNOTATTACHSURFACE
;
360 /* check: Where should it go in the chain? This puts it on the head. */
362 This
->attached
->prev_attached
= surf
;
363 surf
->next_attached
= This
->attached
;
364 surf
->prev_attached
= NULL
;
365 This
->attached
= surf
;
366 surf
->surface_owner
= This
;
368 IDirectDrawSurface7_AddRef(pAttach
);
373 /* MSDN: "not currently implemented." */
375 Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface
,
378 TRACE("(%p)->(%p)\n",iface
,pRect
);
379 return DDERR_UNSUPPORTED
; /* unchecked */
382 /* MSDN: "not currently implemented." */
384 Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface
,
385 LPDDBLTBATCH pBatch
, DWORD dwCount
,
388 TRACE("(%p)->(%p,%ld,%08lx)\n",iface
,pBatch
,dwCount
,dwFlags
);
389 return DDERR_UNSUPPORTED
; /* unchecked */
393 Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface
)
395 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
396 volatile IDirectDrawSurfaceImpl
* vThis
= This
;
398 TRACE("(%p)\n",This
);
399 /* A uniquness value of 0 is apparently special.
400 * This needs to be checked. */
403 DWORD old_uniqueness_value
= vThis
->uniqueness_value
;
404 DWORD new_uniqueness_value
= old_uniqueness_value
+1;
406 if (old_uniqueness_value
== 0) break;
407 if (new_uniqueness_value
== 0) new_uniqueness_value
= 1;
409 if (InterlockedCompareExchange((LONG
*)&vThis
->uniqueness_value
,
410 old_uniqueness_value
,
411 new_uniqueness_value
)
412 == old_uniqueness_value
)
420 Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface
,
422 LPDIRECTDRAWSURFACE7 pAttach
)
424 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
425 IDirectDrawSurfaceImpl
* surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
,
426 IDirectDrawSurface7
, pAttach
);
428 TRACE("(%p)->(%08lx,%p)\n",This
,dwFlags
,pAttach
);
430 if (!surf
|| (surf
->surface_owner
!= This
))
431 return DDERR_SURFACENOTATTACHED
; /* unchecked */
435 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
436 if (This
->surface_desc
.ddsCaps
.dwCaps
&
437 surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
) {
438 surf
->surface_desc
.ddsCaps
.dwCaps2
&= ~DDSCAPS2_MIPMAPSUBLEVEL
;
439 /* FIXME: we should probably also subtract from dwMipMapCount of this
440 * and all parent surfaces */
443 if (surf
->next_attached
)
444 surf
->next_attached
->prev_attached
= surf
->prev_attached
;
445 if (surf
->prev_attached
)
446 surf
->prev_attached
->next_attached
= surf
->next_attached
;
447 if (This
->attached
== surf
)
448 This
->attached
= surf
->next_attached
;
450 IDirectDrawSurface7_Release(pAttach
);
456 Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface
,
458 LPDDENUMSURFACESCALLBACK7 cb
)
460 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
461 IDirectDrawSurfaceImpl
* surf
;
464 TRACE("(%p)->(%p,%p)\n",This
,context
,cb
);
466 for (surf
= This
->attached
; surf
!= NULL
; surf
= surf
->next_attached
)
468 LPDIRECTDRAWSURFACE7 isurf
= ICOM_INTERFACE(surf
, IDirectDrawSurface7
);
470 if (TRACE_ON(ddraw
)) {
471 TRACE(" => enumerating surface %p (priv. %p) with description:\n", isurf
, surf
);
472 DDRAW_dump_surface_desc(&surf
->surface_desc
);
475 IDirectDrawSurface7_AddRef(isurf
);
476 desc
= surf
->surface_desc
;
477 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
478 if (cb(isurf
, &desc
, context
) == DDENUMRET_CANCEL
)
482 TRACE(" end of enumeration.\n");
488 Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface
,
489 DWORD dwFlags
, LPVOID context
,
490 LPDDENUMSURFACESCALLBACK7 cb
)
492 TRACE("(%p)->(%08lx,%p,%p)\n",iface
,dwFlags
,context
,cb
);
496 BOOL
Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl
* front
,
497 IDirectDrawSurfaceImpl
* back
,
500 /* uniqueness_value? */
501 /* This is necessary. But is it safe? */
503 HDC tmp
= front
->hDC
;
504 front
->hDC
= back
->hDC
;
509 BOOL tmp
= front
->dc_in_use
;
510 front
->dc_in_use
= back
->dc_in_use
;
511 back
->dc_in_use
= tmp
;
515 FLATPTR tmp
= front
->global
.fpVidMem
;
516 front
->global
.fpVidMem
= back
->global
.fpVidMem
;
517 back
->global
.fpVidMem
= tmp
;
521 ULONG_PTR tmp
= front
->global_more
.hKernelSurface
;
522 front
->global_more
.hKernelSurface
= back
->global_more
.hKernelSurface
;
523 back
->global_more
.hKernelSurface
= tmp
;
529 /* This is unnecessarely complicated :-) */
530 #define MEASUREMENT_WINDOW 5
531 #define NUMBER_OF_WINDOWS 10
533 static LONGLONG perf_freq
;
534 static LONGLONG perf_storage
[NUMBER_OF_WINDOWS
];
535 static LONGLONG prev_time
= 0;
536 static unsigned int current_window
;
537 static unsigned int measurements_in_window
;
538 static unsigned int valid_windows
;
541 Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface
,
542 LPDIRECTDRAWSURFACE7 override
, DWORD dwFlags
)
544 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
545 IDirectDrawSurfaceImpl
* target
;
548 TRACE("(%p)->(%p,%08lx)\n",This
,override
,dwFlags
);
550 if (TRACE_ON(ddraw_fps
)) {
551 LONGLONG current_time
;
552 LONGLONG frame_duration
;
553 QueryPerformanceCounter((LARGE_INTEGER
*) ¤t_time
);
555 if (prev_time
!= 0) {
556 LONGLONG total_time
= 0;
559 frame_duration
= current_time
- prev_time
;
560 prev_time
= current_time
;
562 perf_storage
[current_window
] += frame_duration
;
563 measurements_in_window
++;
565 if (measurements_in_window
>= MEASUREMENT_WINDOW
) {
569 if (valid_windows
< NUMBER_OF_WINDOWS
) {
571 tot_meas
= valid_windows
* MEASUREMENT_WINDOW
;
572 for (i
= 0; i
< valid_windows
; i
++) {
573 total_time
+= perf_storage
[i
];
577 tot_meas
= NUMBER_OF_WINDOWS
* MEASUREMENT_WINDOW
;
578 for (i
= 0; i
< NUMBER_OF_WINDOWS
; i
++) {
579 total_time
+= perf_storage
[i
];
583 TRACE_(ddraw_fps
)(" %9.5f\n", (double) (perf_freq
* tot_meas
) / (double) total_time
);
585 if (current_window
>= NUMBER_OF_WINDOWS
) {
588 perf_storage
[current_window
] = 0;
589 measurements_in_window
= 0;
592 prev_time
= current_time
;
593 memset(perf_storage
, 0, sizeof(perf_storage
));
596 measurements_in_window
= 0;
597 QueryPerformanceFrequency((LARGE_INTEGER
*) &perf_freq
);
601 /* MSDN: "This method can be called only for a surface that has the
602 * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
603 if ((This
->surface_desc
.ddsCaps
.dwCaps
&(DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
))
604 != (DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
))
605 return DDERR_NOTFLIPPABLE
;
608 if (This
->aux_flip(This
->aux_ctx
, This
->aux_data
))
611 /* 1. find the flip target */
612 /* XXX I don't think this algorithm works for more than 1 backbuffer. */
613 if (override
== NULL
)
615 static DDSCAPS2 back_caps
= { DDSCAPS_BACKBUFFER
};
616 LPDIRECTDRAWSURFACE7 tgt
;
618 hr
= IDirectDrawSurface7_GetAttachedSurface(iface
, &back_caps
, &tgt
);
619 if (FAILED(hr
)) return DDERR_NOTFLIPPABLE
; /* unchecked */
621 target
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
,
623 IDirectDrawSurface7_Release(tgt
);
627 BOOL on_chain
= FALSE
;
628 IDirectDrawSurfaceImpl
* surf
;
630 /* MSDN: "The method fails if the specified [override] surface is not
631 * a member of the flipping chain." */
633 /* Verify that override is on this flip chain. We assume that
634 * surf is the head of the flipping chain, because it's the front
636 target
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
,
639 /* Either target is (indirectly) attached to This or This is
640 * (indirectly) attached to target. */
641 for (surf
= target
; surf
!= NULL
; surf
= surf
->surface_owner
)
651 return DDERR_INVALIDPARAMS
; /* unchecked */
654 TRACE("flip to backbuffer: %p\n",target
);
655 if (TRACE_ON(ddraw_flip
)) {
656 static unsigned int flip_count
= 0;
657 IDirectDrawPaletteImpl
*palette
;
661 /* Hack for paletted games... */
662 palette
= target
->palette
;
663 target
->palette
= This
->palette
;
665 sprintf(buf
, "flip_%08d.ppm", flip_count
++);
666 TRACE_(ddraw_flip
)("Dumping file %s to disk.\n", buf
);
667 f
= fopen(buf
, "wb");
668 DDRAW_dump_surface_to_disk(target
, f
, 8);
669 target
->palette
= palette
;
672 if (This
->flip_data(This
, target
, dwFlags
))
673 This
->flip_update(This
, dwFlags
);
678 static PrivateData
* find_private_data(IDirectDrawSurfaceImpl
*This
,
682 for (data
= This
->private_data
; data
!= NULL
; data
= data
->next
)
684 if (IsEqualGUID(&data
->tag
, tag
)) break;
691 Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface
, REFGUID tag
)
693 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
696 data
= find_private_data(This
, tag
);
697 if (data
== NULL
) return DDERR_NOTFOUND
;
700 data
->prev
->next
= data
->next
;
702 data
->next
->prev
= data
->prev
;
704 if (data
->flags
& DDSPD_IUNKNOWNPTR
)
706 if (data
->ptr
.object
!= NULL
)
707 IUnknown_Release(data
->ptr
.object
);
710 HeapFree(GetProcessHeap(), 0, data
->ptr
.data
);
712 HeapFree(GetProcessHeap(), 0, data
);
718 Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface
,
720 LPDIRECTDRAWSURFACE7
* ppSurface
)
722 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
723 IDirectDrawSurfaceImpl
* surf
;
724 IDirectDrawSurfaceImpl
* found
= NULL
;
727 if (TRACE_ON(ddraw
)) {
728 TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This
,pCaps
->dwCaps
, pCaps
->dwCaps2
,
729 pCaps
->dwCaps3
, pCaps
->dwCaps4
, ppSurface
);
730 TRACE(" Caps are : "); DDRAW_dump_DDSCAPS2(pCaps
); TRACE("\n");
734 if ((This
->ddraw_owner
->local
.dwLocalFlags
& DDRAWILCL_DIRECTDRAW7
) == 0) {
735 /* As this is not a DirectDraw7 application, remove the garbage that some games
736 put in the new fields of the DDSCAPS2 structure. */
737 our_caps
.dwCaps2
= 0;
738 our_caps
.dwCaps3
= 0;
739 our_caps
.dwCaps4
= 0;
740 if (TRACE_ON(ddraw
)) {
741 TRACE(" Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps
); TRACE("\n");
745 for (surf
= This
->attached
; surf
!= NULL
; surf
= surf
->next_attached
)
747 if (TRACE_ON(ddraw
)) {
748 TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf
,
749 surf
->surface_desc
.ddsCaps
.dwCaps
,
750 surf
->surface_desc
.ddsCaps
.dwCaps2
,
751 surf
->surface_desc
.ddsCaps
.dwCaps3
,
752 surf
->surface_desc
.ddsCaps
.dwCaps4
);
753 TRACE(" Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf
->surface_desc
.ddsCaps
)); TRACE("\n");
755 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
756 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
))
758 /* MSDN: "This method fails if more than one surface is attached
759 * that matches the capabilities requested." */
762 FIXME("More than one attached surface matches requested caps. What should we do here?\n");
763 /* Previous code returned 'DDERR_NOTFOUND'. That appears not
764 to be correct, given what 3DMark expects from MipMapped surfaces.
765 We shall just continue instead. */
773 TRACE("Did not find any valid surface\n");
774 return DDERR_NOTFOUND
;
777 *ppSurface
= ICOM_INTERFACE(found
, IDirectDrawSurface7
);
779 if (TRACE_ON(ddraw
)) {
780 TRACE("Returning surface %p with description :\n", *ppSurface
);
781 DDRAW_dump_surface_desc(&(found
->surface_desc
));
784 /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
785 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found
, IDirectDrawSurface7
));
790 Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface
, DWORD dwFlags
)
792 TRACE("(%p)->(%08lx)\n",iface
,dwFlags
);
797 case DDGBS_ISBLTDONE
:
801 return DDERR_INVALIDPARAMS
;
806 Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface
, LPDDSCAPS2 pCaps
)
808 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
810 TRACE("(%p)->(%p)\n",This
,pCaps
);
811 *pCaps
= This
->surface_desc
.ddsCaps
;
816 Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface
,
817 LPDIRECTDRAWCLIPPER
* ppClipper
)
819 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
821 TRACE("(%p)->(%p)\n",This
,ppClipper
);
822 if (This
->clipper
== NULL
)
823 return DDERR_NOCLIPPERATTACHED
;
825 *ppClipper
= ICOM_INTERFACE(This
->clipper
, IDirectDrawClipper
);
826 IDirectDrawClipper_AddRef(ICOM_INTERFACE(This
->clipper
,
827 IDirectDrawClipper
));
832 Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface
, DWORD dwFlags
,
835 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
836 * isn't there? That's like saying that an int isn't there. (Which MS
837 * has done in other docs.) */
839 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
841 TRACE("(%p)->(%08lx,%p)\n",This
,dwFlags
,pCKey
);
842 if (TRACE_ON(ddraw
)) {
843 TRACE(" - colorkey flags : ");
844 DDRAW_dump_colorkeyflag(dwFlags
);
850 *pCKey
= This
->surface_desc
.ddckCKDestBlt
;
853 case DDCKEY_DESTOVERLAY
:
854 *pCKey
= This
->surface_desc
.u3
.ddckCKDestOverlay
;
858 *pCKey
= This
->surface_desc
.ddckCKSrcBlt
;
861 case DDCKEY_SRCOVERLAY
:
862 *pCKey
= This
->surface_desc
.ddckCKSrcOverlay
;
866 return DDERR_INVALIDPARAMS
;
872 /* XXX We need to do something with the DC if the surface gets lost. */
874 Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface
, HDC
*phDC
)
878 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
880 TRACE("(%p)->(%p)\n",This
,phDC
);
888 return DDERR_DCALREADYCREATED
;
892 * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
893 * thread has it locked, but GetDC does not. */
894 ddsd
.dwSize
= sizeof(ddsd
);
895 hr
= IDirectDrawSurface7_Lock(iface
, NULL
, &ddsd
, 0, 0);
902 hr
= This
->get_dc(This
, &This
->hDC
);
904 if ((This
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) &&
905 (This
->palette
== NULL
)) {
906 IDirectDrawImpl
*ddraw
= This
->ddraw_owner
;
907 IDirectDrawSurfaceImpl
*surf
;
909 for (surf
= ddraw
->surfaces
; surf
!= NULL
; surf
= surf
->next_ddraw
) {
910 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
)) == (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
)) &&
911 (surf
->palette
!= NULL
)) {
913 IDirectDrawPaletteImpl
*pal
= surf
->palette
;
915 for (n
=0; n
<256; n
++) {
916 col
[n
].rgbRed
= pal
->palents
[n
].peRed
;
917 col
[n
].rgbGreen
= pal
->palents
[n
].peGreen
;
918 col
[n
].rgbBlue
= pal
->palents
[n
].peBlue
;
919 col
[n
].rgbReserved
= 0;
921 SetDIBColorTable(This
->hDC
, 0, 256, col
);
930 TRACE("returning %p\n",This
->hDC
);
933 This
->dc_in_use
= TRUE
;
935 else WARN("No DC! Prepare for trouble\n");
942 Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface
, LPVOID
* pDD
)
944 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
946 TRACE("(%p)->(%p)\n",This
,pDD
);
947 *pDD
= ICOM_INTERFACE(This
->ddraw_owner
, IDirectDraw7
);
948 IDirectDraw7_AddRef(ICOM_INTERFACE(This
->ddraw_owner
, IDirectDraw7
));
953 Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface
, DWORD dwFlags
)
955 /* XXX: DDERR_INVALIDSURFACETYPE */
957 TRACE("(%p)->(%08lx)\n",iface
,dwFlags
);
961 case DDGFS_ISFLIPDONE
:
965 return DDERR_INVALIDPARAMS
;
970 Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface
, LPDWORD pdwMaxLOD
)
972 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
974 TRACE("(%p)->(%p)\n",This
,pdwMaxLOD
);
977 *pdwMaxLOD
= This
->max_lod
;
982 Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface
,
983 LPLONG pX
, LPLONG pY
)
985 return DDERR_NOTAOVERLAYSURFACE
;
989 Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface
,
990 LPDIRECTDRAWPALETTE
* ppPalette
)
992 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
994 TRACE("(%p)->(%p)\n",This
,ppPalette
);
995 if (This
->palette
== NULL
)
996 return DDERR_NOPALETTEATTACHED
;
998 *ppPalette
= ICOM_INTERFACE(This
->palette
, IDirectDrawPalette
);
999 IDirectDrawPalette_AddRef(ICOM_INTERFACE(This
->palette
,
1000 IDirectDrawPalette
));
1005 Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface
,
1006 LPDDPIXELFORMAT pDDPixelFormat
)
1008 /* What is DDERR_INVALIDSURFACETYPE for here? */
1009 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1011 TRACE("(%p)->(%p)\n",This
,pDDPixelFormat
);
1012 DD_STRUCT_COPY_BYSIZE(pDDPixelFormat
,&This
->surface_desc
.u4
.ddpfPixelFormat
);
1017 Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface
,
1018 LPDWORD pdwPriority
)
1020 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1022 TRACE("(%p)->(%p)\n",This
,pdwPriority
);
1023 CHECK_TEXTURE(This
);
1025 *pdwPriority
= This
->priority
;
1030 Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface
,
1031 REFGUID tag
, LPVOID pBuffer
,
1032 LPDWORD pcbBufferSize
)
1034 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1037 TRACE("(%p)->(%p), size = %ld\n", This
, pBuffer
, *pcbBufferSize
);
1039 data
= find_private_data(This
, tag
);
1040 if (data
== NULL
) return DDERR_NOTFOUND
;
1042 /* This may not be right. */
1043 if ((data
->flags
& DDSPD_VOLATILE
)
1044 && data
->uniqueness_value
!= This
->uniqueness_value
)
1045 return DDERR_EXPIRED
;
1047 if (*pcbBufferSize
< data
->size
)
1049 *pcbBufferSize
= data
->size
;
1050 return DDERR_MOREDATA
;
1053 if (data
->flags
& DDSPD_IUNKNOWNPTR
)
1055 *(LPUNKNOWN
*)pBuffer
= data
->ptr
.object
;
1056 IUnknown_AddRef(data
->ptr
.object
);
1060 memcpy(pBuffer
, data
->ptr
.data
, data
->size
);
1067 Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface
,
1068 LPDDSURFACEDESC2 pDDSD
)
1070 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1072 TRACE("(%p)->(%p)\n",This
,pDDSD
);
1073 if ((pDDSD
->dwSize
< sizeof(DDSURFACEDESC
)) ||
1074 (pDDSD
->dwSize
> sizeof(DDSURFACEDESC2
))) {
1075 ERR("Impossible/Strange struct size %ld.\n",pDDSD
->dwSize
);
1076 return DDERR_GENERIC
;
1079 DD_STRUCT_COPY_BYSIZE(pDDSD
,&This
->surface_desc
);
1080 if (TRACE_ON(ddraw
)) {
1081 DDRAW_dump_surface_desc(pDDSD
);
1087 Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface
,
1090 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1092 TRACE("(%p)->(%p)\n",This
,pValue
);
1093 *pValue
= This
->uniqueness_value
;
1098 Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface
,
1099 LPDIRECTDRAW pDD
, LPDDSURFACEDESC2 pDDSD
)
1101 TRACE("(%p)->(%p,%p)\n",iface
,pDD
,pDDSD
);
1102 return DDERR_ALREADYINITIALIZED
;
1106 Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface
)
1108 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1110 TRACE("(%p) is%s lost\n",This
, (This
->lost
? "" : " not"));
1111 return This
->lost
? DDERR_SURFACELOST
: DD_OK
;
1115 /* XXX This doesn't actually do any locking or keep track of the locked
1116 * rectangles. The behaviour is poorly documented. */
1118 Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface
, LPRECT prect
,
1119 LPDDSURFACEDESC2 pDDSD
, DWORD flags
, HANDLE h
)
1121 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1123 if (TRACE_ON(ddraw
)) {
1124 TRACE("(%p)->Lock(%p,%p,%08lx,%p)\n",This
,prect
,pDDSD
,flags
,h
);
1125 TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags
);
1127 if (WARN_ON(ddraw
)) {
1128 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
)) {
1129 WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
));
1133 return DDERR_INVALIDPARAMS
;
1135 if (NULL
== pDDSD
) {
1136 return DDERR_INVALIDPARAMS
;
1139 /* If the surface is already locked, return busy */
1141 WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
1142 return DDERR_SURFACEBUSY
;
1145 /* First, copy the Surface description */
1146 DD_STRUCT_COPY_BYSIZE(pDDSD
,&(This
->surface_desc
));
1148 /* Used to optimize the D3D Device locking */
1149 This
->lastlocktype
= flags
& (DDLOCK_READONLY
|DDLOCK_WRITEONLY
);
1151 /* If asked only for a part, change the surface pointer.
1152 * (Not documented.) */
1153 if (prect
!= NULL
) {
1154 TRACE(" lprect: %ldx%ld-%ldx%ld\n",
1155 prect
->left
,prect
->top
,prect
->right
,prect
->bottom
);
1156 /* First do some sanity checkings on the rectangle we receive.
1157 DungeonSiege seems to gives us once a very bad rectangle for example */
1158 if ((prect
->top
< 0) ||
1159 (prect
->left
< 0) ||
1160 (prect
->bottom
< 0) ||
1161 (prect
->right
< 0) ||
1162 (prect
->left
>= prect
->right
) ||
1163 (prect
->top
>= prect
->bottom
) ||
1164 (prect
->left
>= This
->surface_desc
.dwWidth
) ||
1165 (prect
->right
> This
->surface_desc
.dwWidth
) ||
1166 (prect
->top
>= This
->surface_desc
.dwHeight
) ||
1167 (prect
->bottom
> This
->surface_desc
.dwHeight
)) {
1168 ERR(" Invalid values in LPRECT !!!\n");
1169 return DDERR_INVALIDPARAMS
;
1172 This
->lock_update(This
, prect
, flags
);
1174 if (pDDSD
->u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) {
1176 switch(pDDSD
->u4
.ddpfPixelFormat
.dwFourCC
) {
1177 case MAKE_FOURCC('D','X','T','1') : blksize
= 8; break;
1178 case MAKE_FOURCC('D','X','T','3') : blksize
= 16; break;
1179 case MAKE_FOURCC('D','X','T','5') : blksize
= 16; break;
1180 default: return DDERR_INVALIDPIXELFORMAT
;
1182 pDDSD
->lpSurface
= (char *)This
->surface_desc
.lpSurface
1183 + prect
->top
/4 * (pDDSD
->dwWidth
+3)/4 * blksize
1184 + prect
->left
/4 * blksize
;
1186 pDDSD
->lpSurface
= (char *)This
->surface_desc
.lpSurface
1187 + prect
->top
* This
->surface_desc
.u1
.lPitch
1188 + prect
->left
* GET_BPP(This
->surface_desc
);
1190 This
->lock_update(This
, NULL
, flags
);
1193 This
->locked
= TRUE
;
1195 TRACE("locked surface returning description :\n");
1196 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(pDDSD
);
1202 Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface
, DWORD dwFlags
)
1204 /* Some surface types should return DDERR_CANTPAGELOCK. */
1209 Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface
, DWORD dwFlags
)
1211 /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
1212 * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
1217 Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface
, HDC hDC
)
1220 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1222 TRACE("(%p)->(%p)\n",This
,hDC
);
1224 if (!This
->dc_in_use
|| This
->hDC
!= hDC
)
1225 return DDERR_INVALIDPARAMS
;
1227 This
->release_dc(This
, hDC
);
1229 hr
= IDirectDrawSurface7_Unlock(iface
, NULL
);
1230 if (FAILED(hr
)) return hr
;
1232 This
->dc_in_use
= FALSE
;
1241 Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface
,
1242 LPDIRECTDRAWCLIPPER pDDClipper
)
1244 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1246 TRACE("(%p)->(%p)\n",This
,pDDClipper
);
1247 if (pDDClipper
== ICOM_INTERFACE(This
->clipper
, IDirectDrawClipper
))
1250 if (This
->clipper
!= NULL
)
1251 IDirectDrawClipper_Release(ICOM_INTERFACE(This
->clipper
,
1252 IDirectDrawClipper
));
1254 This
->clipper
= ICOM_OBJECT(IDirectDrawClipperImpl
, IDirectDrawClipper
,
1256 if (pDDClipper
!= NULL
)
1257 IDirectDrawClipper_AddRef(pDDClipper
);
1263 Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface
,
1264 DWORD dwFlags
, LPDDCOLORKEY pCKey
)
1266 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1268 TRACE("(%p)->(%08lx,%p)\n",This
,dwFlags
,pCKey
);
1270 if (TRACE_ON(ddraw
)) {
1271 TRACE(" - colorkey flags : ");
1272 DDRAW_dump_colorkeyflag(dwFlags
);
1275 if ((dwFlags
& DDCKEY_COLORSPACE
) != 0) {
1276 FIXME(" colorkey value not supported (%08lx) !\n", dwFlags
);
1277 return DDERR_INVALIDPARAMS
;
1280 /* TODO: investigate if this function can take multiple bits set at the same
1281 time (ie setting multiple colorkey values at the same time with only
1285 switch (dwFlags
& ~DDCKEY_COLORSPACE
) {
1286 case DDCKEY_DESTBLT
:
1287 This
->surface_desc
.ddckCKDestBlt
= *pCKey
;
1288 This
->surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1291 case DDCKEY_DESTOVERLAY
:
1292 This
->surface_desc
.u3
.ddckCKDestOverlay
= *pCKey
;
1293 This
->surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1296 case DDCKEY_SRCOVERLAY
:
1297 This
->surface_desc
.ddckCKSrcOverlay
= *pCKey
;
1298 This
->surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1302 This
->surface_desc
.ddckCKSrcBlt
= *pCKey
;
1303 This
->surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1307 return DDERR_INVALIDPARAMS
;
1310 switch (dwFlags
& ~DDCKEY_COLORSPACE
) {
1311 case DDCKEY_DESTBLT
:
1312 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTBLT
;
1315 case DDCKEY_DESTOVERLAY
:
1316 This
->surface_desc
.dwFlags
&= ~DDSD_CKDESTOVERLAY
;
1319 case DDCKEY_SRCOVERLAY
:
1320 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCOVERLAY
;
1324 This
->surface_desc
.dwFlags
&= ~DDSD_CKSRCBLT
;
1328 return DDERR_INVALIDPARAMS
;
1332 if (This
->aux_setcolorkey_cb
) This
->aux_setcolorkey_cb(This
, dwFlags
, pCKey
);
1338 Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface
, DWORD dwMaxLOD
)
1340 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1342 TRACE("(%p)->(%08lx)\n",This
,dwMaxLOD
);
1343 CHECK_TEXTURE(This
);
1345 This
->max_lod
= dwMaxLOD
;
1350 Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface
,
1353 return DDERR_NOTAOVERLAYSURFACE
;
1357 Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface
,
1358 LPDIRECTDRAWPALETTE pPalette
)
1360 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1361 IDirectDrawPalette
*pal_to_rel
= NULL
;
1363 TRACE("(%p)->(%p)\n",This
,pPalette
);
1364 if (pPalette
== ICOM_INTERFACE(This
->palette
, IDirectDrawPalette
))
1367 if (This
->palette
!= NULL
) {
1368 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1369 This
->palette
->global
.dwFlags
&= ~DDPCAPS_PRIMARYSURFACE
;
1370 pal_to_rel
= ICOM_INTERFACE(This
->palette
, IDirectDrawPalette
);
1373 This
->palette
= ICOM_OBJECT(IDirectDrawPaletteImpl
, IDirectDrawPalette
,
1375 if (pPalette
!= NULL
) {
1376 IDirectDrawPalette_AddRef(pPalette
);
1377 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1378 This
->palette
->global
.dwFlags
|= DDPCAPS_PRIMARYSURFACE
;
1381 This
->set_palette(This
, This
->palette
);
1383 /* Do the palette release at the end to prevent doing some 'loop' when removing
1384 * the surface maintaining the last reference on a palette.
1386 if (pal_to_rel
!= NULL
)
1387 IDirectDrawPalette_Release(pal_to_rel
);
1393 Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface
,
1396 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1398 TRACE("(%p)->(%08lx)\n",This
,dwPriority
);
1399 CHECK_TEXTURE(This
);
1401 This
->priority
= dwPriority
;
1405 /* Be careful when locking this: it is risky to call the object's AddRef
1406 * or Release holding a lock. */
1408 Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface
,
1409 REFGUID tag
, LPVOID pData
,
1410 DWORD cbSize
, DWORD dwFlags
)
1413 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1415 TRACE("(%p)->(%p), size=%ld\n", This
, pData
, cbSize
);
1417 data
= find_private_data(This
, tag
);
1420 data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*data
));
1421 if (data
== NULL
) return DDERR_OUTOFMEMORY
;
1424 data
->flags
= dwFlags
;
1425 data
->uniqueness_value
= This
->uniqueness_value
;
1427 if (dwFlags
& DDSPD_IUNKNOWNPTR
)
1429 data
->ptr
.object
= (LPUNKNOWN
)pData
;
1430 data
->size
= sizeof(LPUNKNOWN
);
1431 IUnknown_AddRef(data
->ptr
.object
);
1435 data
->ptr
.data
= HeapAlloc(GetProcessHeap(), 0, cbSize
);
1436 if (data
->ptr
.data
== NULL
)
1438 HeapFree(GetProcessHeap(), 0, data
);
1439 return DDERR_OUTOFMEMORY
;
1442 data
->size
= cbSize
;
1443 memcpy(data
->ptr
.data
, pData
, data
->size
);
1447 data
->next
= This
->private_data
;
1449 if (This
->private_data
)
1450 This
->private_data
->prev
= data
;
1451 This
->private_data
= data
;
1457 /* I don't actually know how windows handles this case. The only
1458 * reason I don't just call FreePrivateData is because I want to
1459 * guarantee SetPrivateData working when using LPUNKNOWN or data
1460 * that is no larger than the old data. */
1462 FIXME("Replacing existing private data not implemented yet.\n");
1467 /* SetSurfaceDesc */
1470 Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface
, LPRECT pRect
)
1472 IDirectDrawSurfaceImpl
*This
= (IDirectDrawSurfaceImpl
*)iface
;
1474 TRACE("(%p)->Unlock(%p)\n",This
,pRect
);
1476 if (!This
->locked
) {
1477 WARN("Surface not locked - returing DDERR_NOTLOCKED\n");
1478 return DDERR_NOTLOCKED
;
1481 This
->locked
= FALSE
;
1482 This
->unlock_update(This
, pRect
);
1483 if (This
->aux_unlock
)
1484 This
->aux_unlock(This
->aux_ctx
, This
->aux_data
, pRect
);
1490 Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface
,
1492 LPDIRECTDRAWSURFACE7 pDstSurface
,
1493 LPRECT pDstRect
, DWORD dwFlags
,
1496 return DDERR_UNSUPPORTED
;
1499 /* MSDN: "not currently implemented." */
1501 Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface
,
1504 return DDERR_UNSUPPORTED
;
1508 Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface
,
1510 LPDIRECTDRAWSURFACE7 pDDSRef
)
1512 return DDERR_NOTAOVERLAYSURFACE
;