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
27 #include "mesa_private.h"
28 #include "wine/debug.h"
29 #include "ddraw_private.h"
30 #include "dsurface/main.h"
31 #include "ddraw/main.h"
32 #include "dsurface/thunks.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
36 /** Creation/Destruction functions */
39 Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
41 const DDSURFACEDESC2 *pDDSD)
43 if (pDDSD != &This->surface_desc) {
44 This->surface_desc.dwSize = sizeof(This->surface_desc);
45 DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD);
47 This->uniqueness_value = 1; /* unchecked */
50 This->local.lpSurfMore = &This->more;
51 This->local.lpGbl = &This->global;
52 This->local.dwProcessId = GetCurrentProcessId();
53 This->local.dwFlags = 0; /* FIXME */
54 This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps;
55 /* FIXME: more local stuff */
56 This->more.lpDD_lcl = &pDD->local;
57 This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2;
58 This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3;
59 This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4;
60 /* FIXME: more more stuff */
61 This->gmore = &This->global_more;
62 This->global.u3.lpDD = pDD->local.lpGbl;
63 /* FIXME: more global stuff */
65 This->final_release = Main_DirectDrawSurface_final_release;
66 This->late_allocate = Main_DirectDrawSurface_late_allocate;
67 This->attach = Main_DirectDrawSurface_attach;
68 This->detach = Main_DirectDrawSurface_detach;
69 This->lock_update = Main_DirectDrawSurface_lock_update;
70 This->unlock_update = Main_DirectDrawSurface_unlock_update;
71 This->lose_surface = Main_DirectDrawSurface_lose_surface;
72 This->set_palette = Main_DirectDrawSurface_set_palette;
73 This->update_palette = Main_DirectDrawSurface_update_palette;
74 This->get_display_window = Main_DirectDrawSurface_get_display_window;
75 This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp;
76 This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp;
78 ICOM_INIT_INTERFACE(This, IDirectDrawSurface3,
79 DDRAW_IDDS3_Thunk_VTable);
80 ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
82 /* There is no generic implementation of IDDS7 */
84 Main_DirectDraw_AddSurface(pDD, This);
88 void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
90 Main_DirectDraw_RemoveSurface(This->ddraw_owner, This);
93 HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
98 static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
100 This->final_release(This);
101 if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
102 HeapFree(GetProcessHeap(), 0, This);
105 void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This)
107 WARN("destroying surface %p with refcnt %lu\n", This, This->ref);
108 Main_DirectDrawSurface_Destroy(This);
111 ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface)
113 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
115 if (--This->ref == 0)
117 if (This->aux_release)
118 This->aux_release(This->aux_ctx, This->aux_data);
119 Main_DirectDrawSurface_Destroy(This);
126 ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface)
128 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
134 Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
137 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
138 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
140 if (IsEqualGUID(&IID_IUnknown, riid)
141 || IsEqualGUID(&IID_IDirectDrawSurface7, riid)
142 || IsEqualGUID(&IID_IDirectDrawSurface4, riid))
145 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7);
148 else if (IsEqualGUID(&IID_IDirectDrawSurface, riid)
149 || IsEqualGUID(&IID_IDirectDrawSurface2, riid)
150 || IsEqualGUID(&IID_IDirectDrawSurface3, riid))
153 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3);
156 else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
159 *ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
163 else if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) )
166 return is_OpenGL_dx3(riid, This, (IDirect3DDeviceImpl**)ppObj)?S_OK:E_NOINTERFACE;
168 else if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
170 LPDIRECT3DTEXTURE iface;
172 iface = d3dtexture_create(This);
174 *ppObj = (LPVOID)iface;
177 return E_NOINTERFACE;
179 else if (IsEqualGUID( &IID_IDirect3DTexture2, riid ))
181 LPDIRECT3DTEXTURE2 iface;
183 iface = d3dtexture2_create(This);
185 *ppObj = (LPVOID)iface;
188 return E_NOINTERFACE;
192 return E_NOINTERFACE;
198 Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
199 IDirectDrawSurfaceImpl *to)
204 BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
210 Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
216 Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
222 Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This)
227 Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
228 IDirectDrawPaletteImpl* pal)
233 Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
234 IDirectDrawPaletteImpl* pal,
235 DWORD dwStart, DWORD dwCount,
236 LPPALETTEENTRY palent)
241 Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
247 Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
249 LPDDGAMMARAMP lpGammaRamp)
253 hr = This->get_dc(This, &hDC);
254 if (FAILED(hr)) return hr;
255 hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
256 This->release_dc(This, hDC);
261 Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
263 LPDDGAMMARAMP lpGammaRamp)
267 hr = This->get_dc(This, &hDC);
268 if (FAILED(hr)) return hr;
269 hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
270 This->release_dc(This, hDC);
275 /*** Interface functions */
278 Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
279 LPDIRECTDRAWSURFACE7 pAttach)
281 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
282 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
283 IDirectDrawSurface7, pAttach);
285 TRACE("(%p)->(%p)\n",This,pAttach);
287 /* Does windows check this? */
289 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
291 /* Does windows check this? */
292 if (surf->ddraw_owner != This->ddraw_owner)
293 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
295 if (surf->surface_owner != NULL)
296 return DDERR_SURFACEALREADYATTACHED; /* unchecked */
298 /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
299 * But apparently backbuffers and mipmaps can be attached too. */
301 /* Set MIPMAPSUBLEVEL if this seems to be one */
302 if (This->surface_desc.ddsCaps.dwCaps &
303 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
304 surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
305 /* FIXME: we should probably also add to dwMipMapCount of this
306 * and all parent surfaces (update create_texture if you do) */
309 /* Callback to allow the surface to do something special now that it is
310 * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
311 if (!surf->attach(surf, This))
312 return DDERR_CANNOTATTACHSURFACE;
314 /* check: Where should it go in the chain? This puts it on the head. */
316 This->attached->prev_attached = surf;
317 surf->next_attached = This->attached;
318 surf->prev_attached = NULL;
319 This->attached = surf;
320 surf->surface_owner = This;
322 IDirectDrawSurface7_AddRef(pAttach);
327 /* MSDN: "not currently implemented." */
329 Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
332 TRACE("(%p)->(%p)\n",iface,pRect);
333 return DDERR_UNSUPPORTED; /* unchecked */
336 /* MSDN: "not currently implemented." */
338 Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
339 LPDDBLTBATCH pBatch, DWORD dwCount,
342 TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags);
343 return DDERR_UNSUPPORTED; /* unchecked */
347 Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface)
349 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
350 volatile IDirectDrawSurfaceImpl* vThis = This;
352 TRACE("(%p)\n",This);
353 /* A uniquness value of 0 is apparently special.
354 * This needs to be checked. */
357 DWORD old_uniqueness_value = vThis->uniqueness_value;
358 DWORD new_uniqueness_value = old_uniqueness_value+1;
360 if (old_uniqueness_value == 0) break;
361 if (new_uniqueness_value == 0) new_uniqueness_value = 1;
363 if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
364 old_uniqueness_value,
365 new_uniqueness_value)
366 == old_uniqueness_value)
374 Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
376 LPDIRECTDRAWSURFACE7 pAttach)
378 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
379 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
380 IDirectDrawSurface7, pAttach);
382 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);
384 if (!surf || (surf->surface_owner != This))
385 return DDERR_SURFACENOTATTACHED; /* unchecked */
389 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
390 if (This->surface_desc.ddsCaps.dwCaps &
391 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
392 surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
393 /* FIXME: we should probably also subtract from dwMipMapCount of this
394 * and all parent surfaces */
397 if (surf->next_attached)
398 surf->next_attached->prev_attached = surf->prev_attached;
399 if (surf->prev_attached)
400 surf->prev_attached->next_attached = surf->next_attached;
401 if (This->attached == surf)
402 This->attached = surf->next_attached;
404 IDirectDrawSurface7_Release(pAttach);
410 Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
412 LPDDENUMSURFACESCALLBACK7 cb)
414 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
415 IDirectDrawSurfaceImpl* surf;
417 TRACE("(%p)->(%p,%p)\n",This,context,cb);
419 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
421 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
422 if (cb(ICOM_INTERFACE(surf, IDirectDrawSurface7), &surf->surface_desc,
423 context) == DDENUMRET_CANCEL)
431 Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
432 DWORD dwFlags, LPVOID context,
433 LPDDENUMSURFACESCALLBACK7 cb)
435 TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb);
439 BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
440 IDirectDrawSurfaceImpl* back,
443 /* uniqueness_value? */
444 /* This is necessary. But is it safe? */
446 HDC tmp = front->hDC;
447 front->hDC = back->hDC;
452 BOOL tmp = front->dc_in_use;
453 front->dc_in_use = back->dc_in_use;
454 back->dc_in_use = tmp;
458 FLATPTR tmp = front->global.fpVidMem;
459 front->global.fpVidMem = back->global.fpVidMem;
460 back->global.fpVidMem = tmp;
464 ULONG_PTR tmp = front->global_more.hKernelSurface;
465 front->global_more.hKernelSurface = back->global_more.hKernelSurface;
466 back->global_more.hKernelSurface = tmp;
473 Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
474 LPDIRECTDRAWSURFACE7 override, DWORD dwFlags)
476 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
477 IDirectDrawSurfaceImpl* target;
480 TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags);
482 /* MSDN: "This method can be called only for a surface that has the
483 * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
484 if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
485 != (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
486 return DDERR_NOTFLIPPABLE;
489 if (This->aux_flip(This->aux_ctx, This->aux_data))
492 /* 1. find the flip target */
493 /* XXX I don't think this algorithm works for more than 1 backbuffer. */
494 if (override == NULL)
496 static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
497 LPDIRECTDRAWSURFACE7 tgt;
499 hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
500 if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */
502 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
504 IDirectDrawSurface7_Release(tgt);
508 BOOL on_chain = FALSE;
509 IDirectDrawSurfaceImpl* surf;
511 /* MSDN: "The method fails if the specified [override] surface is not
512 * a member of the flipping chain." */
514 /* Verify that override is on this flip chain. We assume that
515 * surf is the head of the flipping chain, because it's the front
517 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
520 /* Either target is (indirectly) attached to This or This is
521 * (indirectly) attached to target. */
522 for (surf = target; surf != NULL; surf = surf->surface_owner)
532 return DDERR_INVALIDPARAMS; /* unchecked */
535 TRACE("flip to backbuffer: %p\n",target);
536 if (This->flip_data(This, target, dwFlags))
537 This->flip_update(This, dwFlags);
542 static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This,
546 for (data = This->private_data; data != NULL; data = data->next)
548 if (IsEqualGUID(&data->tag, tag)) break;
555 Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag)
557 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
560 data = find_private_data(This, tag);
561 if (data == NULL) return DDERR_NOTFOUND;
564 data->prev->next = data->next;
566 data->next->prev = data->prev;
568 if (data->flags & DDSPD_IUNKNOWNPTR)
570 if (data->ptr.object != NULL)
571 IUnknown_Release(data->ptr.object);
574 HeapFree(GetProcessHeap(), 0, data->ptr.data);
576 HeapFree(GetProcessHeap(), 0, data);
582 Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
584 LPDIRECTDRAWSURFACE7* ppSurface)
586 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
587 IDirectDrawSurfaceImpl* surf;
588 IDirectDrawSurfaceImpl* found = NULL;
590 TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2,
591 pCaps->dwCaps3, pCaps->dwCaps4, ppSurface);
593 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
595 TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx \n",surf ,
596 surf->surface_desc.ddsCaps.dwCaps,
597 surf->surface_desc.ddsCaps.dwCaps2,
598 surf->surface_desc.ddsCaps.dwCaps3,
599 surf->surface_desc.ddsCaps.dwCaps4);
600 if (((surf->surface_desc.ddsCaps.dwCaps & pCaps->dwCaps) == pCaps->dwCaps)
601 && ((surf->surface_desc.ddsCaps.dwCaps2 & pCaps->dwCaps2) == pCaps->dwCaps2))
603 /* MSDN: "This method fails if more than one surface is attached
604 * that matches the capabilities requested." */
607 FIXME("More than one attached surface matches requested caps. What should we do here?\n");
608 /* Previous code returned 'DDERR_NOTFOUND'. That appears not
609 to be correct, given what 3DMark expects from MipMapped surfaces.
610 We shall just continue instead. */
618 return DDERR_NOTFOUND;
620 *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7);
622 /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
623 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7));
628 Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
630 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
635 case DDGBS_ISBLTDONE:
639 return DDERR_INVALIDPARAMS;
644 Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps)
646 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
648 TRACE("(%p)->(%p)\n",This,pCaps);
649 *pCaps = This->surface_desc.ddsCaps;
654 Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
655 LPDIRECTDRAWCLIPPER* ppClipper)
657 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
659 TRACE("(%p)->(%p)\n",This,ppClipper);
660 if (This->clipper == NULL)
661 return DDERR_NOCLIPPERATTACHED;
663 *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
664 IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper,
665 IDirectDrawClipper));
670 Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags,
673 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
674 * isn't there? That's like saying that an int isn't there. (Which MS
675 * has done in other docs.) */
677 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
679 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
683 *pCKey = This->surface_desc.ddckCKDestBlt;
686 case DDCKEY_DESTOVERLAY:
687 *pCKey = This->surface_desc.u3.ddckCKDestOverlay;
691 *pCKey = This->surface_desc.ddckCKSrcBlt;
694 case DDCKEY_SRCOVERLAY:
695 *pCKey = This->surface_desc.ddckCKSrcOverlay;
699 return DDERR_INVALIDPARAMS;
705 /* XXX We need to do something with the DC if the surface gets lost. */
707 Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
711 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
713 TRACE("(%p)->(%p)\n",This,phDC);
721 return DDERR_DCALREADYCREATED;
725 * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
726 * thread has it locked, but GetDC does not. */
727 ddsd.dwSize = sizeof(ddsd);
728 hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, DDLOCK_READONLY, 0);
735 hr = This->get_dc(This, &This->hDC);
738 TRACE("returning %p\n",This->hDC);
741 This->dc_in_use = TRUE;
743 else WARN("No DC! Prepare for trouble\n");
750 Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD)
752 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
754 TRACE("(%p)->(%p)\n",This,pDD);
755 *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7);
756 IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
761 Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
763 /* XXX: DDERR_INVALIDSURFACETYPE */
765 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
769 case DDGFS_ISFLIPDONE:
773 return DDERR_INVALIDPARAMS;
778 Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD)
780 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
782 TRACE("(%p)->(%p)\n",This,pdwMaxLOD);
785 *pdwMaxLOD = This->max_lod;
790 Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
791 LPLONG pX, LPLONG pY)
793 return DDERR_NOTAOVERLAYSURFACE;
797 Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
798 LPDIRECTDRAWPALETTE* ppPalette)
800 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
802 TRACE("(%p)->(%p)\n",This,ppPalette);
803 if (This->palette == NULL)
804 return DDERR_NOPALETTEATTACHED;
806 *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
807 IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette,
808 IDirectDrawPalette));
813 Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
814 LPDDPIXELFORMAT pDDPixelFormat)
816 /* What is DDERR_INVALIDSURFACETYPE for here? */
817 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
819 TRACE("(%p)->(%p)\n",This,pDDPixelFormat);
820 DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
825 Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
828 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
830 TRACE("(%p)->(%p)\n",This,pdwPriority);
833 *pdwPriority = This->priority;
838 Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface,
839 REFGUID tag, LPVOID pBuffer,
840 LPDWORD pcbBufferSize)
842 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
845 data = find_private_data(This, tag);
846 if (data == NULL) return DDERR_NOTFOUND;
848 /* This may not be right. */
849 if ((data->flags & DDSPD_VOLATILE)
850 && data->uniqueness_value != This->uniqueness_value)
851 return DDERR_EXPIRED;
853 if (*pcbBufferSize < data->size)
855 *pcbBufferSize = data->size;
856 return DDERR_MOREDATA;
859 if (data->flags & DDSPD_IUNKNOWNPTR)
861 *(LPUNKNOWN *)pBuffer = data->ptr.object;
862 IUnknown_AddRef(data->ptr.object);
866 memcpy(pBuffer, data->ptr.data, data->size);
873 Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
874 LPDDSURFACEDESC2 pDDSD)
876 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
878 TRACE("(%p)->(%p)\n",This,pDDSD);
879 if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) ||
880 (pDDSD->dwSize > sizeof(DDSURFACEDESC2))) {
881 ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize);
882 return DDERR_GENERIC;
885 DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc);
886 if (TRACE_ON(ddraw)) {
887 DDRAW_dump_surface_desc(pDDSD);
893 Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
896 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
898 TRACE("(%p)->(%p)\n",This,pValue);
899 *pValue = This->uniqueness_value;
904 Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
905 LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD)
907 TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD);
908 return DDERR_ALREADYINITIALIZED;
912 Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface)
914 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
916 TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not"));
917 return This->lost ? DDERR_SURFACELOST : DD_OK;
921 /* XXX This doesn't actually do any locking or keep track of the locked
922 * rectangles. The behaviour is poorly documented. */
924 Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
925 LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h)
927 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
929 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",This,prect,pDDSD,flags,(DWORD)h);
931 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
932 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
933 This,prect,pDDSD,flags,(DWORD)h);
935 /* First, copy the Surface description */
936 DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc));
938 TRACE("locked surface returning description : \n");
939 if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD);
941 /* If asked only for a part, change the surface pointer.
942 * (Not documented.) */
944 TRACE(" lprect: %dx%d-%dx%d\n",
945 prect->top,prect->left,prect->bottom,prect->right
947 if ((prect->top < 0) ||
949 (prect->bottom < 0) ||
950 (prect->right < 0)) {
951 ERR(" Negative values in LPRECT !!!\n");
952 return DDERR_INVALIDPARAMS;
955 This->lock_update(This, prect, flags);
957 pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
958 + prect->top * This->surface_desc.u1.lPitch
959 + prect->left * GET_BPP(This->surface_desc);
961 This->lock_update(This, NULL, flags);
968 Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
970 /* Some surface types should return DDERR_CANTPAGELOCK. */
975 Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
977 /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
978 * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
983 Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
986 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
988 TRACE("(%p)->(%p)\n",This,hDC);
990 if (!This->dc_in_use || This->hDC != hDC)
991 return DDERR_INVALIDPARAMS;
993 This->release_dc(This, hDC);
995 hr = IDirectDrawSurface7_Unlock(iface, NULL);
996 if (FAILED(hr)) return hr;
998 This->dc_in_use = FALSE;
1007 Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
1008 LPDIRECTDRAWCLIPPER pDDClipper)
1010 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1012 TRACE("(%p)->(%p)\n",This,pDDClipper);
1013 if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper))
1016 if (This->clipper != NULL)
1017 IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
1018 IDirectDrawClipper));
1020 This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
1022 if (pDDClipper != NULL)
1023 IDirectDrawClipper_AddRef(pDDClipper);
1029 Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
1030 DWORD dwFlags, LPDDCOLORKEY pCKey)
1032 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1034 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
1037 FIXME("supposedly removing color key %lu\n",
1038 dwFlags & ~DDCKEY_COLORSPACE);
1042 switch (dwFlags & ~DDCKEY_COLORSPACE)
1044 case DDCKEY_DESTBLT:
1045 This->surface_desc.ddckCKDestBlt = *pCKey;
1048 case DDCKEY_DESTOVERLAY:
1049 This->surface_desc.u3.ddckCKDestOverlay = *pCKey;
1052 case DDCKEY_SRCOVERLAY:
1053 This->surface_desc.ddckCKSrcOverlay = *pCKey;
1057 This->surface_desc.ddckCKSrcBlt = *pCKey;
1061 return DDERR_INVALIDPARAMS;
1068 Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD)
1070 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1072 TRACE("(%p)->(%08lx)\n",This,dwMaxLOD);
1073 CHECK_TEXTURE(This);
1075 This->max_lod = dwMaxLOD;
1080 Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
1083 return DDERR_NOTAOVERLAYSURFACE;
1087 Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
1088 LPDIRECTDRAWPALETTE pPalette)
1090 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1092 TRACE("(%p)->(%p)\n",This,pPalette);
1093 if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette))
1096 if (This->palette != NULL) {
1097 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1098 This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE;
1099 IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette,
1100 IDirectDrawPalette));
1103 This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
1105 if (pPalette != NULL) {
1106 IDirectDrawPalette_AddRef(pPalette);
1107 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1108 This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE;
1111 This->set_palette(This, This->palette);
1117 Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
1120 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1122 TRACE("(%p)->(%08lx)\n",This,dwPriority);
1123 CHECK_TEXTURE(This);
1125 This->priority = dwPriority;
1129 /* Be careful when locking this: it is risky to call the object's AddRef
1130 * or Release holding a lock. */
1132 Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
1133 REFGUID tag, LPVOID pData,
1134 DWORD cbSize, DWORD dwFlags)
1137 ICOM_THIS(IDirectDrawSurfaceImpl, iface);
1139 data = find_private_data(This, tag);
1142 data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
1143 if (data == NULL) return DDERR_OUTOFMEMORY;
1146 data->flags = dwFlags;
1147 data->uniqueness_value = This->uniqueness_value;
1149 if (dwFlags & DDSPD_IUNKNOWNPTR)
1151 data->ptr.object = (LPUNKNOWN)pData;
1152 data->size = sizeof(LPUNKNOWN);
1153 IUnknown_AddRef(data->ptr.object);
1157 data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize);
1158 if (data->ptr.data == NULL)
1160 HeapFree(GetProcessHeap(), 0, data);
1161 return DDERR_OUTOFMEMORY;
1166 data->next = This->private_data;
1168 if (This->private_data)
1169 This->private_data->prev = data;
1170 This->private_data = data;
1176 /* I don't actually know how windows handles this case. The only
1177 * reason I don't just call FreePrivateData is because I want to
1178 * guarantee SetPrivateData working when using LPUNKNOWN or data
1179 * that is no larger than the old data. */
1185 /* SetSurfaceDesc */
1188 Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect)
1190 ICOM_THIS(IDirectDrawSurfaceImpl,iface);
1192 TRACE("(%p)->Unlock(%p)\n",This,pRect);
1194 This->unlock_update(This, pRect);
1195 if (This->aux_unlock)
1196 This->aux_unlock(This->aux_ctx, This->aux_data, pRect);
1202 Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
1204 LPDIRECTDRAWSURFACE7 pDstSurface,
1205 LPRECT pDstRect, DWORD dwFlags,
1208 return DDERR_UNSUPPORTED;
1211 /* MSDN: "not currently implemented." */
1213 Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
1216 return DDERR_UNSUPPORTED;
1220 Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
1222 LPDIRECTDRAWSURFACE7 pDDSRef)
1224 return DDERR_NOTAOVERLAYSURFACE;