/*		DirectDrawSurface base implementation
 *
 * Copyright 1997-2000 Marcus Meissner
 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
 * Copyright 2000-2001 TransGaming Technologies Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "config.h"

#include <assert.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "mesa_private.h"
#include "wine/debug.h"
#include "ddraw_private.h"
#include "dsurface/main.h"
#include "ddraw/main.h"
#include "dsurface/thunks.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip);
WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps);

/** Creation/Destruction functions */

HRESULT
Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
				 IDirectDrawImpl *pDD,
				 const DDSURFACEDESC2 *pDDSD)
{
    TRACE("(%p)->(%p,%p)\n", This, pDD, pDDSD);

    if (pDDSD != &This->surface_desc) {
	This->surface_desc.dwSize = sizeof(This->surface_desc);
	DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD);
    }
    This->uniqueness_value = 1; /* unchecked */
    This->ref = 1;

    This->local.lpSurfMore = &This->more;
    This->local.lpGbl = &This->global;
    This->local.dwProcessId = GetCurrentProcessId();
    This->local.dwFlags = 0; /* FIXME */
    This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps;
    /* FIXME: more local stuff */
    This->more.lpDD_lcl = &pDD->local;
    This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2;
    This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3;
    This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4;
    /* FIXME: more more stuff */
    This->gmore = &This->global_more;
    This->global.u3.lpDD = pDD->local.lpGbl;
    /* FIXME: more global stuff */

    This->final_release = Main_DirectDrawSurface_final_release;
    This->late_allocate = Main_DirectDrawSurface_late_allocate;
    This->attach = Main_DirectDrawSurface_attach;
    This->detach = Main_DirectDrawSurface_detach;
    This->lock_update = Main_DirectDrawSurface_lock_update;
    This->unlock_update = Main_DirectDrawSurface_unlock_update;
    This->lose_surface = Main_DirectDrawSurface_lose_surface;
    This->set_palette    = Main_DirectDrawSurface_set_palette;
    This->update_palette = Main_DirectDrawSurface_update_palette;
    This->get_display_window = Main_DirectDrawSurface_get_display_window;
    This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp;
    This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp;

    ICOM_INIT_INTERFACE(This, IDirectDrawSurface3,
			DDRAW_IDDS3_Thunk_VTable);
    ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
			DDRAW_IDDGC_VTable);

    /* There is no generic implementation of IDDS7 or texture */

    Main_DirectDraw_AddSurface(pDD, This);
    return DD_OK;
}

void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
{
    Main_DirectDraw_RemoveSurface(This->ddraw_owner, This);
}

HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
{
    return DD_OK;
}

static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
{
    if (This->palette) {
        IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette));
	This->palette = NULL;
    }
    This->final_release(This);
    if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
    if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);
    HeapFree(GetProcessHeap(), 0, This);
}

void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This)
{
    WARN("destroying surface %p with refcnt %lu\n", This, This->ref);
    Main_DirectDrawSurface_Destroy(This);
}

ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(): decreasing from %ld\n", This, ref + 1);
    
    if (ref == 0)
    {
	if (This->aux_release)
	    This->aux_release(This->aux_ctx, This->aux_data);
	Main_DirectDrawSurface_Destroy(This);

	TRACE("released surface %p\n", This);
	
	return 0;
    }

    return ref;
}

ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(): increasing from %ld\n", This, ref - 1);
    
    return ref;
}

HRESULT WINAPI
Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
				      LPVOID* ppObj)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);

    *ppObj = NULL;

    if (IsEqualGUID(&IID_IUnknown, riid)
	|| IsEqualGUID(&IID_IDirectDrawSurface7, riid)
	|| IsEqualGUID(&IID_IDirectDrawSurface4, riid))
    {
        InterlockedIncrement(&This->ref);
	*ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7);
	return S_OK;
    }
    else if (IsEqualGUID(&IID_IDirectDrawSurface, riid)
	     || IsEqualGUID(&IID_IDirectDrawSurface2, riid)
	     || IsEqualGUID(&IID_IDirectDrawSurface3, riid))
    {
        InterlockedIncrement(&This->ref);
	*ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3);
	return S_OK;
    }
    else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
    {
        InterlockedIncrement(&This->ref);
	*ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
	return S_OK;
    }
#ifdef HAVE_OPENGL
    /* interfaces following here require OpenGL */
    if( !opengl_initialized )
        return E_NOINTERFACE;

    if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) ||
	  IsEqualGUID( &IID_IDirect3DHALDevice, riid) )
    {
        IDirect3DDeviceImpl *d3ddevimpl;
	HRESULT ret_value;

	ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, TRUE);
	if (FAILED(ret_value)) return ret_value;

	*ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);
	TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj);
	
	InterlockedIncrement(&This->ref); /* No idea if this is correct.. Need to check using real Windows */
	return ret_value;
    }
    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
	     IsEqualGUID( &IID_IDirect3DTexture2, riid ))
    {
	HRESULT ret_value = S_OK;

	/* Note: this is not exactly how Windows does it... But this seems not to hurt the only
	         application I know creating a texture without this flag set and it will prevent
		 bugs in other parts of Wine.
	*/
	This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;

	/* In case the texture surface was created before the D3D creation */
	if (This->tex_private == NULL) {
   	    if (This->ddraw_owner->d3d_private == NULL) {
	        ERR("Texture created with no D3D object yet.. Not supported !\n");
		return E_NOINTERFACE;
	    }

	    ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main);
	    if (FAILED(ret_value)) return ret_value;
	}
	if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
	    TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
	} else {
	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
	    TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
	}
	InterlockedIncrement(&This->ref);
	return ret_value;
    }
#endif

    return E_NOINTERFACE;
}

/*** Callbacks */

BOOL
Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
			      IDirectDrawSurfaceImpl *to)
{
    return TRUE;
}

BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
{
    return TRUE;
}

void
Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
	DWORD dwFlags)
{
}

void
Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
				     LPCRECT pRect)
{
}

void
Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This)
{
}

void
Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
				   IDirectDrawPaletteImpl* pal)
{
}

void
Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
				      IDirectDrawPaletteImpl* pal,
				      DWORD dwStart, DWORD dwCount,
				      LPPALETTEENTRY palent)
{
}

HWND
Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
{
    return 0;
}

HRESULT
Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
				      DWORD dwFlags,
				      LPDDGAMMARAMP lpGammaRamp)
{
    HDC hDC;
    HRESULT hr;
    hr = This->get_dc(This, &hDC);
    if (FAILED(hr)) return hr;
    hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
    This->release_dc(This, hDC);
    return hr;
}

HRESULT
Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
				      DWORD dwFlags,
				      LPDDGAMMARAMP lpGammaRamp)
{
    HDC hDC;
    HRESULT hr;
    hr = This->get_dc(This, &hDC);
    if (FAILED(hr)) return hr;
    hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
    This->release_dc(This, hDC);
    return hr;
}


/*** Interface functions */

HRESULT WINAPI
Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
					  LPDIRECTDRAWSURFACE7 pAttach)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
					       IDirectDrawSurface7, pAttach);

    TRACE("(%p)->(%p)\n",This,pAttach);

    /* Does windows check this? */
    if (surf == This)
	return DDERR_CANNOTATTACHSURFACE; /* unchecked */

    /* Does windows check this? */
    if (surf->ddraw_owner != This->ddraw_owner)
	return DDERR_CANNOTATTACHSURFACE; /* unchecked */

    if (surf->surface_owner != NULL)
	return DDERR_SURFACEALREADYATTACHED; /* unchecked */

    /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
     * But apparently backbuffers and mipmaps can be attached too. */

    /* Set MIPMAPSUBLEVEL if this seems to be one */
    if (This->surface_desc.ddsCaps.dwCaps &
	surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
	surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
	/* FIXME: we should probably also add to dwMipMapCount of this
	 * and all parent surfaces (update create_texture if you do) */
    }

    /* Callback to allow the surface to do something special now that it is
     * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
    if (!surf->attach(surf, This))
	return DDERR_CANNOTATTACHSURFACE;

    /* check: Where should it go in the chain? This puts it on the head. */
    if (This->attached)
	This->attached->prev_attached = surf;
    surf->next_attached = This->attached;
    surf->prev_attached = NULL;
    This->attached = surf;
    surf->surface_owner = This;

    IDirectDrawSurface7_AddRef(pAttach);

    return DD_OK;
}

/* MSDN: "not currently implemented." */
HRESULT WINAPI
Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
					   LPRECT pRect)
{
    TRACE("(%p)->(%p)\n",iface,pRect);
    return DDERR_UNSUPPORTED; /* unchecked */
}

/* MSDN: "not currently implemented." */
HRESULT WINAPI
Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
				LPDDBLTBATCH pBatch, DWORD dwCount,
				DWORD dwFlags)
{
    TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags);
    return DDERR_UNSUPPORTED; /* unchecked */
}

HRESULT WINAPI
Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    volatile IDirectDrawSurfaceImpl* vThis = This;

    TRACE("(%p)\n",This);
    /* A uniquness value of 0 is apparently special.
     * This needs to be checked. */
    while (1)
    {
	DWORD old_uniqueness_value = vThis->uniqueness_value;
	DWORD new_uniqueness_value = old_uniqueness_value+1;

	if (old_uniqueness_value == 0) break;
	if (new_uniqueness_value == 0) new_uniqueness_value = 1;

	if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
                                       old_uniqueness_value,
                                       new_uniqueness_value)
	    == old_uniqueness_value)
	    break;
    }

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
					     DWORD dwFlags,
					     LPDIRECTDRAWSURFACE7 pAttach)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
					       IDirectDrawSurface7, pAttach);

    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);

    if (!surf || (surf->surface_owner != This))
	return DDERR_SURFACENOTATTACHED; /* unchecked */

    surf->detach(surf);

    /* Remove MIPMAPSUBLEVEL if this seemed to be one */
    if (This->surface_desc.ddsCaps.dwCaps &
	surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
	surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
	/* FIXME: we should probably also subtract from dwMipMapCount of this
	 * and all parent surfaces */
    }

    if (surf->next_attached)
	surf->next_attached->prev_attached = surf->prev_attached;
    if (surf->prev_attached)
	surf->prev_attached->next_attached = surf->next_attached;
    if (This->attached == surf)
	This->attached = surf->next_attached;

    IDirectDrawSurface7_Release(pAttach);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
					    LPVOID context,
					    LPDDENUMSURFACESCALLBACK7 cb)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl* surf;

    TRACE("(%p)->(%p,%p)\n",This,context,cb);

    for (surf = This->attached; surf != NULL; surf = surf->next_attached)
    {
	/* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
	if (cb(ICOM_INTERFACE(surf, IDirectDrawSurface7), &surf->surface_desc,
	       context) == DDENUMRET_CANCEL)
	    break;
    }

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
					  DWORD dwFlags, LPVOID context,
					  LPDDENUMSURFACESCALLBACK7 cb)
{
    TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb);
    return DD_OK;
}

BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
				      IDirectDrawSurfaceImpl* back,
				      DWORD dwFlags)
{
    /* uniqueness_value? */
    /* This is necessary. But is it safe? */
    {
	HDC tmp = front->hDC;
	front->hDC = back->hDC;
	back->hDC = tmp;
    }

    {
	BOOL tmp = front->dc_in_use;
	front->dc_in_use = back->dc_in_use;
	back->dc_in_use = tmp;
    }

    {
	FLATPTR tmp = front->global.fpVidMem;
	front->global.fpVidMem = back->global.fpVidMem;
	back->global.fpVidMem = tmp;
    }

    {
	ULONG_PTR tmp = front->global_more.hKernelSurface;
	front->global_more.hKernelSurface = back->global_more.hKernelSurface;
	back->global_more.hKernelSurface = tmp;
    }

    return TRUE;
}

/* This is unnecessarely complicated :-) */
#define MEASUREMENT_WINDOW 5
#define NUMBER_OF_WINDOWS 10

static LONGLONG perf_freq;
static LONGLONG perf_storage[NUMBER_OF_WINDOWS];
static LONGLONG prev_time = 0;
static unsigned int current_window;
static unsigned int measurements_in_window;
static unsigned int valid_windows;

HRESULT WINAPI
Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
			    LPDIRECTDRAWSURFACE7 override, DWORD dwFlags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl* target;
    HRESULT hr;

    TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags);

    if (TRACE_ON(ddraw_fps)) {
	LONGLONG current_time;
	LONGLONG frame_duration;
	QueryPerformanceCounter((LARGE_INTEGER *) &current_time);

	if (prev_time != 0) {
	    LONGLONG total_time = 0;
	    int tot_meas;
	    
	    frame_duration = current_time - prev_time;
	    prev_time = current_time;
	    
	    perf_storage[current_window] += frame_duration;
	    measurements_in_window++;
	    
	    if (measurements_in_window >= MEASUREMENT_WINDOW) {
		current_window++;
		valid_windows++;

		if (valid_windows < NUMBER_OF_WINDOWS) {
		    unsigned int i;
		    tot_meas = valid_windows * MEASUREMENT_WINDOW;
		    for (i = 0; i < valid_windows; i++) {
			total_time += perf_storage[i];
		    }
		} else {
		    int i;
		    tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW;
		    for (i = 0; i < NUMBER_OF_WINDOWS; i++) {
			total_time += perf_storage[i];
		    }
		}

		TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time);
		
		if (current_window >= NUMBER_OF_WINDOWS) {
		    current_window = 0;
		}
		perf_storage[current_window] = 0;
		measurements_in_window = 0;
	    }
	} else {
	    prev_time = current_time;
	    memset(perf_storage, 0, sizeof(perf_storage));
	    current_window = 0;
	    valid_windows = 0;
	    measurements_in_window = 0;
	    QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq);
	}
    }
    
    /* MSDN: "This method can be called only for a surface that has the
     * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
    if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
	!= (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
	return DDERR_NOTFLIPPABLE;

    if (This->aux_flip)
	if (This->aux_flip(This->aux_ctx, This->aux_data))
	    return DD_OK;

    /* 1. find the flip target */
    /* XXX I don't think this algorithm works for more than 1 backbuffer. */
    if (override == NULL)
    {
	static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
	LPDIRECTDRAWSURFACE7 tgt;

	hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
	if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */

	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
			     tgt);
	IDirectDrawSurface7_Release(tgt);
    }
    else
    {
	BOOL on_chain = FALSE;
	IDirectDrawSurfaceImpl* surf;

	/* MSDN: "The method fails if the specified [override] surface is not
	 * a member of the flipping chain." */

	/* Verify that override is on this flip chain. We assume that
	 * surf is the head of the flipping chain, because it's the front
	 * buffer. */
	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
			     override);

	/* Either target is (indirectly) attached to This or This is
	 * (indirectly) attached to target. */
	for (surf = target; surf != NULL; surf = surf->surface_owner)
	{
	    if (surf == This)
	    {
		on_chain = TRUE;
		break;
	    }
	}

	if (!on_chain)
	    return DDERR_INVALIDPARAMS; /* unchecked */
    }

    TRACE("flip to backbuffer: %p\n",target);
    if (TRACE_ON(ddraw_flip)) {
	static unsigned int flip_count = 0;
	IDirectDrawPaletteImpl *palette;
	char buf[32];
	FILE *f;

	/* Hack for paletted games... */
	palette = target->palette;
	target->palette = This->palette;
	
	sprintf(buf, "flip_%08d.ppm", flip_count++);
	TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf);
	f = fopen(buf, "wb");
	DDRAW_dump_surface_to_disk(target, f, 8);
	target->palette = palette;
    }

    if (This->flip_data(This, target, dwFlags))
	This->flip_update(This, dwFlags);
    
    return DD_OK;
}

static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This,
				      REFGUID tag)
{
    PrivateData* data;
    for (data = This->private_data; data != NULL; data = data->next)
    {
	if (IsEqualGUID(&data->tag, tag)) break;
    }

    return data;
}

HRESULT WINAPI
Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    PrivateData *data;

    data = find_private_data(This, tag);
    if (data == NULL) return DDERR_NOTFOUND;

    if (data->prev)
	data->prev->next = data->next;
    if (data->next)
	data->next->prev = data->prev;

    if (data->flags & DDSPD_IUNKNOWNPTR)
    {
	if (data->ptr.object != NULL)
	    IUnknown_Release(data->ptr.object);
    }
    else
	HeapFree(GetProcessHeap(), 0, data->ptr.data);

    HeapFree(GetProcessHeap(), 0, data);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
					  LPDDSCAPS2 pCaps,
					  LPDIRECTDRAWSURFACE7* ppSurface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl* surf;
    IDirectDrawSurfaceImpl* found = NULL;
    DDSCAPS2 our_caps;
    
    if (TRACE_ON(ddraw)) {
        TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2,
	      pCaps->dwCaps3, pCaps->dwCaps4, ppSurface);
	TRACE("   Caps are : "); DDRAW_dump_DDSCAPS2(pCaps); TRACE("\n");
    }

    our_caps = *pCaps;
    if ((This->ddraw_owner->local.dwLocalFlags & DDRAWILCL_DIRECTDRAW7) == 0) {
        /* As this is not a DirectDraw7 application, remove the garbage that some games
	   put in the new fields of the DDSCAPS2 structure. */
        our_caps.dwCaps2 = 0;
	our_caps.dwCaps3 = 0;
	our_caps.dwCaps4 = 0;
	if (TRACE_ON(ddraw)) {
	    TRACE("   Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps); TRACE("\n");
	}
    }
    
    for (surf = This->attached; surf != NULL; surf = surf->next_attached)
    {
        if (TRACE_ON(ddraw)) {
	    TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx \n",surf ,
		  surf->surface_desc.ddsCaps.dwCaps,
		  surf->surface_desc.ddsCaps.dwCaps2,
		  surf->surface_desc.ddsCaps.dwCaps3,
		  surf->surface_desc.ddsCaps.dwCaps4);
	    TRACE("   Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf->surface_desc.ddsCaps)); TRACE("\n");
	}
	if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
	    ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2))
	{
	    /* MSDN: "This method fails if more than one surface is attached
	     * that matches the capabilities requested." */
	    if (found != NULL)
            {
                FIXME("More than one attached surface matches requested caps.  What should we do here?\n");
                /* Previous code returned 'DDERR_NOTFOUND'.  That appears not
                   to be correct, given what 3DMark expects from MipMapped surfaces.
                   We shall just continue instead. */
            }

	    found = surf;
	}
    }

    if (found == NULL) {
        TRACE("Did not find any valid surface\n");
	return DDERR_NOTFOUND;
    }

    *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7);

    if (TRACE_ON(ddraw)) {
        TRACE("Returning surface %p with description : \n", *ppSurface);
	DDRAW_dump_surface_desc(&(found->surface_desc));
    }
    
    /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
    IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7));
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
{
    TRACE("(%p)->(%08lx)\n",iface,dwFlags);

    switch (dwFlags)
    {
    case DDGBS_CANBLT:
    case DDGBS_ISBLTDONE:
	return DD_OK;

    default:
	return DDERR_INVALIDPARAMS;
    }
}

HRESULT WINAPI
Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pCaps);
    *pCaps = This->surface_desc.ddsCaps;
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
				  LPDIRECTDRAWCLIPPER* ppClipper)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,ppClipper);
    if (This->clipper == NULL)
	return DDERR_NOCLIPPERATTACHED;

    *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
    IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper,
					     IDirectDrawClipper));
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags,
				   LPDDCOLORKEY pCKey)
{
    /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
     * isn't there? That's like saying that an int isn't there. (Which MS
     * has done in other docs.) */

    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
    if (TRACE_ON(ddraw)) {
        TRACE(" - colorkey flags : ");
	DDRAW_dump_colorkeyflag(dwFlags);
    }

    switch (dwFlags)
    {
    case DDCKEY_DESTBLT:
	*pCKey = This->surface_desc.ddckCKDestBlt;
	break;

    case DDCKEY_DESTOVERLAY:
	*pCKey = This->surface_desc.u3.ddckCKDestOverlay;
	break;

    case DDCKEY_SRCBLT:
	*pCKey = This->surface_desc.ddckCKSrcBlt;
	break;

    case DDCKEY_SRCOVERLAY:
	*pCKey = This->surface_desc.ddckCKSrcOverlay;
	break;

    default:
	return DDERR_INVALIDPARAMS;
    }

    return DD_OK;
}

/* XXX We need to do something with the DC if the surface gets lost. */
HRESULT WINAPI
Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
{
    DDSURFACEDESC2 ddsd;
    HRESULT hr;
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,phDC);
    CHECK_LOST(This);

    LOCK_OBJECT(This);

    if (This->dc_in_use)
    {
	UNLOCK_OBJECT(This);
	return DDERR_DCALREADYCREATED;
    }

    /* Lock as per MSDN.
     * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
     * thread has it locked, but GetDC does not. */
    ddsd.dwSize = sizeof(ddsd);
    hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0);
    if (FAILED(hr))
    {
	UNLOCK_OBJECT(This);
	return hr;
    }

    hr = This->get_dc(This, &This->hDC);
    if (SUCCEEDED(hr))
    {
	TRACE("returning %p\n",This->hDC);

	*phDC = This->hDC;
	This->dc_in_use = TRUE;
    }
    else WARN("No DC! Prepare for trouble\n");

    UNLOCK_OBJECT(This);
    return hr;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pDD);
    *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7);
    IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
{
    /* XXX: DDERR_INVALIDSURFACETYPE */

    TRACE("(%p)->(%08lx)\n",iface,dwFlags);
    switch (dwFlags)
    {
    case DDGFS_CANFLIP:
    case DDGFS_ISFLIPDONE:
	return DD_OK;

    default:
	return DDERR_INVALIDPARAMS;
    }
}

HRESULT WINAPI
Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pdwMaxLOD);
    CHECK_TEXTURE(This);

    *pdwMaxLOD = This->max_lod;
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
					  LPLONG pX, LPLONG pY)
{
    return DDERR_NOTAOVERLAYSURFACE;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
				  LPDIRECTDRAWPALETTE* ppPalette)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,ppPalette);
    if (This->palette == NULL)
	return DDERR_NOPALETTEATTACHED;

    *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
    IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette,
					     IDirectDrawPalette));
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
				      LPDDPIXELFORMAT pDDPixelFormat)
{
    /* What is DDERR_INVALIDSURFACETYPE for here? */
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pDDPixelFormat);
    DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
				   LPDWORD pdwPriority)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pdwPriority);
    CHECK_TEXTURE(This);

    *pdwPriority = This->priority;
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface,
				      REFGUID tag, LPVOID pBuffer,
				      LPDWORD pcbBufferSize)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    PrivateData* data;

    data = find_private_data(This, tag);
    if (data == NULL) return DDERR_NOTFOUND;

    /* This may not be right. */
    if ((data->flags & DDSPD_VOLATILE)
	&& data->uniqueness_value != This->uniqueness_value)
	return DDERR_EXPIRED;

    if (*pcbBufferSize < data->size)
    {
	*pcbBufferSize = data->size;
	return DDERR_MOREDATA;
    }

    if (data->flags & DDSPD_IUNKNOWNPTR)
    {
	*(LPUNKNOWN *)pBuffer = data->ptr.object;
	IUnknown_AddRef(data->ptr.object);
    }
    else
    {
	memcpy(pBuffer, data->ptr.data, data->size);
    }

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
				      LPDDSURFACEDESC2 pDDSD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pDDSD);
    if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) ||
    	(pDDSD->dwSize > sizeof(DDSURFACEDESC2))) {
	ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize);
	return DDERR_GENERIC;
    }

    DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc);
    if (TRACE_ON(ddraw)) {
      DDRAW_dump_surface_desc(pDDSD);
    }
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
					  LPDWORD pValue)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pValue);
    *pValue = This->uniqueness_value;
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
				  LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD)
{
    TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD);
    return DDERR_ALREADYINITIALIZED;
}

HRESULT WINAPI
Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not"));
    return This->lost ? DDERR_SURFACELOST : DD_OK;
}


/* XXX This doesn't actually do any locking or keep track of the locked
 * rectangles. The behaviour is poorly documented. */
HRESULT WINAPI
Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
			    LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    if (TRACE_ON(ddraw)) {
        TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",This,prect,pDDSD,flags,(DWORD)h);
	TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags);
    }
    if (WARN_ON(ddraw)) {
	if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) {
	    WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY));
	}
    }

    /* First, copy the Surface description */
    DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc));

    /* Used to optimize the D3D Device locking */
    This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY);
    
    /* If asked only for a part, change the surface pointer.
     * (Not documented.) */
    if (prect != NULL) {
	TRACE("	lprect: %ldx%ld-%ldx%ld\n",
		prect->left,prect->top,prect->right,prect->bottom);
	/* First do some sanity checkings on the rectangle we receive.
	   DungeonSiege seems to gives us once a very bad rectangle for example */
	if ((prect->top < 0) ||
	    (prect->left < 0) ||
	    (prect->bottom < 0) ||
	    (prect->right < 0) ||
	    (prect->left >= prect->right) ||
	    (prect->top >= prect->bottom) ||
	    (prect->left >= This->surface_desc.dwWidth) ||
	    (prect->right > This->surface_desc.dwWidth) ||
	    (prect->top >= This->surface_desc.dwHeight) ||
	    (prect->bottom > This->surface_desc.dwHeight)) {
	    ERR(" Invalid values in LPRECT !!!\n");
	    return DDERR_INVALIDPARAMS;
	}

	This->lock_update(This, prect, flags);

	if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
	    int blksize;
	    switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) {
		case MAKE_FOURCC('D','X','T','1') : blksize = 8; break;
		case MAKE_FOURCC('D','X','T','3') : blksize = 16; break;
		case MAKE_FOURCC('D','X','T','5') : blksize = 16; break;
		default: return DDERR_INVALIDPIXELFORMAT;
	    }
	    pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
		+ prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize
	    	+ prect->left/4 * blksize;
	} else
	    pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
		+ prect->top * This->surface_desc.u1.lPitch
		+ prect->left * GET_BPP(This->surface_desc);
    } else {
	This->lock_update(This, NULL, flags);
    }

    TRACE("locked surface returning description : \n");
    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD);
    
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
{
    /* Some surface types should return DDERR_CANTPAGELOCK. */
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
{
    /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
     * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
{
    HRESULT hr;
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,hDC);

    if (!This->dc_in_use || This->hDC != hDC)
	return DDERR_INVALIDPARAMS;

    This->release_dc(This, hDC);

    hr = IDirectDrawSurface7_Unlock(iface, NULL);
    if (FAILED(hr)) return hr;

    This->dc_in_use = FALSE;
    This->hDC = 0;

    return DD_OK;
}

/* Restore */

HRESULT WINAPI
Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
				  LPDIRECTDRAWCLIPPER pDDClipper)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,pDDClipper);
    if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper))
	return DD_OK;

    if (This->clipper != NULL)
	IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
						  IDirectDrawClipper));

    This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
				pDDClipper);
    if (pDDClipper != NULL)
	IDirectDrawClipper_AddRef(pDDClipper);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
				   DWORD dwFlags, LPDDCOLORKEY pCKey)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    
    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);

    if (TRACE_ON(ddraw)) {
        TRACE(" - colorkey flags : ");
	DDRAW_dump_colorkeyflag(dwFlags);
    }

    if ((dwFlags & DDCKEY_COLORSPACE) != 0) {
        FIXME(" colorkey value not supported (%08lx) !\n", dwFlags);
	return DDERR_INVALIDPARAMS;
    }
    
    /* TODO: investigate if this function can take multiple bits set at the same
             time (ie setting multiple colorkey values at the same time with only
	     one API call).
    */
    if (pCKey) {
        switch (dwFlags & ~DDCKEY_COLORSPACE) {
	    case DDCKEY_DESTBLT:
	        This->surface_desc.ddckCKDestBlt = *pCKey;
		This->surface_desc.dwFlags |= DDSD_CKDESTBLT;
		break;

	    case DDCKEY_DESTOVERLAY:
	        This->surface_desc.u3.ddckCKDestOverlay = *pCKey;
		This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
		break;

	    case DDCKEY_SRCOVERLAY:
	        This->surface_desc.ddckCKSrcOverlay = *pCKey;
		This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
		break;

	    case DDCKEY_SRCBLT:
	        This->surface_desc.ddckCKSrcBlt = *pCKey;
		This->surface_desc.dwFlags |= DDSD_CKSRCBLT;
		break;

	    default:
	        return DDERR_INVALIDPARAMS;
	}
    } else {
        switch (dwFlags & ~DDCKEY_COLORSPACE) {
	    case DDCKEY_DESTBLT:
		This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT;
		break;

	    case DDCKEY_DESTOVERLAY:
		This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY;
		break;

	    case DDCKEY_SRCOVERLAY:
		This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY;
		break;

	    case DDCKEY_SRCBLT:
		This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT;
		break;

	    default:
	        return DDERR_INVALIDPARAMS;
	}
    }

    if (This->aux_setcolorkey_cb) This->aux_setcolorkey_cb(This, dwFlags, pCKey);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%08lx)\n",This,dwMaxLOD);
    CHECK_TEXTURE(This);

    This->max_lod = dwMaxLOD;
    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
					  LONG X, LONG Y)
{
    return DDERR_NOTAOVERLAYSURFACE;
}

HRESULT WINAPI
Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
				  LPDIRECTDRAWPALETTE pPalette)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawPalette *pal_to_rel = NULL;

    TRACE("(%p)->(%p)\n",This,pPalette);
    if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette))
	return DD_OK;

    if (This->palette != NULL) {
	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
	    This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE;
	pal_to_rel = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
    }

    This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
				pPalette);
    if (pPalette != NULL) {
	IDirectDrawPalette_AddRef(pPalette);
	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
	    This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE;
    }

    This->set_palette(This, This->palette);

    /* Do the palette release at the end to prevent doing some 'loop' when removing
     * the surface maintaining the last reference on a palette.
     */
    if (pal_to_rel != NULL)
	IDirectDrawPalette_Release(pal_to_rel);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
				   DWORD dwPriority)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->(%08lx)\n",This,dwPriority);
    CHECK_TEXTURE(This);

    This->priority = dwPriority;
    return DD_OK;
}

/* Be careful when locking this: it is risky to call the object's AddRef
 * or Release holding a lock. */
HRESULT WINAPI
Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
				      REFGUID tag, LPVOID pData,
				      DWORD cbSize, DWORD dwFlags)
{
    PrivateData* data;
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    data = find_private_data(This, tag);
    if (data == NULL)
    {
	data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
	if (data == NULL) return DDERR_OUTOFMEMORY;

	data->tag = *tag;
	data->flags = dwFlags;
	data->uniqueness_value = This->uniqueness_value;

	if (dwFlags & DDSPD_IUNKNOWNPTR)
	{
	    data->ptr.object = (LPUNKNOWN)pData;
	    data->size = sizeof(LPUNKNOWN);
	    IUnknown_AddRef(data->ptr.object);
	}
	else
	{
	    data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize);
	    if (data->ptr.data == NULL)
	    {
		HeapFree(GetProcessHeap(), 0, data);
		return DDERR_OUTOFMEMORY;
	    }
	}

	/* link it in */
	data->next = This->private_data;
	data->prev = NULL;
	if (This->private_data)
	    This->private_data->prev = data;
	This->private_data = data;

	return DD_OK;
    }
    else
    {
	/* I don't actually know how windows handles this case. The only
	 * reason I don't just call FreePrivateData is because I want to
	 * guarantee SetPrivateData working when using LPUNKNOWN or data
	 * that is no larger than the old data. */

	return E_FAIL;
    }
}

/* SetSurfaceDesc */

HRESULT WINAPI
Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    TRACE("(%p)->Unlock(%p)\n",This,pRect);

    This->unlock_update(This, pRect);
    if (This->aux_unlock)
	This->aux_unlock(This->aux_ctx, This->aux_data, pRect);

    return DD_OK;
}

HRESULT WINAPI
Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
				     LPRECT pSrcRect,
				     LPDIRECTDRAWSURFACE7 pDstSurface,
				     LPRECT pDstRect, DWORD dwFlags,
				     LPDDOVERLAYFX pFX)
{
    return DDERR_UNSUPPORTED;
}

/* MSDN: "not currently implemented." */
HRESULT WINAPI
Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
					    DWORD dwFlags)
{
    return DDERR_UNSUPPORTED;
}

HRESULT WINAPI
Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
					   DWORD dwFlags,
					   LPDIRECTDRAWSURFACE7 pDDSRef)
{
    return DDERR_NOTAOVERLAYSURFACE;
}
