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
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
33 #include "mesa_private.h"
34 #include "wine/debug.h"
35 #include "ddraw_private.h"
36 #include "dsurface/main.h"
37 #include "ddraw/main.h"
38 #include "dsurface/thunks.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
41 WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip);
42 WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps);
44 /** Creation/Destruction functions */
47 Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
49 const DDSURFACEDESC2 *pDDSD)
51 TRACE("(%p)->(%p,%p)\n", This, pDD, pDDSD);
53 if (pDDSD != &This->surface_desc) {
54 This->surface_desc.dwSize = sizeof(This->surface_desc);
55 DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD);
57 This->uniqueness_value = 1; /* unchecked */
60 This->local.lpSurfMore = &This->more;
61 This->local.lpGbl = &This->global;
62 This->local.dwProcessId = GetCurrentProcessId();
63 This->local.dwFlags = 0; /* FIXME */
64 This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps;
65 /* FIXME: more local stuff */
66 This->more.lpDD_lcl = &pDD->local;
67 This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2;
68 This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3;
69 This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4;
70 /* FIXME: more more stuff */
71 This->gmore = &This->global_more;
72 This->global.u3.lpDD = pDD->local.lpGbl;
73 /* FIXME: more global stuff */
75 This->final_release = Main_DirectDrawSurface_final_release;
76 This->late_allocate = Main_DirectDrawSurface_late_allocate;
77 This->attach = Main_DirectDrawSurface_attach;
78 This->detach = Main_DirectDrawSurface_detach;
79 This->lock_update = Main_DirectDrawSurface_lock_update;
80 This->unlock_update = Main_DirectDrawSurface_unlock_update;
81 This->lose_surface = Main_DirectDrawSurface_lose_surface;
82 This->set_palette = Main_DirectDrawSurface_set_palette;
83 This->update_palette = Main_DirectDrawSurface_update_palette;
84 This->get_display_window = Main_DirectDrawSurface_get_display_window;
85 This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp;
86 This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp;
88 ICOM_INIT_INTERFACE(This, IDirectDrawSurface3,
89 DDRAW_IDDS3_Thunk_VTable);
90 ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
93 /* There is no generic implementation of IDDS7 or texture */
95 Main_DirectDraw_AddSurface(pDD, This);
99 void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
101 Main_DirectDraw_RemoveSurface(This->ddraw_owner, This);
104 HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
109 static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
112 IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette));
113 This->palette = NULL;
115 This->final_release(This);
116 if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
117 if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);
118 HeapFree(GetProcessHeap(), 0, This);
121 void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This)
123 WARN("destroying surface %p with refcnt %lu\n", This, This->ref);
124 Main_DirectDrawSurface_Destroy(This);
127 ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface)
129 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
130 ULONG ref = InterlockedDecrement(&This->ref);
132 TRACE("(%p)->(): decreasing from %ld\n", This, ref + 1);
136 if (This->aux_release)
137 This->aux_release(This->aux_ctx, This->aux_data);
138 Main_DirectDrawSurface_Destroy(This);
140 TRACE("released surface %p\n", This);
148 ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface)
150 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
151 ULONG ref = InterlockedIncrement(&This->ref);
153 TRACE("(%p)->(): increasing from %ld\n", This, ref - 1);
159 Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
162 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
163 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
167 if (IsEqualGUID(&IID_IUnknown, riid)
168 || IsEqualGUID(&IID_IDirectDrawSurface7, riid)
169 || IsEqualGUID(&IID_IDirectDrawSurface4, riid))
171 InterlockedIncrement(&This->ref);
172 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7);
175 else if (IsEqualGUID(&IID_IDirectDrawSurface, riid)
176 || IsEqualGUID(&IID_IDirectDrawSurface2, riid)
177 || IsEqualGUID(&IID_IDirectDrawSurface3, riid))
179 InterlockedIncrement(&This->ref);
180 *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3);
183 else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
185 InterlockedIncrement(&This->ref);
186 *ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
190 /* interfaces following here require OpenGL */
191 if( !opengl_initialized )
192 return E_NOINTERFACE;
194 if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) ||
195 IsEqualGUID( &IID_IDirect3DHALDevice, riid) )
197 IDirect3DDeviceImpl *d3ddevimpl;
200 ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, 1);
201 if (FAILED(ret_value)) return ret_value;
203 *ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);
204 TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj);
206 InterlockedIncrement(&This->ref); /* No idea if this is correct.. Need to check using real Windows */
209 else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
210 IsEqualGUID( &IID_IDirect3DTexture2, riid ))
212 HRESULT ret_value = S_OK;
214 /* Note: this is not exactly how Windows does it... But this seems not to hurt the only
215 application I know creating a texture without this flag set and it will prevent
216 bugs in other parts of Wine.
218 This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
220 /* In case the texture surface was created before the D3D creation */
221 if (This->tex_private == NULL) {
222 if (This->ddraw_owner->d3d_private == NULL) {
223 ERR("Texture created with no D3D object yet.. Not supported !\n");
224 return E_NOINTERFACE;
227 ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main);
228 if (FAILED(ret_value)) return ret_value;
230 if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
231 *ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
232 TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
234 *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
235 TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
237 InterlockedIncrement(&This->ref);
242 return E_NOINTERFACE;
248 Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
249 IDirectDrawSurfaceImpl *to)
254 BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
260 Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
266 Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
272 Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This)
277 Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
278 IDirectDrawPaletteImpl* pal)
283 Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
284 IDirectDrawPaletteImpl* pal,
285 DWORD dwStart, DWORD dwCount,
286 LPPALETTEENTRY palent)
291 Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
297 Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
299 LPDDGAMMARAMP lpGammaRamp)
303 hr = This->get_dc(This, &hDC);
304 if (FAILED(hr)) return hr;
305 hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
306 This->release_dc(This, hDC);
311 Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
313 LPDDGAMMARAMP lpGammaRamp)
317 hr = This->get_dc(This, &hDC);
318 if (FAILED(hr)) return hr;
319 hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
320 This->release_dc(This, hDC);
325 /*** Interface functions */
328 Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
329 LPDIRECTDRAWSURFACE7 pAttach)
331 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
332 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
333 IDirectDrawSurface7, pAttach);
335 TRACE("(%p)->(%p)\n",This,pAttach);
337 /* Does windows check this? */
339 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
341 /* Does windows check this? */
342 if (surf->ddraw_owner != This->ddraw_owner)
343 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
345 if (surf->surface_owner != NULL)
346 return DDERR_SURFACEALREADYATTACHED; /* unchecked */
348 /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
349 * But apparently backbuffers and mipmaps can be attached too. */
351 /* Set MIPMAPSUBLEVEL if this seems to be one */
352 if (This->surface_desc.ddsCaps.dwCaps &
353 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
354 surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
355 /* FIXME: we should probably also add to dwMipMapCount of this
356 * and all parent surfaces (update create_texture if you do) */
359 /* Callback to allow the surface to do something special now that it is
360 * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
361 if (!surf->attach(surf, This))
362 return DDERR_CANNOTATTACHSURFACE;
364 /* check: Where should it go in the chain? This puts it on the head. */
366 This->attached->prev_attached = surf;
367 surf->next_attached = This->attached;
368 surf->prev_attached = NULL;
369 This->attached = surf;
370 surf->surface_owner = This;
372 IDirectDrawSurface7_AddRef(pAttach);
377 /* MSDN: "not currently implemented." */
379 Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
382 TRACE("(%p)->(%p)\n",iface,pRect);
383 return DDERR_UNSUPPORTED; /* unchecked */
386 /* MSDN: "not currently implemented." */
388 Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
389 LPDDBLTBATCH pBatch, DWORD dwCount,
392 TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags);
393 return DDERR_UNSUPPORTED; /* unchecked */
397 Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface)
399 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
400 volatile IDirectDrawSurfaceImpl* vThis = This;
402 TRACE("(%p)\n",This);
403 /* A uniquness value of 0 is apparently special.
404 * This needs to be checked. */
407 DWORD old_uniqueness_value = vThis->uniqueness_value;
408 DWORD new_uniqueness_value = old_uniqueness_value+1;
410 if (old_uniqueness_value == 0) break;
411 if (new_uniqueness_value == 0) new_uniqueness_value = 1;
413 if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
414 old_uniqueness_value,
415 new_uniqueness_value)
416 == old_uniqueness_value)
424 Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
426 LPDIRECTDRAWSURFACE7 pAttach)
428 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
429 IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
430 IDirectDrawSurface7, pAttach);
432 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);
434 if (!surf || (surf->surface_owner != This))
435 return DDERR_SURFACENOTATTACHED; /* unchecked */
439 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
440 if (This->surface_desc.ddsCaps.dwCaps &
441 surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
442 surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
443 /* FIXME: we should probably also subtract from dwMipMapCount of this
444 * and all parent surfaces */
447 if (surf->next_attached)
448 surf->next_attached->prev_attached = surf->prev_attached;
449 if (surf->prev_attached)
450 surf->prev_attached->next_attached = surf->next_attached;
451 if (This->attached == surf)
452 This->attached = surf->next_attached;
454 IDirectDrawSurface7_Release(pAttach);
460 Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
462 LPDDENUMSURFACESCALLBACK7 cb)
464 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
465 IDirectDrawSurfaceImpl* surf;
467 TRACE("(%p)->(%p,%p)\n",This,context,cb);
469 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
471 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
472 if (cb(ICOM_INTERFACE(surf, IDirectDrawSurface7), &surf->surface_desc,
473 context) == DDENUMRET_CANCEL)
481 Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
482 DWORD dwFlags, LPVOID context,
483 LPDDENUMSURFACESCALLBACK7 cb)
485 TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb);
489 BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
490 IDirectDrawSurfaceImpl* back,
493 /* uniqueness_value? */
494 /* This is necessary. But is it safe? */
496 HDC tmp = front->hDC;
497 front->hDC = back->hDC;
502 BOOL tmp = front->dc_in_use;
503 front->dc_in_use = back->dc_in_use;
504 back->dc_in_use = tmp;
508 FLATPTR tmp = front->global.fpVidMem;
509 front->global.fpVidMem = back->global.fpVidMem;
510 back->global.fpVidMem = tmp;
514 ULONG_PTR tmp = front->global_more.hKernelSurface;
515 front->global_more.hKernelSurface = back->global_more.hKernelSurface;
516 back->global_more.hKernelSurface = tmp;
522 /* This is unnecessarely complicated :-) */
523 #define MEASUREMENT_WINDOW 5
524 #define NUMBER_OF_WINDOWS 10
526 static LONGLONG perf_freq;
527 static LONGLONG perf_storage[NUMBER_OF_WINDOWS];
528 static LONGLONG prev_time = 0;
529 static unsigned int current_window;
530 static unsigned int measurements_in_window;
531 static unsigned int valid_windows;
534 Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
535 LPDIRECTDRAWSURFACE7 override, DWORD dwFlags)
537 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
538 IDirectDrawSurfaceImpl* target;
541 TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags);
543 if (TRACE_ON(ddraw_fps)) {
544 LONGLONG current_time;
545 LONGLONG frame_duration;
546 QueryPerformanceCounter((LARGE_INTEGER *) ¤t_time);
548 if (prev_time != 0) {
549 LONGLONG total_time = 0;
552 frame_duration = current_time - prev_time;
553 prev_time = current_time;
555 perf_storage[current_window] += frame_duration;
556 measurements_in_window++;
558 if (measurements_in_window >= MEASUREMENT_WINDOW) {
562 if (valid_windows < NUMBER_OF_WINDOWS) {
564 tot_meas = valid_windows * MEASUREMENT_WINDOW;
565 for (i = 0; i < valid_windows; i++) {
566 total_time += perf_storage[i];
570 tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW;
571 for (i = 0; i < NUMBER_OF_WINDOWS; i++) {
572 total_time += perf_storage[i];
576 TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time);
578 if (current_window >= NUMBER_OF_WINDOWS) {
581 perf_storage[current_window] = 0;
582 measurements_in_window = 0;
585 prev_time = current_time;
586 memset(perf_storage, 0, sizeof(perf_storage));
589 measurements_in_window = 0;
590 QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq);
594 /* MSDN: "This method can be called only for a surface that has the
595 * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
596 if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
597 != (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
598 return DDERR_NOTFLIPPABLE;
601 if (This->aux_flip(This->aux_ctx, This->aux_data))
604 /* 1. find the flip target */
605 /* XXX I don't think this algorithm works for more than 1 backbuffer. */
606 if (override == NULL)
608 static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
609 LPDIRECTDRAWSURFACE7 tgt;
611 hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
612 if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */
614 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
616 IDirectDrawSurface7_Release(tgt);
620 BOOL on_chain = FALSE;
621 IDirectDrawSurfaceImpl* surf;
623 /* MSDN: "The method fails if the specified [override] surface is not
624 * a member of the flipping chain." */
626 /* Verify that override is on this flip chain. We assume that
627 * surf is the head of the flipping chain, because it's the front
629 target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
632 /* Either target is (indirectly) attached to This or This is
633 * (indirectly) attached to target. */
634 for (surf = target; surf != NULL; surf = surf->surface_owner)
644 return DDERR_INVALIDPARAMS; /* unchecked */
647 TRACE("flip to backbuffer: %p\n",target);
648 if (TRACE_ON(ddraw_flip)) {
649 static unsigned int flip_count = 0;
650 IDirectDrawPaletteImpl *palette;
654 /* Hack for paletted games... */
655 palette = target->palette;
656 target->palette = This->palette;
658 sprintf(buf, "flip_%08d.ppm", flip_count++);
659 TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf);
660 f = fopen(buf, "wb");
661 DDRAW_dump_surface_to_disk(target, f, 8);
662 target->palette = palette;
665 if (This->flip_data(This, target, dwFlags))
666 This->flip_update(This, dwFlags);
671 static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This,
675 for (data = This->private_data; data != NULL; data = data->next)
677 if (IsEqualGUID(&data->tag, tag)) break;
684 Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag)
686 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
689 data = find_private_data(This, tag);
690 if (data == NULL) return DDERR_NOTFOUND;
693 data->prev->next = data->next;
695 data->next->prev = data->prev;
697 if (data->flags & DDSPD_IUNKNOWNPTR)
699 if (data->ptr.object != NULL)
700 IUnknown_Release(data->ptr.object);
703 HeapFree(GetProcessHeap(), 0, data->ptr.data);
705 HeapFree(GetProcessHeap(), 0, data);
711 Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
713 LPDIRECTDRAWSURFACE7* ppSurface)
715 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
716 IDirectDrawSurfaceImpl* surf;
717 IDirectDrawSurfaceImpl* found = NULL;
720 if (TRACE_ON(ddraw)) {
721 TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2,
722 pCaps->dwCaps3, pCaps->dwCaps4, ppSurface);
723 TRACE(" Caps are : "); DDRAW_dump_DDSCAPS2(pCaps); TRACE("\n");
727 if ((This->ddraw_owner->local.dwLocalFlags & DDRAWILCL_DIRECTDRAW7) == 0) {
728 /* As this is not a DirectDraw7 application, remove the garbage that some games
729 put in the new fields of the DDSCAPS2 structure. */
730 our_caps.dwCaps2 = 0;
731 our_caps.dwCaps3 = 0;
732 our_caps.dwCaps4 = 0;
733 if (TRACE_ON(ddraw)) {
734 TRACE(" Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps); TRACE("\n");
738 for (surf = This->attached; surf != NULL; surf = surf->next_attached)
740 if (TRACE_ON(ddraw)) {
741 TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx \n",surf ,
742 surf->surface_desc.ddsCaps.dwCaps,
743 surf->surface_desc.ddsCaps.dwCaps2,
744 surf->surface_desc.ddsCaps.dwCaps3,
745 surf->surface_desc.ddsCaps.dwCaps4);
746 TRACE(" Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf->surface_desc.ddsCaps)); TRACE("\n");
748 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
749 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2))
751 /* MSDN: "This method fails if more than one surface is attached
752 * that matches the capabilities requested." */
755 FIXME("More than one attached surface matches requested caps. What should we do here?\n");
756 /* Previous code returned 'DDERR_NOTFOUND'. That appears not
757 to be correct, given what 3DMark expects from MipMapped surfaces.
758 We shall just continue instead. */
766 TRACE("Did not find any valid surface\n");
767 return DDERR_NOTFOUND;
770 *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7);
772 if (TRACE_ON(ddraw)) {
773 TRACE("Returning surface %p with description : \n", *ppSurface);
774 DDRAW_dump_surface_desc(&(found->surface_desc));
777 /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
778 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7));
783 Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
785 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
790 case DDGBS_ISBLTDONE:
794 return DDERR_INVALIDPARAMS;
799 Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps)
801 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
803 TRACE("(%p)->(%p)\n",This,pCaps);
804 *pCaps = This->surface_desc.ddsCaps;
809 Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
810 LPDIRECTDRAWCLIPPER* ppClipper)
812 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
814 TRACE("(%p)->(%p)\n",This,ppClipper);
815 if (This->clipper == NULL)
816 return DDERR_NOCLIPPERATTACHED;
818 *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
819 IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper,
820 IDirectDrawClipper));
825 Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags,
828 /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
829 * isn't there? That's like saying that an int isn't there. (Which MS
830 * has done in other docs.) */
832 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
834 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
835 if (TRACE_ON(ddraw)) {
836 TRACE(" - colorkey flags : ");
837 DDRAW_dump_colorkeyflag(dwFlags);
843 *pCKey = This->surface_desc.ddckCKDestBlt;
846 case DDCKEY_DESTOVERLAY:
847 *pCKey = This->surface_desc.u3.ddckCKDestOverlay;
851 *pCKey = This->surface_desc.ddckCKSrcBlt;
854 case DDCKEY_SRCOVERLAY:
855 *pCKey = This->surface_desc.ddckCKSrcOverlay;
859 return DDERR_INVALIDPARAMS;
865 /* XXX We need to do something with the DC if the surface gets lost. */
867 Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
871 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
873 TRACE("(%p)->(%p)\n",This,phDC);
881 return DDERR_DCALREADYCREATED;
885 * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
886 * thread has it locked, but GetDC does not. */
887 ddsd.dwSize = sizeof(ddsd);
888 hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0);
895 hr = This->get_dc(This, &This->hDC);
898 TRACE("returning %p\n",This->hDC);
901 This->dc_in_use = TRUE;
903 else WARN("No DC! Prepare for trouble\n");
910 Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD)
912 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
914 TRACE("(%p)->(%p)\n",This,pDD);
915 *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7);
916 IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
921 Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
923 /* XXX: DDERR_INVALIDSURFACETYPE */
925 TRACE("(%p)->(%08lx)\n",iface,dwFlags);
929 case DDGFS_ISFLIPDONE:
933 return DDERR_INVALIDPARAMS;
938 Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD)
940 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
942 TRACE("(%p)->(%p)\n",This,pdwMaxLOD);
945 *pdwMaxLOD = This->max_lod;
950 Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
951 LPLONG pX, LPLONG pY)
953 return DDERR_NOTAOVERLAYSURFACE;
957 Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
958 LPDIRECTDRAWPALETTE* ppPalette)
960 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
962 TRACE("(%p)->(%p)\n",This,ppPalette);
963 if (This->palette == NULL)
964 return DDERR_NOPALETTEATTACHED;
966 *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
967 IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette,
968 IDirectDrawPalette));
973 Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
974 LPDDPIXELFORMAT pDDPixelFormat)
976 /* What is DDERR_INVALIDSURFACETYPE for here? */
977 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
979 TRACE("(%p)->(%p)\n",This,pDDPixelFormat);
980 DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
985 Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
988 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
990 TRACE("(%p)->(%p)\n",This,pdwPriority);
993 *pdwPriority = This->priority;
998 Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface,
999 REFGUID tag, LPVOID pBuffer,
1000 LPDWORD pcbBufferSize)
1002 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1005 TRACE("(%p)->(%p), size = %ld\n", This, pBuffer, *pcbBufferSize);
1007 data = find_private_data(This, tag);
1008 if (data == NULL) return DDERR_NOTFOUND;
1010 /* This may not be right. */
1011 if ((data->flags & DDSPD_VOLATILE)
1012 && data->uniqueness_value != This->uniqueness_value)
1013 return DDERR_EXPIRED;
1015 if (*pcbBufferSize < data->size)
1017 *pcbBufferSize = data->size;
1018 return DDERR_MOREDATA;
1021 if (data->flags & DDSPD_IUNKNOWNPTR)
1023 *(LPUNKNOWN *)pBuffer = data->ptr.object;
1024 IUnknown_AddRef(data->ptr.object);
1028 memcpy(pBuffer, data->ptr.data, data->size);
1035 Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
1036 LPDDSURFACEDESC2 pDDSD)
1038 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1040 TRACE("(%p)->(%p)\n",This,pDDSD);
1041 if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) ||
1042 (pDDSD->dwSize > sizeof(DDSURFACEDESC2))) {
1043 ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize);
1044 return DDERR_GENERIC;
1047 DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc);
1048 if (TRACE_ON(ddraw)) {
1049 DDRAW_dump_surface_desc(pDDSD);
1055 Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
1058 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1060 TRACE("(%p)->(%p)\n",This,pValue);
1061 *pValue = This->uniqueness_value;
1066 Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
1067 LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD)
1069 TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD);
1070 return DDERR_ALREADYINITIALIZED;
1074 Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface)
1076 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1078 TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not"));
1079 return This->lost ? DDERR_SURFACELOST : DD_OK;
1083 /* XXX This doesn't actually do any locking or keep track of the locked
1084 * rectangles. The behaviour is poorly documented. */
1086 Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
1087 LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h)
1089 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1091 if (TRACE_ON(ddraw)) {
1092 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",This,prect,pDDSD,flags,(DWORD)h);
1093 TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags);
1095 if (WARN_ON(ddraw)) {
1096 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) {
1097 WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY));
1101 /* If the surface is already locked, return busy */
1103 WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
1104 return DDERR_SURFACEBUSY;
1107 /* First, copy the Surface description */
1108 DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc));
1110 /* Used to optimize the D3D Device locking */
1111 This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY);
1113 /* If asked only for a part, change the surface pointer.
1114 * (Not documented.) */
1115 if (prect != NULL) {
1116 TRACE(" lprect: %ldx%ld-%ldx%ld\n",
1117 prect->left,prect->top,prect->right,prect->bottom);
1118 /* First do some sanity checkings on the rectangle we receive.
1119 DungeonSiege seems to gives us once a very bad rectangle for example */
1120 if ((prect->top < 0) ||
1121 (prect->left < 0) ||
1122 (prect->bottom < 0) ||
1123 (prect->right < 0) ||
1124 (prect->left >= prect->right) ||
1125 (prect->top >= prect->bottom) ||
1126 (prect->left >= This->surface_desc.dwWidth) ||
1127 (prect->right > This->surface_desc.dwWidth) ||
1128 (prect->top >= This->surface_desc.dwHeight) ||
1129 (prect->bottom > This->surface_desc.dwHeight)) {
1130 ERR(" Invalid values in LPRECT !!!\n");
1131 return DDERR_INVALIDPARAMS;
1134 This->lock_update(This, prect, flags);
1136 if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
1138 switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) {
1139 case MAKE_FOURCC('D','X','T','1') : blksize = 8; break;
1140 case MAKE_FOURCC('D','X','T','3') : blksize = 16; break;
1141 case MAKE_FOURCC('D','X','T','5') : blksize = 16; break;
1142 default: return DDERR_INVALIDPIXELFORMAT;
1144 pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
1145 + prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize
1146 + prect->left/4 * blksize;
1148 pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
1149 + prect->top * This->surface_desc.u1.lPitch
1150 + prect->left * GET_BPP(This->surface_desc);
1152 This->lock_update(This, NULL, flags);
1155 This->locked = TRUE;
1157 TRACE("locked surface returning description : \n");
1158 if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD);
1164 Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
1166 /* Some surface types should return DDERR_CANTPAGELOCK. */
1171 Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
1173 /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
1174 * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
1179 Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
1182 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1184 TRACE("(%p)->(%p)\n",This,hDC);
1186 if (!This->dc_in_use || This->hDC != hDC)
1187 return DDERR_INVALIDPARAMS;
1189 This->release_dc(This, hDC);
1191 hr = IDirectDrawSurface7_Unlock(iface, NULL);
1192 if (FAILED(hr)) return hr;
1194 This->dc_in_use = FALSE;
1203 Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
1204 LPDIRECTDRAWCLIPPER pDDClipper)
1206 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1208 TRACE("(%p)->(%p)\n",This,pDDClipper);
1209 if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper))
1212 if (This->clipper != NULL)
1213 IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
1214 IDirectDrawClipper));
1216 This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
1218 if (pDDClipper != NULL)
1219 IDirectDrawClipper_AddRef(pDDClipper);
1225 Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
1226 DWORD dwFlags, LPDDCOLORKEY pCKey)
1228 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1230 TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
1232 if (TRACE_ON(ddraw)) {
1233 TRACE(" - colorkey flags : ");
1234 DDRAW_dump_colorkeyflag(dwFlags);
1237 if ((dwFlags & DDCKEY_COLORSPACE) != 0) {
1238 FIXME(" colorkey value not supported (%08lx) !\n", dwFlags);
1239 return DDERR_INVALIDPARAMS;
1242 /* TODO: investigate if this function can take multiple bits set at the same
1243 time (ie setting multiple colorkey values at the same time with only
1247 switch (dwFlags & ~DDCKEY_COLORSPACE) {
1248 case DDCKEY_DESTBLT:
1249 This->surface_desc.ddckCKDestBlt = *pCKey;
1250 This->surface_desc.dwFlags |= DDSD_CKDESTBLT;
1253 case DDCKEY_DESTOVERLAY:
1254 This->surface_desc.u3.ddckCKDestOverlay = *pCKey;
1255 This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1258 case DDCKEY_SRCOVERLAY:
1259 This->surface_desc.ddckCKSrcOverlay = *pCKey;
1260 This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1264 This->surface_desc.ddckCKSrcBlt = *pCKey;
1265 This->surface_desc.dwFlags |= DDSD_CKSRCBLT;
1269 return DDERR_INVALIDPARAMS;
1272 switch (dwFlags & ~DDCKEY_COLORSPACE) {
1273 case DDCKEY_DESTBLT:
1274 This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT;
1277 case DDCKEY_DESTOVERLAY:
1278 This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY;
1281 case DDCKEY_SRCOVERLAY:
1282 This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY;
1286 This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT;
1290 return DDERR_INVALIDPARAMS;
1294 if (This->aux_setcolorkey_cb) This->aux_setcolorkey_cb(This, dwFlags, pCKey);
1300 Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD)
1302 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1304 TRACE("(%p)->(%08lx)\n",This,dwMaxLOD);
1305 CHECK_TEXTURE(This);
1307 This->max_lod = dwMaxLOD;
1312 Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
1315 return DDERR_NOTAOVERLAYSURFACE;
1319 Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
1320 LPDIRECTDRAWPALETTE pPalette)
1322 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1323 IDirectDrawPalette *pal_to_rel = NULL;
1325 TRACE("(%p)->(%p)\n",This,pPalette);
1326 if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette))
1329 if (This->palette != NULL) {
1330 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1331 This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE;
1332 pal_to_rel = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
1335 This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
1337 if (pPalette != NULL) {
1338 IDirectDrawPalette_AddRef(pPalette);
1339 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1340 This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE;
1343 This->set_palette(This, This->palette);
1345 /* Do the palette release at the end to prevent doing some 'loop' when removing
1346 * the surface maintaining the last reference on a palette.
1348 if (pal_to_rel != NULL)
1349 IDirectDrawPalette_Release(pal_to_rel);
1355 Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
1358 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1360 TRACE("(%p)->(%08lx)\n",This,dwPriority);
1361 CHECK_TEXTURE(This);
1363 This->priority = dwPriority;
1367 /* Be careful when locking this: it is risky to call the object's AddRef
1368 * or Release holding a lock. */
1370 Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
1371 REFGUID tag, LPVOID pData,
1372 DWORD cbSize, DWORD dwFlags)
1375 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1377 TRACE("(%p)->(%p), size=%ld\n", This, pData, cbSize);
1379 data = find_private_data(This, tag);
1382 data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
1383 if (data == NULL) return DDERR_OUTOFMEMORY;
1386 data->flags = dwFlags;
1387 data->uniqueness_value = This->uniqueness_value;
1389 if (dwFlags & DDSPD_IUNKNOWNPTR)
1391 data->ptr.object = (LPUNKNOWN)pData;
1392 data->size = sizeof(LPUNKNOWN);
1393 IUnknown_AddRef(data->ptr.object);
1397 data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize);
1398 if (data->ptr.data == NULL)
1400 HeapFree(GetProcessHeap(), 0, data);
1401 return DDERR_OUTOFMEMORY;
1404 data->size = cbSize;
1405 memcpy(data->ptr.data, pData, data->size);
1409 data->next = This->private_data;
1411 if (This->private_data)
1412 This->private_data->prev = data;
1413 This->private_data = data;
1419 /* I don't actually know how windows handles this case. The only
1420 * reason I don't just call FreePrivateData is because I want to
1421 * guarantee SetPrivateData working when using LPUNKNOWN or data
1422 * that is no larger than the old data. */
1424 FIXME("Replacing existing private data not implemented yet.\n");
1429 /* SetSurfaceDesc */
1432 Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect)
1434 IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
1436 TRACE("(%p)->Unlock(%p)\n",This,pRect);
1438 if (!This->locked) {
1439 WARN("Surface not locked - returing DDERR_NOTLOCKED\n");
1440 return DDERR_NOTLOCKED;
1443 This->locked = FALSE;
1444 This->unlock_update(This, pRect);
1445 if (This->aux_unlock)
1446 This->aux_unlock(This->aux_ctx, This->aux_data, pRect);
1452 Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
1454 LPDIRECTDRAWSURFACE7 pDstSurface,
1455 LPRECT pDstRect, DWORD dwFlags,
1458 return DDERR_UNSUPPORTED;
1461 /* MSDN: "not currently implemented." */
1463 Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
1466 return DDERR_UNSUPPORTED;
1470 Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
1472 LPDIRECTDRAWSURFACE7 pDDSRef)
1474 return DDERR_NOTAOVERLAYSURFACE;