/* DirectDraw Surface Implementation
 *
 * Copyright (c) 1997-2000 Marcus Meissner
 * Copyright (c) 1998-2000 Lionel Ulmer
 * Copyright (c) 2000-2001 TransGaming Technologies Inc.
 * Copyright (c) 2006 Stefan Dösinger
 *
 * This file contains the (internal) driver registration functions,
 * driver enumeration APIs and DirectDraw creation functions.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

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

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wingdi.h"
#include "wine/exception.h"

#include "ddraw.h"
#include "d3d.h"

#include "ddraw_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

/*****************************************************************************
 * IUnknown parts follow
 *****************************************************************************/

/*****************************************************************************
 * IDirectDrawSurface7::QueryInterface
 *
 * A normal QueryInterface implementation. For QueryInterface rules
 * see ddraw.c, IDirectDraw7::QueryInterface. This method
 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
 * in all versions, the IDirectDrawGammaControl interface and it can
 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
 *
 * Params:
 *  riid: The interface id queried for
 *  obj: Address to write the pointer to
 *
 * Returns:
 *  S_OK on success
 *  E_NOINTERFACE if the requested interface wasn't found
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface,
                                      REFIID riid,
                                      void **obj)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
    *obj = NULL;

    if(!riid)
        return DDERR_INVALIDPARAMS;

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj);
    if (IsEqualGUID(riid, &IID_IUnknown)
     || IsEqualGUID(riid, &IID_IDirectDrawSurface7)
     || IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
    {
        IUnknown_AddRef(iface);
        *obj = iface;
        TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface2)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface) )
    {
        IUnknown_AddRef(iface);
        *obj = &This->IDirectDrawSurface3_vtbl;
        TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) )
    {
        IUnknown_AddRef(iface);
        *obj = &This->IDirectDrawGammaControl_vtbl;
        TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_D3DDEVICE_WineD3D) ||
             IsEqualGUID(riid, &IID_IDirect3DHALDevice)||
             IsEqualGUID(riid, &IID_IDirect3DRGBDevice) )
    {
        IDirect3DDevice7 *d3d;

        /* Call into IDirect3D7 for creation */
        IDirect3D7_CreateDevice((IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl, riid, (IDirectDrawSurface7 *)This, &d3d);

        *obj = d3d ? (IDirect3DDevice *)&((IDirect3DDeviceImpl *)d3d)->IDirect3DDevice_vtbl : NULL;
        TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);

        return S_OK;
    }
    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
             IsEqualGUID( &IID_IDirect3DTexture2, riid ))
    {
        if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
        {
            *obj = &This->IDirect3DTexture_vtbl;
            TRACE(" returning Direct3DTexture interface at %p.\n", *obj);
        }
        else
        {
            *obj = &This->IDirect3DTexture2_vtbl;
            TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj);
        }
        IUnknown_AddRef( (IUnknown *) *obj);
        return S_OK;
    }

    ERR("No interface\n");
    return E_NOINTERFACE;
}

/*****************************************************************************
 * IDirectDrawSurface7::AddRef
 *
 * A normal addref implementation
 *
 * Returns:
 *  The new refcount
 *
 *****************************************************************************/
static ULONG WINAPI
IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7 *iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    if (refCount == 1 && This->WineD3DSurface)
    {
        EnterCriticalSection(&ddraw_cs);
        IWineD3DSurface_AddRef(This->WineD3DSurface);
        LeaveCriticalSection(&ddraw_cs);
    }

    TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
    return refCount;
}

/*****************************************************************************
 * IDirectDrawSurfaceImpl_Destroy
 *
 * A helper function for IDirectDrawSurface7::Release
 *
 * Frees the surface, regardless of its refcount.
 *  See IDirectDrawSurface7::Release for more information
 *
 * Params:
 *  This: Surface to free
 *
 *****************************************************************************/
void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This)
{
    TRACE("(%p)\n", This);

    /* Check the refcount and give a warning */
    if(This->ref > 1)
    {
        /* This can happen when a complex surface is destroyed,
         * because the 2nd surface was addref()ed when the app
         * called GetAttachedSurface
         */
        WARN("(%p): Destroying surface with refount %d\n", This, This->ref);
    }

    /* Check for attached surfaces and detach them */
    if(This->first_attached != This)
    {
        /* Well, this shouldn't happen: The surface being attached is addref()ed
          * in AddAttachedSurface, so it shouldn't be released until DeleteAttachedSurface
          * is called, because the refcount is held. It looks like the app released()
          * it often enough to force this
          */
        IDirectDrawSurface7 *root = (IDirectDrawSurface7 *)This->first_attached;
        IDirectDrawSurface7 *detach = (IDirectDrawSurface7 *)This;

        FIXME("(%p) Freeing a surface that is attached to surface %p\n", This, This->first_attached);

        /* The refcount will drop to -1 here */
        if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK)
        {
            ERR("(%p) DeleteAttachedSurface failed!\n", This);
        }
    }

    while(This->next_attached != NULL)
    {
        IDirectDrawSurface7 *root = (IDirectDrawSurface7 *)This;
        IDirectDrawSurface7 *detach = (IDirectDrawSurface7 *)This->next_attached;

        if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK)
        {
            ERR("(%p) DeleteAttachedSurface failed!\n", This);
            assert(0);
        }
    }

    /* Now destroy the surface. Wait: It could have been released if we are a texture */
    if(This->WineD3DSurface)
        IWineD3DSurface_Release(This->WineD3DSurface);

    /* Having a texture handle set implies that the device still exists */
    if(This->Handle)
    {
        This->ddraw->d3ddevice->Handles[This->Handle - 1].ptr = NULL;
        This->ddraw->d3ddevice->Handles[This->Handle - 1].type = DDrawHandle_Unknown;
    }

    /* Reduce the ddraw surface count */
    InterlockedDecrement(&This->ddraw->surfaces);
    list_remove(&This->surface_list_entry);

    HeapFree(GetProcessHeap(), 0, This);
}

/*****************************************************************************
 * IDirectDrawSurface7::Release
 *
 * Reduces the surface's refcount by 1. If the refcount falls to 0, the
 * surface is destroyed.
 *
 * Destroying the surface is a bit tricky. For the connection between
 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
 * It has a nice graph explaining the connection.
 *
 * What happens here is basically this:
 * When a surface is destroyed, its WineD3DSurface is released,
 * and the refcount of the DirectDraw interface is reduced by 1. If it has
 * complex surfaces attached to it, then these surfaces are destroyed too,
 * regardless of their refcount. If any surface being destroyed has another
 * surface attached to it (with a "soft" attachment, not complex), then
 * this surface is detached with DeleteAttachedSurface.
 *
 * When the surface is a texture, the WineD3DTexture is released.
 * If the surface is the Direct3D render target, then the D3D
 * capabilities of the WineD3DDevice are uninitialized, which causes the
 * swapchain to be released.
 *
 * When a complex sublevel falls to ref zero, then this is ignored.
 *
 * Returns:
 *  The new refcount
 *
 *****************************************************************************/
static ULONG WINAPI
IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    ULONG ref;
    TRACE("(%p) : Releasing from %d\n", This, This->ref);
    ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {

        IDirectDrawSurfaceImpl *surf;
        IDirectDrawImpl *ddraw;
        IUnknown *ifaceToRelease = This->ifaceToRelease;
        UINT i;

        /* Complex attached surfaces are destroyed implicitly when the root is released */
        EnterCriticalSection(&ddraw_cs);
        if(!This->is_complex_root)
        {
            WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This);
            LeaveCriticalSection(&ddraw_cs);
            return ref;
        }
        ddraw = This->ddraw;

        /* If it's a texture, destroy the WineD3DTexture.
         * WineD3D will destroy the IParent interfaces
         * of the sublevels, which destroys the WineD3DSurfaces.
         * Set the surfaces to NULL to avoid destroying them again later
         */
        if(This->wineD3DTexture)
        {
            IWineD3DBaseTexture_Release(This->wineD3DTexture);
        }
        /* If it's the RenderTarget, destroy the d3ddevice */
        else if(This->wineD3DSwapChain)
        {
            if((ddraw->d3d_initialized) && (This == ddraw->d3d_target)) {
                TRACE("(%p) Destroying the render target, uninitializing D3D\n", This);

                /* Unset any index buffer, just to be sure */
                IWineD3DDevice_SetIndexBuffer(ddraw->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
                IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL);
                IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL);
                for(i = 0; i < ddraw->numConvertedDecls; i++)
                {
                    IWineD3DVertexDeclaration_Release(ddraw->decls[i].decl);
                }
                HeapFree(GetProcessHeap(), 0, ddraw->decls);
                ddraw->numConvertedDecls = 0;

                if (FAILED(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroySwapChain)))
                {
                    /* Not good */
                    ERR("(%p) Failed to uninit 3D\n", This);
                }
                else
                {
                    /* Free the d3d window if one was created */
                    if(ddraw->d3d_window != 0 && ddraw->d3d_window != ddraw->dest_window)
                    {
                        TRACE(" (%p) Destroying the hidden render window %p\n", This, ddraw->d3d_window);
                        DestroyWindow(ddraw->d3d_window);
                        ddraw->d3d_window = 0;
                    }
                    /* Unset the pointers */
                }

                This->wineD3DSwapChain = NULL; /* Uninit3D releases the swapchain */
                ddraw->d3d_initialized = FALSE;
                ddraw->d3d_target = NULL;
            } else {
                IWineD3DDevice_UninitGDI(ddraw->wineD3DDevice, D3D7CB_DestroySwapChain);
                This->wineD3DSwapChain = NULL;
            }

            /* Reset to the default surface implementation type. This is needed if apps use
             * non render target surfaces and expect blits to work after destroying the render
             * target.
             *
             * TODO: Recreate existing offscreen surfaces
             */
            ddraw->ImplType = DefaultSurfaceType;

            /* Write a trace because D3D unloading was the reason for many
             * crashes during development.
             */
            TRACE("(%p) D3D unloaded\n", This);
        }

        /* The refcount test shows that the palette is detached when the surface is destroyed */
        IDirectDrawSurface7_SetPalette((IDirectDrawSurface7 *)This, NULL);

        /* Loop through all complex attached surfaces,
         * and destroy them.
         *
         * Yet again, only the root can have more than one complexly attached surface, all the others
         * have a total of one;
         */
        for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
        {
            if(!This->complex_array[i]) break;

            surf = This->complex_array[i];
            This->complex_array[i] = NULL;
            while(surf)
            {
                IDirectDrawSurfaceImpl *destroy = surf;
                surf = surf->complex_array[0];              /* Iterate through the "tree" */
                IDirectDrawSurfaceImpl_Destroy(destroy);    /* Destroy it */
            }
        }

        /* Destroy the root surface.
         */
        IDirectDrawSurfaceImpl_Destroy(This);

        /* Reduce the ddraw refcount */
        if(ifaceToRelease) IUnknown_Release(ifaceToRelease);
        LeaveCriticalSection(&ddraw_cs);
    }

    return ref;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetAttachedSurface
 *
 * Returns an attached surface with the requested caps. Surface attachment
 * and complex surfaces are not clearly described by the MSDN or sdk,
 * so this method is tricky and likely to contain problems.
 * This implementation searches the complex list first, then the
 * attachment chain.
 *
 * The chains are searched from This down to the last surface in the chain,
 * not from the first element in the chain. The first surface found is
 * returned. The MSDN says that this method fails if more than one surface
 * matches the caps, but it is not sure if that is right. The attachment
 * structure may not even allow two matching surfaces.
 *
 * The found surface is AddRef-ed before it is returned.
 *
 * Params:
 *  Caps: Pointer to a DDCAPS2 structure describing the caps asked for
 *  Surface: Address to store the found surface
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if Caps or Surface is NULL
 *  DDERR_NOTFOUND if no surface was found
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface,
                                          DDSCAPS2 *Caps,
                                          IDirectDrawSurface7 **Surface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *surf;
    DDSCAPS2 our_caps;
    int i;

    TRACE("(%p)->(%p,%p)\n", This, Caps, Surface);
    EnterCriticalSection(&ddraw_cs);

    if(This->version < 7)
    {
        /* Earlier dx apps put garbage into these members, clear them */
        our_caps.dwCaps = Caps->dwCaps;
        our_caps.dwCaps2 = 0;
        our_caps.dwCaps3 = 0;
        our_caps.dwCaps4 = 0;
    }
    else
    {
        our_caps = *Caps;
    }

    TRACE("(%p): Looking for caps: %x,%x,%x,%x\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.dwCaps4); /* FIXME: Better debugging */

    for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
    {
        surf = This->complex_array[i];
        if(!surf) break;

        if (TRACE_ON(ddraw))
        {
            TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf,
                   surf->surface_desc.ddsCaps.dwCaps,
                   surf->surface_desc.ddsCaps.dwCaps2,
                   surf->surface_desc.ddsCaps.dwCaps3,
                   surf->surface_desc.ddsCaps.dwCaps4);
        }

        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."
             *
             * Not sure how to test this.
             */

            TRACE("(%p): Returning surface %p\n", This, surf);
            TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level);
            *Surface = (IDirectDrawSurface7 *)surf;
            IDirectDrawSurface7_AddRef(*Surface);
            LeaveCriticalSection(&ddraw_cs);
            return DD_OK;
        }
    }

    /* Next, look at the attachment chain */
    surf = This;

    while( (surf = surf->next_attached) )
    {
        if (TRACE_ON(ddraw))
        {
            TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf,
                   surf->surface_desc.ddsCaps.dwCaps,
                   surf->surface_desc.ddsCaps.dwCaps2,
                   surf->surface_desc.ddsCaps.dwCaps3,
                   surf->surface_desc.ddsCaps.dwCaps4);
        }

        if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
            ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {

            TRACE("(%p): Returning surface %p\n", This, surf);
            *Surface = (IDirectDrawSurface7 *)surf;
            IDirectDrawSurface7_AddRef(*Surface);
            LeaveCriticalSection(&ddraw_cs);
            return DD_OK;
        }
    }

    TRACE("(%p) Didn't find a valid surface\n", This);
    LeaveCriticalSection(&ddraw_cs);

    *Surface = NULL;
    return DDERR_NOTFOUND;
}

/*****************************************************************************
 * IDirectDrawSurface7::Lock
 *
 * Locks the surface and returns a pointer to the surface's memory
 *
 * Params:
 *  Rect: Rectangle to lock. If NULL, the whole surface is locked
 *  DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
 *  Flags: Locking flags, e.g Read only or write only
 *  h: An event handle that's not used and must be NULL
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if DDSD is NULL
 *  For more details, see IWineD3DSurface::LockRect
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface,
                            RECT *Rect,
                            DDSURFACEDESC2 *DDSD,
                            DWORD Flags,
                            HANDLE h)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    WINED3DLOCKED_RECT LockedRect;
    HRESULT hr;
    TRACE("(%p)->(%p,%p,%x,%p)\n", This, Rect, DDSD, Flags, h);

    if(!DDSD)
        return DDERR_INVALIDPARAMS;

    /* This->surface_desc.dwWidth and dwHeight are changeable, thus lock */
    EnterCriticalSection(&ddraw_cs);

    /* Should I check for the handle to be NULL?
     *
     * The DDLOCK flags and the D3DLOCK flags are equal
     * for the supported values. The others are ignored by WineD3D
     */

    if(DDSD->dwSize != sizeof(DDSURFACEDESC) &&
       DDSD->dwSize != sizeof(DDSURFACEDESC2))
    {
        WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", DDERR_INVALIDPARAMS);
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDPARAMS;
    }

    /* Windows zeroes this if the rect is invalid */
    DDSD->lpSurface = 0;

    if (Rect)
    {
        if ((Rect->left < 0)
                || (Rect->top < 0)
                || (Rect->left > Rect->right)
                || (Rect->top > Rect->bottom)
                || (Rect->right > This->surface_desc.dwWidth)
                || (Rect->bottom > This->surface_desc.dwHeight))
        {
            WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDPARAMS;
        }
    }

    hr = IWineD3DSurface_LockRect(This->WineD3DSurface,
                                  &LockedRect,
                                  Rect,
                                  Flags);
    if(hr != D3D_OK)
    {
        LeaveCriticalSection(&ddraw_cs);
        switch(hr)
        {
            /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more
             * specific error. But since IWineD3DSurface::LockRect returns that error in this
             * only occasion, keep d3d8 and d3d9 free from the return value override. There are
             * many different places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it
             * is much easier to do it in one place in ddraw
             */
            case WINED3DERR_INVALIDCALL:    return DDERR_SURFACEBUSY;
            default:                        return hr;
        }
    }

    /* Override the memory area. The pitch should be set already. Strangely windows
     * does not set the LPSURFACE flag on locked surfaces !?!.
     * DDSD->dwFlags |= DDSD_LPSURFACE;
     */
    This->surface_desc.lpSurface = LockedRect.pBits;
    DD_STRUCT_COPY_BYSIZE(DDSD,&(This->surface_desc));

    TRACE("locked surface returning description :\n");
    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD);

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::Unlock
 *
 * Unlocks an locked surface
 *
 * Params:
 *  Rect: Not used by this implementation
 *
 * Returns:
 *  D3D_OK on success
 *  For more details, see IWineD3DSurface::UnlockRect
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Unlock(IDirectDrawSurface7 *iface,
                              RECT *pRect)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%p)\n", This, pRect);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_UnlockRect(This->WineD3DSurface);
    if(SUCCEEDED(hr))
    {
        This->surface_desc.lpSurface = NULL;
    }
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::Flip
 *
 * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
 * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
 * the flip target is passed to WineD3D, even if the app didn't specify one
 *
 * Params:
 *  DestOverride: Specifies the surface that will become the new front
 *                buffer. If NULL, the current back buffer is used
 *  Flags: some DirectDraw flags, see include/ddraw.h
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_NOTFLIPPABLE if no flip target could be found
 *  DDERR_INVALIDOBJECT if the surface isn't a front buffer
 *  For more details, see IWineD3DSurface::Flip
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7 *iface,
                            IDirectDrawSurface7 *DestOverride,
                            DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Override = (IDirectDrawSurfaceImpl *)DestOverride;
    IDirectDrawSurface7 *Override7;
    HRESULT hr;
    TRACE("(%p)->(%p,%x)\n", This, DestOverride, Flags);

    /* Flip has to be called from a front buffer
     * What about overlay surfaces, AFAIK they can flip too?
     */
    if( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)) )
        return DDERR_INVALIDOBJECT; /* Unchecked */

    EnterCriticalSection(&ddraw_cs);

    /* WineD3D doesn't keep track of attached surface, so find the target */
    if(!Override)
    {
        DDSCAPS2 Caps;

        memset(&Caps, 0, sizeof(Caps));
        Caps.dwCaps |= DDSCAPS_BACKBUFFER;
        hr = IDirectDrawSurface7_GetAttachedSurface(iface, &Caps, &Override7);
        if(hr != DD_OK)
        {
            ERR("Can't find a flip target\n");
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_NOTFLIPPABLE; /* Unchecked */
        }
        Override = (IDirectDrawSurfaceImpl *)Override7;

        /* For the GetAttachedSurface */
        IDirectDrawSurface7_Release(Override7);
    }

    hr = IWineD3DSurface_Flip(This->WineD3DSurface,
                              Override->WineD3DSurface,
                              Flags);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::Blt
 *
 * Performs a blit on the surface
 *
 * Params:
 *  DestRect: Destination rectangle, can be NULL
 *  SrcSurface: Source surface, can be NULL
 *  SrcRect: Source rectangle, can be NULL
 *  Flags: Blt flags
 *  DDBltFx: Some extended blt parameters, connected to the flags
 *
 * Returns:
 *  D3D_OK on success
 *  See IWineD3DSurface::Blt for more details
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
                           RECT *DestRect,
                           IDirectDrawSurface7 *SrcSurface,
                           RECT *SrcRect,
                           DWORD Flags,
                           DDBLTFX *DDBltFx)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Src = (IDirectDrawSurfaceImpl *)SrcSurface;
    HRESULT hr;
    TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);

    /* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have
     * to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-)
     */
    if((Flags & DDBLT_KEYSRCOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYSRC)) {
        WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
        return DDERR_INVALIDPARAMS;
    }

    if((Flags & DDBLT_KEYDESTOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYDEST)) {
        WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
        return DDERR_INVALIDPARAMS;
    }

    /* Sizes can change, therefore hold the lock when testing the rectangles */
    EnterCriticalSection(&ddraw_cs);
    if(DestRect)
    {
        if(DestRect->top >= DestRect->bottom || DestRect->left >= DestRect->right ||
           DestRect->right > This->surface_desc.dwWidth ||
           DestRect->bottom > This->surface_desc.dwHeight)
        {
            WARN("Destination rectangle is invalid, returning DDERR_INVALIDRECT\n");
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDRECT;
        }
    }
    if(Src && SrcRect)
    {
        if(SrcRect->top >= SrcRect->bottom || SrcRect->left >=SrcRect->right ||
           SrcRect->right > Src->surface_desc.dwWidth ||
           SrcRect->bottom > Src->surface_desc.dwHeight)
        {
            WARN("Source rectangle is invalid, returning DDERR_INVALIDRECT\n");
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDRECT;
        }
    }

    if(Flags & DDBLT_KEYSRC && (!Src || !(Src->surface_desc.dwFlags & DDSD_CKSRCBLT))) {
        WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDPARAMS;
    }

    /* TODO: Check if the DDBltFx contains any ddraw surface pointers. If it does, copy the struct,
     * and replace the ddraw surfaces with the wined3d surfaces
     * So far no blitting operations using surfaces in the bltfx struct are supported anyway.
     */
    hr = IWineD3DSurface_Blt(This->WineD3DSurface,
                             DestRect,
                             Src ? Src->WineD3DSurface : NULL,
                             SrcRect,
                             Flags,
                             (WINEDDBLTFX *) DDBltFx,
                             WINED3DTEXF_POINT);

    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        case WINED3DERR_NOTAVAILABLE:       return DDERR_UNSUPPORTED;
        case WINED3DERR_WRONGTEXTUREFORMAT: return DDERR_INVALIDPIXELFORMAT;
        default:                            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::AddAttachedSurface
 *
 * Attaches a surface to another surface. How the surface attachments work
 * is not totally understood yet, and this method is prone to problems.
 * he surface that is attached is AddRef-ed.
 *
 * Tests with complex surfaces suggest that the surface attachments form a
 * tree, but no method to test this has been found yet.
 *
 * The attachment list consists of a first surface (first_attached) and
 * for each surface a pointer to the next attached surface (next_attached).
 * For the first surface, and a surface that has no attachments
 * first_attached points to the surface itself. A surface that has
 * no successors in the chain has next_attached set to NULL.
 *
 * Newly attached surfaces are attached right after the root surface.
 * If a surface is attached to a complex surface compound, it's attached to
 * the surface that the app requested, not the complex root. See
 * GetAttachedSurface for a description how surfaces are found.
 *
 * This is how the current implementation works, and it was coded by looking
 * at the needs of the applications.
 *
 * So far only Z-Buffer attachments are tested, and they are activated in
 * WineD3D. Mipmaps could be tricky to activate in WineD3D.
 * Back buffers should work in 2D mode, but they are not tested(They can be
 * attached in older iface versions). Rendering to the front buffer and
 * switching between that and double buffering is not yet implemented in
 * WineD3D, so for 3D it might have unexpected results.
 *
 * IDirectDrawSurfaceImpl_AddAttachedSurface is the real thing,
 * IDirectDrawSurface7Impl_AddAttachedSurface is a wrapper around it that
 * performs additional checks. Version 7 of this interface is much more restrictive
 * than its predecessors.
 *
 * Params:
 *  Attach: Surface to attach to iface
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
 *
 *****************************************************************************/
HRESULT WINAPI
IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl *This,
                                          IDirectDrawSurfaceImpl *Surf)
{
    TRACE("(%p)->(%p)\n", This, Surf);

    if(Surf == This)
        return DDERR_CANNOTATTACHSURFACE; /* unchecked */

    EnterCriticalSection(&ddraw_cs);

    /* Check if the surface is already attached somewhere */
    if( (Surf->next_attached != NULL) ||
        (Surf->first_attached != Surf) )
    {
        /* TODO: Test for the structure of the manual attachment. Is it a chain or a list?
         * What happens if one surface is attached to 2 different surfaces?
         */
        FIXME("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This, Surf, Surf->next_attached, Surf->first_attached);
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_SURFACEALREADYATTACHED;
    }

    /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
    Surf->next_attached = This->next_attached;
    Surf->first_attached = This->first_attached;
    This->next_attached = Surf;

    /* Check if the WineD3D depth stencil needs updating */
    if(This->ddraw->d3ddevice)
    {
        IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice);
    }

    IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)Surf);
    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

static HRESULT WINAPI
IDirectDrawSurface7Impl_AddAttachedSurface(IDirectDrawSurface7 *iface,
                                           IDirectDrawSurface7 *Attach)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Surf = (IDirectDrawSurfaceImpl *)Attach;

    /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
    if(!(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
    {

        WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
              Surf->surface_desc.ddsCaps.dwCaps);
        return DDERR_CANNOTATTACHSURFACE;
    }

    return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
                                                     Surf);
}
/*****************************************************************************
 * IDirectDrawSurface7::DeleteAttachedSurface
 *
 * Removes a surface from the attachment chain. The surface's refcount
 * is decreased by one after it has been removed
 *
 * Params:
 *  Flags: Some flags, not used by this implementation
 *  Attach: Surface to detach
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_SURFACENOTATTACHED if the surface isn't attached to
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7 *iface,
                                             DWORD Flags,
                                             IDirectDrawSurface7 *Attach)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Surf = (IDirectDrawSurfaceImpl *)Attach;
    IDirectDrawSurfaceImpl *Prev = This;
    TRACE("(%p)->(%08x,%p)\n", This, Flags, Surf);

    EnterCriticalSection(&ddraw_cs);
    if (!Surf || (Surf->first_attached != This) || (Surf == This) )
    {
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_CANNOTDETACHSURFACE;
    }

    /* 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 */
    }

    /* Find the predecessor of the detached surface */
    while(Prev)
    {
        if(Prev->next_attached == Surf) break;
        Prev = Prev->next_attached;
    }

    /* There must be a surface, otherwise there's a bug */
    assert(Prev != NULL);

    /* Unchain the surface */
    Prev->next_attached = Surf->next_attached;
    Surf->next_attached = NULL;
    Surf->first_attached = Surf;

    /* Check if the WineD3D depth stencil needs updating */
    if(This->ddraw->d3ddevice)
    {
        IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice);
    }

    IDirectDrawSurface7_Release(Attach);
    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::AddOverlayDirtyRect
 *
 * "This method is not currently implemented"
 *
 * Params:
 *  Rect: ?
 *
 * Returns:
 *  DDERR_UNSUPPORTED
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7 *iface,
                                           LPRECT Rect)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p)\n",This,Rect);

    /* MSDN says it's not implemented. I could forward it to WineD3D,
     * then we'd implement it, but I don't think that's a good idea
     * (Stefan Dösinger)
     */
#if 0
    return IWineD3DSurface_AddOverlayDirtyRect(This->WineD3DSurface, pRect);
#endif
    return DDERR_UNSUPPORTED; /* unchecked */
}

/*****************************************************************************
 * IDirectDrawSurface7::GetDC
 *
 * Returns a GDI device context for the surface
 *
 * Params:
 *  hdc: Address of a HDC variable to store the dc to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if hdc is NULL
 *  For details, see IWineD3DSurface::GetDC
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetDC(IDirectDrawSurface7 *iface,
                             HDC *hdc)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%p): Relay\n", This, hdc);

    if(!hdc)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetDC(This->WineD3DSurface,
                               hdc);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        /* Some, but not all errors set *hdc to NULL. E.g. DCALREADYCREATED does not
         * touch *hdc
         */
        case WINED3DERR_INVALIDCALL:
            if(hdc) *hdc = NULL;
            return DDERR_INVALIDPARAMS;

        default: return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::ReleaseDC
 *
 * Releases the DC that was constructed with GetDC
 *
 * Params:
 *  hdc: HDC to release
 *
 * Returns:
 *  DD_OK on success
 *  For more details, see IWineD3DSurface::ReleaseDC
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_ReleaseDC(IDirectDrawSurface7 *iface,
                                 HDC hdc)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%p): Relay\n", This, hdc);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_ReleaseDC(This->WineD3DSurface, hdc);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetCaps
 *
 * Returns the surface's caps
 *
 * Params:
 *  Caps: Address to write the caps to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if Caps is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetCaps(IDirectDrawSurface7 *iface,
                               DDSCAPS2 *Caps)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p)\n",This,Caps);

    if(!Caps)
        return DDERR_INVALIDPARAMS;

    *Caps = This->surface_desc.ddsCaps;
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetPriority
 *
 * Sets a texture priority for managed textures.
 *
 * Params:
 *  Priority: The new priority
 *
 * Returns:
 *  DD_OK on success
 *  For more details, see IWineD3DSurface::SetPriority
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetPriority(IDirectDrawSurface7 *iface, DWORD Priority)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%d): Relay!\n",This,Priority);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_SetPriority(This->WineD3DSurface, Priority);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetPriority
 *
 * Returns the surface's priority
 *
 * Params:
 *  Priority: Address of a variable to write the priority to
 *
 * Returns:
 *  D3D_OK on success
 *  DDERR_INVALIDPARAMS if Priority == NULL
 *  For more details, see IWineD3DSurface::GetPriority
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetPriority(IDirectDrawSurface7 *iface,
                                   DWORD *Priority)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p): Relay\n",This,Priority);

    if(!Priority)
    {
        return DDERR_INVALIDPARAMS;
    }

    EnterCriticalSection(&ddraw_cs);
    *Priority = IWineD3DSurface_GetPriority(This->WineD3DSurface);
    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetPrivateData
 *
 * Stores some data in the surface that is intended for the application's
 * use.
 *
 * Params:
 *  tag: GUID that identifies the data
 *  Data: Pointer to the private data
 *  Size: Size of the private data
 *  Flags: Some flags
 *
 * Returns:
 *  D3D_OK on success
 *  For more details, see IWineD3DSurface::SetPrivateData
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetPrivateData(IDirectDrawSurface7 *iface,
                                      REFGUID tag,
                                      void *Data,
                                      DWORD Size,
                                      DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%s,%p,%d,%x): Relay\n", This, debugstr_guid(tag), Data, Size, Flags);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_SetPrivateData(This->WineD3DSurface,
                                        tag,
                                        Data,
                                        Size,
                                        Flags);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
        default:                            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::GetPrivateData
 *
 * Returns the private data set with IDirectDrawSurface7::SetPrivateData
 *
 * Params:
 *  tag: GUID of the data to return
 *  Data: Address where to write the data to
 *  Size: Size of the buffer at Data
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if Data is NULL
 *  For more details, see IWineD3DSurface::GetPrivateData
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetPrivateData(IDirectDrawSurface7 *iface,
                                      REFGUID tag,
                                      void *Data,
                                      DWORD *Size)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%s,%p,%p): Relay\n", This, debugstr_guid(tag), Data, Size);

    if(!Data)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetPrivateData(This->WineD3DSurface,
                                        tag,
                                        Data,
                                        Size);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::FreePrivateData
 *
 * Frees private data stored in the surface
 *
 * Params:
 *  tag: Tag of the data to free
 *
 * Returns:
 *  D3D_OK on success
 *  For more details, see IWineD3DSurface::FreePrivateData
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_FreePrivateData(IDirectDrawSurface7 *iface,
                                       REFGUID tag)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%s): Relay\n", This, debugstr_guid(tag));

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_FreePrivateData(This->WineD3DSurface, tag);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::PageLock
 *
 * Prevents a sysmem surface from being paged out
 *
 * Params:
 *  Flags: Not used, must be 0(unchecked)
 *
 * Returns:
 *  DD_OK, because it's a stub
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_PageLock(IDirectDrawSurface7 *iface,
                                DWORD Flags)
{
    TRACE("(%p)->(%x)\n", iface, Flags);

    /* This is Windows memory management related - we don't need this */
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::PageUnlock
 *
 * Allows a sysmem surface to be paged out
 *
 * Params:
 *  Flags: Not used, must be 0(unchecked)
 *
 * Returns:
 *  DD_OK, because it's a stub
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_PageUnlock(IDirectDrawSurface7 *iface,
                                  DWORD Flags)
{
    TRACE("(%p)->(%x)\n", iface, Flags);

    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::BltBatch
 *
 * An unimplemented function
 *
 * Params:
 *  ?
 *
 * Returns:
 *  DDERR_UNSUPPORTED
 *
 *****************************************************************************/
static HRESULT WINAPI IDirectDrawSurfaceImpl_BltBatch(IDirectDrawSurface7 *iface, DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
{
    TRACE("(%p)->(%p,%d,%08x)\n",iface,Batch,Count,Flags);

    /* MSDN: "not currently implemented" */
    return DDERR_UNSUPPORTED;
}

/*****************************************************************************
 * IDirectDrawSurface7::EnumAttachedSurfaces
 *
 * Enumerates all surfaces attached to this surface
 *
 * Params:
 *  context: Pointer to pass unmodified to the callback
 *  cb: Callback function to call for each surface
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if cb is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7 *iface,
                                            void *context,
                                            LPDDENUMSURFACESCALLBACK7 cb)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *surf;
    DDSURFACEDESC2 desc;
    int i;

    /* Attached surfaces aren't handled in WineD3D */
    TRACE("(%p)->(%p,%p)\n",This,context,cb);

    if(!cb)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
    {
        surf = This->complex_array[i];
        if(!surf) break;

        IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surf);
        desc = surf->surface_desc;
        /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
        if (cb((IDirectDrawSurface7 *)surf, &desc, context) == DDENUMRET_CANCEL)
        {
            LeaveCriticalSection(&ddraw_cs);
            return DD_OK;
        }
    }

    for (surf = This->next_attached; surf != NULL; surf = surf->next_attached)
    {
        IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surf);
        desc = surf->surface_desc;
        /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
        if (cb((IDirectDrawSurface7 *)surf, &desc, context) == DDENUMRET_CANCEL)
        {
            LeaveCriticalSection(&ddraw_cs);
            return DD_OK;
        }
    }

    TRACE(" end of enumeration.\n");

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::EnumOverlayZOrders
 *
 * "Enumerates the overlay surfaces on the specified destination"
 *
 * Params:
 *  Flags: DDENUMOVERLAYZ_BACKTOFRONT  or DDENUMOVERLAYZ_FRONTTOBACK
 *  context: context to pass back to the callback
 *  cb: callback function to call for each enumerated surface
 *
 * Returns:
 *  DD_OK, because it's a stub
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_EnumOverlayZOrders(IDirectDrawSurface7 *iface,
                                          DWORD Flags,
                                          void *context,
                                          LPDDENUMSURFACESCALLBACK7 cb)
{
     FIXME("(%p)->(%x,%p,%p): Stub!\n", iface, Flags, context, cb);

    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetBltStatus
 *
 * Returns the blitting status
 *
 * Params:
 *  Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
 *
 * Returns:
 *  See IWineD3DSurface::Blt
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetBltStatus(IDirectDrawSurface7 *iface,
                                    DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%x): Relay\n", This, Flags);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetBltStatus(This->WineD3DSurface, Flags);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
        default:                            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::GetColorKey
 *
 * Returns the color key assigned to the surface
 *
 * Params:
 *  Flags: Some flags
 *  CKey: Address to store the key to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if CKey is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetColorKey(IDirectDrawSurface7 *iface,
                                   DWORD Flags,
                                   DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%08x,%p)\n", This, Flags, CKey);

    if(!CKey)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);

    switch (Flags)
    {
    case DDCKEY_DESTBLT:
        if (!(This->surface_desc.dwFlags & DDSD_CKDESTBLT))
        {
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_NOCOLORKEY;
        }
        *CKey = This->surface_desc.ddckCKDestBlt;
        break;

    case DDCKEY_DESTOVERLAY:
        if (!(This->surface_desc.dwFlags & DDSD_CKDESTOVERLAY))
            {
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_NOCOLORKEY;
            }
        *CKey = This->surface_desc.u3.ddckCKDestOverlay;
        break;

    case DDCKEY_SRCBLT:
        if (!(This->surface_desc.dwFlags & DDSD_CKSRCBLT))
        {
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_NOCOLORKEY;
        }
        *CKey = This->surface_desc.ddckCKSrcBlt;
        break;

    case DDCKEY_SRCOVERLAY:
        if (!(This->surface_desc.dwFlags & DDSD_CKSRCOVERLAY))
        {
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_NOCOLORKEY;
        }
        *CKey = This->surface_desc.ddckCKSrcOverlay;
        break;

    default:
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDPARAMS;
    }

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetFlipStatus
 *
 * Returns the flipping status of the surface
 *
 * Params:
 *  Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
 *
 * Returns:
 *  See IWineD3DSurface::GetFlipStatus
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetFlipStatus(IDirectDrawSurface7 *iface,
                                     DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%x): Relay\n", This, Flags);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetFlipStatus(This->WineD3DSurface, Flags);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
        default:                            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::GetOverlayPosition
 *
 * Returns the display coordinates of a visible and active overlay surface
 *
 * Params:
 *  X
 *  Y
 *
 * Returns:
 *  DDERR_NOTAOVERLAYSURFACE, because it's a stub
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetOverlayPosition(IDirectDrawSurface7 *iface,
                                          LONG *X,
                                          LONG *Y) {
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%p,%p): Relay\n", This, X, Y);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetOverlayPosition(This->WineD3DSurface,
                                            X,
                                            Y);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetPixelFormat
 *
 * Returns the pixel format of the Surface
 *
 * Params:
 *  PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
 *               format should be written
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if PixelFormat is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetPixelFormat(IDirectDrawSurface7 *iface,
                                      DDPIXELFORMAT *PixelFormat)
{
    /* What is DDERR_INVALIDSURFACETYPE for here? */
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p)\n",This,PixelFormat);

    if(!PixelFormat)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    DD_STRUCT_COPY_BYSIZE(PixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
    LeaveCriticalSection(&ddraw_cs);

    return DD_OK;
}


/*****************************************************************************
 * IDirectDrawSurface7::GetSurfaceDesc
 *
 * Returns the description of this surface
 *
 * Params:
 *  DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
 *        surface desc
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if DDSD is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetSurfaceDesc(IDirectDrawSurface7 *iface,
                                      DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

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

    if(!DDSD)
        return DDERR_INVALIDPARAMS;

    if (DDSD->dwSize != sizeof(DDSURFACEDESC2))
    {
        WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",DDSD->dwSize);
        return DDERR_INVALIDPARAMS;
    }

    EnterCriticalSection(&ddraw_cs);
    DD_STRUCT_COPY_BYSIZE(DDSD,&This->surface_desc);
    TRACE("Returning surface desc:\n");
    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD);

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::Initialize
 *
 * Initializes the surface. This is a no-op in Wine
 *
 * Params:
 *  DD: Pointer to an DirectDraw interface
 *  DDSD: Surface description for initialization
 *
 * Returns:
 *  DDERR_ALREADYINITIALIZED
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Initialize(IDirectDrawSurface7 *iface,
                                  IDirectDraw *DD,
                                  DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawImpl *ddimpl = DD ? ddraw_from_ddraw1(DD) : NULL;
    TRACE("(%p)->(%p,%p)\n",This,ddimpl,DDSD);

    return DDERR_ALREADYINITIALIZED;
}

/*****************************************************************************
 * IDirectDrawSurface7::IsLost
 *
 * Checks if the surface is lost
 *
 * Returns:
 *  DD_OK, if the surface is usable
 *  DDERR_ISLOST if the surface is lost
 *  See IWineD3DSurface::IsLost for more details
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_IsLost(IDirectDrawSurface7 *iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)\n", This);

    EnterCriticalSection(&ddraw_cs);
    /* We lose the surface if the implementation was changed */
    if(This->ImplType != This->ddraw->ImplType)
    {
        /* But this shouldn't happen. When we change the implementation,
         * all surfaces are re-created automatically, and their content
         * is copied
         */
        ERR(" (%p) Implementation was changed from %d to %d\n", This, This->ImplType, This->ddraw->ImplType);
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_SURFACELOST;
    }

    hr = IWineD3DSurface_IsLost(This->WineD3DSurface);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        /* D3D8 and 9 loose full devices, thus there's only a DEVICELOST error.
         * WineD3D uses the same error for surfaces
         */
        case WINED3DERR_DEVICELOST:         return DDERR_SURFACELOST;
        default:                            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::Restore
 *
 * Restores a lost surface. This makes the surface usable again, but
 * doesn't reload its old contents
 *
 * Returns:
 *  DD_OK on success
 *  See IWineD3DSurface::Restore for more details
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7 *iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)\n", This);

    EnterCriticalSection(&ddraw_cs);
    if(This->ImplType != This->ddraw->ImplType)
    {
        /* Call the recreation callback. Make sure to AddRef first */
        IDirectDrawSurface_AddRef(iface);
        IDirectDrawImpl_RecreateSurfacesCallback(iface,
                                                 &This->surface_desc,
                                                 NULL /* Not needed */);
    }
    hr = IWineD3DSurface_Restore(This->WineD3DSurface);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetOverlayPosition
 *
 * Changes the display coordinates of an overlay surface
 *
 * Params:
 *  X:
 *  Y:
 *
 * Returns:
 *   DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetOverlayPosition(IDirectDrawSurface7 *iface,
                                          LONG X,
                                          LONG Y)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%d,%d): Relay\n", This, X, Y);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_SetOverlayPosition(This->WineD3DSurface,
                                            X,
                                            Y);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::UpdateOverlay
 *
 * Modifies the attributes of an overlay surface.
 *
 * Params:
 *  SrcRect: The section of the source being used for the overlay
 *  DstSurface: Address of the surface that is overlaid
 *  DstRect: Place of the overlay
 *  Flags: some DDOVER_* flags
 *
 * Returns:
 *  DDERR_UNSUPPORTED, because we don't support overlays
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_UpdateOverlay(IDirectDrawSurface7 *iface,
                                     LPRECT SrcRect,
                                     IDirectDrawSurface7 *DstSurface,
                                     LPRECT DstRect,
                                     DWORD Flags,
                                     LPDDOVERLAYFX FX)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Dst = (IDirectDrawSurfaceImpl *)DstSurface;
    HRESULT hr;
    TRACE("(%p)->(%p,%p,%p,%x,%p): Relay\n", This, SrcRect, Dst, DstRect, Flags, FX);

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_UpdateOverlay(This->WineD3DSurface,
                                       SrcRect,
                                       Dst ? Dst->WineD3DSurface : NULL,
                                       DstRect,
                                       Flags,
                                       (WINEDDOVERLAYFX *) FX);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr) {
        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
        case WINEDDERR_NOTAOVERLAYSURFACE:  return DDERR_NOTAOVERLAYSURFACE;
        case WINEDDERR_OVERLAYNOTVISIBLE:   return DDERR_OVERLAYNOTVISIBLE;
        default:
            return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::UpdateOverlayDisplay
 *
 * The DX7 sdk says that it's not implemented
 *
 * Params:
 *  Flags: ?
 *
 * Returns: DDERR_UNSUPPORTED, because we don't support overlays
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_UpdateOverlayDisplay(IDirectDrawSurface7 *iface,
                                            DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%x)\n", This, Flags);
    return DDERR_UNSUPPORTED;
}

/*****************************************************************************
 * IDirectDrawSurface7::UpdateOverlayZOrder
 *
 * Sets an overlay's Z order
 *
 * Params:
 *  Flags: DDOVERZ_* flags
 *  DDSRef: Defines the relative position in the overlay chain
 *
 * Returns:
 *  DDERR_NOTOVERLAYSURFACE, because we don't support overlays
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_UpdateOverlayZOrder(IDirectDrawSurface7 *iface,
                                           DWORD Flags,
                                           IDirectDrawSurface7 *DDSRef)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *Ref = (IDirectDrawSurfaceImpl *)DDSRef;
    HRESULT hr;

    TRACE("(%p)->(%x,%p): Relay\n", This, Flags, Ref);
    EnterCriticalSection(&ddraw_cs);
    hr =  IWineD3DSurface_UpdateOverlayZOrder(This->WineD3DSurface,
                                              Flags,
                                              Ref ? Ref->WineD3DSurface : NULL);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetDDInterface
 *
 * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
 * surface belongs to
 *
 * Params:
 *  DD: Address to write the interface pointer to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if DD is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface,
                                      void **DD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

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

    if(!DD)
        return DDERR_INVALIDPARAMS;

    switch(This->version)
    {
        case 7:
            *DD = This->ddraw;
            break;

        case 4:
            *DD = &This->ddraw->IDirectDraw4_vtbl;
            break;

        case 2:
            *DD = &This->ddraw->IDirectDraw2_vtbl;
            break;

        case 1:
            *DD = &This->ddraw->IDirectDraw_vtbl;
            break;

    }
    IUnknown_AddRef((IUnknown *)*DD);

    return DD_OK;
}

/* This seems also windows implementation specific - I don't think WineD3D needs this */
static HRESULT WINAPI IDirectDrawSurfaceImpl_ChangeUniquenessValue(IDirectDrawSurface7 *iface)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    volatile IDirectDrawSurfaceImpl* vThis = This;

    TRACE("(%p)\n",This);
    EnterCriticalSection(&ddraw_cs);
    /* A uniqueness value of 0 is apparently special.
     * This needs to be checked.
     * TODO: Write tests for this code and check if the volatile, interlocked stuff is really needed
     */
    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;
    }

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurfaceImpl_GetUniquenessValue(IDirectDrawSurface7 *iface, LPDWORD pValue)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;

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

/*****************************************************************************
 * IDirectDrawSurface7::SetLOD
 *
 * Sets the level of detail of a texture
 *
 * Params:
 *  MaxLOD: LOD to set
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDOBJECT if the surface is invalid for this method
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetLOD(IDirectDrawSurface7 *iface,
                              DWORD MaxLOD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    HRESULT hr;
    TRACE("(%p)->(%d)\n", This, MaxLOD);

    EnterCriticalSection(&ddraw_cs);
    if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
    {
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDOBJECT;
    }

    if(!This->wineD3DTexture)
    {
        ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This);
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDOBJECT;
    }

    hr = IWineD3DBaseTexture_SetLOD(This->wineD3DTexture,
                                    MaxLOD);
    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetLOD
 *
 * Returns the level of detail of a Direct3D texture
 *
 * Params:
 *  MaxLOD: Address to write the LOD to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if MaxLOD is NULL
 *  DDERR_INVALIDOBJECT if the surface is invalid for this method
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetLOD(IDirectDrawSurface7 *iface,
                              DWORD *MaxLOD)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p)\n", This, MaxLOD);

    if(!MaxLOD)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
    {
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDOBJECT;
    }

    *MaxLOD = IWineD3DBaseTexture_GetLOD(This->wineD3DTexture);
    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::BltFast
 *
 * Performs a fast Blit.
 *
 * Params:
 *  dstx: The x coordinate to blit to on the destination
 *  dsty: The y coordinate to blit to on the destination
 *  Source: The source surface
 *  rsrc: The source rectangle
 *  trans: Type of transfer. Some DDBLTFAST_* flags
 *
 * Returns:
 *  DD_OK on success
 *  For more details, see IWineD3DSurface::BltFast
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7 *iface,
                               DWORD dstx,
                               DWORD dsty,
                               IDirectDrawSurface7 *Source,
                               RECT *rsrc,
                               DWORD trans)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)Source;
    DWORD src_w, src_h, dst_w, dst_h;
    HRESULT hr;
    TRACE("(%p)->(%d,%d,%p,%p,%d): Relay\n", This, dstx, dsty, Source, rsrc, trans);

    dst_w = This->surface_desc.dwWidth;
    dst_h = This->surface_desc.dwHeight;

    /* Source must be != NULL, This is not checked by windows. Windows happily throws a 0xc0000005
     * in that case
     */
    if(rsrc)
    {
        if(rsrc->top > rsrc->bottom || rsrc->left > rsrc->right ||
           rsrc->right > src->surface_desc.dwWidth ||
           rsrc->bottom > src->surface_desc.dwHeight)
        {
            WARN("Source rectangle is invalid, returning DDERR_INVALIDRECT\n");
            return DDERR_INVALIDRECT;
        }

        src_w = rsrc->right - rsrc->left;
        src_h = rsrc->bottom - rsrc->top;
    }
    else
    {
        src_w = src->surface_desc.dwWidth;
        src_h = src->surface_desc.dwHeight;
    }

    if (src_w > dst_w || dstx > dst_w - src_w
            || src_h > dst_h || dsty > dst_h - src_h)
    {
        WARN("Destination area out of bounds, returning DDERR_INVALIDRECT.\n");
        return DDERR_INVALIDRECT;
    }

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_BltFast(This->WineD3DSurface,
                                 dstx, dsty,
                                 src ? src->WineD3DSurface : NULL,
                                 rsrc,
                                 trans);
    LeaveCriticalSection(&ddraw_cs);
    switch(hr)
    {
        case WINED3DERR_NOTAVAILABLE:           return DDERR_UNSUPPORTED;
        case WINED3DERR_WRONGTEXTUREFORMAT:     return DDERR_INVALIDPIXELFORMAT;
        default:                                return hr;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::GetClipper
 *
 * Returns the IDirectDrawClipper interface of the clipper assigned to this
 * surface
 *
 * Params:
 *  Clipper: Address to store the interface pointer at
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if Clipper is NULL
 *  DDERR_NOCLIPPERATTACHED if there's no clipper attached
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetClipper(IDirectDrawSurface7 *iface,
                                  IDirectDrawClipper **Clipper)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    TRACE("(%p)->(%p)\n", This, Clipper);

    if(!Clipper)
    {
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_INVALIDPARAMS;
    }

    EnterCriticalSection(&ddraw_cs);
    if(This->clipper == NULL)
    {
        LeaveCriticalSection(&ddraw_cs);
        return DDERR_NOCLIPPERATTACHED;
    }

    *Clipper = (IDirectDrawClipper *)This->clipper;
    IDirectDrawClipper_AddRef(*Clipper);
    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetClipper
 *
 * Sets a clipper for the surface
 *
 * Params:
 *  Clipper: IDirectDrawClipper interface of the clipper to set
 *
 * Returns:
 *  DD_OK on success
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetClipper(IDirectDrawSurface7 *iface,
                                  IDirectDrawClipper *Clipper)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawClipperImpl *oldClipper = This->clipper;
    HWND clipWindow;
    HRESULT hr;
    TRACE("(%p)->(%p)\n",This,Clipper);

    EnterCriticalSection(&ddraw_cs);
    if ((IDirectDrawClipperImpl *)Clipper == This->clipper)
    {
        LeaveCriticalSection(&ddraw_cs);
        return DD_OK;
    }

    This->clipper = (IDirectDrawClipperImpl *)Clipper;

    if (Clipper != NULL)
        IDirectDrawClipper_AddRef(Clipper);
    if(oldClipper)
        IDirectDrawClipper_Release((IDirectDrawClipper *)oldClipper);

    hr = IWineD3DSurface_SetClipper(This->WineD3DSurface, This->clipper ? This->clipper->wineD3DClipper : NULL);

    if(This->wineD3DSwapChain) {
        clipWindow = NULL;
        if(Clipper) {
            IDirectDrawClipper_GetHWnd(Clipper, &clipWindow);
        }

        if(clipWindow) {
            IWineD3DSwapChain_SetDestWindowOverride(This->wineD3DSwapChain,
                                                    clipWindow);
        } else {
            IWineD3DSwapChain_SetDestWindowOverride(This->wineD3DSwapChain,
                                                    This->ddraw->d3d_window);
        }
    }

    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetSurfaceDesc
 *
 * Sets the surface description. It can override the pixel format, the surface
 * memory, ...
 * It's not really tested.
 *
 * Params:
 * DDSD: Pointer to the new surface description to set
 * Flags: Some flags
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if DDSD is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7 *iface,
                                      DDSURFACEDESC2 *DDSD,
                                      DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    WINED3DFORMAT newFormat = WINED3DFMT_UNKNOWN;
    HRESULT hr;
    TRACE("(%p)->(%p,%x)\n", This, DDSD, Flags);

    if(!DDSD)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    if (DDSD->dwFlags & DDSD_PIXELFORMAT)
    {
        newFormat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);

        if(newFormat == WINED3DFMT_UNKNOWN)
        {
            ERR("Requested to set an unknown pixelformat\n");
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDPARAMS;
        }
        if(newFormat != PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat) )
        {
            hr = IWineD3DSurface_SetFormat(This->WineD3DSurface,
                                           newFormat);
            if(hr != DD_OK)
            {
                LeaveCriticalSection(&ddraw_cs);
                return hr;
            }
        }
    }
    if (DDSD->dwFlags & DDSD_CKDESTOVERLAY)
    {
        IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                    DDCKEY_DESTOVERLAY,
                                    (WINEDDCOLORKEY *) &DDSD->u3.ddckCKDestOverlay);
    }
    if (DDSD->dwFlags & DDSD_CKDESTBLT)
    {
        IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                    DDCKEY_DESTBLT,
                                    (WINEDDCOLORKEY *) &DDSD->ddckCKDestBlt);
    }
    if (DDSD->dwFlags & DDSD_CKSRCOVERLAY)
    {
        IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                    DDCKEY_SRCOVERLAY,
                                    (WINEDDCOLORKEY *) &DDSD->ddckCKSrcOverlay);
    }
    if (DDSD->dwFlags & DDSD_CKSRCBLT)
    {
        IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                    DDCKEY_SRCBLT,
                                    (WINEDDCOLORKEY *) &DDSD->ddckCKSrcBlt);
    }
    if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface)
    {
        hr = IWineD3DSurface_SetMem(This->WineD3DSurface, DDSD->lpSurface);
        if(hr != WINED3D_OK)
        {
            /* No need for a trace here, wined3d does that for us */
            switch(hr)
            {
                case WINED3DERR_INVALIDCALL:
                    LeaveCriticalSection(&ddraw_cs);
                    return DDERR_INVALIDPARAMS;
                default:
                    break; /* Go on */
            }
        }
    }

    This->surface_desc = *DDSD;

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::GetPalette
 *
 * Returns the IDirectDrawPalette interface of the palette currently assigned
 * to the surface
 *
 * Params:
 *  Pal: Address to write the interface pointer to
 *
 * Returns:
 *  DD_OK on success
 *  DDERR_INVALIDPARAMS if Pal is NULL
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7 *iface,
                                  IDirectDrawPalette **Pal)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IWineD3DPalette *wPal;
    HRESULT hr;
    TRACE("(%p)->(%p): Relay\n", This, Pal);

    if(!Pal)
        return DDERR_INVALIDPARAMS;

    EnterCriticalSection(&ddraw_cs);
    hr = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wPal);
    if(hr != DD_OK)
    {
        LeaveCriticalSection(&ddraw_cs);
        return hr;
    }

    if(wPal)
    {
        hr = IWineD3DPalette_GetParent(wPal, (IUnknown **) Pal);
    }
    else
    {
        *Pal = NULL;
        hr = DDERR_NOPALETTEATTACHED;
    }

    LeaveCriticalSection(&ddraw_cs);
    return hr;
}

/*****************************************************************************
 * SetColorKeyEnum
 *
 * EnumAttachedSurface callback for SetColorKey. Used to set color keys
 * recursively in the surface tree
 *
 *****************************************************************************/
struct SCKContext
{
    HRESULT ret;
    WINEDDCOLORKEY *CKey;
    DWORD Flags;
};

static HRESULT WINAPI
SetColorKeyEnum(IDirectDrawSurface7 *surface,
                DDSURFACEDESC2 *desc,
                void *context)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)surface;
    struct SCKContext *ctx = context;
    HRESULT hr;

    hr = IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                     ctx->Flags,
                                     ctx->CKey);
    if(hr != DD_OK)
    {
        WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr);
        ctx->ret = hr;
    }

    IDirectDrawSurface7_EnumAttachedSurfaces(surface,
                                             context,
                                             SetColorKeyEnum);
    IDirectDrawSurface7_Release(surface);
    return DDENUMRET_OK;
}

/*****************************************************************************
 * IDirectDrawSurface7::SetColorKey
 *
 * Sets the color keying options for the surface. Observations showed that
 * in case of complex surfaces the color key has to be assigned to all
 * sublevels.
 *
 * Params:
 *  Flags: DDCKEY_*
 *  CKey: The new color key
 *
 * Returns:
 *  DD_OK on success
 *  See IWineD3DSurface::SetColorKey for details
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7 *iface,
                                   DWORD Flags,
                                   DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    DDCOLORKEY FixedCKey;
    struct SCKContext ctx = { DD_OK, (WINEDDCOLORKEY *) (CKey ? &FixedCKey : NULL), Flags };
    TRACE("(%p)->(%x,%p)\n", This, Flags, CKey);

    EnterCriticalSection(&ddraw_cs);
    if (CKey)
    {
        FixedCKey = *CKey;
        /* Handle case where dwColorSpaceHighValue < dwColorSpaceLowValue */
        if (FixedCKey.dwColorSpaceHighValue < FixedCKey.dwColorSpaceLowValue)
            FixedCKey.dwColorSpaceHighValue = FixedCKey.dwColorSpaceLowValue;

        switch (Flags & ~DDCKEY_COLORSPACE)
        {
        case DDCKEY_DESTBLT:
            This->surface_desc.ddckCKDestBlt = FixedCKey;
            This->surface_desc.dwFlags |= DDSD_CKDESTBLT;
            break;

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

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

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

        default:
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDPARAMS;
        }
    }
    else
    {
        switch (Flags & ~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:
            LeaveCriticalSection(&ddraw_cs);
            return DDERR_INVALIDPARAMS;
        }
    }
    ctx.ret = IWineD3DSurface_SetColorKey(This->WineD3DSurface,
                                          Flags,
                                          ctx.CKey);
    IDirectDrawSurface7_EnumAttachedSurfaces(iface,
                                             &ctx,
                                             SetColorKeyEnum);
    LeaveCriticalSection(&ddraw_cs);
    switch(ctx.ret)
    {
        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
        default:                            return ctx.ret;
    }
}

/*****************************************************************************
 * IDirectDrawSurface7::SetPalette
 *
 * Assigns a DirectDrawPalette object to the surface
 *
 * Params:
 *  Pal: Interface to the palette to set
 *
 * Returns:
 *  DD_OK on success
 *
 *****************************************************************************/
static HRESULT WINAPI
IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7 *iface,
                                  IDirectDrawPalette *Pal)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
    IDirectDrawPalette *oldPal;
    IDirectDrawSurfaceImpl *surf;
    IDirectDrawPaletteImpl *PalImpl = (IDirectDrawPaletteImpl *)Pal;
    HRESULT hr;
    TRACE("(%p)->(%p)\n", This, Pal);

    if (!(This->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
            DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) {
        return DDERR_INVALIDPIXELFORMAT;
    }

    /* Find the old palette */
    EnterCriticalSection(&ddraw_cs);
    hr = IDirectDrawSurface_GetPalette(iface, &oldPal);
    if(hr != DD_OK && hr != DDERR_NOPALETTEATTACHED)
    {
        LeaveCriticalSection(&ddraw_cs);
        return hr;
    }
    if(oldPal) IDirectDrawPalette_Release(oldPal);  /* For the GetPalette */

    /* Set the new Palette */
    IWineD3DSurface_SetPalette(This->WineD3DSurface,
                               PalImpl ? PalImpl->wineD3DPalette : NULL);
    /* AddRef the Palette */
    if(Pal) IDirectDrawPalette_AddRef(Pal);

    /* Release the old palette */
    if(oldPal) IDirectDrawPalette_Release(oldPal);

    /* If this is a front buffer, also update the back buffers
     * TODO: How do things work for palettized cube textures?
     */
    if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
    {
        /* For primary surfaces the tree is just a list, so the simpler scheme fits too */
        DDSCAPS2 caps2 = { DDSCAPS_PRIMARYSURFACE, 0, 0, 0 };

        surf = This;
        while(1)
        {
            IDirectDrawSurface7 *attach;
            HRESULT hr;
            hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)surf, &caps2, &attach);
            if(hr != DD_OK)
            {
                break;
            }

            TRACE("Setting palette on %p\n", attach);
            IDirectDrawSurface7_SetPalette(attach,
                                           Pal);
            surf = (IDirectDrawSurfaceImpl *)attach;
            IDirectDrawSurface7_Release(attach);
        }
    }

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

/*****************************************************************************
 * The VTable
 *****************************************************************************/

const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl =
{
    /*** IUnknown ***/
    IDirectDrawSurfaceImpl_QueryInterface,
    IDirectDrawSurfaceImpl_AddRef,
    IDirectDrawSurfaceImpl_Release,
    /*** IDirectDrawSurface ***/
    IDirectDrawSurface7Impl_AddAttachedSurface,
    IDirectDrawSurfaceImpl_AddOverlayDirtyRect,
    IDirectDrawSurfaceImpl_Blt,
    IDirectDrawSurfaceImpl_BltBatch,
    IDirectDrawSurfaceImpl_BltFast,
    IDirectDrawSurfaceImpl_DeleteAttachedSurface,
    IDirectDrawSurfaceImpl_EnumAttachedSurfaces,
    IDirectDrawSurfaceImpl_EnumOverlayZOrders,
    IDirectDrawSurfaceImpl_Flip,
    IDirectDrawSurfaceImpl_GetAttachedSurface,
    IDirectDrawSurfaceImpl_GetBltStatus,
    IDirectDrawSurfaceImpl_GetCaps,
    IDirectDrawSurfaceImpl_GetClipper,
    IDirectDrawSurfaceImpl_GetColorKey,
    IDirectDrawSurfaceImpl_GetDC,
    IDirectDrawSurfaceImpl_GetFlipStatus,
    IDirectDrawSurfaceImpl_GetOverlayPosition,
    IDirectDrawSurfaceImpl_GetPalette,
    IDirectDrawSurfaceImpl_GetPixelFormat,
    IDirectDrawSurfaceImpl_GetSurfaceDesc,
    IDirectDrawSurfaceImpl_Initialize,
    IDirectDrawSurfaceImpl_IsLost,
    IDirectDrawSurfaceImpl_Lock,
    IDirectDrawSurfaceImpl_ReleaseDC,
    IDirectDrawSurfaceImpl_Restore,
    IDirectDrawSurfaceImpl_SetClipper,
    IDirectDrawSurfaceImpl_SetColorKey,
    IDirectDrawSurfaceImpl_SetOverlayPosition,
    IDirectDrawSurfaceImpl_SetPalette,
    IDirectDrawSurfaceImpl_Unlock,
    IDirectDrawSurfaceImpl_UpdateOverlay,
    IDirectDrawSurfaceImpl_UpdateOverlayDisplay,
    IDirectDrawSurfaceImpl_UpdateOverlayZOrder,
    /*** IDirectDrawSurface2 ***/
    IDirectDrawSurfaceImpl_GetDDInterface,
    IDirectDrawSurfaceImpl_PageLock,
    IDirectDrawSurfaceImpl_PageUnlock,
    /*** IDirectDrawSurface3 ***/
    IDirectDrawSurfaceImpl_SetSurfaceDesc,
    /*** IDirectDrawSurface4 ***/
    IDirectDrawSurfaceImpl_SetPrivateData,
    IDirectDrawSurfaceImpl_GetPrivateData,
    IDirectDrawSurfaceImpl_FreePrivateData,
    IDirectDrawSurfaceImpl_GetUniquenessValue,
    IDirectDrawSurfaceImpl_ChangeUniquenessValue,
    /*** IDirectDrawSurface7 ***/
    IDirectDrawSurfaceImpl_SetPriority,
    IDirectDrawSurfaceImpl_GetPriority,
    IDirectDrawSurfaceImpl_SetLOD,
    IDirectDrawSurfaceImpl_GetLOD
};
