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);
164 return DDERR_INVALIDPARAMS;
166 if (IsEqualGUID(&IID_IUnknown, riid)
167 || IsEqualGUID(&IID_IDirectDrawSurface7, riid)
168 || IsEqualGUID(&IID_IDirectDrawSurface4, riid))
170 InterlockedIncrement(&This->ref);
171 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7);
174 else if (IsEqualGUID(&IID_IDirectDrawSurface, riid)
175 || IsEqualGUID(&IID_IDirectDrawSurface2, riid)
176 || IsEqualGUID(&IID_IDirectDrawSurface3, riid))
178 InterlockedIncrement(&This->ref);
179 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3);
182 else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
184 InterlockedIncrement(&This->ref);
185 *ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
189 /* interfaces following here require OpenGL */
190 if( !opengl_initialized )
191 return E_NOINTERFACE;
193 if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) ||
194 IsEqualGUID( &IID_IDirect3DHALDevice, riid) )
196 IDirect3DDeviceImpl *d3ddevimpl;
199 ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, 1);
200 if (FAILED(ret_value)) return ret_value;
202 *ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);
203 TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj);
205 InterlockedIncrement(&This->ref); /* No idea if this is correct.. Need to check using real Windows */
208 else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
209 IsEqualGUID( &IID_IDirect3DTexture2, riid ))
211 HRESULT ret_value = S_OK;
213 /* Note: this is not exactly how Windows does it... But this seems not to hurt the only
214 application I know creating a texture without this flag set and it will prevent
215 bugs in other parts of Wine.
217 This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
219 /* In case the texture surface was created before the D3D creation */
220 if (This->tex_private == NULL) {
221 if (This->ddraw_owner->d3d_private == NULL) {
222 ERR("Texture created with no D3D object yet.. Not supported !\n");
223 return E_NOINTERFACE;
226 ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main);
227 if (FAILED(ret_value)) return ret_value;
229 if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
230 *ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
231 TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
233 *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
234 TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
236 InterlockedIncrement(&This->ref);
241 return E_NOINTERFACE;
247 Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
248 IDirectDrawSurfaceImpl *to)
253 BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
259 Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
265 Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
271 Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This)
276 Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
277 IDirectDrawPaletteImpl* pal)
282 Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
283 IDirectDrawPaletteImpl* pal,
284 DWORD dwStart, DWORD dwCount,
285 LPPALETTEENTRY palent)
290 Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
296 Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
298 LPDDGAMMARAMP lpGammaRamp)
302 hr = This->get_dc(This, &hDC);
303 if (FAILED(hr)) return hr;
304 hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
305 This->release_dc(This, hDC);
310 Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
312 LPDDGAMMARAMP lpGammaRamp)
316 hr = This->get_dc(This, &hDC);
317 if (FAILED(hr)) return hr;
318 hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
319 This->release_dc(This, hDC);
324 /*** Interface functions */
327 Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
328 LPDIRECTDRAWSURFACE7 pAttach)
330 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
331 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
332 IDirectDrawSurface7, pAttach);
334 TRACE("(%p)->(%p)\n",This,pAttach);
336 /* Does windows check this? */
338 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
340 /* Does windows check this? */
341 if (surf->ddraw_owner != This->ddraw_owner)
342 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
344 if (surf->surface_owner != NULL)
345 return DDERR_SURFACEALREADYATTACHED; /* unchecked */
347 /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
348 * But apparently backbuffers and mipmaps can be attached too. */
350 /* Set MIPMAPSUBLEVEL if this seems to be one */
351 if (This->surface_desc.ddsCaps.dwCaps &
352 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
353 surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
354 /* FIXME: we should probably also add to dwMipMapCount of this
355 * and all parent surfaces (update create_texture if you do) */
358 /* Callback to allow the surface to do something special now that it is
359 * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
360 if (!surf->attach(surf, This))
361 return DDERR_CANNOTATTACHSURFACE;
363 /* check: Where should it go in the chain? This puts it on the head. */
365 This->attached->prev_attached = surf;
366 surf->next_attached = This->attached;
367 surf->prev_attached = NULL;
368 This->attached = surf;
369 surf->surface_owner = This;
371 IDirectDrawSurface7_AddRef(pAttach);
376 /* MSDN: "not currently implemented." */
378 Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
381 TRACE("(%p)->(%p)\n",iface,pRect);
382 return DDERR_UNSUPPORTED; /* unchecked */
385 /* MSDN: "not currently implemented." */
387 Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
388 LPDDBLTBATCH pBatch, DWORD dwCount,
391 TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags);
392 return DDERR_UNSUPPORTED; /* unchecked */
396 Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface)
398 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
399 volatile IDirectDrawSurfaceImpl* vThis = This;
401 TRACE("(%p)\n",This);
402 /* A uniquness value of 0 is apparently special.
403 * This needs to be checked. */
406 DWORD old_uniqueness_value = vThis->uniqueness_value;
407 DWORD new_uniqueness_value = old_uniqueness_value+1;
409 if (old_uniqueness_value == 0) break;
410 if (new_uniqueness_value == 0) new_uniqueness_value = 1;
412 if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
413 old_uniqueness_value,
414 new_uniqueness_value)
415 == old_uniqueness_value)
423 Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
425 LPDIRECTDRAWSURFACE7 pAttach)
427 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
428 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
429 IDirectDrawSurface7, pAttach);
431 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);
433 if (!surf || (surf->surface_owner != This))
434 return DDERR_SURFACENOTATTACHED; /* unchecked */
438 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
439 if (This->surface_desc.ddsCaps.dwCaps &
440 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
441 surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
442 /* FIXME: we should probably also subtract from dwMipMapCount of this
443 * and all parent surfaces */
446 if (surf->next_attached)
447 surf->next_attached->prev_attached = surf->prev_attached;
448 if (surf->prev_attached)
449 surf->prev_attached->next_attached = surf->next_attached;
450 if (This->attached == surf)
451 This->attached = surf->next_attached;
453 IDirectDrawSurface7_Release(pAttach);
459 Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
461 LPDDENUMSURFACESCALLBACK7 cb)
463 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
464 IDirectDrawSurfaceImpl* surf;
467 TRACE("(%p)->(%p,%p)\n",This,context,cb);
469 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
471 LPDIRECTDRAWSURFACE7 isurf = ICOM_INTERFACE(surf, IDirectDrawSurface7);
473 if (TRACE_ON(ddraw)) {
474 TRACE(" => enumerating surface %p (priv. %p) with description:\n", isurf, surf);
475 DDRAW_dump_surface_desc(&surf->surface_desc);
478 IDirectDrawSurface7_AddRef(isurf);
479 desc = surf->surface_desc;
480 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
481 if (cb(isurf, &desc, context) == DDENUMRET_CANCEL)
485 TRACE(" end of enumeration.\n");
491 Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
492 DWORD dwFlags, LPVOID context,
493 LPDDENUMSURFACESCALLBACK7 cb)
495 TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb);
499 BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
500 IDirectDrawSurfaceImpl* back,
503 /* uniqueness_value? */
504 /* This is necessary. But is it safe? */
506 HDC tmp = front->hDC;
507 front->hDC = back->hDC;
512 BOOL tmp = front->dc_in_use;
513 front->dc_in_use = back->dc_in_use;
514 back->dc_in_use = tmp;
518 FLATPTR tmp = front->global.fpVidMem;
519 front->global.fpVidMem = back->global.fpVidMem;
520 back->global.fpVidMem = tmp;
524 ULONG_PTR tmp = front->global_more.hKernelSurface;
525 front->global_more.hKernelSurface = back->global_more.hKernelSurface;
526 back->global_more.hKernelSurface = tmp;
532 /* This is unnecessarely complicated :-) */
533 #define MEASUREMENT_WINDOW 5
534 #define NUMBER_OF_WINDOWS 10
536 static LONGLONG perf_freq;
537 static LONGLONG perf_storage[NUMBER_OF_WINDOWS];
538 static LONGLONG prev_time = 0;
539 static unsigned int current_window;
540 static unsigned int measurements_in_window;
541 static unsigned int valid_windows;
544 Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
545 LPDIRECTDRAWSURFACE7 override, DWORD dwFlags)
547 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
548 IDirectDrawSurfaceImpl* target;
551 TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags);
553 if (TRACE_ON(ddraw_fps)) {
554 LONGLONG current_time;
555 LONGLONG frame_duration;
556 QueryPerformanceCounter((LARGE_INTEGER *) ¤t_time);
558 if (prev_time != 0) {
559 LONGLONG total_time = 0;
562 frame_duration = current_time - prev_time;
563 prev_time = current_time;
565 perf_storage[current_window] += frame_duration;
566 measurements_in_window++;
568 if (measurements_in_window >= MEASUREMENT_WINDOW) {
572 if (valid_windows < NUMBER_OF_WINDOWS) {
574 tot_meas = valid_windows * MEASUREMENT_WINDOW;
575 for (i = 0; i < valid_windows; i++) {
576 total_time += perf_storage[i];
580 tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW;
581 for (i = 0; i < NUMBER_OF_WINDOWS; i++) {
582 total_time += perf_storage[i];
586 TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time);
588 if (current_window >= NUMBER_OF_WINDOWS) {
591 perf_storage[current_window] = 0;
592 measurements_in_window = 0;
595 prev_time = current_time;
596 memset(perf_storage, 0, sizeof(perf_storage));
599 measurements_in_window = 0;
600 QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq);
604 /* MSDN: "This method can be called only for a surface that has the
605 * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
606 if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
607 != (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
608 return DDERR_NOTFLIPPABLE;
611 if (This->aux_flip(This->aux_ctx, This->aux_data))
614 /* 1. find the flip target */
615 /* XXX I don't think this algorithm works for more than 1 backbuffer. */
616 if (override == NULL)
618 static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
619 LPDIRECTDRAWSURFACE7 tgt;
621 hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
622 if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */
624 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
626 IDirectDrawSurface7_Release(tgt);
630 BOOL on_chain = FALSE;
631 IDirectDrawSurfaceImpl* surf;
633 /* MSDN: "The method fails if the specified [override] surface is not
634 * a member of the flipping chain." */
636 /* Verify that override is on this flip chain. We assume that
637 * surf is the head of the flipping chain, because it's the front
639 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
642 /* Either target is (indirectly) attached to This or This is
643 * (indirectly) attached to target. */
644 for (surf = target; surf != NULL; surf = surf->surface_owner)
654 return DDERR_INVALIDPARAMS; /* unchecked */
657 TRACE("flip to backbuffer: %p\n",target);
658 if (TRACE_ON(ddraw_flip)) {
659 static unsigned int flip_count = 0;
660 IDirectDrawPaletteImpl *palette;
664 /* Hack for paletted games... */
665 palette = target->palette;
666 target->palette = This->palette;
668 sprintf(buf, "flip_%08d.ppm", flip_count++);
669 TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf);
670 f = fopen(buf, "wb");
671 DDRAW_dump_surface_to_disk(target, f, 8);
672 target->palette = palette;
675 if (This->flip_data(This, target, dwFlags))
676 This->flip_update(This, dwFlags);
681 static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This,
685 for (data = This->private_data; data != NULL; data = data->next)
687 if (IsEqualGUID(&data->tag, tag)) break;
694 Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag)
696 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
699 data = find_private_data(This, tag);
700 if (data == NULL) return DDERR_NOTFOUND;
703 data->prev->next = data->next;
705 data->next->prev = data->prev;
707 if (data->flags & DDSPD_IUNKNOWNPTR)
709 if (data->ptr.object != NULL)
710 IUnknown_Release(data->ptr.object);
713 HeapFree(GetProcessHeap(), 0, data->ptr.data);
715 HeapFree(GetProcessHeap(), 0, data);
721 Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
723 LPDIRECTDRAWSURFACE7* ppSurface)
725 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
726 IDirectDrawSurfaceImpl* surf;
727 IDirectDrawSurfaceImpl* found = NULL;
730 if (TRACE_ON(ddraw)) {
731 TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2,
732 pCaps->dwCaps3, pCaps->dwCaps4, ppSurface);
733 TRACE(" Caps are : "); DDRAW_dump_DDSCAPS2(pCaps); TRACE("\n");
737 if ((This->ddraw_owner->local.dwLocalFlags & DDRAWILCL_DIRECTDRAW7) == 0) {
738 /* As this is not a DirectDraw7 application, remove the garbage that some games
739 put in the new fields of the DDSCAPS2 structure. */
740 our_caps.dwCaps2 = 0;
741 our_caps.dwCaps3 = 0;
742 our_caps.dwCaps4 = 0;
743 if (TRACE_ON(ddraw)) {
744 TRACE(" Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps); TRACE("\n");
748 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
750 if (TRACE_ON(ddraw)) {
751 TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf,
752 surf->surface_desc.ddsCaps.dwCaps,
753 surf->surface_desc.ddsCaps.dwCaps2,
754 surf->surface_desc.ddsCaps.dwCaps3,
755 surf->surface_desc.ddsCaps.dwCaps4);
756 TRACE(" Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf->surface_desc.ddsCaps)); TRACE("\n");
758 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
759 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2))
761 /* MSDN: "This method fails if more than one surface is attached
762 * that matches the capabilities requested." */
765 FIXME("More than one attached surface matches requested caps. What should we do here?\n");
766 /* Previous code returned 'DDERR_NOTFOUND'. That appears not
767 to be correct, given what 3DMark expects from MipMapped surfaces.
768 We shall just continue instead. */
776 TRACE("Did not find any valid surface\n");
777 return DDERR_NOTFOUND;
780 *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7);
782 if (TRACE_ON(ddraw)) {
783 TRACE("Returning surface %p with description :\n", *ppSurface);
784 DDRAW_dump_surface_desc(&(found->surface_desc));
787 /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
788 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7));
793 Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
795 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
800 case DDGBS_ISBLTDONE:
804 return DDERR_INVALIDPARAMS;
809 Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps)
811 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
813 TRACE("(%p)->(%p)\n",This,pCaps);
814 *pCaps = This->surface_desc.ddsCaps;
819 Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
820 LPDIRECTDRAWCLIPPER* ppClipper)
822 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
824 TRACE("(%p)->(%p)\n",This,ppClipper);
825 if (This->clipper == NULL)
826 return DDERR_NOCLIPPERATTACHED;
828 *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
829 IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper,
830 IDirectDrawClipper));
835 Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags,
838 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
839 * isn't there? That's like saying that an int isn't there. (Which MS
840 * has done in other docs.) */
842 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
844 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
845 if (TRACE_ON(ddraw)) {
846 TRACE(" - colorkey flags : ");
847 DDRAW_dump_colorkeyflag(dwFlags);
853 *pCKey = This->surface_desc.ddckCKDestBlt;
856 case DDCKEY_DESTOVERLAY:
857 *pCKey = This->surface_desc.u3.ddckCKDestOverlay;
861 *pCKey = This->surface_desc.ddckCKSrcBlt;
864 case DDCKEY_SRCOVERLAY:
865 *pCKey = This->surface_desc.ddckCKSrcOverlay;
869 return DDERR_INVALIDPARAMS;
875 /* XXX We need to do something with the DC if the surface gets lost. */
877 Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
881 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
883 TRACE("(%p)->(%p)\n",This,phDC);
891 return DDERR_DCALREADYCREATED;
895 * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
896 * thread has it locked, but GetDC does not. */
897 ddsd.dwSize = sizeof(ddsd);
898 hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0);
905 hr = This->get_dc(This, &This->hDC);
907 if ((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) &&
908 (This->palette == NULL)) {
909 IDirectDrawImpl *ddraw = This->ddraw_owner;
910 IDirectDrawSurfaceImpl *surf;
912 for (surf = ddraw->surfaces; surf != NULL; surf = surf->next_ddraw) {
913 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) &&
914 (surf->palette != NULL)) {
916 IDirectDrawPaletteImpl *pal = surf->palette;
918 for (n=0; n<256; n++) {
919 col[n].rgbRed = pal->palents[n].peRed;
920 col[n].rgbGreen = pal->palents[n].peGreen;
921 col[n].rgbBlue = pal->palents[n].peBlue;
922 col[n].rgbReserved = 0;
924 SetDIBColorTable(This->hDC, 0, 256, col);
933 TRACE("returning %p\n",This->hDC);
936 This->dc_in_use = TRUE;
938 else WARN("No DC! Prepare for trouble\n");
945 Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD)
947 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
949 TRACE("(%p)->(%p)\n",This,pDD);
950 *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7);
951 IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
956 Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
958 /* XXX: DDERR_INVALIDSURFACETYPE */
960 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
964 case DDGFS_ISFLIPDONE:
968 return DDERR_INVALIDPARAMS;
973 Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD)
975 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
977 TRACE("(%p)->(%p)\n",This,pdwMaxLOD);
980 *pdwMaxLOD = This->max_lod;
985 Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
986 LPLONG pX, LPLONG pY)
988 return DDERR_NOTAOVERLAYSURFACE;
992 Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
993 LPDIRECTDRAWPALETTE* ppPalette)
995 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
997 TRACE("(%p)->(%p)\n",This,ppPalette);
998 if (This->palette == NULL)
999 return DDERR_NOPALETTEATTACHED;
1001 *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
1002 IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette,
1003 IDirectDrawPalette));
1008 Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
1009 LPDDPIXELFORMAT pDDPixelFormat)
1011 /* What is DDERR_INVALIDSURFACETYPE for here? */
1012 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1014 TRACE("(%p)->(%p)\n",This,pDDPixelFormat);
1015 DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
1020 Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
1021 LPDWORD pdwPriority)
1023 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1025 TRACE("(%p)->(%p)\n",This,pdwPriority);
1026 CHECK_TEXTURE(This);
1028 *pdwPriority = This->priority;
1033 Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface,
1034 REFGUID tag, LPVOID pBuffer,
1035 LPDWORD pcbBufferSize)
1037 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1040 TRACE("(%p)->(%p), size = %ld\n", This, pBuffer, *pcbBufferSize);
1042 data = find_private_data(This, tag);
1043 if (data == NULL) return DDERR_NOTFOUND;
1045 /* This may not be right. */
1046 if ((data->flags & DDSPD_VOLATILE)
1047 && data->uniqueness_value != This->uniqueness_value)
1048 return DDERR_EXPIRED;
1050 if (*pcbBufferSize < data->size)
1052 *pcbBufferSize = data->size;
1053 return DDERR_MOREDATA;
1056 if (data->flags & DDSPD_IUNKNOWNPTR)
1058 *(LPUNKNOWN *)pBuffer = data->ptr.object;
1059 IUnknown_AddRef(data->ptr.object);
1063 memcpy(pBuffer, data->ptr.data, data->size);
1070 Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
1071 LPDDSURFACEDESC2 pDDSD)
1073 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1075 TRACE("(%p)->(%p)\n",This,pDDSD);
1076 if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) ||
1077 (pDDSD->dwSize > sizeof(DDSURFACEDESC2))) {
1078 ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize);
1079 return DDERR_GENERIC;
1082 DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc);
1083 if (TRACE_ON(ddraw)) {
1084 DDRAW_dump_surface_desc(pDDSD);
1090 Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
1093 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1095 TRACE("(%p)->(%p)\n",This,pValue);
1096 *pValue = This->uniqueness_value;
1101 Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
1102 LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD)
1104 TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD);
1105 return DDERR_ALREADYINITIALIZED;
1109 Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface)
1111 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1113 TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not"));
1114 return This->lost ? DDERR_SURFACELOST : DD_OK;
1118 /* XXX This doesn't actually do any locking or keep track of the locked
1119 * rectangles. The behaviour is poorly documented. */
1121 Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
1122 LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h)
1124 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1126 if (TRACE_ON(ddraw)) {
1127 TRACE("(%p)->Lock(%p,%p,%08lx,%p)\n",This,prect,pDDSD,flags,h);
1128 TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags);
1130 if (WARN_ON(ddraw)) {
1131 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) {
1132 WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY));
1136 return DDERR_INVALIDPARAMS;
1138 if (NULL == pDDSD) {
1139 return DDERR_INVALIDPARAMS;
1142 /* If the surface is already locked, return busy */
1144 WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
1145 return DDERR_SURFACEBUSY;
1148 /* First, copy the Surface description */
1149 DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc));
1151 /* Used to optimize the D3D Device locking */
1152 This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY);
1154 /* If asked only for a part, change the surface pointer.
1155 * (Not documented.) */
1156 if (prect != NULL) {
1157 TRACE(" lprect: %ldx%ld-%ldx%ld\n",
1158 prect->left,prect->top,prect->right,prect->bottom);
1159 /* First do some sanity checkings on the rectangle we receive.
1160 DungeonSiege seems to gives us once a very bad rectangle for example */
1161 if ((prect->top < 0) ||
1162 (prect->left < 0) ||
1163 (prect->bottom < 0) ||
1164 (prect->right < 0) ||
1165 (prect->left >= prect->right) ||
1166 (prect->top >= prect->bottom) ||
1167 (prect->left >= This->surface_desc.dwWidth) ||
1168 (prect->right > This->surface_desc.dwWidth) ||
1169 (prect->top >= This->surface_desc.dwHeight) ||
1170 (prect->bottom > This->surface_desc.dwHeight)) {
1171 ERR(" Invalid values in LPRECT !!!\n");
1172 return DDERR_INVALIDPARAMS;
1175 This->lock_update(This, prect, flags);
1177 if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
1179 switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) {
1180 case MAKE_FOURCC('D','X','T','1') : blksize = 8; break;
1181 case MAKE_FOURCC('D','X','T','3') : blksize = 16; break;
1182 case MAKE_FOURCC('D','X','T','5') : blksize = 16; break;
1183 default: return DDERR_INVALIDPIXELFORMAT;
1185 pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
1186 + prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize
1187 + prect->left/4 * blksize;
1189 pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
1190 + prect->top * This->surface_desc.u1.lPitch
1191 + prect->left * GET_BPP(This->surface_desc);
1193 This->lock_update(This, NULL, flags);
1196 This->locked = TRUE;
1198 TRACE("locked surface returning description :\n");
1199 if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD);
1205 Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
1207 /* Some surface types should return DDERR_CANTPAGELOCK. */
1212 Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
1214 /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
1215 * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
1220 Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
1223 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1225 TRACE("(%p)->(%p)\n",This,hDC);
1227 if (!This->dc_in_use || This->hDC != hDC)
1228 return DDERR_INVALIDPARAMS;
1230 This->release_dc(This, hDC);
1232 hr = IDirectDrawSurface7_Unlock(iface, NULL);
1233 if (FAILED(hr)) return hr;
1235 This->dc_in_use = FALSE;
1244 Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
1245 LPDIRECTDRAWCLIPPER pDDClipper)
1247 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1249 TRACE("(%p)->(%p)\n",This,pDDClipper);
1250 if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper))
1253 if (This->clipper != NULL)
1254 IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
1255 IDirectDrawClipper));
1257 This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
1259 if (pDDClipper != NULL)
1260 IDirectDrawClipper_AddRef(pDDClipper);
1266 Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
1267 DWORD dwFlags, LPDDCOLORKEY pCKey)
1269 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1271 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
1273 if (TRACE_ON(ddraw)) {
1274 TRACE(" - colorkey flags : ");
1275 DDRAW_dump_colorkeyflag(dwFlags);
1278 if ((dwFlags & DDCKEY_COLORSPACE) != 0) {
1279 FIXME(" colorkey value not supported (%08lx) !\n", dwFlags);
1280 return DDERR_INVALIDPARAMS;
1283 /* TODO: investigate if this function can take multiple bits set at the same
1284 time (ie setting multiple colorkey values at the same time with only
1288 switch (dwFlags & ~DDCKEY_COLORSPACE) {
1289 case DDCKEY_DESTBLT:
1290 This->surface_desc.ddckCKDestBlt = *pCKey;
1291 This->surface_desc.dwFlags |= DDSD_CKDESTBLT;
1294 case DDCKEY_DESTOVERLAY:
1295 This->surface_desc.u3.ddckCKDestOverlay = *pCKey;
1296 This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1299 case DDCKEY_SRCOVERLAY:
1300 This->surface_desc.ddckCKSrcOverlay = *pCKey;
1301 This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1305 This->surface_desc.ddckCKSrcBlt = *pCKey;
1306 This->surface_desc.dwFlags |= DDSD_CKSRCBLT;
1310 return DDERR_INVALIDPARAMS;
1313 switch (dwFlags & ~DDCKEY_COLORSPACE) {
1314 case DDCKEY_DESTBLT:
1315 This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT;
1318 case DDCKEY_DESTOVERLAY:
1319 This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY;
1322 case DDCKEY_SRCOVERLAY:
1323 This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY;
1327 This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT;
1331 return DDERR_INVALIDPARAMS;
1335 if (This->aux_setcolorkey_cb) This->aux_setcolorkey_cb(This, dwFlags, pCKey);
1341 Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD)
1343 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1345 TRACE("(%p)->(%08lx)\n",This,dwMaxLOD);
1346 CHECK_TEXTURE(This);
1348 This->max_lod = dwMaxLOD;
1353 Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
1356 return DDERR_NOTAOVERLAYSURFACE;
1360 Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
1361 LPDIRECTDRAWPALETTE pPalette)
1363 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1364 IDirectDrawPalette *pal_to_rel = NULL;
1366 TRACE("(%p)->(%p)\n",This,pPalette);
1367 if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette))
1370 if (This->palette != NULL) {
1371 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1372 This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE;
1373 pal_to_rel = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
1376 This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
1378 if (pPalette != NULL) {
1379 IDirectDrawPalette_AddRef(pPalette);
1380 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1381 This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE;
1384 This->set_palette(This, This->palette);
1386 /* Do the palette release at the end to prevent doing some 'loop' when removing
1387 * the surface maintaining the last reference on a palette.
1389 if (pal_to_rel != NULL)
1390 IDirectDrawPalette_Release(pal_to_rel);
1396 Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
1399 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1401 TRACE("(%p)->(%08lx)\n",This,dwPriority);
1402 CHECK_TEXTURE(This);
1404 This->priority = dwPriority;
1408 /* Be careful when locking this: it is risky to call the object's AddRef
1409 * or Release holding a lock. */
1411 Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
1412 REFGUID tag, LPVOID pData,
1413 DWORD cbSize, DWORD dwFlags)
1416 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1418 TRACE("(%p)->(%p), size=%ld\n", This, pData, cbSize);
1420 data = find_private_data(This, tag);
1423 data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
1424 if (data == NULL) return DDERR_OUTOFMEMORY;
1427 data->flags = dwFlags;
1428 data->uniqueness_value = This->uniqueness_value;
1430 if (dwFlags & DDSPD_IUNKNOWNPTR)
1432 data->ptr.object = (LPUNKNOWN)pData;
1433 data->size = sizeof(LPUNKNOWN);
1434 IUnknown_AddRef(data->ptr.object);
1438 data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize);
1439 if (data->ptr.data == NULL)
1441 HeapFree(GetProcessHeap(), 0, data);
1442 return DDERR_OUTOFMEMORY;
1445 data->size = cbSize;
1446 memcpy(data->ptr.data, pData, data->size);
1450 data->next = This->private_data;
1452 if (This->private_data)
1453 This->private_data->prev = data;
1454 This->private_data = data;
1460 /* I don't actually know how windows handles this case. The only
1461 * reason I don't just call FreePrivateData is because I want to
1462 * guarantee SetPrivateData working when using LPUNKNOWN or data
1463 * that is no larger than the old data. */
1465 FIXME("Replacing existing private data not implemented yet.\n");
1470 /* SetSurfaceDesc */
1473 Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect)
1475 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1477 TRACE("(%p)->Unlock(%p)\n",This,pRect);
1479 if (!This->locked) {
1480 WARN("Surface not locked - returing DDERR_NOTLOCKED\n");
1481 return DDERR_NOTLOCKED;
1484 This->locked = FALSE;
1485 This->unlock_update(This, pRect);
1486 if (This->aux_unlock)
1487 This->aux_unlock(This->aux_ctx, This->aux_data, pRect);
1493 Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
1495 LPDIRECTDRAWSURFACE7 pDstSurface,
1496 LPRECT pDstRect, DWORD dwFlags,
1499 return DDERR_UNSUPPORTED;
1502 /* MSDN: "not currently implemented." */
1504 Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
1507 return DDERR_UNSUPPORTED;
1511 Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
1513 LPDIRECTDRAWSURFACE7 pDDSRef)
1515 return DDERR_NOTAOVERLAYSURFACE;