[DDRAW] Directory reorganization (part 5)

Christian Costa titan.costa at wanadoo.fr
Fri Jun 3 16:22:28 CDT 2005


Hi,

Changelog:
Moved ddraw object files to ddraw root dir.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.357
diff -u -r1.357 configure.ac
--- configure.ac	3 Jun 2005 11:30:11 -0000	1.357
+++ configure.ac	3 Jun 2005 18:46:54 -0000
@@ -1508,7 +1508,6 @@
 AH_TOP([#define __WINE_CONFIG_H])
 
 WINE_CONFIG_EXTRA_DIR(dlls/ddraw/d3ddevice)
-WINE_CONFIG_EXTRA_DIR(dlls/ddraw/ddraw)
 WINE_CONFIG_EXTRA_DIR(dlls/ddraw/direct3d)
 WINE_CONFIG_EXTRA_DIR(dlls/ddraw/dsurface)
 WINE_CONFIG_EXTRA_DIR(dlls/gdi/enhmfdrv)
Index: dlls/ddraw/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/Makefile.in,v
retrieving revision 1.36
diff -u -r1.36 Makefile.in
--- dlls/ddraw/Makefile.in	3 Jun 2005 11:30:11 -0000	1.36
+++ dlls/ddraw/Makefile.in	3 Jun 2005 18:46:55 -0000
@@ -25,11 +25,11 @@
 C_SRCS = \
 	@OPENGLFILES@ \
 	clipper.c \
+	ddraw_hal.c \
+	ddraw_main.c \
+	ddraw_thunks.c \
+	ddraw_user.c \
 	ddraw_utils.c \
-	ddraw/hal.c \
-	ddraw/main.c \
-	ddraw/thunks.c \
-	ddraw/user.c \
 	dsurface/dib.c \
 	dsurface/fakezbuffer.c \
 	dsurface/gamma.c \
@@ -49,7 +49,6 @@
 
 EXTRASUBDIRS = \
 	d3ddevice \
-	ddraw \
 	direct3d \
 	dsurface
 
--- dlls/ddraw/ddraw/main.c	2005-06-03 20:49:37.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,1728 +0,0 @@
-/*		DirectDraw IDirectDraw interface (generic)
- *
- * 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
- *
- * NOTES
- *
- * WINE currently implements a very basic set of the DirectDraw functionality
- * in graphics/ddraw.c. This implementation uses either the XFree86-DGA extension 
- * to get very fast access to the graphics card framebuffer and doublebuffering
- * features or Xlib, which is slower.
- * The implementation using XFree86-DGA is as fast as the MS equivalent for the
- * stuff that is implemented.
- *
- * Several applications already work, see below.
- * Problems of the implementation using XFree86-DGA:
- *
- *	- XFree86 cannot switch depth on the fly.
- *	  This is a problem with X and unavoidable.
- *	  Current solution is to pop up a MessageBox with an error for 
- *	  mismatched parameters and advice the user to restart the X server
- *	  with the specified depth.
- *	- The rest of the functionality that has to be implemented will have
- *	  to be done in software and will be very slow.
- *	- This requires WINE to be run as root user so XF86DGA can mmap the
- *	  framebuffer into the addressspace of the process.
- *	- Blocks all other X windowed applications.
- *
- * This file contains all the interface functions that are shared between
- * all interfaces. Or better, it is a "common stub" library for the
- * IDirectDraw* objects
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#define CONST_VTABLE
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-
-#include "ddraw_private.h"
-#include "mesa_private.h" /* To have the D3D creation function */
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-extern const IDirectDrawVtbl DDRAW_IDirectDraw_VTable;
-extern const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable;
-extern const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable;
-
-static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This);
-
-static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This);
-static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This);
-static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This);
-static void LosePrimarySurface(IDirectDrawImpl* This);
-
-static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) ;
-static void free_memory(IDirectDrawImpl *This, DWORD mem) ;
-
-
-static const char ddProp[] = "WINE_DDRAW_Property";
-
-/* Not called from the vtable. */
-HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
-{
-    /* NOTE: The creator must use HEAP_ZERO_MEMORY or equivalent. */
-    This->ref = 1;
-    This->ex = ex;
-
-    if (ex) This->local.dwLocalFlags |= DDRAWILCL_DIRECTDRAW7;
-    This->local.dwProcessId = GetCurrentProcessId();
-
-    This->final_release = Main_DirectDraw_final_release;
-
-    This->create_palette = Main_DirectDrawPalette_Create;
-
-    This->create_offscreen = Main_create_offscreen;
-    This->create_texture   = Main_create_texture;
-    This->create_zbuffer   = Main_create_zbuffer;
-    /* There are no generic versions of create_{primary,backbuffer}. */
-
-    ICOM_INIT_INTERFACE(This, IDirectDraw,  DDRAW_IDirectDraw_VTable);
-    ICOM_INIT_INTERFACE(This, IDirectDraw2, DDRAW_IDirectDraw2_VTable);
-    ICOM_INIT_INTERFACE(This, IDirectDraw4, DDRAW_IDirectDraw4_VTable);
-    /* There is no generic implementation of IDD7 */
-
-    /* This is for the moment here... */
-    This->free_memory = free_memory;
-    This->allocate_memory = allocate_memory;
-    This->total_vidmem = 64 * 1024 * 1024;
-    This->available_vidmem = This->total_vidmem;
-      
-    return DD_OK;
-}
-
-void Main_DirectDraw_final_release(IDirectDrawImpl* This)
-{
-    if (IsWindow(This->window))
-    {
-	if (GetPropA(This->window, ddProp))
-	    DDRAW_UnsubclassWindow(This);
-	else
-	    FIXME("this shouldn't happen, right?\n");
-    }
-
-    Main_DirectDraw_DeleteSurfaces(This);
-    Main_DirectDraw_DeleteClippers(This);
-    Main_DirectDraw_DeletePalettes(This);
-    if (This->local.lpGbl && This->local.lpGbl->lpExclusiveOwner == &This->local)
-    {
-	This->local.lpGbl->lpExclusiveOwner = NULL;
-	if (This->set_exclusive_mode)
-	    This->set_exclusive_mode(This, FALSE);
-    }
-}
-
-/* There is no Main_DirectDraw_Create. */
-
-ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface) {
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->() incrementing from %lu.\n", This, ref -1);
-
-    return ref;
-}
-
-ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface) {
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->() decrementing from %lu.\n", This, ref +1);
-
-    if (ref == 0)
-    {
-	if (This->final_release != NULL)
-	    This->final_release(This);
-
-	/* We free the private. This is an artifact of the fact that I don't
-	 * have the destructors set up correctly. */
-	if (This->private != (This+1))
-	    HeapFree(GetProcessHeap(), 0, This->private);
-
-	HeapFree(GetProcessHeap(), 0, This);
-    }
-
-    return ref;
-}
-
-HRESULT WINAPI Main_DirectDraw_QueryInterface(
-    LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj
-) {
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
-
-    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
-    *obj = NULL;
-    
-    if ( IsEqualGUID( &IID_IUnknown, refiid )
-	 || IsEqualGUID( &IID_IDirectDraw7, refiid ) )
-    {
-	*obj = ICOM_INTERFACE(This, IDirectDraw7);
-    }
-    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
-    {
-	*obj = ICOM_INTERFACE(This, IDirectDraw);
-    }
-    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
-    {
-	*obj = ICOM_INTERFACE(This, IDirectDraw2);
-    }
-    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
-    {
-	*obj = ICOM_INTERFACE(This, IDirectDraw4);
-    }
-#ifdef HAVE_OPENGL
-    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )
-    {
-        if (opengl_initialized) {
-	    HRESULT ret_value;
-
-	    ret_value = direct3d_create(This);
-	    if (FAILED(ret_value)) return ret_value;
-	    
-	    if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ) {
-	        *obj = ICOM_INTERFACE(This, IDirect3D);
-		TRACE(" returning Direct3D interface at %p.\n", *obj);	    
-	    } else if ( IsEqualGUID( &IID_IDirect3D2  , refiid ) ) {
-	        *obj = ICOM_INTERFACE(This, IDirect3D2);
-		TRACE(" returning Direct3D2 interface at %p.\n", *obj);	    
-	    } else if ( IsEqualGUID( &IID_IDirect3D3  , refiid ) ) {
-	        *obj = ICOM_INTERFACE(This, IDirect3D3);
-		TRACE(" returning Direct3D3 interface at %p.\n", *obj);	    
-	    } else {
-	        *obj = ICOM_INTERFACE(This, IDirect3D7);
-		TRACE(" returning Direct3D7 interface at %p.\n", *obj);	    
-	    }
-	} else {
-	    ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n");
-	    ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
-	    return E_NOINTERFACE;
-	}
-    }
-#else
-    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
-	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )
-    {
-        ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n");
-	ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
-	return E_NOINTERFACE;
-    }
-#endif
-    else
-    {
-	FIXME("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
-	return E_NOINTERFACE;
-    }
-
-    IDirectDraw7_AddRef(iface);
-    return S_OK;
-}
-
-/* MSDN: "not currently implemented". */
-HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
-{
-    TRACE("(%p)\n", iface);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface,
-					     DWORD dwFlags,
-					     LPDIRECTDRAWCLIPPER *ppClipper,
-					     IUnknown *pUnkOuter)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    HRESULT hr;
-
-    TRACE("(%p)->(0x%lx, %p, %p)\n", iface, dwFlags, ppClipper, pUnkOuter);
-
-    hr = DirectDrawCreateClipper(dwFlags, ppClipper, pUnkOuter);
-    if (FAILED(hr)) return hr;
-
-    /* dwFlags is passed twice, apparently an API wart. */
-    hr = IDirectDrawClipper_Initialize(*ppClipper,
-				       ICOM_INTERFACE(This, IDirectDraw),
-				       dwFlags);
-    if (FAILED(hr))
-    {
-	IDirectDrawClipper_Release(*ppClipper);
-	return hr;
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			      LPPALETTEENTRY palent,
-			      LPDIRECTDRAWPALETTE* ppPalette,
-			      LPUNKNOWN pUnknown)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    LPDIRECTDRAWPALETTE pPalette;
-    HRESULT hr;
-
-    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ppPalette,pUnknown);
-
-    if (ppPalette == NULL) return E_POINTER; /* unchecked */
-    if (pUnknown != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */
-
-    hr = This->create_palette(This, dwFlags, &pPalette, pUnknown);
-    if (FAILED(hr)) return hr;
-
-    hr = IDirectDrawPalette_SetEntries(pPalette, 0, 0,
-				       Main_DirectDrawPalette_Size(dwFlags),
-				       palent);
-    if (FAILED(hr))
-    {
-	IDirectDrawPalette_Release(pPalette);
-	return hr;
-    }
-    else
-    {
-	*ppPalette = pPalette;
-	return DD_OK;
-    }
-}
-
-HRESULT
-Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
-		      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
-{
-    assert(pOuter == NULL);
-
-    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
-}
-
-HRESULT
-Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
-		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,
-		    DWORD dwMipMapLevel)
-{
-    assert(pOuter == NULL);
-
-    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
-}
-
-HRESULT
-Main_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
-		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
-{
-    assert(pOuter == NULL);
-
-    return FakeZBuffer_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
-}
-
-/* Does the texture surface described in pDDSD have any smaller mipmaps? */
-static BOOL more_mipmaps(const DDSURFACEDESC2 *pDDSD)
-{
-    return ((pDDSD->dwFlags & DDSD_MIPMAPCOUNT) && pDDSD->u2.dwMipMapCount > 1
-	    && (pDDSD->dwWidth > 1 || pDDSD->dwHeight > 1));
-}
-
-/* Create a texture surface along with any of its mipmaps. */
-static HRESULT
-create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
-	       LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
-{
-    DDSURFACEDESC2 ddsd;
-    DWORD mipmap_level = 0;
-    HRESULT hr;
-
-    assert(pUnkOuter == NULL);
-
-    /* is this check right? (pixelformat can be copied from primary) */
-    if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
-	return DDERR_INVALIDPARAMS;
-
-    ddsd.dwSize = sizeof(ddsd);
-    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
-
-    if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
-    {
-	ddsd.u4.ddpfPixelFormat = This->pixelformat;
-    }
-
-#ifdef HAVE_OPENGL
-    /* We support for now only DXT1, DXT3 & DXT5 compressed texture formats... */
-    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
-        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','1')) &&
-        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','3')) &&
-        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','5')) )
-    {
-        return DDERR_INVALIDPIXELFORMAT;
-    }
-
-    /* Check if we can really support DXT1, DXT3 & DXT5 */
-    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
-	!GL_extensions.s3tc_compressed_texture && !s3tc_initialized) {
-	static BOOLEAN user_warned = 0;
-	if (user_warned == 0) {
-	    ERR("Trying to create DXT1, DXT3 or DXT5 texture which is not supported by the video card!!!\n");
-	    ERR("However there is a library libtxc_dxtn.so that can be used to do the software decompression...\n");
-	    user_warned = 1;
-	}
-        return DDERR_INVALIDPIXELFORMAT;
-    }
-#else
-    if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
-    {
-	return DDERR_INVALIDPIXELFORMAT;
-    }
-#endif
-
-    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_LINEARSIZE))
-    {
-	int size = 0;
-	int width = ddsd.dwWidth;
-	int height = ddsd.dwHeight;
-	switch(ddsd.u4.ddpfPixelFormat.dwFourCC) {
-	    case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
-	    case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
-	    case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
-	    default: FIXME("FOURCC not supported\n"); break;
-	}
-	ddsd.u1.dwLinearSize = size;
-	ddsd.dwFlags |= DDSD_LINEARSIZE;
-    } else if (!(ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_PITCH)) {
-	ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
-	ddsd.dwFlags |= DDSD_PITCH;
-    }
-
-    if((ddsd.ddsCaps.dwCaps & DDSCAPS_MIPMAP) &&
-        !(ddsd.dwFlags & DDSD_MIPMAPCOUNT))
-    {
-        if(ddsd.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
-        {
-            /* Undocumented feature: if DDSCAPS_MIPMAP and DDSCAPS_COMPLEX are
-             * both set, but mipmap count isn't given, as many mipmap levels
-             * as necessary are created to get down to a size where either
-             * the width or the height of the texture is 1.
-             *
-             * This is needed by Anarchy Online. */
-            DWORD min = ddsd.dwWidth < ddsd.dwHeight ?
-                        ddsd.dwWidth : ddsd.dwHeight;
-            ddsd.u2.dwMipMapCount = 0;
-            while( min )
-            {
-                ddsd.u2.dwMipMapCount++;
-                min >>= 1;
-            }
-        }
-        else
-            /* Create a single mipmap. */
-            ddsd.u2.dwMipMapCount = 1;
- 
-        ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
-    }
-    
-    ddsd.dwFlags |= DDSD_PIXELFORMAT;
-
-    hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
-    if (FAILED(hr)) return hr;
-
-    if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE, 
-						    ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
-
-    /* Create attached mipmaps if required. */
-    if (more_mipmaps(&ddsd))
-    {
-	LPDIRECTDRAWSURFACE7 mipmap;
-	LPDIRECTDRAWSURFACE7 prev_mipmap;
-	DDSURFACEDESC2 mipmap_surface_desc;
-
-	prev_mipmap = *ppSurf;
-	IDirectDrawSurface7_AddRef(prev_mipmap);
-	mipmap_surface_desc = ddsd;
-	mipmap_surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
-
-	while (more_mipmaps(&mipmap_surface_desc))
-	{
-	    IDirectDrawSurfaceImpl *mipmap_impl;
-	    
-	    mipmap_level++;
-	    mipmap_surface_desc.u2.dwMipMapCount--;
-
-	    if (mipmap_surface_desc.dwWidth > 1)
-		mipmap_surface_desc.dwWidth /= 2;
-
-	    if (mipmap_surface_desc.dwHeight > 1)
-		mipmap_surface_desc.dwHeight /= 2;
-
-	    if (mipmap_surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
-		int size = 0;
-		int width = mipmap_surface_desc.dwWidth;
-		int height = mipmap_surface_desc.dwHeight;
-		switch(mipmap_surface_desc.u4.ddpfPixelFormat.dwFourCC) {
-		    case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
-		    case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
-		    case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
-		    default: FIXME("FOURCC not supported\n"); break;
-		}
-		mipmap_surface_desc.u1.dwLinearSize = size;
-	    } else {
-		ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
-		mipmap_surface_desc.u1.lPitch
-		    = DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth,
-					       GET_BPP(ddsd)*8);
-	    }
-
-	    hr = This->create_texture(This, &mipmap_surface_desc, &mipmap,
-				      pUnkOuter, mipmap_level);
-	    if (FAILED(hr))
-	    {
-		IDirectDrawSurface7_Release(prev_mipmap);
-		IDirectDrawSurface7_Release(*ppSurf);
-		return hr;
-	    }
-	    
-	    /* This is needed for delayed mipmap creation */
-	    mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap);
-	    mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf);
-	    mipmap_impl->mipmap_level = mipmap_level;
-
-	    if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE,
-							    ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
-
-	    IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
-	    IDirectDrawSurface7_Release(prev_mipmap);
-	    prev_mipmap = mipmap;
-	}
-
-	IDirectDrawSurface7_Release(prev_mipmap);
-    }
-
-    return DD_OK;
-}
-
-/* Creates a primary surface and any indicated backbuffers. */
-static HRESULT
-create_primary(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
-	       LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
-{
-    DDSURFACEDESC2 ddsd;
-    HRESULT hr;
-
-    assert(pUnkOuter == NULL);
-
-    if (This->primary_surface != NULL)
-	return DDERR_PRIMARYSURFACEALREADYEXISTS;
-
-    /* as documented (what about pitch?) */
-    if (pDDSD->dwFlags & (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT))
-	return DDERR_INVALIDPARAMS;
-
-    ddsd.dwSize = sizeof(ddsd);
-    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
-    ddsd.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
-    ddsd.dwHeight = This->height;
-    ddsd.dwWidth = This->width;
-    ddsd.u1.lPitch = This->pitch;
-    ddsd.u4.ddpfPixelFormat = This->pixelformat;
-    ddsd.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY
-	| DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER;
-
-    if ((ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) && ddsd.dwBackBufferCount > 0)
-	ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP;
-
-    hr = This->create_primary(This, &ddsd, ppSurf, pUnkOuter);
-    if (FAILED(hr)) return hr;
-
-    if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT)
-    {
-	IDirectDrawSurfaceImpl* primary;
-	LPDIRECTDRAWSURFACE7 pPrev;
-	DWORD i;
-
-	ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
-	ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE
-				 | DDSCAPS_BACKBUFFER | DDSCAPS_FRONTBUFFER);
-
-	primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7,
-			      *ppSurf);
-	pPrev = *ppSurf;
-	IDirectDrawSurface7_AddRef(pPrev);
-
-	for (i=0; i < ddsd.dwBackBufferCount; i++)
-	{
-	    LPDIRECTDRAWSURFACE7 pBack;
-
-	    if (i == 0)
-		ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
-	    else
-		ddsd.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
-
-	    hr = This->create_backbuffer(This, &ddsd, &pBack, pUnkOuter,
-					 primary);
-
-	    if (FAILED(hr))
-	    {
-		IDirectDraw7_Release(pPrev);
-		IDirectDraw7_Release(*ppSurf);
-		return hr;
-	    }
-
-	    IDirectDrawSurface7_AddAttachedSurface(pPrev, pBack);
-	    IDirectDrawSurface7_Release(pPrev);
-	    pPrev = pBack;
-	}
-
-	IDirectDrawSurface7_Release(pPrev);
-    }
-
-    This->primary_surface = (IDirectDrawSurfaceImpl *)*ppSurf;
-
-    return DD_OK;
-}
-
-static HRESULT
-create_offscreen(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
-		 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
-{
-    DDSURFACEDESC2 ddsd;
-    HRESULT hr;
-
-    /* is this check right? (pixelformat can be copied from primary) */
-    if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
-	return DDERR_INVALIDPARAMS;
-
-    ddsd.dwSize = sizeof(ddsd);
-    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
-
-    if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
-    {
-	ddsd.u4.ddpfPixelFormat = This->pixelformat;
-    }
-
-    if (!(ddsd.dwFlags & DDSD_PITCH))
-    {
-	ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,
-						  GET_BPP(ddsd)*8);
-    }
-
-    ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT;
-
-    hr = This->create_offscreen(This, &ddsd, ppSurf, pUnkOuter);
-    if (FAILED(hr)) return hr;
-
-    return hr;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
-			      LPDIRECTDRAWSURFACE7 *ppSurf,
-			      IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    TRACE("(%p)->(%p,%p,%p)\n",This,pDDSD,ppSurf,pUnkOuter);
-    if (TRACE_ON(ddraw)) {
-        TRACE("Requesting surface desc :\n");
-        DDRAW_dump_surface_desc(pDDSD);
-    }
-
-    if (pUnkOuter != NULL) {
-	FIXME("outer != NULL?\n");
-	return CLASS_E_NOAGGREGATION; /* unchecked */
-    }
-
-    if (!(pDDSD->dwFlags & DDSD_CAPS)) {
-	/* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
-    	pDDSD->dwFlags |= DDSD_CAPS;
-    }
-    if (pDDSD->ddsCaps.dwCaps == 0) {
-	/* This has been checked on real Windows */
-	pDDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
-    }
-
-    if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) {
-        /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
-        pDDSD->dwFlags &= ~DDSD_LPSURFACE;
-    }
-
-    if ((pDDSD->dwFlags & DDSD_LPSURFACE) && (pDDSD->lpSurface == NULL)) {
-        /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */
-        WARN("Null surface pointer specified, ignore it!\n");
-        pDDSD->dwFlags &= ~DDSD_LPSURFACE;
-    }
-
-    if (ppSurf == NULL) {
-	FIXME("You want to get back a surface? Don't give NULL ptrs!\n");
-	return E_POINTER; /* unchecked */
-    }
-
-    if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-	/* create primary surface & backbuffers */
-	hr = create_primary(This, pDDSD, ppSurf, pUnkOuter);
-    }
-    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
-    {
-       /* create backbuffer surface */
-       hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL);
-    }
-    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
-    {
-	/* create texture */
-	hr = create_texture(This, pDDSD, ppSurf, pUnkOuter);
-    }
-    else if ( (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) &&
-	     !(pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) /* Support DDSCAPS_SYSTEMMEMORY */
-    {
-	/* create z-buffer */
-	hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter);
-    }
-    else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) ||
-	     (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */
-    {
-	/* create offscreenplain surface */
-	hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
-    }
-    else
-    {
-	/* Otherwise, assume offscreenplain surface */
-	TRACE("App didn't request a valid surface type - assuming offscreenplain\n");
-	hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
-    }
-
-    if (FAILED(hr)) {
-	FIXME("failed surface creation with code 0x%08lx\n",hr);
-	return hr;
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
-				 LPDIRECTDRAWSURFACE7* dst)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, src);
-
-    TRACE("(%p)->(%p,%p)\n",This,src,dst);
-
-    return pSrc->duplicate_surface(pSrc, dst);
-}
-
-/* EnumDisplayModes */
-
-BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested,
-					 const DDPIXELFORMAT *provided)
-{
-    /* Some flags must be present in both or neither for a match. */
-    static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
-	| DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC
-	| DDPF_ZBUFFER | DDPF_STENCILBUFFER;
-
-    if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
-	return FALSE;
-
-    if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match))
-	return FALSE;
-
-    if (requested->dwFlags & DDPF_FOURCC)
-	if (requested->dwFourCC != provided->dwFourCC)
-	    return FALSE;
-
-    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA
-			      |DDPF_LUMINANCE|DDPF_BUMPDUDV))
-	if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount)
-	    return FALSE;
-
-    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
-			      |DDPF_LUMINANCE|DDPF_BUMPDUDV))
-	if (requested->u2.dwRBitMask != provided->u2.dwRBitMask)
-	    return FALSE;
-
-    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV))
-	if (requested->u3.dwGBitMask != provided->u3.dwGBitMask)
-	    return FALSE;
-
-    /* I could be wrong about the bumpmapping. MSDN docs are vague. */
-    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
-			      |DDPF_BUMPDUDV))
-	if (requested->u4.dwBBitMask != provided->u4.dwBBitMask)
-	    return FALSE;
-
-    if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS))
-	if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask)
-	    return FALSE;
-
-    return TRUE;
-}
-
-BOOL Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2* requested,
-				const DDSURFACEDESC2* provided)
-{
-    struct compare_info
-    {
-	DWORD flag;
-	ptrdiff_t offset;
-	size_t size;
-    };
-
-#define CMP(FLAG, FIELD)				\
-	{ DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD),	\
-	  sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) }
-
-    static const struct compare_info compare[] = {
-	CMP(ALPHABITDEPTH, dwAlphaBitDepth),
-	CMP(BACKBUFFERCOUNT, dwBackBufferCount),
-	CMP(CAPS, ddsCaps),
-	CMP(CKDESTBLT, ddckCKDestBlt),
-	CMP(CKDESTOVERLAY, u3.ddckCKDestOverlay),
-	CMP(CKSRCBLT, ddckCKSrcBlt),
-	CMP(CKSRCOVERLAY, ddckCKSrcOverlay),
-	CMP(HEIGHT, dwHeight),
-	CMP(LINEARSIZE, u1.dwLinearSize),
-	CMP(LPSURFACE, lpSurface),
-	CMP(MIPMAPCOUNT, u2.dwMipMapCount),
-	CMP(PITCH, u1.lPitch),
-	/* PIXELFORMAT: manual */
-	CMP(REFRESHRATE, u2.dwRefreshRate),
-	CMP(TEXTURESTAGE, dwTextureStage),
-	CMP(WIDTH, dwWidth),
-	/* ZBUFFERBITDEPTH: "obsolete" */
-    };
-
-#undef CMP
-
-    unsigned int i;
-
-    if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
-	return FALSE;
-
-    for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++)
-    {
-	if (requested->dwFlags & compare[i].flag
-	    && memcmp((const char *)provided + compare[i].offset,
-		      (const char *)requested + compare[i].offset,
-		      compare[i].size) != 0)
-	    return FALSE;
-    }
-
-    if (requested->dwFlags & DDSD_PIXELFORMAT)
-    {
-	if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat,
-						 &provided->u4.ddpfPixelFormat))
-	    return FALSE;
-    }
-
-    return TRUE;
-}
-
-#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
-#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
-
-/* This should be extended so that it can be used by
- * IDirectDrawSurface7::EnumAttachedSurfaces. */
-HRESULT
-Main_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
-				     LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
-				     LPDDENUMSURFACESCALLBACK7 callback)
-{
-    IDirectDrawSurfaceImpl *surf;
-    BOOL all, nomatch;
-
-    /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */
-    if (lpDDSD2 == NULL && !(dwFlags & DDENUMSURFACES_ALL))
-	return DDERR_INVALIDPARAMS;
-
-    all = dwFlags & DDENUMSURFACES_ALL;
-    nomatch = dwFlags & DDENUMSURFACES_NOMATCH;
-
-    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
-    {
-	if (all
-	    || (nomatch != Main_DirectDraw_DDSD_Match(lpDDSD2,
-						      &surf->surface_desc)))
-	{
-	    LPDIRECTDRAWSURFACE7 surface = ICOM_INTERFACE(surf,
-							  IDirectDrawSurface7);
-
-	    /* BOGUS! Violates COM rules, but MSDN says so. */
-	    IDirectDrawSurface7_AddRef(surface);
-
-	    if (callback(surface, &surf->surface_desc, context)
-		== DDENUMRET_CANCEL)
-		break;
-	}
-    }
-
-    return DD_OK;
-}
-
-/* I really don't understand how this is supposed to work.
- * We only consider dwHeight, dwWidth and ddpfPixelFormat.dwFlags. */
-HRESULT
-Main_DirectDraw_EnumCreateableSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
-				       LPDDSURFACEDESC2 lpDDSD2,
-				       LPVOID context,
-				       LPDDENUMSURFACESCALLBACK7 callback)
-{
-    FIXME("This isn't going to work.\n");
-
-    if ((dwFlags & DDENUMSURFACES_MATCHTYPE) != DDENUMSURFACES_MATCH)
-	return DDERR_INVALIDPARAMS;
-
-    /* TODO: implement this.
-     * Does this work before SCL is called?
-     * Does it only consider off-screen surfaces?
-     */
-
-    return E_FAIL;
-}
-
-/* For unsigned x. 0 is not a power of 2. */
-#define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
-
-HRESULT WINAPI
-Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			     LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
-			     LPDDENUMSURFACESCALLBACK7 callback)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(0x%lx, %p, %p, %p)\n", iface, dwFlags, lpDDSD2, context,
-	  callback);
-
-    if (callback == NULL)
-	return DDERR_INVALIDPARAMS;
-
-    if (dwFlags & ~(DDENUMSURFACES_SEARCHTYPE|DDENUMSURFACES_MATCHTYPE))
-	return DDERR_INVALIDPARAMS;
-
-    if (!IS_POW_2(dwFlags & DDENUMSURFACES_SEARCHTYPE)
-	|| !IS_POW_2(dwFlags & DDENUMSURFACES_MATCHTYPE))
-	return DDERR_INVALIDPARAMS;
-
-    if (dwFlags & DDENUMSURFACES_DOESEXIST)
-    {
-	return Main_DirectDraw_EnumExistingSurfaces(This, dwFlags, lpDDSD2,
-						    context, callback);
-    }
-    else
-    {
-	return Main_DirectDraw_EnumCreateableSurfaces(This, dwFlags, lpDDSD2,
-						      context, callback);
-    }
-}
-
-HRESULT WINAPI
-Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->() stub\n", This);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->()\n",This);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
-			LPDDCAPS pHELCaps)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p,%p,%p)\n",This,pDriverCaps,pHELCaps);
-    if (pDriverCaps != NULL) {
-	DD_STRUCT_COPY_BYSIZE(pDriverCaps,&This->caps);
-	if (TRACE_ON(ddraw)) {
-	  TRACE("Driver Caps : \n");
-	  DDRAW_dump_DDCAPS(pDriverCaps);
-	}
-    }
-    if (pHELCaps != NULL) {
-	DD_STRUCT_COPY_BYSIZE(pHELCaps,&This->caps);
-	if (TRACE_ON(ddraw)) {
-	  TRACE("HEL Caps : \n");
-	  DDRAW_dump_DDCAPS(pHELCaps);
-	}
-    }
-    return DD_OK;
-}
-
-/* GetCaps */
-/* GetDeviceIdentifier */
-/* GetDIsplayMode */
-
-HRESULT WINAPI
-Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
-			       LPDWORD pCodes)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    if (*pNumCodes) {
-	    *pNumCodes=0;
-    }
-    FIXME("(%p,%p,%p), stub\n",This,pNumCodes,pCodes);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
-			      LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(%p)\n", This, lplpGDIDDSSurface);
-    TRACE("returning primary (%p)\n", This->primary_surface);
-    *lplpGDIDDSSurface = ICOM_INTERFACE(This->primary_surface, IDirectDrawSurface7);
-    if (*lplpGDIDDSSurface)
-	IDirectDrawSurface7_AddRef(*lplpGDIDDSSurface);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
-    *freq = 60*100; /* 60 Hz */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    static BOOL hide;
-
-    /* Since this method is called often, show the fixme only once */
-    if (!hide) {
-	FIXME("(%p)->(%p) semi-stub\n", This, lpdwScanLine);
-	hide = TRUE;
-    }
-
-    /* Fake the line sweeping of the monitor */
-    /* FIXME: We should synchronize with a source to keep the refresh rate */ 
-    *lpdwScanLine = This->cur_scanline++;
-    /* Assume 20 scan lines in the vertical blank */
-    if (This->cur_scanline >= This->height + 20)
-	This->cur_scanline = 0;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
-				 LPDIRECTDRAWSURFACE7 *lpDDS)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(%p)\n",This,status);
-    *status = TRUE;
-    return DD_OK;
-}
-
-/* If we were not initialised then Uninit_Main_IDirectDraw7_Initialize would
- * have been called instead. */
-HRESULT WINAPI
-Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid)
-{
-    TRACE("(%p)->(%s)\n", iface, debugstr_guid(lpGuid));
-
-    return DDERR_ALREADYINITIALIZED;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    IDirectDrawSurfaceImpl* surf;
-
-    TRACE("(%p)->()\n", This);
-
-    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
-	IDirectDrawSurface7_Restore(ICOM_INTERFACE(surf, IDirectDrawSurface7));
-
-    return DD_OK;
-}
-
-static void DDRAW_SubclassWindow(IDirectDrawImpl* This)
-{
-    /* Well we don't actually subclass the window yet. */
-    SetPropA(This->window, ddProp, This);
-}
-
-static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This)
-{
-    RemovePropA(This->window, ddProp);
-}
-
-HRESULT WINAPI
-Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
-				    DWORD cooplevel)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
-    DDRAW_dump_cooperativelevel(cooplevel);
-
-    /* Makes realMYST test happy. */
-    if (This->cooperative_level == cooplevel
-	&& This->window == hwnd)
-	return DD_OK;
-
-    /* XXX "It cannot be reset while the process has surfaces or palettes
-     * created." Otherwise the window can be changed???
-     *
-     * This appears to be wrong - comment it out for now.
-    if (This->window)
-	return DDERR_HWNDALREADYSET;
-    */
-
-    if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL)))
-	return DDERR_INVALIDPARAMS;
-
-    This->window = hwnd;
-    This->cooperative_level = cooplevel;
-
-    This->local.hWnd = (ULONG_PTR)hwnd;
-    This->local.dwLocalFlags |= DDRAWILCL_SETCOOPCALLED;
-    /* not entirely sure about these */
-    if (cooplevel & DDSCL_EXCLUSIVE)     This->local.dwLocalFlags |= DDRAWILCL_HASEXCLUSIVEMODE;
-    if (cooplevel & DDSCL_FULLSCREEN)    This->local.dwLocalFlags |= DDRAWILCL_ISFULLSCREEN;
-    if (cooplevel & DDSCL_ALLOWMODEX)    This->local.dwLocalFlags |= DDRAWILCL_ALLOWMODEX;
-    if (cooplevel & DDSCL_MULTITHREADED) This->local.dwLocalFlags |= DDRAWILCL_MULTITHREADED;
-    if (cooplevel & DDSCL_FPUSETUP)      This->local.dwLocalFlags |= DDRAWILCL_FPUSETUP;
-    if (cooplevel & DDSCL_FPUPRESERVE)   This->local.dwLocalFlags |= DDRAWILCL_FPUPRESERVE;
-
-    if (This->local.lpGbl) {
-	/* assume that this app is the active app (in wine, there's
-	 * probably only one app per global ddraw object anyway) */
-	if (cooplevel & DDSCL_EXCLUSIVE) This->local.lpGbl->lpExclusiveOwner = &This->local;
-	else if (This->local.lpGbl->lpExclusiveOwner == &This->local)
-	    This->local.lpGbl->lpExclusiveOwner = NULL;
-	if (This->set_exclusive_mode)
-	    This->set_exclusive_mode(This, (cooplevel & DDSCL_EXCLUSIVE) != 0);
-    }
-
-    ShowWindow(hwnd, SW_SHOW);
-
-    DDRAW_SubclassWindow(This);
-
-    /* TODO Does it also get resized to the current screen size? */
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-			       DWORD dwHeight, LONG lPitch,
-			       DWORD dwRefreshRate, DWORD dwFlags,
-			       const DDPIXELFORMAT* pixelformat)
-{
-    short screenX;
-    short screenY;
-
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    TRACE("(%p)->SetDisplayMode(%ld,%ld)\n",This,dwWidth,dwHeight);
-
-    if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
-	return DDERR_NOEXCLUSIVEMODE;
-
-    if (!IsWindow(This->window))
-	return DDERR_GENERIC; /* unchecked */
-
-    LosePrimarySurface(This);
-
-    screenX = GetSystemMetrics(SM_CXSCREEN);
-    screenY = GetSystemMetrics(SM_CYSCREEN);
-
-    This->width = dwWidth;
-    This->height = dwHeight;
-    This->pitch = lPitch;
-    This->pixelformat = *pixelformat;
-
-    /* Position the window in the center of the screen - don't center for now */
-    /* MoveWindow(This->window, (screenX-dwWidth)/2, (screenY-dwHeight)/2,
-                  dwWidth, dwHeight, TRUE);*/
-    MoveWindow(This->window, 0, 0, dwWidth, dwHeight, TRUE);
-
-    SetFocus(This->window);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    TRACE("(%p)\n",This);
-    if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
-	return DDERR_NOEXCLUSIVEMODE;
-
-    /* Lose the primary surface if the resolution changes. */
-    if (This->orig_width != This->width || This->orig_height != This->height
-	|| This->orig_pitch != This->pitch
-	|| This->orig_pixelformat.dwFlags != This->pixelformat.dwFlags
-	|| !Main_DirectDraw_DDPIXELFORMAT_Match(&This->pixelformat,
-						&This->orig_pixelformat))
-    {
-	LosePrimarySurface(This);
-    }
-
-    /* TODO Move the window back where it belongs. */
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				     HANDLE h)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->(flags=0x%08lx,handle=%p)\n",This,dwFlags,h);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->GetDisplayMode(%p)\n",This,pDDSD);
-
-    pDDSD->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_REFRESHRATE;
-    pDDSD->dwHeight = This->height;
-    pDDSD->dwWidth = This->width;
-    pDDSD->u1.lPitch = This->pitch;
-    pDDSD->u2.dwRefreshRate = 60;
-    pDDSD->u4.ddpfPixelFormat = This->pixelformat;
-    pDDSD->ddsCaps.dwCaps = 0;
-
-    return DD_OK;
-}
-
-static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem)
-{
-    if (mem > This->available_vidmem) return -1;
-    This->available_vidmem -= mem;
-    return This->available_vidmem;
-}
-
-static void free_memory(IDirectDrawImpl *This, DWORD mem)
-{
-    This->available_vidmem += mem;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
-				   LPDWORD total, LPDWORD free)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" Asking for memory of type : ");
-        DDRAW_dump_DDSCAPS2(ddscaps); TRACE("\n");
-    }
-
-    /* We have 16 MB videomemory */
-    if (total)	*total= This->total_vidmem;
-    if (free)	*free = This->available_vidmem;
-
-    TRACE(" returning (total) %ld / (free) %ld\n", 
-	  total != NULL ? *total : 0, 
-	  free  != NULL ? *free  : 0);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) {
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    TRACE("(%p)->(): stub\n", This);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
-			      DWORD dwNumModes, DWORD dwFlags)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->() stub\n", This);
-
-    return DD_OK;
-}
-
-/*** Owned object management. */
-
-void Main_DirectDraw_AddSurface(IDirectDrawImpl* This,
-				IDirectDrawSurfaceImpl* surface)
-{
-    assert(surface->ddraw_owner == NULL || surface->ddraw_owner == This);
-
-    surface->ddraw_owner = This;
-
-    /* where should it go? */
-    surface->next_ddraw = This->surfaces;
-    surface->prev_ddraw = NULL;
-    if (This->surfaces)
-	This->surfaces->prev_ddraw = surface;
-    This->surfaces = surface;
-}
-
-void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This,
-				   IDirectDrawSurfaceImpl* surface)
-{
-    assert(surface->ddraw_owner == This);
-
-    if (This->surfaces == surface)
-	This->surfaces = surface->next_ddraw;
-
-    if (This->primary_surface == surface)
-	This->primary_surface = NULL;
-
-    if (surface->next_ddraw)
-	surface->next_ddraw->prev_ddraw = surface->prev_ddraw;
-    if (surface->prev_ddraw)
-	surface->prev_ddraw->next_ddraw = surface->next_ddraw;
-}
-
-static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This)
-{
-    while (This->surfaces != NULL)
-	Main_DirectDrawSurface_ForceDestroy(This->surfaces);
-}
-
-void Main_DirectDraw_AddClipper(IDirectDrawImpl* This,
-				IDirectDrawClipperImpl* clipper)
-{
-    assert(clipper->ddraw_owner == NULL || clipper->ddraw_owner == This);
-
-    clipper->ddraw_owner = This;
-
-    clipper->next_ddraw = This->clippers;
-    clipper->prev_ddraw = NULL;
-    if (This->clippers)
-	This->clippers->prev_ddraw = clipper;
-    This->clippers = clipper;
-}
-
-void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This,
-				   IDirectDrawClipperImpl* clipper)
-{
-    assert(clipper->ddraw_owner == This);
-
-    if (This->clippers == clipper)
-	This->clippers = clipper->next_ddraw;
-
-    if (clipper->next_ddraw)
-	clipper->next_ddraw->prev_ddraw = clipper->prev_ddraw;
-    if (clipper->prev_ddraw)
-	clipper->prev_ddraw->next_ddraw = clipper->next_ddraw;
-}
-
-static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This)
-{
-    while (This->clippers != NULL)
-	Main_DirectDrawClipper_ForceDestroy(This->clippers);
-}
-
-void Main_DirectDraw_AddPalette(IDirectDrawImpl* This,
-				IDirectDrawPaletteImpl* palette)
-{
-    assert(palette->ddraw_owner == NULL || palette->ddraw_owner == This);
-
-    palette->ddraw_owner = This;
-
-    /* where should it go? */
-    palette->next_ddraw = This->palettes;
-    palette->prev_ddraw = NULL;
-    if (This->palettes)
-	This->palettes->prev_ddraw = palette;
-    This->palettes = palette;
-}
-
-void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This,
-				   IDirectDrawPaletteImpl* palette)
-{
-    IDirectDrawSurfaceImpl *surf;
-
-    assert(palette->ddraw_owner == This);
-
-    if (This->palettes == palette)
-	This->palettes = palette->next_ddraw;
-
-    if (palette->next_ddraw)
-	palette->next_ddraw->prev_ddraw = palette->prev_ddraw;
-    if (palette->prev_ddraw)
-	palette->prev_ddraw->next_ddraw = palette->next_ddraw;
-
-    /* Here we need also to remove tha palette from any surface which has it as the
-     * current palette (checked on Windows)
-     */
-    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) {
-	if (surf->palette == palette) {
-	    TRACE("Palette %p attached to surface %p.\n", palette, surf);
-	    surf->palette = NULL;
-	    surf->set_palette(surf, NULL);
-	}
-    }
-}
-
-static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This)
-{
-    while (This->palettes != NULL)
-	Main_DirectDrawPalette_ForceDestroy(This->palettes);
-}
-
-/*** ??? */
-
-static void
-LoseSurface(IDirectDrawSurfaceImpl *surface)
-{
-    if (surface != NULL) surface->lose_surface(surface);
-}
-
-static void
-LosePrimarySurface(IDirectDrawImpl *This)
-{
-    /* MSDN: "If another application changes the display mode, the primary
-     * surface is lost, and the method returns DDERR_SURFACELOST until the
-     * primary surface is recreated to match the new display mode."
-     *
-     * We mark all the primary surfaces as lost as soon as the display
-     * mode is changed (by any application). */
-
-    LoseSurface(This->primary_surface);
-}
-
-/******************************************************************************
- * Uninitialised DirectDraw functions
- *
- * This vtable is used when a DirectDraw object is created with
- * CoCreateInstance. The only usable method is Initialize.
- */
-
-void Uninit_DirectDraw_final_release(IDirectDrawImpl *This)
-{
-    Main_DirectDraw_final_release(This);
-}
-
-static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable;
-
-/* Not called from the vtable. */
-HRESULT Uninit_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
-{
-    HRESULT hr;
-
-    hr = Main_DirectDraw_Construct(This, ex);
-    if (FAILED(hr)) return hr;
-
-    This->final_release = Uninit_DirectDraw_final_release;
-    ICOM_INIT_INTERFACE(This, IDirectDraw7, Uninit_DirectDraw_VTable);
-
-    return S_OK;
-}
-
-HRESULT Uninit_DirectDraw_Create(const GUID* pGUID,
-				       LPDIRECTDRAW7* pIface,
-				       IUnknown* pUnkOuter, BOOL ex)
-{
-    HRESULT hr;
-    IDirectDrawImpl* This;
-
-    assert(pUnkOuter == NULL); /* XXX no: we must check this */
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(IDirectDrawImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    hr = Uninit_DirectDraw_Construct(This, ex);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This);
-    else
-	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID pDeviceGuid)
-{
-    const ddraw_driver* driver;
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    TRACE("(%p)->(%p)\n", iface, pDeviceGuid);
-
-    driver = DDRAW_FindDriver(pDeviceGuid);
-    /* XXX This return value is not documented. (Not checked.) */
-    if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID;
-
-    return driver->init(This, pDeviceGuid);
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_Compact(LPDIRECTDRAW7 iface)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				LPDIRECTDRAWCLIPPER *lplpDDClipper,
-				IUnknown *pUnkOuter)
-
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				LPPALETTEENTRY lpColorTable,
-				LPDIRECTDRAWPALETTE *lplpDDPalette,
-				IUnknown *pUnkOuter)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface,
-				LPDDSURFACEDESC2 lpDDSurfaceDesc,
-				LPDIRECTDRAWSURFACE7 *lplpDDSurface,
-				IUnknown *pUnkOuter)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface,
-				   LPDIRECTDRAWSURFACE7 pSurf,
-				   LPDIRECTDRAWSURFACE7 *pDupSurf)
-
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				   LPDDSURFACEDESC2 lpDDSD,
-				   LPVOID context,
-				   LPDDENUMMODESCALLBACK2 cb)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			       LPDDSURFACEDESC2 pDDSD, LPVOID context,
-			       LPDDENUMSURFACESCALLBACK7 cb)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
-			  LPDDCAPS pHELCaps)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface,
-				 LPDDSURFACEDESC2 pDDSD)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
-				 LPDWORD pCodes)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
-				LPDIRECTDRAWSURFACE7 *pGDISurf)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface, LPDWORD pdwFreq)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD pdwScanLine)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, PBOOL pbIsInVB)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hWnd,
-				      DWORD dwFlags)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-				 DWORD dwHeight, DWORD dwBPP,
-				 DWORD dwRefreshRate, DWORD dwFlags)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				       HANDLE hEvent)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 pDDCaps,
-				     LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hDC,
-				   LPDIRECTDRAWSURFACE7 *pSurf)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
-				      LPDDDEVICEIDENTIFIER2 pDDDI,
-				      DWORD dwFlags)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pszModes,
-				DWORD cModes, DWORD dwFlags)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static HRESULT WINAPI
-Uninit_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			       LPDWORD pTimeout)
-{
-    return DDERR_NOTINITIALIZED;
-}
-
-static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable =
-{
-    Main_DirectDraw_QueryInterface,
-    Main_DirectDraw_AddRef,
-    Main_DirectDraw_Release,
-    Uninit_DirectDraw_Compact,
-    Uninit_DirectDraw_CreateClipper,
-    Uninit_DirectDraw_CreatePalette,
-    Uninit_DirectDraw_CreateSurface,
-    Uninit_DirectDraw_DuplicateSurface,
-    Uninit_DirectDraw_EnumDisplayModes,
-    Uninit_DirectDraw_EnumSurfaces,
-    Uninit_DirectDraw_FlipToGDISurface,
-    Uninit_DirectDraw_GetCaps,
-    Uninit_DirectDraw_GetDisplayMode,
-    Uninit_DirectDraw_GetFourCCCodes,
-    Uninit_DirectDraw_GetGDISurface,
-    Uninit_DirectDraw_GetMonitorFrequency,
-    Uninit_DirectDraw_GetScanLine,
-    Uninit_DirectDraw_GetVerticalBlankStatus,
-    Uninit_DirectDraw_Initialize,
-    Uninit_DirectDraw_RestoreDisplayMode,
-    Uninit_DirectDraw_SetCooperativeLevel,
-    Uninit_DirectDraw_SetDisplayMode,
-    Uninit_DirectDraw_WaitForVerticalBlank,
-    Uninit_DirectDraw_GetAvailableVidMem,
-    Uninit_DirectDraw_GetSurfaceFromDC,
-    Uninit_DirectDraw_RestoreAllSurfaces,
-    Uninit_DirectDraw_TestCooperativeLevel,
-    Uninit_DirectDraw_GetDeviceIdentifier,
-    Uninit_DirectDraw_StartModeTest,
-    Uninit_DirectDraw_EvaluateMode
-};
--- dlls/ddraw/ddraw/hal.c	2005-06-02 21:37:42.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,580 +0,0 @@
-/*	DirectDraw HAL driver
- *
- * Copyright 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 <stdarg.h>
-#include <stdlib.h>
-
-#define CONST_VTABLE
-
-#include "wine/debug.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "ddrawi.h"
-#include "d3dhal.h"
-
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static const IDirectDraw7Vtbl HAL_DirectDraw_VTable;
-
-static DDVERSIONDATA hal_version;
-static DD32BITDRIVERDATA hal_driverdata;
-static HINSTANCE hal_instance;
-
-static const DDDEVICEIDENTIFIER2 hal_device =
-{
-    "display",
-    "DirectDraw HAL",
-    { { 0x00010001, 0x00010001 } },
-    0, 0, 0, 0,
-    /* 40c1b248-9d7d-4a29-b7d7-4cd8109f3d5d */
-    {0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}},
-    0
-};
-
-HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-			      IUnknown* pUnkOuter, BOOL ex);
-HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
-
-static const ddraw_driver hal_driver =
-{
-    &hal_device,
-    100, /* we prefer the HAL */
-    HAL_DirectDraw_Create,
-    HAL_DirectDraw_Initialize
-};
-
-static DDHAL_CALLBACKS dd_cbs;
-static DDRAWI_DIRECTDRAW_GBL dd_gbl;
-
-static D3DHAL_GLOBALDRIVERDATA d3d_hal_data;
-static D3DHAL_D3DEXTENDEDCAPS d3d_hal_extcaps;
-static D3DHAL_CALLBACKS d3d_hal_cbs1;
-static D3DHAL_CALLBACKS2 d3d_hal_cbs2;
-
-/* in real windoze, these entry points are 16-bit, but we can work in 32-bit */
-static BOOL WINAPI set_hal_info(LPDDHALINFO lpDDHalInfo, BOOL reset)
-{
-    dd_cbs.HALDD	= *lpDDHalInfo->lpDDCallbacks;
-    dd_cbs.HALDDSurface	= *lpDDHalInfo->lpDDSurfaceCallbacks;
-    dd_cbs.HALDDPalette	= *lpDDHalInfo->lpDDPaletteCallbacks;
-    if (lpDDHalInfo->lpDDExeBufCallbacks)
-	dd_cbs.HALDDExeBuf	= *lpDDHalInfo->lpDDExeBufCallbacks;
-
-    dd_gbl.lpDDCBtmp = &dd_cbs;
-
-    dd_gbl.ddCaps		 = lpDDHalInfo->ddCaps;
-    dd_gbl.dwMonitorFrequency	 = lpDDHalInfo->dwMonitorFrequency;
-    dd_gbl.vmiData		 = lpDDHalInfo->vmiData;
-    dd_gbl.dwModeIndex		 = lpDDHalInfo->dwModeIndex;
-    dd_gbl.dwNumFourCC	         = lpDDHalInfo->ddCaps.dwNumFourCCCodes;
-    dd_gbl.lpdwFourCC		 = lpDDHalInfo->lpdwFourCC;
-    dd_gbl.dwNumModes		 = lpDDHalInfo->dwNumModes;
-    dd_gbl.lpModeInfo		 = lpDDHalInfo->lpModeInfo;
-    /* FIXME: dwFlags */
-    dd_gbl.dwPDevice		 = (DWORD)lpDDHalInfo->lpPDevice;
-    dd_gbl.hInstance		 = lpDDHalInfo->hInstance;
-    /* DirectX 2 */
-    if (lpDDHalInfo->lpD3DGlobalDriverData)
-	memcpy(&d3d_hal_data, (LPVOID)lpDDHalInfo->lpD3DGlobalDriverData, sizeof(D3DDEVICEDESC_V1));
-    else
-	memset(&d3d_hal_data, 0, sizeof(D3DDEVICEDESC_V1));
-    dd_gbl.lpD3DGlobalDriverData = (ULONG_PTR)&d3d_hal_data;
-
-    if (lpDDHalInfo->lpD3DHALCallbacks)
-	memcpy(&d3d_hal_cbs1, (LPVOID)lpDDHalInfo->lpD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS));
-    else
-	memset(&d3d_hal_cbs1, 0, sizeof(D3DHAL_CALLBACKS));
-    dd_gbl.lpD3DHALCallbacks	 = (ULONG_PTR)&d3d_hal_cbs1;
-
-    if (lpDDHalInfo->dwFlags & DDHALINFO_GETDRIVERINFOSET) {
-	DDHAL_GETDRIVERINFODATA data;
-	data.dwSize = sizeof(DDHAL_GETDRIVERINFODATA);
-	data.dwFlags = 0; /* ? */
-	data.dwContext = hal_driverdata.dwContext; /* ? */
-
-	data.guidInfo = GUID_D3DExtendedCaps;
-	data.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
-	data.lpvData = &d3d_hal_extcaps;
-	data.dwActualSize = 0;
-	data.ddRVal = 0;
-	lpDDHalInfo->GetDriverInfo(&data);
-	d3d_hal_extcaps.dwSize = data.dwActualSize;
-	dd_gbl.lpD3DExtendedCaps = (ULONG_PTR)&d3d_hal_extcaps;
-
-	data.guidInfo = GUID_D3DCallbacks2;
-	data.dwExpectedSize = sizeof(D3DHAL_CALLBACKS2);
-	data.lpvData = &d3d_hal_cbs2;
-	data.dwActualSize = 0;
-	data.ddRVal = 0;
-	lpDDHalInfo->GetDriverInfo(&data);
-	d3d_hal_cbs2.dwSize = data.dwActualSize;
-	dd_gbl.lpD3DHALCallbacks2 = (ULONG_PTR)&d3d_hal_cbs2;
-    }
-
-    if( opengl_initialized && 
-           (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) ) {
-        /*GL_DirectDraw_Init(&dd_gbl);*/
-    }
-
-    return FALSE;
-}
-
-static DDHALDDRAWFNS hal_funcs = {
-    sizeof(DDHALDDRAWFNS),
-    set_hal_info,
-    NULL, /* VidMemAlloc */
-    NULL  /* VidMemFree */
-};
-
-/* Called from DllInit, which is synchronised so there are no threading
- * concerns. */
-static BOOL initialize(void)
-{
-    DCICMD cmd;
-    INT ncmd = DCICOMMAND;
-    BOOL ret;
-    HDC dc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-    INT ver = Escape(dc, QUERYESCSUPPORT, sizeof(ncmd), (LPVOID)&ncmd, NULL);
-    if (ver != DD_HAL_VERSION) {
-	DeleteDC(dc);
-	TRACE("DirectDraw HAL not available\n");
-	return FALSE;
-    }
-    cmd.dwVersion = DD_VERSION;
-    cmd.dwReserved = 0;
-
-    /* the DDNEWCALLBACKFNS is supposed to give the 16-bit driver entry points
-     * in ddraw16.dll, but since Wine doesn't have or use 16-bit display drivers,
-     * we'll just work in 32-bit, who'll notice... */
-    cmd.dwCommand = DDNEWCALLBACKFNS;
-    cmd.dwParam1 = (DWORD)&hal_funcs;
-    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, 0, NULL);
-
-    /* next, exchange version information */
-    cmd.dwCommand = DDVERSIONINFO;
-    cmd.dwParam1 = DD_RUNTIME_VERSION; /* not sure what should *really* go here */
-    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_version), (LPVOID)&hal_version);
-
-    /* get 32-bit driver data (dll name and entry point) */
-    cmd.dwCommand = DDGET32BITDRIVERNAME;
-    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_driverdata), (LPVOID)&hal_driverdata);
-    /* we're supposed to load the DLL in hal_driverdata.szName, then GetProcAddress
-     * the hal_driverdata.szEntryPoint, and call it with hal_driverdata.dwContext
-     * as a parameter... but since this is only more remains from the 16-bit world,
-     * we'll ignore it */
-
-    /* finally, initialize the driver object */
-    cmd.dwCommand = DDCREATEDRIVEROBJECT;
-    ret = ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_instance), (LPVOID)&hal_instance);
-    if (ret) {
-	/* the driver should have called our set_hal_info now */
-	if (!dd_gbl.lpDDCBtmp) ret = FALSE;
-    }
-
-    /* init done */
-    DeleteDC(dc);
-
-    TRACE("%s DirectDraw HAL\n", ret ? "enabling" : "disabling");
-
-    return ret;
-}
-
-static void cleanup(void)
-{
-    DDHAL_DESTROYDRIVERDATA data;
-
-    if (!dd_cbs.HALDD.DestroyDriver) return;
-
-    data.lpDD = NULL;
-    data.ddRVal = 0;
-    data.DestroyDriver = dd_cbs.HALDD.DestroyDriver;
-    data.DestroyDriver(&data);
-}
-
-static DWORD choose_mode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
-			 DWORD dwRefreshRate, DWORD dwFlags)
-{
-    int best = -1;
-    unsigned int i;
-
-    if (!dd_gbl.dwNumModes) return 0;
-
-/* let's support HALs that cannot switch depths (XVidMode),
- * these should return dwBPP == 0 for all their resolutions */
-#define BPP_MATCH(dd, bpp) ((!(dd)) || ((dd) == bpp))
-
-/* FIXME: we should try to match the refresh rate too */
-
-    /* Choose the smallest mode that is large enough. */
-    for (i=0; i < dd_gbl.dwNumModes; i++)
-    {
-	if (dd_gbl.lpModeInfo[i].dwWidth >= dwWidth &&
-	    dd_gbl.lpModeInfo[i].dwHeight >= dwHeight &&
-	    BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
-	{
-	    if (best == -1) best = i;
-	    else
-	    {
-		if (dd_gbl.lpModeInfo[i].dwWidth < dd_gbl.lpModeInfo[best].dwWidth ||
-		    dd_gbl.lpModeInfo[i].dwHeight < dd_gbl.lpModeInfo[best].dwHeight)
-		    best = i;
-	    }
-	}
-    }
-
-    if (best == -1)
-    {
-	TRACE("all modes too small\n");
-	/* ok, let's use the largest */
-
-	for (i=0; i < dd_gbl.dwNumModes; i++)
-	{
-	    if (BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
-	    {
-		if (best == -1) best = i;
-		else
-		{
-		    if (dd_gbl.lpModeInfo[i].dwWidth > dd_gbl.lpModeInfo[best].dwWidth ||
-			dd_gbl.lpModeInfo[i].dwHeight > dd_gbl.lpModeInfo[best].dwHeight)
-			best = i;
-		}
-	    }
-	}
-    }
-#undef BPP_MATCH
-
-    if (best == -1)
-    {
-	ERR("requested color depth (%ld) not available, try reconfiguring X server\n", dwBPP);
-	return dd_gbl.dwModeIndex;
-    }
-
-    TRACE("using mode %d\n", best);
-
-    return best;
-}
-
-static HRESULT set_mode(IDirectDrawImpl *This, DWORD dwMode)
-{
-    HRESULT hr = DD_OK;
-
-    if (dwMode != dd_gbl.dwModeIndex)
-    {
-	DDHAL_SETMODEDATA data;
-	data.lpDD = &dd_gbl;
-	data.dwModeIndex = dwMode;
-	data.ddRVal = 0;
-	data.SetMode = dd_cbs.HALDD.SetMode;
-	data.inexcl = 0;
-	data.useRefreshRate = FALSE;
-	if (data.SetMode)
-	    data.SetMode(&data);
-	hr = data.ddRVal;
-	if (SUCCEEDED(hr))
-	    dd_gbl.dwModeIndex = dwMode;
-    }
-    return hr;
-}
-
-static HRESULT set_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl)
-{
-    DDHAL_SETEXCLUSIVEMODEDATA data;
-
-    data.lpDD = &dd_gbl;
-    data.dwEnterExcl = dwEnterExcl;
-    data.dwReserved = 0;
-    data.ddRVal = 0;
-    data.SetExclusiveMode = dd_cbs.HALDD.SetExclusiveMode;
-    if (data.SetExclusiveMode)
-	data.SetExclusiveMode(&data);
-    return data.ddRVal;
-}
-
-BOOL DDRAW_HAL_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
-{
-    if (fdwReason == DLL_PROCESS_ATTACH)
-    {
-	if (initialize())
-	    DDRAW_register_driver(&hal_driver);
-    }
-    else if (fdwReason == DLL_PROCESS_DETACH)
-    {
-	cleanup();
-    }
-
-    return TRUE;
-}
-
-/* Not called from the vtable. */
-HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
-{
-    HRESULT hr;
-
-    TRACE("(%p,%d)\n", This, ex);
-
-    hr = User_DirectDraw_Construct(This, ex);
-    if (FAILED(hr)) return hr;
-
-    This->local.lpGbl = &dd_gbl;
-
-    This->final_release = HAL_DirectDraw_final_release;
-    This->set_exclusive_mode = set_exclusive_mode;
-
-    This->create_palette = HAL_DirectDrawPalette_Create;
-
-    This->create_primary    = HAL_DirectDraw_create_primary;
-    This->create_backbuffer = HAL_DirectDraw_create_backbuffer;
-    This->create_texture    = HAL_DirectDraw_create_texture;
-
-    ICOM_INIT_INTERFACE(This, IDirectDraw7, HAL_DirectDraw_VTable);
-
-    /* merge HAL caps */
-    This->caps.dwCaps |= dd_gbl.ddCaps.dwCaps;
-    This->caps.dwCaps2 |= dd_gbl.ddCaps.dwCaps2;
-    This->caps.dwCKeyCaps |= dd_gbl.ddCaps.dwCKeyCaps;
-    This->caps.dwFXCaps |= dd_gbl.ddCaps.dwFXCaps;
-    This->caps.dwPalCaps |= dd_gbl.ddCaps.dwPalCaps;
-    /* FIXME: merge more caps */
-    This->caps.ddsCaps.dwCaps |= dd_gbl.ddCaps.ddsCaps.dwCaps;
-    This->caps.ddsCaps.dwCaps2 |= dd_gbl.ddsCapsMore.dwCaps2;
-    This->caps.ddsCaps.dwCaps3 |= dd_gbl.ddsCapsMore.dwCaps3;
-    This->caps.ddsCaps.dwCaps4 |= dd_gbl.ddsCapsMore.dwCaps4;
-    This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
-
-    return S_OK;
-}
-
-/* This function is called from DirectDrawCreate(Ex) on the most-derived
- * class to start construction.
- * Not called from the vtable. */
-HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-			      IUnknown* pUnkOuter, BOOL ex)
-{
-    HRESULT hr;
-    IDirectDrawImpl* This;
-
-    TRACE("\n");
-
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(IDirectDrawImpl)
-		     + sizeof(HAL_DirectDrawImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    /* Note that this relation does *not* hold true if the DD object was
-     * CoCreateInstanced then Initialized. */
-    This->private = (HAL_DirectDrawImpl *)(This+1);
-
-    /* Initialize the DDCAPS structure */
-    This->caps.dwSize = sizeof(This->caps);
-
-    hr = HAL_DirectDraw_Construct(This, ex);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
-
-    return hr;
-}
-
-/* This function is called from Uninit_DirectDraw_Initialize on the
- * most-derived-class to start initialization.
- * Not called from the vtable. */
-HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
-{
-    HRESULT hr;
-
-    TRACE("\n");
-
-    This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			      sizeof(HAL_DirectDrawImpl));
-    if (This->private == NULL) return E_OUTOFMEMORY;
-
-    /* Initialize the DDCAPS structure */
-    This->caps.dwSize = sizeof(This->caps);
-
-    hr = HAL_DirectDraw_Construct(This, TRUE); /* XXX ex? */
-    if (FAILED(hr))
-    {
-	HeapFree(GetProcessHeap(), 0, This->private);
-	return hr;
-    }
-
-    return DD_OK;
-}
-
-/* Called from an internal function pointer. */
-void HAL_DirectDraw_final_release(IDirectDrawImpl *This)
-{
-    if (dd_gbl.dwFlags & DDRAWI_MODECHANGED) set_mode(This, dd_gbl.dwModeIndexOrig);
-    User_DirectDraw_final_release(This);
-}
-
-HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This,
-				      const DDSURFACEDESC2* pDDSD,
-				      LPDIRECTDRAWSURFACE7* ppSurf,
-				      IUnknown* pUnkOuter)
-{
-    if (This->cooperative_level & DDSCL_EXCLUSIVE)
-	return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-    else
-	return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-}
-
-HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
-					 const DDSURFACEDESC2* pDDSD,
-					 LPDIRECTDRAWSURFACE7* ppSurf,
-					 IUnknown* pUnkOuter,
-					 IDirectDrawSurfaceImpl* primary)
-{
-    if (This->cooperative_level & DDSCL_EXCLUSIVE)
-	return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-    else
-	return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-}
-
-HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
-				      const DDSURFACEDESC2* pDDSD,
-				      LPDIRECTDRAWSURFACE7* ppSurf,
-				      LPUNKNOWN pOuter,
-				      DWORD dwMipMapLevel)
-{
-    return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
-}
-
-HRESULT WINAPI
-HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
-				   LPDDDEVICEIDENTIFIER2 pDDDI,
-				   DWORD dwFlags)
-{
-    *pDDDI = hal_device;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    HRESULT hr;
-
-    TRACE("(%p)\n", iface);
-
-    if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) return DD_OK;
-
-    hr = Main_DirectDraw_RestoreDisplayMode(iface);
-    if (SUCCEEDED(hr)) {
-	hr = set_mode(This, dd_gbl.dwModeIndexOrig);
-	if (SUCCEEDED(hr)) dd_gbl.dwFlags &= ~DDRAWI_MODECHANGED;
-    }
-
-    return hr;
-}
-
-HRESULT WINAPI
-HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-			      DWORD dwHeight, DWORD dwBPP,
-			      DWORD dwRefreshRate, DWORD dwFlags)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    HRESULT hr;
-
-    TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
-    hr = User_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP,
-					dwRefreshRate, dwFlags);
-
-    if (SUCCEEDED(hr)) {
-	if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) dd_gbl.dwModeIndexOrig = dd_gbl.dwModeIndex;
-	hr = set_mode(This, choose_mode(dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags));
-	if (SUCCEEDED(hr)) dd_gbl.dwFlags |= DDRAWI_MODECHANGED;
-    }
-
-    return hr;
-}
-
-HRESULT WINAPI
-HAL_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
-			       LPDWORD pCodes)
-{
-    unsigned int i;
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    if (*pNumCodes)
-	*pNumCodes=dd_gbl.dwNumFourCC;
-    if (pCodes && dd_gbl.dwNumFourCC)
-	memcpy(pCodes,dd_gbl.lpdwFourCC,sizeof(pCodes[0])*dd_gbl.dwNumFourCC);
-    FIXME("(%p,%p,%p)\n",This,pNumCodes,pCodes);
-    if (dd_gbl.dwNumFourCC) {
-	if (pCodes && FIXME_ON(ddraw)) {
-	    FIXME("returning: ");
-	    for (i=0;i<dd_gbl.dwNumFourCC;i++) {
-		MESSAGE("%c%c%c%c,",
-			((LPBYTE)(pCodes+i))[0],
-			((LPBYTE)(pCodes+i))[1],
-			((LPBYTE)(pCodes+i))[2],
-			((LPBYTE)(pCodes+i))[3]
-		);
-	    }
-	    MESSAGE("\n");
-	}
-    }
-    return DD_OK;
-}
-
-
-static const IDirectDraw7Vtbl HAL_DirectDraw_VTable =
-{
-    Main_DirectDraw_QueryInterface,
-    Main_DirectDraw_AddRef,
-    Main_DirectDraw_Release,
-    Main_DirectDraw_Compact,
-    Main_DirectDraw_CreateClipper,
-    Main_DirectDraw_CreatePalette,
-    Main_DirectDraw_CreateSurface,
-    Main_DirectDraw_DuplicateSurface,
-    User_DirectDraw_EnumDisplayModes,
-    Main_DirectDraw_EnumSurfaces,
-    Main_DirectDraw_FlipToGDISurface,
-    Main_DirectDraw_GetCaps,
-    Main_DirectDraw_GetDisplayMode,
-    HAL_DirectDraw_GetFourCCCodes,
-    Main_DirectDraw_GetGDISurface,
-    Main_DirectDraw_GetMonitorFrequency,
-    Main_DirectDraw_GetScanLine,
-    Main_DirectDraw_GetVerticalBlankStatus,
-    Main_DirectDraw_Initialize,
-    HAL_DirectDraw_RestoreDisplayMode,
-    Main_DirectDraw_SetCooperativeLevel,
-    HAL_DirectDraw_SetDisplayMode,
-    Main_DirectDraw_WaitForVerticalBlank,
-    Main_DirectDraw_GetAvailableVidMem,
-    Main_DirectDraw_GetSurfaceFromDC,
-    Main_DirectDraw_RestoreAllSurfaces,
-    Main_DirectDraw_TestCooperativeLevel,
-    HAL_DirectDraw_GetDeviceIdentifier,
-    Main_DirectDraw_StartModeTest,
-    Main_DirectDraw_EvaluateMode
-};
--- dlls/ddraw/ddraw/thunks.c	2005-05-28 14:49:22.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,1032 +0,0 @@
-/* Direct Draw Thunks and old vtables
- * Copyright 2000 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 <stdarg.h>
-
-#define CONST_VTABLE
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "ddraw_private.h"
-#include "ddcomimpl.h"
-
-static HRESULT WINAPI
-IDirectDrawImpl_QueryInterface(LPDIRECTDRAW This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw,
-							  IDirectDraw7, This),
-				       iid, ppObj);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_QueryInterface(LPDIRECTDRAW2 This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw2,
-							  IDirectDraw7, This),
-				       iid, ppObj);
-}
-
-
-static HRESULT WINAPI
-IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw4,
-							  IDirectDraw7, This),
-				       iid, ppObj);
-}
-
-static ULONG WINAPI
-IDirectDrawImpl_AddRef(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
-						  IDirectDraw, IDirectDraw7,
-						  This));
-}
-
-static ULONG WINAPI
-IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
-						  IDirectDraw2, IDirectDraw7,
-						  This));
-}
-
-static ULONG WINAPI
-IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
-						  IDirectDraw4, IDirectDraw7,
-						  This));
-}
-
-static ULONG WINAPI
-IDirectDrawImpl_Release(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw, IDirectDraw7,
-						   This));
-}
-
-static ULONG WINAPI
-IDirectDraw2Impl_Release(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw2, IDirectDraw7,
-						   This));
-}
-
-static ULONG WINAPI
-IDirectDraw4Impl_Release(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw4, IDirectDraw7,
-						   This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_Compact(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw, IDirectDraw7,
-						   This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_Compact(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw2, IDirectDraw7,
-						   This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_Compact(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw4, IDirectDraw7,
-						   This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreateClipper(LPDIRECTDRAW This, DWORD dwFlags,
-			      LPDIRECTDRAWCLIPPER *ppClipper,
-			      IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreateClipper(LPDIRECTDRAW2 This, DWORD dwFlags,
-			       LPDIRECTDRAWCLIPPER *ppClipper,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw2,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreateClipper(LPDIRECTDRAW4 This, DWORD dwFlags,
-			       LPDIRECTDRAWCLIPPER *ppClipper,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw4,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
-			      LPPALETTEENTRY pEntries,
-			      LPDIRECTDRAWPALETTE *ppPalette,
-			      IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, pEntries, ppPalette, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
-			       LPPALETTEENTRY pEntries,
-			       LPDIRECTDRAWPALETTE *ppPalette,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw2,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, pEntries, ppPalette, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
-			       LPPALETTEENTRY pEntries,
-			       LPDIRECTDRAWPALETTE *ppPalette,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw4,
-							 IDirectDraw7,
-							 This),
-				      dwFlags, pEntries, ppPalette, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
-			      LPDIRECTDRAWSURFACE *ppSurface,
-			      IUnknown *pUnkOuter)
-{
-    LPDIRECTDRAWSURFACE7 pSurface7;
-    HRESULT hr;
-
-    /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
-     * since the data layout is the same */
-    hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw,
-						       IDirectDraw7,
-						       This),
-				    (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurface = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
-				    IDirectDrawSurface7, IDirectDrawSurface3,
-				    pSurface7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
-			       LPDIRECTDRAWSURFACE *ppSurface,
-			       IUnknown *pUnkOuter)
-{
-    LPDIRECTDRAWSURFACE7 pSurface7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw2,
-						       IDirectDraw7,
-						       This),
-				    (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurface = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
-				    IDirectDrawSurface7, IDirectDrawSurface3,
-				    pSurface7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
-			       LPDIRECTDRAWSURFACE4 *ppSurface,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw4,
-							 IDirectDraw7,
-							 This),
-				      pSDesc,
-				      (LPDIRECTDRAWSURFACE7 *)ppSurface,
-				      pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
-				 LPDIRECTDRAWSURFACE *ppDst)
-{
-    LPDIRECTDRAWSURFACE7 pDst7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw,
-							  IDirectDraw7, This),
-				       COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
-							  IDirectDrawSurface3,
-							  IDirectDrawSurface7,
-							  pSrc),
-				       &pDst7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-				IDirectDrawSurface3, pDst7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
-				  LPDIRECTDRAWSURFACE *ppDst)
-{
-    LPDIRECTDRAWSURFACE7 pDst7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw2,
-							  IDirectDraw7, This),
-				       COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
-							  IDirectDrawSurface3,
-							  IDirectDrawSurface7,
-							  pSrc),
-				       &pDst7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-				IDirectDrawSurface3, pDst7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
-				  LPDIRECTDRAWSURFACE4 pSrc,
-				  LPDIRECTDRAWSURFACE4 *ppDst)
-{
-    return IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw4,
-							    IDirectDraw7,
-							    This),
-					 (LPDIRECTDRAWSURFACE7)pSrc,
-					 (LPDIRECTDRAWSURFACE7 *)ppDst);
-}
-
-struct displaymodescallback_context
-{
-    LPDDENUMMODESCALLBACK func;
-    LPVOID context;
-};
-
-static HRESULT CALLBACK
-EnumDisplayModesCallbackThunk(LPDDSURFACEDESC2 pDDSD2, LPVOID context)
-{
-    DDSURFACEDESC DDSD;
-    struct displaymodescallback_context *cbcontext = context;
-
-    memcpy(&DDSD,pDDSD2,sizeof(DDSD));
-    DDSD.dwSize = sizeof(DDSD);
-
-    return cbcontext->func(&DDSD, cbcontext->context);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_EnumDisplayModes(LPDIRECTDRAW This, DWORD dwFlags,
-				 LPDDSURFACEDESC pDDSD, LPVOID context,
-				 LPDDENUMMODESCALLBACK cb)
-{
-    struct displaymodescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw,
-							    IDirectDraw7,
-							    This),
-					 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
-					 EnumDisplayModesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_EnumDisplayModes(LPDIRECTDRAW2 This, DWORD dwFlags,
-				  LPDDSURFACEDESC pDDSD, LPVOID context,
-				  LPDDENUMMODESCALLBACK cb)
-{
-    struct displaymodescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw2,
-							    IDirectDraw7,
-							    This),
-					 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
-					 EnumDisplayModesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_EnumDisplayModes(LPDIRECTDRAW4 This, DWORD dwFlags,
-				  LPDDSURFACEDESC2 pDDSD, LPVOID context,
-				  LPDDENUMMODESCALLBACK2 cb)
-{
-    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw4,
-							    IDirectDraw7,
-							    This),
-					 dwFlags, pDDSD, context, cb);
-}
-
-struct surfacescallback_context
-{
-    LPDDENUMSURFACESCALLBACK func;
-    LPVOID context;
-};
-
-static HRESULT CALLBACK
-EnumSurfacesCallbackThunk(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
-			  LPVOID context)
-{
-    struct surfacescallback_context *cbcontext = context;
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    return cbcontext->func((LPDIRECTDRAWSURFACE)
-                           COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
-					      IDirectDrawSurface7,
-					      IDirectDrawSurface3, pSurf),
-			   (LPDDSURFACEDESC)pDDSD, cbcontext->context);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_EnumSurfaces(LPDIRECTDRAW This, DWORD dwFlags,
-			     LPDDSURFACEDESC pDDSD, LPVOID context,
-			     LPDDENUMSURFACESCALLBACK cb)
-{
-    struct surfacescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
-							IDirectDraw,
-							IDirectDraw7, This),
-				     dwFlags, (LPDDSURFACEDESC2)pDDSD,
-				     &cbcontext, EnumSurfacesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
-			      LPDDSURFACEDESC pDDSD, LPVOID context,
-			      LPDDENUMSURFACESCALLBACK cb)
-{
-    struct surfacescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
-							IDirectDraw2,
-							IDirectDraw7, This),
-				     dwFlags, (LPDDSURFACEDESC2)pDDSD,
-				     &cbcontext, EnumSurfacesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_EnumSurfaces(LPDIRECTDRAW4 This, DWORD dwFlags,
-			      LPDDSURFACEDESC2 pDDSD, LPVOID context,
-			      LPDDENUMSURFACESCALLBACK2 cb)
-{
-    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
-							IDirectDraw4,
-							IDirectDraw7, This),
-				     dwFlags, pDDSD, context,
-				     (LPDDENUMSURFACESCALLBACK7)cb);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_FlipToGDISurface(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw,
-							    IDirectDraw7,
-							    This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw2,
-							    IDirectDraw7,
-							    This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_FlipToGDISurface(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw4,
-							    IDirectDraw7,
-							    This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetCaps(LPDIRECTDRAW This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw, IDirectDraw7,
-						   This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetCaps(LPDIRECTDRAW2 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw2, IDirectDraw7,
-						   This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetCaps(LPDIRECTDRAW4 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
-						   IDirectDraw4, IDirectDraw7,
-						   This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetDisplayMode(LPDIRECTDRAW This, LPDDSURFACEDESC pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw,
-							  IDirectDraw7, This),
-				       (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetDisplayMode(LPDIRECTDRAW2 This, LPDDSURFACEDESC pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw2,
-							  IDirectDraw7, This),
-				       (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetDisplayMode(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw4,
-							  IDirectDraw7, This),
-				       pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetFourCCCodes(LPDIRECTDRAW This, LPDWORD lpNumCodes,
-			       LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw,
-							  IDirectDraw7,
-							  This),
-				       lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetFourCCCodes(LPDIRECTDRAW2 This, LPDWORD lpNumCodes,
-				LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw2,
-							  IDirectDraw7,
-							  This),
-				       lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetFourCCCodes(LPDIRECTDRAW4 This, LPDWORD lpNumCodes,
-				LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw4,
-							  IDirectDraw7,
-							  This),
-				       lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetGDISurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE *ppSurf)
-{
-    LPDIRECTDRAWSURFACE7 pSurf7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw,
-						       IDirectDraw7,
-						       This), &pSurf7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurf = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-				 IDirectDrawSurface3, pSurf7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE *ppSurf)
-{
-    LPDIRECTDRAWSURFACE7 pSurf7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw2,
-						       IDirectDraw7,
-						       This), &pSurf7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurf = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-				 IDirectDrawSurface3, pSurf7);
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetGDISurface(LPDIRECTDRAW4 This,
-			       LPDIRECTDRAWSURFACE4 *ppSurf)
-{
-    return IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw4,
-							 IDirectDraw7,
-							 This),
-				      (LPDIRECTDRAWSURFACE7 *)ppSurf);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetMonitorFrequency(LPDIRECTDRAW This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw,
-							       IDirectDraw7,
-							       This),
-					    pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetMonitorFrequency(LPDIRECTDRAW2 This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw2,
-							       IDirectDraw7,
-							       This),
-					    pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetMonitorFrequency(LPDIRECTDRAW4 This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw4,
-							       IDirectDraw7,
-							       This),
-					    pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetScanLine(LPDIRECTDRAW This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw,
-						       IDirectDraw7,
-						       This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw2,
-						       IDirectDraw7,
-						       This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetScanLine(LPDIRECTDRAW4 This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
-						       IDirectDraw4,
-						       IDirectDraw7,
-						       This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetVerticalBlankStatus(LPDIRECTDRAW This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
-								  IDirectDraw,
-								  IDirectDraw7,
-								  This),
-					       lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetVerticalBlankStatus(LPDIRECTDRAW2 This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
-								  IDirectDraw2,
-								  IDirectDraw7,
-								  This),
-					       lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetVerticalBlankStatus(LPDIRECTDRAW4 This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
-								  IDirectDraw4,
-								  IDirectDraw7,
-								  This),
-					       lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_Initialize(LPDIRECTDRAW iface, LPGUID pGUID)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
-    HRESULT ret_value;
-
-    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
-    
-    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
-    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
-    
-    return ret_value;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, LPGUID pGUID)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
-    HRESULT ret_value;
-    
-    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
-
-    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
-    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
-    
-    return ret_value;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_Initialize(LPDIRECTDRAW4 iface, LPGUID pGUID)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
-    HRESULT ret_value;
-    
-    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
-    
-    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
-    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
-    
-    return ret_value;
-}
-
-
-static HRESULT WINAPI
-IDirectDrawImpl_RestoreDisplayMode(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw,
-							      IDirectDraw7,
-							      This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw2,
-							      IDirectDraw7,
-							      This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_RestoreDisplayMode(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw4,
-							      IDirectDraw7,
-							      This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_SetCooperativeLevel(LPDIRECTDRAW This, HWND hWnd,
-				    DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw,
-							       IDirectDraw7,
-							       This),
-					    hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_SetCooperativeLevel(LPDIRECTDRAW2 This, HWND hWnd,
-				     DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw2,
-							       IDirectDraw7,
-							       This),
-					    hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_SetCooperativeLevel(LPDIRECTDRAW4 This, HWND hWnd,
-				     DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
-							       IDirectDraw4,
-							       IDirectDraw7,
-							       This),
-					    hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_SetDisplayMode(LPDIRECTDRAW This, DWORD a, DWORD b, DWORD c)
-{
-    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw,
-							  IDirectDraw7,
-							  This),
-				       a, b, c, 0, 0);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_SetDisplayMode(LPDIRECTDRAW2 This, DWORD a, DWORD b, DWORD c,
-				DWORD d, DWORD e)
-{
-    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw2,
-							  IDirectDraw7,
-							  This),
-				       a, b, c, d, e);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_SetDisplayMode(LPDIRECTDRAW4 This, DWORD a, DWORD b, DWORD c,
-				DWORD d, DWORD e)
-{
-    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
-							  IDirectDraw4,
-							  IDirectDraw7,
-							  This),
-				       a, b, c, d, e);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_WaitForVerticalBlank(LPDIRECTDRAW This, DWORD dwFlags,
-				     HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
-								IDirectDraw,
-								IDirectDraw7,
-								This),
-					     dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_WaitForVerticalBlank(LPDIRECTDRAW2 This, DWORD dwFlags,
-				      HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
-								IDirectDraw2,
-								IDirectDraw7,
-								This),
-					     dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_WaitForVerticalBlank(LPDIRECTDRAW4 This, DWORD dwFlags,
-				      HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
-								IDirectDraw4,
-								IDirectDraw7,
-								This),
-					     dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetAvailableVidMem(LPDIRECTDRAW2 This, LPDDSCAPS pCaps,
-				    LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    DDSCAPS2 Caps2;
-    DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
-
-    return IDirectDraw7_GetAvailableVidMem(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw2,
-							      IDirectDraw7,
-							      This),
-					   &Caps2, pdwTotal, pdwFree);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetAvailableVidMem(LPDIRECTDRAW4 This, LPDDSCAPS2 pCaps,
-				    LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    return IDirectDraw7_GetAvailableVidMem(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw4,
-							      IDirectDraw7,
-							      This),
-					   pCaps, pdwTotal, pdwFree);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 This, HDC hDC,
-				  LPDIRECTDRAWSURFACE4 *pSurf)
-{
-    return IDirectDraw7_GetSurfaceFromDC(COM_INTERFACE_CAST(IDirectDrawImpl,
-							    IDirectDraw4,
-							    IDirectDraw7,
-							    This),
-					 hDC, (LPDIRECTDRAWSURFACE7 *)pSurf);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_RestoreAllSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
-							      IDirectDraw4,
-							      IDirectDraw7,
-							      This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_TestCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
-								IDirectDraw4,
-								IDirectDraw7,
-								This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 This,
-				     LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags)
-{
-    DDDEVICEIDENTIFIER2 DDDI2;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetDeviceIdentifier(COM_INTERFACE_CAST(IDirectDrawImpl,
-							     IDirectDraw4,
-							     IDirectDraw7,
-							     This),
-					  &DDDI2, dwFlags);
-
-    DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(&DDDI2, pDDDI);
-
-    return hr;
-}
-
-const IDirectDrawVtbl DDRAW_IDirectDraw_VTable =
-{
-    IDirectDrawImpl_QueryInterface,
-    IDirectDrawImpl_AddRef,
-    IDirectDrawImpl_Release,
-    IDirectDrawImpl_Compact,
-    IDirectDrawImpl_CreateClipper,
-    IDirectDrawImpl_CreatePalette,
-    IDirectDrawImpl_CreateSurface,
-    IDirectDrawImpl_DuplicateSurface,
-    IDirectDrawImpl_EnumDisplayModes,
-    IDirectDrawImpl_EnumSurfaces,
-    IDirectDrawImpl_FlipToGDISurface,
-    IDirectDrawImpl_GetCaps,
-    IDirectDrawImpl_GetDisplayMode,
-    IDirectDrawImpl_GetFourCCCodes,
-    IDirectDrawImpl_GetGDISurface,
-    IDirectDrawImpl_GetMonitorFrequency,
-    IDirectDrawImpl_GetScanLine,
-    IDirectDrawImpl_GetVerticalBlankStatus,
-    IDirectDrawImpl_Initialize,
-    IDirectDrawImpl_RestoreDisplayMode,
-    IDirectDrawImpl_SetCooperativeLevel,
-    IDirectDrawImpl_SetDisplayMode,
-    IDirectDrawImpl_WaitForVerticalBlank,
-};
-
-const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable =
-{
-    IDirectDraw2Impl_QueryInterface,
-    IDirectDraw2Impl_AddRef,
-    IDirectDraw2Impl_Release,
-    IDirectDraw2Impl_Compact,
-    IDirectDraw2Impl_CreateClipper,
-    IDirectDraw2Impl_CreatePalette,
-    IDirectDraw2Impl_CreateSurface,
-    IDirectDraw2Impl_DuplicateSurface,
-    IDirectDraw2Impl_EnumDisplayModes,
-    IDirectDraw2Impl_EnumSurfaces,
-    IDirectDraw2Impl_FlipToGDISurface,
-    IDirectDraw2Impl_GetCaps,
-    IDirectDraw2Impl_GetDisplayMode,
-    IDirectDraw2Impl_GetFourCCCodes,
-    IDirectDraw2Impl_GetGDISurface,
-    IDirectDraw2Impl_GetMonitorFrequency,
-    IDirectDraw2Impl_GetScanLine,
-    IDirectDraw2Impl_GetVerticalBlankStatus,
-    IDirectDraw2Impl_Initialize,
-    IDirectDraw2Impl_RestoreDisplayMode,
-    IDirectDraw2Impl_SetCooperativeLevel,
-    IDirectDraw2Impl_SetDisplayMode,
-    IDirectDraw2Impl_WaitForVerticalBlank,
-    IDirectDraw2Impl_GetAvailableVidMem
-};
-
-const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable =
-{
-    IDirectDraw4Impl_QueryInterface,
-    IDirectDraw4Impl_AddRef,
-    IDirectDraw4Impl_Release,
-    IDirectDraw4Impl_Compact,
-    IDirectDraw4Impl_CreateClipper,
-    IDirectDraw4Impl_CreatePalette,
-    IDirectDraw4Impl_CreateSurface,
-    IDirectDraw4Impl_DuplicateSurface,
-    IDirectDraw4Impl_EnumDisplayModes,
-    IDirectDraw4Impl_EnumSurfaces,
-    IDirectDraw4Impl_FlipToGDISurface,
-    IDirectDraw4Impl_GetCaps,
-    IDirectDraw4Impl_GetDisplayMode,
-    IDirectDraw4Impl_GetFourCCCodes,
-    IDirectDraw4Impl_GetGDISurface,
-    IDirectDraw4Impl_GetMonitorFrequency,
-    IDirectDraw4Impl_GetScanLine,
-    IDirectDraw4Impl_GetVerticalBlankStatus,
-    IDirectDraw4Impl_Initialize,
-    IDirectDraw4Impl_RestoreDisplayMode,
-    IDirectDraw4Impl_SetCooperativeLevel,
-    IDirectDraw4Impl_SetDisplayMode,
-    IDirectDraw4Impl_WaitForVerticalBlank,
-    IDirectDraw4Impl_GetAvailableVidMem,
-    IDirectDraw4Impl_GetSurfaceFromDC,
-    IDirectDraw4Impl_RestoreAllSurfaces,
-    IDirectDraw4Impl_TestCooperativeLevel,
-    IDirectDraw4Impl_GetDeviceIdentifier
-};
--- dlls/ddraw/ddraw/user.c	2005-06-03 20:49:37.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,562 +0,0 @@
-/*	DirectDraw driver for User-based primary surfaces
- *
- * 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 <stdarg.h>
-#include <string.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#define CONST_VTABLE
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "ddraw.h"
-#include "ddraw_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static const IDirectDraw7Vtbl User_DirectDraw_VTable;
-
-static const DDDEVICEIDENTIFIER2 user_device =
-{
-    "display",
-    "User (and GDI)",
-    { { 0x00010001, 0x00010001 } },
-    0, 0, 0, 0,
-    /* fe38440c-8969-4283-bc73-749e7bc3c2eb */
-    {0xfe38440c,0x8969,0x428e, {0x73,0xbc,0x74,0x9e,0x7b,0xc3,0xc2,0xeb}},
-    0
-};
-
-static const DDPIXELFORMAT pixelformats[] =
-{
-    /* 8bpp paletted */
-    { sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_PALETTEINDEXED8, 0, { 8 } },
-    /* 15bpp 5/5/5 */
-    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0x7C00 }, { 0x3E0 },
-      { 0x1F } },
-    /* 16bpp 5/6/5 */
-    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0xF800 }, { 0x7E0 },
-      { 0x1F } },
-    /* 24bpp 8/8/8 */
-    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 24 }, { 0xFF0000 },
-      { 0x00FF00 }, { 0x0000FF } },
-    /* 32bpp 8/8/8 */
-    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 32 }, { 0xFF0000 },
-      { 0x00FF00 }, { 0x0000FF } }
-};
-
-HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-				     IUnknown* pUnkOuter, BOOL ex);
-HRESULT User_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
-
-static const ddraw_driver user_driver =
-{
-    &user_device,
-    10,
-    User_DirectDraw_Create,
-    User_DirectDraw_Initialize
-};
-
-BOOL DDRAW_User_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
-{
-    if (fdwReason == DLL_PROCESS_ATTACH)
-	DDRAW_register_driver(&user_driver);
-
-    return TRUE;
-}
-
-static const DDPIXELFORMAT* pixelformat_for_depth(DWORD depth)
-{
-    switch (depth)
-    {
-    case  8: return pixelformats + 0;
-    case 15: return pixelformats + 1;
-    case 16: return pixelformats + 2;
-    case 24: return pixelformats + 3;
-    case 32: return pixelformats + 4;
-    default: return NULL;
-    }
-}
-
-/* Not called from the vtable. */
-HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
-{
-    HRESULT hr;
-    DWORD depth;
-    HDC hDC;
-
-    TRACE("(%p,%d)\n",This,ex);
-
-    hr = Main_DirectDraw_Construct(This, ex);
-    if (FAILED(hr)) return hr;
-
-    This->final_release = User_DirectDraw_final_release;
-
-    This->create_primary    = User_DirectDraw_create_primary;
-    This->create_backbuffer = User_DirectDraw_create_backbuffer;
-
-    hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
-    depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
-    DeleteDC(hDC);
-
-    This->width       = GetSystemMetrics(SM_CXSCREEN);
-    This->height      = GetSystemMetrics(SM_CYSCREEN);
-    This->pitch       = DDRAW_width_bpp_to_pitch(This->width, depth);
-    This->pixelformat = *pixelformat_for_depth(depth);
-
-    This->orig_width       = This->width;
-    This->orig_height      = This->height;
-    This->orig_pitch       = This->pitch;
-    This->orig_pixelformat = This->pixelformat;
-
-    ICOM_INIT_INTERFACE(This, IDirectDraw7, User_DirectDraw_VTable);
-
-    /* capabilities */
-#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
-	  | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP	  \
-	  | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY			  \
-	  | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
-#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
-#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT	\
-		| DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90	\
-		| DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN		\
-		| DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN		\
-		| DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN		\
-		| DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
-    This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS;
-    if( opengl_initialized )
-    {
-        /* Hack for D3D code */
-        This->caps.dwCaps |= DDCAPS_3D;
-    }
-    This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED |
-			  DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES;
-    This->caps.dwCKeyCaps |= CKEY_CAPS;
-    This->caps.dwFXCaps |= FX_CAPS;
-    This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
-    This->caps.dwVidMemTotal = 16*1024*1024;
-    This->caps.dwVidMemFree = 16*1024*1024;
-    This->caps.dwSVBCaps |= BLIT_CAPS;
-    This->caps.dwSVBCKeyCaps |= CKEY_CAPS;
-    This->caps.dwSVBFXCaps |= FX_CAPS;
-    This->caps.dwVSBCaps |= BLIT_CAPS;
-    This->caps.dwVSBCKeyCaps |= CKEY_CAPS;
-    This->caps.dwVSBFXCaps |= FX_CAPS;
-    This->caps.dwSSBCaps |= BLIT_CAPS;
-    This->caps.dwSSBCKeyCaps |= CKEY_CAPS;
-    This->caps.dwSSBFXCaps |= FX_CAPS;
-    This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER |
-				 DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
-				 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE |
-				 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
-				 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
-    if( opengl_initialized )
-    {
-        /* Hacks for D3D code */
-        This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
-    }
-    
-    This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
-#undef BLIT_CAPS
-#undef CKEY_CAPS
-#undef FX_CAPS
-
-    return S_OK;
-}
-
-/* This function is called from DirectDrawCreate(Ex) on the most-derived
- * class to start construction.
- * Not called from the vtable. */
-HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-			       IUnknown* pUnkOuter, BOOL ex)
-{
-    HRESULT hr;
-    IDirectDrawImpl* This;
-
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(IDirectDrawImpl) + sizeof(User_DirectDrawImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    /* Note that this relation does *not* hold true if the DD object was
-     * CoCreateInstanced then Initialized. */
-    This->private = (User_DirectDrawImpl *)(This+1);
-
-    /* Initialize the DDCAPS structure */
-    This->caps.dwSize = sizeof(This->caps);
-
-    hr = User_DirectDraw_Construct(This, ex);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
-
-    return hr;
-}
-
-/* This function is called from Uninit_DirectDraw_Initialize on the
- * most-derived-class to start initialization.
- * Not called from the vtable. */
-HRESULT User_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
-{
-    HRESULT hr;
-    This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			      sizeof(User_DirectDrawImpl));
-    if (This->private == NULL) return E_OUTOFMEMORY;
-
-    /* Initialize the DDCAPS structure */
-    This->caps.dwSize = sizeof(This->caps);
-
-    hr = User_DirectDraw_Construct(This, TRUE); /* XXX ex? */
-    if (FAILED(hr))
-    {
-	HeapFree(GetProcessHeap(), 0, This->private);
-	return hr;
-    }
-
-    return DD_OK;
-}
-
-/* Called from an internal function pointer. */
-void User_DirectDraw_final_release(IDirectDrawImpl *This)
-{
-    Main_DirectDraw_final_release(This);
-}
-
-/* Compact: generic */
-/* CreateClipper: generic */
-/* CreatePalette: generic (with callback) */
-/* CreateSurface: generic (with callbacks) */
-
-HRESULT
-User_DirectDraw_create_primary(IDirectDrawImpl* This,
-			       const DDSURFACEDESC2* pDDSD,
-			       LPDIRECTDRAWSURFACE7* ppSurf,
-			       IUnknown* pUnkOuter)
-{
-    return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-}
-
-HRESULT
-User_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
-				  const DDSURFACEDESC2* pDDSD,
-				  LPDIRECTDRAWSURFACE7* ppSurf,
-				  IUnknown* pUnkOuter,
-				  IDirectDrawSurfaceImpl* primary)
-{
-    return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
-}
-
-/* DuplicateSurface: generic */
-
-/* Originally derived from Xlib_IDirectDraw2Impl_EnumDisplayModes.
- *
- * The depths are whatever DIBsections support on the client side.
- * Should they be limited by screen depth?
- */
-HRESULT WINAPI
-User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				 LPDDSURFACEDESC2 pDDSD, LPVOID context,
-				 LPDDENUMMODESCALLBACK2 callback)
-{
-    DDSURFACEDESC2 callback_sd;
-    DEVMODEW DevModeW;
-    const DDPIXELFORMAT* pixelformat;
-
-    int i;
-
-    TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",iface,dwFlags,pDDSD,context,callback);
-
-    ZeroMemory(&callback_sd, sizeof(callback_sd));
-    callback_sd.dwSize = sizeof(callback_sd);
-
-    callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS
-	| DDSD_PITCH;
-
-    if (dwFlags & DDEDM_REFRESHRATES)
-	callback_sd.dwFlags |= DDSD_REFRESHRATE;
-
-    callback_sd.u2.dwRefreshRate = 60.0;
-
-    i = 0;
-    while (EnumDisplaySettingsExW(NULL, i, &DevModeW, 0))
-    {
-	callback_sd.dwHeight = DevModeW.dmPelsHeight;
-	callback_sd.dwWidth = DevModeW.dmPelsWidth;
-        if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
-        {
-            callback_sd.u2.dwRefreshRate = DevModeW.dmDisplayFrequency;
-        }
-
-	TRACE("- mode: %ldx%ld\n", callback_sd.dwWidth, callback_sd.dwHeight);
-        
-        pixelformat = pixelformat_for_depth(DevModeW.dmBitsPerPel);
-        callback_sd.u1.lPitch
-            = DDRAW_width_bpp_to_pitch(DevModeW.dmPelsWidth,
-                                       pixelformat->u1.dwRGBBitCount);
-
-        callback_sd.u4.ddpfPixelFormat = *pixelformat;
-
-        callback_sd.ddsCaps.dwCaps = 0;
-        if (pixelformat->dwFlags & DDPF_PALETTEINDEXED8) /* ick */
-            callback_sd.ddsCaps.dwCaps |= DDSCAPS_PALETTE;
-
-        TRACE(" - %2ld bpp, R=%08lx G=%08lx B=%08lx\n",
-            callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
-            callback_sd.u4.ddpfPixelFormat.u2.dwRBitMask,
-            callback_sd.u4.ddpfPixelFormat.u3.dwGBitMask,
-            callback_sd.u4.ddpfPixelFormat.u4.dwBBitMask);
-        if (callback(&callback_sd, context) == DDENUMRET_CANCEL)
-            return DD_OK;
-        i++;
-    }
-
-    return DD_OK;
-}
-
-/* EnumSurfaces: generic */
-/* FlipToGDISurface: ??? */
-
-#if 0
-HRESULT WINAPI
-User_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
-			LPDDCAPS pHELCaps)
-{
-/* Based on my guesses for what is appropriate with some clues from the
- * NVidia driver. Not everything is actually implemented yet.
- * NV has but we don't: Overlays, Video Ports, DDCAPS_READSCANLINE,
- * DDCAPS2_CERTIFIED (heh), DDSCAPS2_NONLOCALVIDMEM, DDSCAPS2_COPYFOURCC.
- * It actually has no FX alpha caps.
- * Oddly, it doesn't list DDPCAPS_PRIMARYSURFACE.
- * And the HEL caps make little sense.
- */
-#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
-	  | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP	  \
-	  | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY			  \
-	  | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
-
-#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
-
-#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT	\
-		| DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90	\
-		| DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN		\
-		| DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN		\
-		| DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN		\
-		| DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
-
-#if 0
-#define ROPS { SRCCOPY, SRCPAINT, SRCAND, SRCINVERT, SRCERASE, NOTSRCCOPY, \
-	NOTSRCERASE, MERGEPAINT, BLACKNESS, WHITENESS, }
-#else
-#define ROPS { 0, }
-#endif
-
-    static const DDCAPS caps =
-    { sizeof(DDCAPS),
-      DDCAPS_3D | DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS,
-      DDCAPS2_CANMANAGETEXTURE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_CERTIFIED
-      | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA
-      | DDCAPS2_WIDESURFACES,
-      CKEY_CAPS,
-      FX_CAPS,
-      0, /* dwFXAlphaCaps */
-      DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,
-      0, /* dwSVCaps */
-      0, /* ? dwAlphaBitConstBitDepths */
-      0, /* ? dwAlphaBitPixelPitDepths */
-      0, /* ? dwAlphaBltSurfaceBitDepths */
-      0, /* ? dwAlphaOverlayConstBitDepths */
-      0, /* ? dwAlphaOverlayPixelBitDepths */
-      0, /* ? dwAlphaOverlaySurfaceBitDepths */
-      DDBD_16, /* ? dwZBufferBitDepths */
-      16*1024*1024, /* dwVidMemTotal */
-      16*1024*1024, /* dwVidMemFree */
-      0, /* dwMaxVisibleOverlays */
-      0, /* dwCurrVisibleOverlays */
-      0, /* dwNumFourCCCodes */
-      0, /* dwAlignBoundarySrc */
-      0, /* dwAlignSizeSrc */
-      0, /* dwAlignBoundaryDest */
-      0, /* dwAlignSizeDest */
-      0, /* dwAlignStrideAlign */
-      ROPS, /* XXX dwRops[DD_ROP_SPACE] */
-      { 0, }, /* XXX ddsOldCaps */
-      1000, /* dwMinOverlayStretch */
-      1000, /* dwMaxOverlayStretch */
-      1000, /* dwMinLiveVideoStretch */
-      1000, /* dwMaxLiveVideoStretch */
-      1000, /* dwMinHwCodecStretch */
-      1000, /* dwMaxHwCodecStretch */
-      0, 0, 0, /* dwReserved1, 2, 3 */
-      BLIT_CAPS, /* dwSVBCaps */
-      CKEY_CAPS, /* dwSVBCKeyCaps */
-      FX_CAPS, /* dwSVBFXCaps */
-      ROPS, /* dwSVBRops */
-      BLIT_CAPS, /* dwVSBCaps */
-      CKEY_CAPS, /* dwVSBCKeyCaps */
-      FX_CAPS, /* dwVSBFXCaps */
-      ROPS, /* dwVSBRops */
-      BLIT_CAPS, /* dwSSBCaps */
-      CKEY_CAPS, /* dwSSBCKeyCaps */
-      FX_CAPS, /* dwSSBFXCaps */
-      ROPS, /* dwSSBRops */
-      0, /* dwMaxVideoPorts */
-      0, /* dwCurrVideoPorts */
-      0, /* ? dwSVBCaps2 */
-      BLIT_CAPS, /* ? dwNLVBCaps */
-      0, /* ? dwNLVBCaps2 */
-      CKEY_CAPS, /* dwNLVBCKeyCaps */
-      FX_CAPS, /* dwNLVBFXCaps */
-      ROPS, /* dwNLVBRops */
-      { /* ddsCaps */
-	  DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP
-	  | DDSCAPS_FRONTBUFFER | DDSCAPS_MIPMAP | DDSCAPS_OFFSCREENPLAIN
-	  | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
-	  | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE
-	  | DDSCAPS_ZBUFFER,
-	  DDSCAPS2_CUBEMAP,
-	  0,
-	  0
-      }
-    };
-
-#undef BLIT_CAPS
-#undef CKEY_CAPS
-#undef FX_CAPS
-#undef ROPS
-
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    TRACE("(%p)->(%p,%p)\n",This,pDriverCaps,pHELCaps);
-
-    if (pDriverCaps != NULL)
-	DD_STRUCT_COPY_BYSIZE(pDriverCaps,&caps);
-
-    if (pHELCaps != NULL)
-	DD_STRUCT_COPY_BYSIZE(pHELCaps,&caps);
-
-    return DD_OK;
-}
-#endif
-
-HRESULT WINAPI
-User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
-				    LPDDDEVICEIDENTIFIER2 pDDDI,
-				    DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%08lx)\n",iface,pDDDI,dwFlags);
-    *pDDDI = user_device;
-    return DD_OK;
-}
-
-/* GetDisplayMode: generic */
-/* GetFourCCCodes: generic */
-/* GetGDISurface: ??? */
-/* GetMonitorFrequency: generic */
-/* GetScanLine: generic */
-/* GetSurfaceFromDC: generic */
-/* GetVerticalBlankStatus: generic */
-/* Initialize: generic */
-/* RestoreAllSurfaces: generic */
-/* RestoreDisplayMode: generic */
-/* SetCooperativeLevel: ??? */
-
-HRESULT WINAPI
-User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-			       DWORD dwHeight, DWORD dwBPP,
-			       DWORD dwRefreshRate, DWORD dwFlags)
-{
-    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-
-    const DDPIXELFORMAT* pixelformat;
-    DEVMODEW devmode;
-    LONG pitch;
-
-    TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
-    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-    devmode.dmBitsPerPel = dwBPP;
-    devmode.dmPelsWidth  = dwWidth;
-    devmode.dmPelsHeight = dwHeight;
-    /* '0' means default frequency */
-    if (dwRefreshRate != 0) 
-    {
-	devmode.dmFields |= DM_DISPLAYFREQUENCY;
-	devmode.dmDisplayFrequency = dwRefreshRate;
-    }
-    if (ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
-	return DDERR_INVALIDMODE;
-
-    pixelformat = pixelformat_for_depth(dwBPP);
-    if (pixelformat == NULL)
-    {
-	assert(0);
-	return DDERR_GENERIC;
-    }
-
-    pitch = DDRAW_width_bpp_to_pitch(dwWidth, dwBPP);
-    return Main_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, pitch,
-					  dwRefreshRate, dwFlags, pixelformat);
-}
-
-/* StartModeTest: ??? */
-/* TestCooperativeLevel: generic? */
-/* WaitForVerticalBlank: ??? */
-
-static const IDirectDraw7Vtbl User_DirectDraw_VTable =
-{
-    Main_DirectDraw_QueryInterface,
-    Main_DirectDraw_AddRef,
-    Main_DirectDraw_Release,
-    Main_DirectDraw_Compact,
-    Main_DirectDraw_CreateClipper,
-    Main_DirectDraw_CreatePalette,
-    Main_DirectDraw_CreateSurface,
-    Main_DirectDraw_DuplicateSurface,
-    User_DirectDraw_EnumDisplayModes,
-    Main_DirectDraw_EnumSurfaces,
-    Main_DirectDraw_FlipToGDISurface,
-    Main_DirectDraw_GetCaps,
-    Main_DirectDraw_GetDisplayMode,
-    Main_DirectDraw_GetFourCCCodes,
-    Main_DirectDraw_GetGDISurface,
-    Main_DirectDraw_GetMonitorFrequency,
-    Main_DirectDraw_GetScanLine,
-    Main_DirectDraw_GetVerticalBlankStatus,
-    Main_DirectDraw_Initialize,
-    Main_DirectDraw_RestoreDisplayMode,
-    Main_DirectDraw_SetCooperativeLevel,
-    User_DirectDraw_SetDisplayMode,
-    Main_DirectDraw_WaitForVerticalBlank,
-    Main_DirectDraw_GetAvailableVidMem,
-    Main_DirectDraw_GetSurfaceFromDC,
-    Main_DirectDraw_RestoreAllSurfaces,
-    Main_DirectDraw_TestCooperativeLevel,
-    User_DirectDraw_GetDeviceIdentifier,
-    Main_DirectDraw_StartModeTest,
-    Main_DirectDraw_EvaluateMode
-};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/ddraw/ddraw_main.c	2005-06-03 20:50:30.000000000 +0100
@@ -0,0 +1,1728 @@
+/*		DirectDraw IDirectDraw interface (generic)
+ *
+ * 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
+ *
+ * NOTES
+ *
+ * WINE currently implements a very basic set of the DirectDraw functionality
+ * in graphics/ddraw.c. This implementation uses either the XFree86-DGA extension 
+ * to get very fast access to the graphics card framebuffer and doublebuffering
+ * features or Xlib, which is slower.
+ * The implementation using XFree86-DGA is as fast as the MS equivalent for the
+ * stuff that is implemented.
+ *
+ * Several applications already work, see below.
+ * Problems of the implementation using XFree86-DGA:
+ *
+ *	- XFree86 cannot switch depth on the fly.
+ *	  This is a problem with X and unavoidable.
+ *	  Current solution is to pop up a MessageBox with an error for 
+ *	  mismatched parameters and advice the user to restart the X server
+ *	  with the specified depth.
+ *	- The rest of the functionality that has to be implemented will have
+ *	  to be done in software and will be very slow.
+ *	- This requires WINE to be run as root user so XF86DGA can mmap the
+ *	  framebuffer into the addressspace of the process.
+ *	- Blocks all other X windowed applications.
+ *
+ * This file contains all the interface functions that are shared between
+ * all interfaces. Or better, it is a "common stub" library for the
+ * IDirectDraw* objects
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#define CONST_VTABLE
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "wine/debug.h"
+
+#include "ddraw_private.h"
+#include "mesa_private.h" /* To have the D3D creation function */
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+extern const IDirectDrawVtbl DDRAW_IDirectDraw_VTable;
+extern const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable;
+extern const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable;
+
+static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This);
+
+static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This);
+static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This);
+static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This);
+static void LosePrimarySurface(IDirectDrawImpl* This);
+
+static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) ;
+static void free_memory(IDirectDrawImpl *This, DWORD mem) ;
+
+
+static const char ddProp[] = "WINE_DDRAW_Property";
+
+/* Not called from the vtable. */
+HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
+{
+    /* NOTE: The creator must use HEAP_ZERO_MEMORY or equivalent. */
+    This->ref = 1;
+    This->ex = ex;
+
+    if (ex) This->local.dwLocalFlags |= DDRAWILCL_DIRECTDRAW7;
+    This->local.dwProcessId = GetCurrentProcessId();
+
+    This->final_release = Main_DirectDraw_final_release;
+
+    This->create_palette = Main_DirectDrawPalette_Create;
+
+    This->create_offscreen = Main_create_offscreen;
+    This->create_texture   = Main_create_texture;
+    This->create_zbuffer   = Main_create_zbuffer;
+    /* There are no generic versions of create_{primary,backbuffer}. */
+
+    ICOM_INIT_INTERFACE(This, IDirectDraw,  DDRAW_IDirectDraw_VTable);
+    ICOM_INIT_INTERFACE(This, IDirectDraw2, DDRAW_IDirectDraw2_VTable);
+    ICOM_INIT_INTERFACE(This, IDirectDraw4, DDRAW_IDirectDraw4_VTable);
+    /* There is no generic implementation of IDD7 */
+
+    /* This is for the moment here... */
+    This->free_memory = free_memory;
+    This->allocate_memory = allocate_memory;
+    This->total_vidmem = 64 * 1024 * 1024;
+    This->available_vidmem = This->total_vidmem;
+      
+    return DD_OK;
+}
+
+void Main_DirectDraw_final_release(IDirectDrawImpl* This)
+{
+    if (IsWindow(This->window))
+    {
+	if (GetPropA(This->window, ddProp))
+	    DDRAW_UnsubclassWindow(This);
+	else
+	    FIXME("this shouldn't happen, right?\n");
+    }
+
+    Main_DirectDraw_DeleteSurfaces(This);
+    Main_DirectDraw_DeleteClippers(This);
+    Main_DirectDraw_DeletePalettes(This);
+    if (This->local.lpGbl && This->local.lpGbl->lpExclusiveOwner == &This->local)
+    {
+	This->local.lpGbl->lpExclusiveOwner = NULL;
+	if (This->set_exclusive_mode)
+	    This->set_exclusive_mode(This, FALSE);
+    }
+}
+
+/* There is no Main_DirectDraw_Create. */
+
+ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface) {
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref -1);
+
+    return ref;
+}
+
+ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface) {
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref +1);
+
+    if (ref == 0)
+    {
+	if (This->final_release != NULL)
+	    This->final_release(This);
+
+	/* We free the private. This is an artifact of the fact that I don't
+	 * have the destructors set up correctly. */
+	if (This->private != (This+1))
+	    HeapFree(GetProcessHeap(), 0, This->private);
+
+	HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+HRESULT WINAPI Main_DirectDraw_QueryInterface(
+    LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj
+) {
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
+
+    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
+    *obj = NULL;
+    
+    if ( IsEqualGUID( &IID_IUnknown, refiid )
+	 || IsEqualGUID( &IID_IDirectDraw7, refiid ) )
+    {
+	*obj = ICOM_INTERFACE(This, IDirectDraw7);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
+    {
+	*obj = ICOM_INTERFACE(This, IDirectDraw);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
+    {
+	*obj = ICOM_INTERFACE(This, IDirectDraw2);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    {
+	*obj = ICOM_INTERFACE(This, IDirectDraw4);
+    }
+#ifdef HAVE_OPENGL
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        if (opengl_initialized) {
+	    HRESULT ret_value;
+
+	    ret_value = direct3d_create(This);
+	    if (FAILED(ret_value)) return ret_value;
+	    
+	    if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ) {
+	        *obj = ICOM_INTERFACE(This, IDirect3D);
+		TRACE(" returning Direct3D interface at %p.\n", *obj);	    
+	    } else if ( IsEqualGUID( &IID_IDirect3D2  , refiid ) ) {
+	        *obj = ICOM_INTERFACE(This, IDirect3D2);
+		TRACE(" returning Direct3D2 interface at %p.\n", *obj);	    
+	    } else if ( IsEqualGUID( &IID_IDirect3D3  , refiid ) ) {
+	        *obj = ICOM_INTERFACE(This, IDirect3D3);
+		TRACE(" returning Direct3D3 interface at %p.\n", *obj);	    
+	    } else {
+	        *obj = ICOM_INTERFACE(This, IDirect3D7);
+		TRACE(" returning Direct3D7 interface at %p.\n", *obj);	    
+	    }
+	} else {
+	    ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n");
+	    ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
+	    return E_NOINTERFACE;
+	}
+    }
+#else
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n");
+	ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
+	return E_NOINTERFACE;
+    }
+#endif
+    else
+    {
+	FIXME("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);
+	return E_NOINTERFACE;
+    }
+
+    IDirectDraw7_AddRef(iface);
+    return S_OK;
+}
+
+/* MSDN: "not currently implemented". */
+HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
+{
+    TRACE("(%p)\n", iface);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface,
+					     DWORD dwFlags,
+					     LPDIRECTDRAWCLIPPER *ppClipper,
+					     IUnknown *pUnkOuter)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    HRESULT hr;
+
+    TRACE("(%p)->(0x%lx, %p, %p)\n", iface, dwFlags, ppClipper, pUnkOuter);
+
+    hr = DirectDrawCreateClipper(dwFlags, ppClipper, pUnkOuter);
+    if (FAILED(hr)) return hr;
+
+    /* dwFlags is passed twice, apparently an API wart. */
+    hr = IDirectDrawClipper_Initialize(*ppClipper,
+				       ICOM_INTERFACE(This, IDirectDraw),
+				       dwFlags);
+    if (FAILED(hr))
+    {
+	IDirectDrawClipper_Release(*ppClipper);
+	return hr;
+    }
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
+			      LPPALETTEENTRY palent,
+			      LPDIRECTDRAWPALETTE* ppPalette,
+			      LPUNKNOWN pUnknown)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    LPDIRECTDRAWPALETTE pPalette;
+    HRESULT hr;
+
+    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ppPalette,pUnknown);
+
+    if (ppPalette == NULL) return E_POINTER; /* unchecked */
+    if (pUnknown != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */
+
+    hr = This->create_palette(This, dwFlags, &pPalette, pUnknown);
+    if (FAILED(hr)) return hr;
+
+    hr = IDirectDrawPalette_SetEntries(pPalette, 0, 0,
+				       Main_DirectDrawPalette_Size(dwFlags),
+				       palent);
+    if (FAILED(hr))
+    {
+	IDirectDrawPalette_Release(pPalette);
+	return hr;
+    }
+    else
+    {
+	*ppPalette = pPalette;
+	return DD_OK;
+    }
+}
+
+HRESULT
+Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
+		      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
+{
+    assert(pOuter == NULL);
+
+    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
+}
+
+HRESULT
+Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
+		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,
+		    DWORD dwMipMapLevel)
+{
+    assert(pOuter == NULL);
+
+    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
+}
+
+HRESULT
+Main_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,
+		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter)
+{
+    assert(pOuter == NULL);
+
+    return FakeZBuffer_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
+}
+
+/* Does the texture surface described in pDDSD have any smaller mipmaps? */
+static BOOL more_mipmaps(const DDSURFACEDESC2 *pDDSD)
+{
+    return ((pDDSD->dwFlags & DDSD_MIPMAPCOUNT) && pDDSD->u2.dwMipMapCount > 1
+	    && (pDDSD->dwWidth > 1 || pDDSD->dwHeight > 1));
+}
+
+/* Create a texture surface along with any of its mipmaps. */
+static HRESULT
+create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
+	       LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
+{
+    DDSURFACEDESC2 ddsd;
+    DWORD mipmap_level = 0;
+    HRESULT hr;
+
+    assert(pUnkOuter == NULL);
+
+    /* is this check right? (pixelformat can be copied from primary) */
+    if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
+	return DDERR_INVALIDPARAMS;
+
+    ddsd.dwSize = sizeof(ddsd);
+    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
+
+    if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
+    {
+	ddsd.u4.ddpfPixelFormat = This->pixelformat;
+    }
+
+#ifdef HAVE_OPENGL
+    /* We support for now only DXT1, DXT3 & DXT5 compressed texture formats... */
+    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
+        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','1')) &&
+        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','3')) &&
+        (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','5')) )
+    {
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
+    /* Check if we can really support DXT1, DXT3 & DXT5 */
+    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
+	!GL_extensions.s3tc_compressed_texture && !s3tc_initialized) {
+	static BOOLEAN user_warned = 0;
+	if (user_warned == 0) {
+	    ERR("Trying to create DXT1, DXT3 or DXT5 texture which is not supported by the video card!!!\n");
+	    ERR("However there is a library libtxc_dxtn.so that can be used to do the software decompression...\n");
+	    user_warned = 1;
+	}
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+#else
+    if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
+    {
+	return DDERR_INVALIDPIXELFORMAT;
+    }
+#endif
+
+    if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_LINEARSIZE))
+    {
+	int size = 0;
+	int width = ddsd.dwWidth;
+	int height = ddsd.dwHeight;
+	switch(ddsd.u4.ddpfPixelFormat.dwFourCC) {
+	    case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
+	    case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
+	    case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
+	    default: FIXME("FOURCC not supported\n"); break;
+	}
+	ddsd.u1.dwLinearSize = size;
+	ddsd.dwFlags |= DDSD_LINEARSIZE;
+    } else if (!(ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_PITCH)) {
+	ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
+	ddsd.dwFlags |= DDSD_PITCH;
+    }
+
+    if((ddsd.ddsCaps.dwCaps & DDSCAPS_MIPMAP) &&
+        !(ddsd.dwFlags & DDSD_MIPMAPCOUNT))
+    {
+        if(ddsd.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
+        {
+            /* Undocumented feature: if DDSCAPS_MIPMAP and DDSCAPS_COMPLEX are
+             * both set, but mipmap count isn't given, as many mipmap levels
+             * as necessary are created to get down to a size where either
+             * the width or the height of the texture is 1.
+             *
+             * This is needed by Anarchy Online. */
+            DWORD min = ddsd.dwWidth < ddsd.dwHeight ?
+                        ddsd.dwWidth : ddsd.dwHeight;
+            ddsd.u2.dwMipMapCount = 0;
+            while( min )
+            {
+                ddsd.u2.dwMipMapCount++;
+                min >>= 1;
+            }
+        }
+        else
+            /* Create a single mipmap. */
+            ddsd.u2.dwMipMapCount = 1;
+ 
+        ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
+    }
+    
+    ddsd.dwFlags |= DDSD_PIXELFORMAT;
+
+    hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
+    if (FAILED(hr)) return hr;
+
+    if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE, 
+						    ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
+
+    /* Create attached mipmaps if required. */
+    if (more_mipmaps(&ddsd))
+    {
+	LPDIRECTDRAWSURFACE7 mipmap;
+	LPDIRECTDRAWSURFACE7 prev_mipmap;
+	DDSURFACEDESC2 mipmap_surface_desc;
+
+	prev_mipmap = *ppSurf;
+	IDirectDrawSurface7_AddRef(prev_mipmap);
+	mipmap_surface_desc = ddsd;
+	mipmap_surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
+
+	while (more_mipmaps(&mipmap_surface_desc))
+	{
+	    IDirectDrawSurfaceImpl *mipmap_impl;
+	    
+	    mipmap_level++;
+	    mipmap_surface_desc.u2.dwMipMapCount--;
+
+	    if (mipmap_surface_desc.dwWidth > 1)
+		mipmap_surface_desc.dwWidth /= 2;
+
+	    if (mipmap_surface_desc.dwHeight > 1)
+		mipmap_surface_desc.dwHeight /= 2;
+
+	    if (mipmap_surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
+		int size = 0;
+		int width = mipmap_surface_desc.dwWidth;
+		int height = mipmap_surface_desc.dwHeight;
+		switch(mipmap_surface_desc.u4.ddpfPixelFormat.dwFourCC) {
+		    case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
+		    case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
+		    case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
+		    default: FIXME("FOURCC not supported\n"); break;
+		}
+		mipmap_surface_desc.u1.dwLinearSize = size;
+	    } else {
+		ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
+		mipmap_surface_desc.u1.lPitch
+		    = DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth,
+					       GET_BPP(ddsd)*8);
+	    }
+
+	    hr = This->create_texture(This, &mipmap_surface_desc, &mipmap,
+				      pUnkOuter, mipmap_level);
+	    if (FAILED(hr))
+	    {
+		IDirectDrawSurface7_Release(prev_mipmap);
+		IDirectDrawSurface7_Release(*ppSurf);
+		return hr;
+	    }
+	    
+	    /* This is needed for delayed mipmap creation */
+	    mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap);
+	    mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf);
+	    mipmap_impl->mipmap_level = mipmap_level;
+
+	    if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE,
+							    ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
+
+	    IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
+	    IDirectDrawSurface7_Release(prev_mipmap);
+	    prev_mipmap = mipmap;
+	}
+
+	IDirectDrawSurface7_Release(prev_mipmap);
+    }
+
+    return DD_OK;
+}
+
+/* Creates a primary surface and any indicated backbuffers. */
+static HRESULT
+create_primary(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
+	       LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
+{
+    DDSURFACEDESC2 ddsd;
+    HRESULT hr;
+
+    assert(pUnkOuter == NULL);
+
+    if (This->primary_surface != NULL)
+	return DDERR_PRIMARYSURFACEALREADYEXISTS;
+
+    /* as documented (what about pitch?) */
+    if (pDDSD->dwFlags & (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT))
+	return DDERR_INVALIDPARAMS;
+
+    ddsd.dwSize = sizeof(ddsd);
+    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
+    ddsd.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
+    ddsd.dwHeight = This->height;
+    ddsd.dwWidth = This->width;
+    ddsd.u1.lPitch = This->pitch;
+    ddsd.u4.ddpfPixelFormat = This->pixelformat;
+    ddsd.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY
+	| DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER;
+
+    if ((ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) && ddsd.dwBackBufferCount > 0)
+	ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP;
+
+    hr = This->create_primary(This, &ddsd, ppSurf, pUnkOuter);
+    if (FAILED(hr)) return hr;
+
+    if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT)
+    {
+	IDirectDrawSurfaceImpl* primary;
+	LPDIRECTDRAWSURFACE7 pPrev;
+	DWORD i;
+
+	ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+	ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE
+				 | DDSCAPS_BACKBUFFER | DDSCAPS_FRONTBUFFER);
+
+	primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7,
+			      *ppSurf);
+	pPrev = *ppSurf;
+	IDirectDrawSurface7_AddRef(pPrev);
+
+	for (i=0; i < ddsd.dwBackBufferCount; i++)
+	{
+	    LPDIRECTDRAWSURFACE7 pBack;
+
+	    if (i == 0)
+		ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+	    else
+		ddsd.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
+
+	    hr = This->create_backbuffer(This, &ddsd, &pBack, pUnkOuter,
+					 primary);
+
+	    if (FAILED(hr))
+	    {
+		IDirectDraw7_Release(pPrev);
+		IDirectDraw7_Release(*ppSurf);
+		return hr;
+	    }
+
+	    IDirectDrawSurface7_AddAttachedSurface(pPrev, pBack);
+	    IDirectDrawSurface7_Release(pPrev);
+	    pPrev = pBack;
+	}
+
+	IDirectDrawSurface7_Release(pPrev);
+    }
+
+    This->primary_surface = (IDirectDrawSurfaceImpl *)*ppSurf;
+
+    return DD_OK;
+}
+
+static HRESULT
+create_offscreen(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD,
+		 LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter)
+{
+    DDSURFACEDESC2 ddsd;
+    HRESULT hr;
+
+    /* is this check right? (pixelformat can be copied from primary) */
+    if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))
+	return DDERR_INVALIDPARAMS;
+
+    ddsd.dwSize = sizeof(ddsd);
+    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);
+
+    if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))
+    {
+	ddsd.u4.ddpfPixelFormat = This->pixelformat;
+    }
+
+    if (!(ddsd.dwFlags & DDSD_PITCH))
+    {
+	ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,
+						  GET_BPP(ddsd)*8);
+    }
+
+    ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT;
+
+    hr = This->create_offscreen(This, &ddsd, ppSurf, pUnkOuter);
+    if (FAILED(hr)) return hr;
+
+    return hr;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
+			      LPDIRECTDRAWSURFACE7 *ppSurf,
+			      IUnknown *pUnkOuter)
+{
+    HRESULT hr;
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)->(%p,%p,%p)\n",This,pDDSD,ppSurf,pUnkOuter);
+    if (TRACE_ON(ddraw)) {
+        TRACE("Requesting surface desc :\n");
+        DDRAW_dump_surface_desc(pDDSD);
+    }
+
+    if (pUnkOuter != NULL) {
+	FIXME("outer != NULL?\n");
+	return CLASS_E_NOAGGREGATION; /* unchecked */
+    }
+
+    if (!(pDDSD->dwFlags & DDSD_CAPS)) {
+	/* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
+    	pDDSD->dwFlags |= DDSD_CAPS;
+    }
+    if (pDDSD->ddsCaps.dwCaps == 0) {
+	/* This has been checked on real Windows */
+	pDDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+    }
+
+    if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) {
+        /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
+        pDDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if ((pDDSD->dwFlags & DDSD_LPSURFACE) && (pDDSD->lpSurface == NULL)) {
+        /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */
+        WARN("Null surface pointer specified, ignore it!\n");
+        pDDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if (ppSurf == NULL) {
+	FIXME("You want to get back a surface? Don't give NULL ptrs!\n");
+	return E_POINTER; /* unchecked */
+    }
+
+    if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+	/* create primary surface & backbuffers */
+	hr = create_primary(This, pDDSD, ppSurf, pUnkOuter);
+    }
+    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
+    {
+       /* create backbuffer surface */
+       hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL);
+    }
+    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
+    {
+	/* create texture */
+	hr = create_texture(This, pDDSD, ppSurf, pUnkOuter);
+    }
+    else if ( (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) &&
+	     !(pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) /* Support DDSCAPS_SYSTEMMEMORY */
+    {
+	/* create z-buffer */
+	hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter);
+    }
+    else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) ||
+	     (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */
+    {
+	/* create offscreenplain surface */
+	hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
+    }
+    else
+    {
+	/* Otherwise, assume offscreenplain surface */
+	TRACE("App didn't request a valid surface type - assuming offscreenplain\n");
+	hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter);
+    }
+
+    if (FAILED(hr)) {
+	FIXME("failed surface creation with code 0x%08lx\n",hr);
+	return hr;
+    }
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
+				 LPDIRECTDRAWSURFACE7* dst)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl,
+					       IDirectDrawSurface7, src);
+
+    TRACE("(%p)->(%p,%p)\n",This,src,dst);
+
+    return pSrc->duplicate_surface(pSrc, dst);
+}
+
+/* EnumDisplayModes */
+
+BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested,
+					 const DDPIXELFORMAT *provided)
+{
+    /* Some flags must be present in both or neither for a match. */
+    static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
+	| DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC
+	| DDPF_ZBUFFER | DDPF_STENCILBUFFER;
+
+    if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
+	return FALSE;
+
+    if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match))
+	return FALSE;
+
+    if (requested->dwFlags & DDPF_FOURCC)
+	if (requested->dwFourCC != provided->dwFourCC)
+	    return FALSE;
+
+    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA
+			      |DDPF_LUMINANCE|DDPF_BUMPDUDV))
+	if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount)
+	    return FALSE;
+
+    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
+			      |DDPF_LUMINANCE|DDPF_BUMPDUDV))
+	if (requested->u2.dwRBitMask != provided->u2.dwRBitMask)
+	    return FALSE;
+
+    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV))
+	if (requested->u3.dwGBitMask != provided->u3.dwGBitMask)
+	    return FALSE;
+
+    /* I could be wrong about the bumpmapping. MSDN docs are vague. */
+    if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER
+			      |DDPF_BUMPDUDV))
+	if (requested->u4.dwBBitMask != provided->u4.dwBBitMask)
+	    return FALSE;
+
+    if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS))
+	if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask)
+	    return FALSE;
+
+    return TRUE;
+}
+
+BOOL Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2* requested,
+				const DDSURFACEDESC2* provided)
+{
+    struct compare_info
+    {
+	DWORD flag;
+	ptrdiff_t offset;
+	size_t size;
+    };
+
+#define CMP(FLAG, FIELD)				\
+	{ DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD),	\
+	  sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) }
+
+    static const struct compare_info compare[] = {
+	CMP(ALPHABITDEPTH, dwAlphaBitDepth),
+	CMP(BACKBUFFERCOUNT, dwBackBufferCount),
+	CMP(CAPS, ddsCaps),
+	CMP(CKDESTBLT, ddckCKDestBlt),
+	CMP(CKDESTOVERLAY, u3.ddckCKDestOverlay),
+	CMP(CKSRCBLT, ddckCKSrcBlt),
+	CMP(CKSRCOVERLAY, ddckCKSrcOverlay),
+	CMP(HEIGHT, dwHeight),
+	CMP(LINEARSIZE, u1.dwLinearSize),
+	CMP(LPSURFACE, lpSurface),
+	CMP(MIPMAPCOUNT, u2.dwMipMapCount),
+	CMP(PITCH, u1.lPitch),
+	/* PIXELFORMAT: manual */
+	CMP(REFRESHRATE, u2.dwRefreshRate),
+	CMP(TEXTURESTAGE, dwTextureStage),
+	CMP(WIDTH, dwWidth),
+	/* ZBUFFERBITDEPTH: "obsolete" */
+    };
+
+#undef CMP
+
+    unsigned int i;
+
+    if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
+	return FALSE;
+
+    for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++)
+    {
+	if (requested->dwFlags & compare[i].flag
+	    && memcmp((const char *)provided + compare[i].offset,
+		      (const char *)requested + compare[i].offset,
+		      compare[i].size) != 0)
+	    return FALSE;
+    }
+
+    if (requested->dwFlags & DDSD_PIXELFORMAT)
+    {
+	if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat,
+						 &provided->u4.ddpfPixelFormat))
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+
+#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
+#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
+
+/* This should be extended so that it can be used by
+ * IDirectDrawSurface7::EnumAttachedSurfaces. */
+HRESULT
+Main_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
+				     LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
+				     LPDDENUMSURFACESCALLBACK7 callback)
+{
+    IDirectDrawSurfaceImpl *surf;
+    BOOL all, nomatch;
+
+    /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */
+    if (lpDDSD2 == NULL && !(dwFlags & DDENUMSURFACES_ALL))
+	return DDERR_INVALIDPARAMS;
+
+    all = dwFlags & DDENUMSURFACES_ALL;
+    nomatch = dwFlags & DDENUMSURFACES_NOMATCH;
+
+    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
+    {
+	if (all
+	    || (nomatch != Main_DirectDraw_DDSD_Match(lpDDSD2,
+						      &surf->surface_desc)))
+	{
+	    LPDIRECTDRAWSURFACE7 surface = ICOM_INTERFACE(surf,
+							  IDirectDrawSurface7);
+
+	    /* BOGUS! Violates COM rules, but MSDN says so. */
+	    IDirectDrawSurface7_AddRef(surface);
+
+	    if (callback(surface, &surf->surface_desc, context)
+		== DDENUMRET_CANCEL)
+		break;
+	}
+    }
+
+    return DD_OK;
+}
+
+/* I really don't understand how this is supposed to work.
+ * We only consider dwHeight, dwWidth and ddpfPixelFormat.dwFlags. */
+HRESULT
+Main_DirectDraw_EnumCreateableSurfaces(IDirectDrawImpl *This, DWORD dwFlags,
+				       LPDDSURFACEDESC2 lpDDSD2,
+				       LPVOID context,
+				       LPDDENUMSURFACESCALLBACK7 callback)
+{
+    FIXME("This isn't going to work.\n");
+
+    if ((dwFlags & DDENUMSURFACES_MATCHTYPE) != DDENUMSURFACES_MATCH)
+	return DDERR_INVALIDPARAMS;
+
+    /* TODO: implement this.
+     * Does this work before SCL is called?
+     * Does it only consider off-screen surfaces?
+     */
+
+    return E_FAIL;
+}
+
+/* For unsigned x. 0 is not a power of 2. */
+#define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
+
+HRESULT WINAPI
+Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
+			     LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
+			     LPDDENUMSURFACESCALLBACK7 callback)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(0x%lx, %p, %p, %p)\n", iface, dwFlags, lpDDSD2, context,
+	  callback);
+
+    if (callback == NULL)
+	return DDERR_INVALIDPARAMS;
+
+    if (dwFlags & ~(DDENUMSURFACES_SEARCHTYPE|DDENUMSURFACES_MATCHTYPE))
+	return DDERR_INVALIDPARAMS;
+
+    if (!IS_POW_2(dwFlags & DDENUMSURFACES_SEARCHTYPE)
+	|| !IS_POW_2(dwFlags & DDENUMSURFACES_MATCHTYPE))
+	return DDERR_INVALIDPARAMS;
+
+    if (dwFlags & DDENUMSURFACES_DOESEXIST)
+    {
+	return Main_DirectDraw_EnumExistingSurfaces(This, dwFlags, lpDDSD2,
+						    context, callback);
+    }
+    else
+    {
+	return Main_DirectDraw_EnumCreateableSurfaces(This, dwFlags, lpDDSD2,
+						      context, callback);
+    }
+}
+
+HRESULT WINAPI
+Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->() stub\n", This);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->()\n",This);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
+			LPDDCAPS pHELCaps)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p,%p,%p)\n",This,pDriverCaps,pHELCaps);
+    if (pDriverCaps != NULL) {
+	DD_STRUCT_COPY_BYSIZE(pDriverCaps,&This->caps);
+	if (TRACE_ON(ddraw)) {
+	  TRACE("Driver Caps : \n");
+	  DDRAW_dump_DDCAPS(pDriverCaps);
+	}
+    }
+    if (pHELCaps != NULL) {
+	DD_STRUCT_COPY_BYSIZE(pHELCaps,&This->caps);
+	if (TRACE_ON(ddraw)) {
+	  TRACE("HEL Caps : \n");
+	  DDRAW_dump_DDCAPS(pHELCaps);
+	}
+    }
+    return DD_OK;
+}
+
+/* GetCaps */
+/* GetDeviceIdentifier */
+/* GetDIsplayMode */
+
+HRESULT WINAPI
+Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
+			       LPDWORD pCodes)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    if (*pNumCodes) {
+	    *pNumCodes=0;
+    }
+    FIXME("(%p,%p,%p), stub\n",This,pNumCodes,pCodes);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
+			      LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p)\n", This, lplpGDIDDSSurface);
+    TRACE("returning primary (%p)\n", This->primary_surface);
+    *lplpGDIDDSSurface = ICOM_INTERFACE(This->primary_surface, IDirectDrawSurface7);
+    if (*lplpGDIDDSSurface)
+	IDirectDrawSurface7_AddRef(*lplpGDIDDSSurface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
+    *freq = 60*100; /* 60 Hz */
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    static BOOL hide;
+
+    /* Since this method is called often, show the fixme only once */
+    if (!hide) {
+	FIXME("(%p)->(%p) semi-stub\n", This, lpdwScanLine);
+	hide = TRUE;
+    }
+
+    /* Fake the line sweeping of the monitor */
+    /* FIXME: We should synchronize with a source to keep the refresh rate */ 
+    *lpdwScanLine = This->cur_scanline++;
+    /* Assume 20 scan lines in the vertical blank */
+    if (This->cur_scanline >= This->height + 20)
+	This->cur_scanline = 0;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
+				 LPDIRECTDRAWSURFACE7 *lpDDS)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p)\n",This,status);
+    *status = TRUE;
+    return DD_OK;
+}
+
+/* If we were not initialised then Uninit_Main_IDirectDraw7_Initialize would
+ * have been called instead. */
+HRESULT WINAPI
+Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid)
+{
+    TRACE("(%p)->(%s)\n", iface, debugstr_guid(lpGuid));
+
+    return DDERR_ALREADYINITIALIZED;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    IDirectDrawSurfaceImpl* surf;
+
+    TRACE("(%p)->()\n", This);
+
+    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw)
+	IDirectDrawSurface7_Restore(ICOM_INTERFACE(surf, IDirectDrawSurface7));
+
+    return DD_OK;
+}
+
+static void DDRAW_SubclassWindow(IDirectDrawImpl* This)
+{
+    /* Well we don't actually subclass the window yet. */
+    SetPropA(This->window, ddProp, This);
+}
+
+static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This)
+{
+    RemovePropA(This->window, ddProp);
+}
+
+HRESULT WINAPI
+Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
+				    DWORD cooplevel)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
+    DDRAW_dump_cooperativelevel(cooplevel);
+
+    /* Makes realMYST test happy. */
+    if (This->cooperative_level == cooplevel
+	&& This->window == hwnd)
+	return DD_OK;
+
+    /* XXX "It cannot be reset while the process has surfaces or palettes
+     * created." Otherwise the window can be changed???
+     *
+     * This appears to be wrong - comment it out for now.
+    if (This->window)
+	return DDERR_HWNDALREADYSET;
+    */
+
+    if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL)))
+	return DDERR_INVALIDPARAMS;
+
+    This->window = hwnd;
+    This->cooperative_level = cooplevel;
+
+    This->local.hWnd = (ULONG_PTR)hwnd;
+    This->local.dwLocalFlags |= DDRAWILCL_SETCOOPCALLED;
+    /* not entirely sure about these */
+    if (cooplevel & DDSCL_EXCLUSIVE)     This->local.dwLocalFlags |= DDRAWILCL_HASEXCLUSIVEMODE;
+    if (cooplevel & DDSCL_FULLSCREEN)    This->local.dwLocalFlags |= DDRAWILCL_ISFULLSCREEN;
+    if (cooplevel & DDSCL_ALLOWMODEX)    This->local.dwLocalFlags |= DDRAWILCL_ALLOWMODEX;
+    if (cooplevel & DDSCL_MULTITHREADED) This->local.dwLocalFlags |= DDRAWILCL_MULTITHREADED;
+    if (cooplevel & DDSCL_FPUSETUP)      This->local.dwLocalFlags |= DDRAWILCL_FPUSETUP;
+    if (cooplevel & DDSCL_FPUPRESERVE)   This->local.dwLocalFlags |= DDRAWILCL_FPUPRESERVE;
+
+    if (This->local.lpGbl) {
+	/* assume that this app is the active app (in wine, there's
+	 * probably only one app per global ddraw object anyway) */
+	if (cooplevel & DDSCL_EXCLUSIVE) This->local.lpGbl->lpExclusiveOwner = &This->local;
+	else if (This->local.lpGbl->lpExclusiveOwner == &This->local)
+	    This->local.lpGbl->lpExclusiveOwner = NULL;
+	if (This->set_exclusive_mode)
+	    This->set_exclusive_mode(This, (cooplevel & DDSCL_EXCLUSIVE) != 0);
+    }
+
+    ShowWindow(hwnd, SW_SHOW);
+
+    DDRAW_SubclassWindow(This);
+
+    /* TODO Does it also get resized to the current screen size? */
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+			       DWORD dwHeight, LONG lPitch,
+			       DWORD dwRefreshRate, DWORD dwFlags,
+			       const DDPIXELFORMAT* pixelformat)
+{
+    short screenX;
+    short screenY;
+
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)->SetDisplayMode(%ld,%ld)\n",This,dwWidth,dwHeight);
+
+    if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
+	return DDERR_NOEXCLUSIVEMODE;
+
+    if (!IsWindow(This->window))
+	return DDERR_GENERIC; /* unchecked */
+
+    LosePrimarySurface(This);
+
+    screenX = GetSystemMetrics(SM_CXSCREEN);
+    screenY = GetSystemMetrics(SM_CYSCREEN);
+
+    This->width = dwWidth;
+    This->height = dwHeight;
+    This->pitch = lPitch;
+    This->pixelformat = *pixelformat;
+
+    /* Position the window in the center of the screen - don't center for now */
+    /* MoveWindow(This->window, (screenX-dwWidth)/2, (screenY-dwHeight)/2,
+                  dwWidth, dwHeight, TRUE);*/
+    MoveWindow(This->window, 0, 0, dwWidth, dwHeight, TRUE);
+
+    SetFocus(This->window);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)\n",This);
+    if (!(This->cooperative_level & DDSCL_EXCLUSIVE))
+	return DDERR_NOEXCLUSIVEMODE;
+
+    /* Lose the primary surface if the resolution changes. */
+    if (This->orig_width != This->width || This->orig_height != This->height
+	|| This->orig_pitch != This->pitch
+	|| This->orig_pixelformat.dwFlags != This->pixelformat.dwFlags
+	|| !Main_DirectDraw_DDPIXELFORMAT_Match(&This->pixelformat,
+						&This->orig_pixelformat))
+    {
+	LosePrimarySurface(This);
+    }
+
+    /* TODO Move the window back where it belongs. */
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				     HANDLE h)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->(flags=0x%08lx,handle=%p)\n",This,dwFlags,h);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->GetDisplayMode(%p)\n",This,pDDSD);
+
+    pDDSD->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_REFRESHRATE;
+    pDDSD->dwHeight = This->height;
+    pDDSD->dwWidth = This->width;
+    pDDSD->u1.lPitch = This->pitch;
+    pDDSD->u2.dwRefreshRate = 60;
+    pDDSD->u4.ddpfPixelFormat = This->pixelformat;
+    pDDSD->ddsCaps.dwCaps = 0;
+
+    return DD_OK;
+}
+
+static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem)
+{
+    if (mem > This->available_vidmem) return -1;
+    This->available_vidmem -= mem;
+    return This->available_vidmem;
+}
+
+static void free_memory(IDirectDrawImpl *This, DWORD mem)
+{
+    This->available_vidmem += mem;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
+				   LPDWORD total, LPDWORD free)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
+
+    if (TRACE_ON(ddraw)) {
+        TRACE(" Asking for memory of type : ");
+        DDRAW_dump_DDSCAPS2(ddscaps); TRACE("\n");
+    }
+
+    /* We have 16 MB videomemory */
+    if (total)	*total= This->total_vidmem;
+    if (free)	*free = This->available_vidmem;
+
+    TRACE(" returning (total) %ld / (free) %ld\n", 
+	  total != NULL ? *total : 0, 
+	  free  != NULL ? *free  : 0);
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) {
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(): stub\n", This);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
+			      DWORD dwNumModes, DWORD dwFlags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->() stub\n", This);
+
+    return DD_OK;
+}
+
+/*** Owned object management. */
+
+void Main_DirectDraw_AddSurface(IDirectDrawImpl* This,
+				IDirectDrawSurfaceImpl* surface)
+{
+    assert(surface->ddraw_owner == NULL || surface->ddraw_owner == This);
+
+    surface->ddraw_owner = This;
+
+    /* where should it go? */
+    surface->next_ddraw = This->surfaces;
+    surface->prev_ddraw = NULL;
+    if (This->surfaces)
+	This->surfaces->prev_ddraw = surface;
+    This->surfaces = surface;
+}
+
+void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This,
+				   IDirectDrawSurfaceImpl* surface)
+{
+    assert(surface->ddraw_owner == This);
+
+    if (This->surfaces == surface)
+	This->surfaces = surface->next_ddraw;
+
+    if (This->primary_surface == surface)
+	This->primary_surface = NULL;
+
+    if (surface->next_ddraw)
+	surface->next_ddraw->prev_ddraw = surface->prev_ddraw;
+    if (surface->prev_ddraw)
+	surface->prev_ddraw->next_ddraw = surface->next_ddraw;
+}
+
+static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This)
+{
+    while (This->surfaces != NULL)
+	Main_DirectDrawSurface_ForceDestroy(This->surfaces);
+}
+
+void Main_DirectDraw_AddClipper(IDirectDrawImpl* This,
+				IDirectDrawClipperImpl* clipper)
+{
+    assert(clipper->ddraw_owner == NULL || clipper->ddraw_owner == This);
+
+    clipper->ddraw_owner = This;
+
+    clipper->next_ddraw = This->clippers;
+    clipper->prev_ddraw = NULL;
+    if (This->clippers)
+	This->clippers->prev_ddraw = clipper;
+    This->clippers = clipper;
+}
+
+void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This,
+				   IDirectDrawClipperImpl* clipper)
+{
+    assert(clipper->ddraw_owner == This);
+
+    if (This->clippers == clipper)
+	This->clippers = clipper->next_ddraw;
+
+    if (clipper->next_ddraw)
+	clipper->next_ddraw->prev_ddraw = clipper->prev_ddraw;
+    if (clipper->prev_ddraw)
+	clipper->prev_ddraw->next_ddraw = clipper->next_ddraw;
+}
+
+static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This)
+{
+    while (This->clippers != NULL)
+	Main_DirectDrawClipper_ForceDestroy(This->clippers);
+}
+
+void Main_DirectDraw_AddPalette(IDirectDrawImpl* This,
+				IDirectDrawPaletteImpl* palette)
+{
+    assert(palette->ddraw_owner == NULL || palette->ddraw_owner == This);
+
+    palette->ddraw_owner = This;
+
+    /* where should it go? */
+    palette->next_ddraw = This->palettes;
+    palette->prev_ddraw = NULL;
+    if (This->palettes)
+	This->palettes->prev_ddraw = palette;
+    This->palettes = palette;
+}
+
+void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This,
+				   IDirectDrawPaletteImpl* palette)
+{
+    IDirectDrawSurfaceImpl *surf;
+
+    assert(palette->ddraw_owner == This);
+
+    if (This->palettes == palette)
+	This->palettes = palette->next_ddraw;
+
+    if (palette->next_ddraw)
+	palette->next_ddraw->prev_ddraw = palette->prev_ddraw;
+    if (palette->prev_ddraw)
+	palette->prev_ddraw->next_ddraw = palette->next_ddraw;
+
+    /* Here we need also to remove tha palette from any surface which has it as the
+     * current palette (checked on Windows)
+     */
+    for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) {
+	if (surf->palette == palette) {
+	    TRACE("Palette %p attached to surface %p.\n", palette, surf);
+	    surf->palette = NULL;
+	    surf->set_palette(surf, NULL);
+	}
+    }
+}
+
+static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This)
+{
+    while (This->palettes != NULL)
+	Main_DirectDrawPalette_ForceDestroy(This->palettes);
+}
+
+/*** ??? */
+
+static void
+LoseSurface(IDirectDrawSurfaceImpl *surface)
+{
+    if (surface != NULL) surface->lose_surface(surface);
+}
+
+static void
+LosePrimarySurface(IDirectDrawImpl *This)
+{
+    /* MSDN: "If another application changes the display mode, the primary
+     * surface is lost, and the method returns DDERR_SURFACELOST until the
+     * primary surface is recreated to match the new display mode."
+     *
+     * We mark all the primary surfaces as lost as soon as the display
+     * mode is changed (by any application). */
+
+    LoseSurface(This->primary_surface);
+}
+
+/******************************************************************************
+ * Uninitialised DirectDraw functions
+ *
+ * This vtable is used when a DirectDraw object is created with
+ * CoCreateInstance. The only usable method is Initialize.
+ */
+
+void Uninit_DirectDraw_final_release(IDirectDrawImpl *This)
+{
+    Main_DirectDraw_final_release(This);
+}
+
+static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable;
+
+/* Not called from the vtable. */
+HRESULT Uninit_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
+{
+    HRESULT hr;
+
+    hr = Main_DirectDraw_Construct(This, ex);
+    if (FAILED(hr)) return hr;
+
+    This->final_release = Uninit_DirectDraw_final_release;
+    ICOM_INIT_INTERFACE(This, IDirectDraw7, Uninit_DirectDraw_VTable);
+
+    return S_OK;
+}
+
+HRESULT Uninit_DirectDraw_Create(const GUID* pGUID,
+				       LPDIRECTDRAW7* pIface,
+				       IUnknown* pUnkOuter, BOOL ex)
+{
+    HRESULT hr;
+    IDirectDrawImpl* This;
+
+    assert(pUnkOuter == NULL); /* XXX no: we must check this */
+
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+		     sizeof(IDirectDrawImpl));
+    if (This == NULL) return E_OUTOFMEMORY;
+
+    hr = Uninit_DirectDraw_Construct(This, ex);
+    if (FAILED(hr))
+	HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This);
+    else
+	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID pDeviceGuid)
+{
+    const ddraw_driver* driver;
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)->(%p)\n", iface, pDeviceGuid);
+
+    driver = DDRAW_FindDriver(pDeviceGuid);
+    /* XXX This return value is not documented. (Not checked.) */
+    if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID;
+
+    return driver->init(This, pDeviceGuid);
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_Compact(LPDIRECTDRAW7 iface)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				LPDIRECTDRAWCLIPPER *lplpDDClipper,
+				IUnknown *pUnkOuter)
+
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				LPPALETTEENTRY lpColorTable,
+				LPDIRECTDRAWPALETTE *lplpDDPalette,
+				IUnknown *pUnkOuter)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface,
+				LPDDSURFACEDESC2 lpDDSurfaceDesc,
+				LPDIRECTDRAWSURFACE7 *lplpDDSurface,
+				IUnknown *pUnkOuter)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface,
+				   LPDIRECTDRAWSURFACE7 pSurf,
+				   LPDIRECTDRAWSURFACE7 *pDupSurf)
+
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				   LPDDSURFACEDESC2 lpDDSD,
+				   LPVOID context,
+				   LPDDENUMMODESCALLBACK2 cb)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
+			       LPDDSURFACEDESC2 pDDSD, LPVOID context,
+			       LPDDENUMSURFACESCALLBACK7 cb)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
+			  LPDDCAPS pHELCaps)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface,
+				 LPDDSURFACEDESC2 pDDSD)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
+				 LPDWORD pCodes)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
+				LPDIRECTDRAWSURFACE7 *pGDISurf)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface, LPDWORD pdwFreq)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD pdwScanLine)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, PBOOL pbIsInVB)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hWnd,
+				      DWORD dwFlags)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+				 DWORD dwHeight, DWORD dwBPP,
+				 DWORD dwRefreshRate, DWORD dwFlags)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				       HANDLE hEvent)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 pDDCaps,
+				     LPDWORD pdwTotal, LPDWORD pdwFree)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hDC,
+				   LPDIRECTDRAWSURFACE7 *pSurf)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
+				      LPDDDEVICEIDENTIFIER2 pDDDI,
+				      DWORD dwFlags)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pszModes,
+				DWORD cModes, DWORD dwFlags)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static HRESULT WINAPI
+Uninit_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface, DWORD dwFlags,
+			       LPDWORD pTimeout)
+{
+    return DDERR_NOTINITIALIZED;
+}
+
+static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable =
+{
+    Main_DirectDraw_QueryInterface,
+    Main_DirectDraw_AddRef,
+    Main_DirectDraw_Release,
+    Uninit_DirectDraw_Compact,
+    Uninit_DirectDraw_CreateClipper,
+    Uninit_DirectDraw_CreatePalette,
+    Uninit_DirectDraw_CreateSurface,
+    Uninit_DirectDraw_DuplicateSurface,
+    Uninit_DirectDraw_EnumDisplayModes,
+    Uninit_DirectDraw_EnumSurfaces,
+    Uninit_DirectDraw_FlipToGDISurface,
+    Uninit_DirectDraw_GetCaps,
+    Uninit_DirectDraw_GetDisplayMode,
+    Uninit_DirectDraw_GetFourCCCodes,
+    Uninit_DirectDraw_GetGDISurface,
+    Uninit_DirectDraw_GetMonitorFrequency,
+    Uninit_DirectDraw_GetScanLine,
+    Uninit_DirectDraw_GetVerticalBlankStatus,
+    Uninit_DirectDraw_Initialize,
+    Uninit_DirectDraw_RestoreDisplayMode,
+    Uninit_DirectDraw_SetCooperativeLevel,
+    Uninit_DirectDraw_SetDisplayMode,
+    Uninit_DirectDraw_WaitForVerticalBlank,
+    Uninit_DirectDraw_GetAvailableVidMem,
+    Uninit_DirectDraw_GetSurfaceFromDC,
+    Uninit_DirectDraw_RestoreAllSurfaces,
+    Uninit_DirectDraw_TestCooperativeLevel,
+    Uninit_DirectDraw_GetDeviceIdentifier,
+    Uninit_DirectDraw_StartModeTest,
+    Uninit_DirectDraw_EvaluateMode
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/ddraw/ddraw_hal.c	2005-06-03 20:50:22.000000000 +0100
@@ -0,0 +1,580 @@
+/*	DirectDraw HAL driver
+ *
+ * Copyright 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 <stdarg.h>
+#include <stdlib.h>
+
+#define CONST_VTABLE
+
+#include "wine/debug.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "ddraw.h"
+#include "ddrawi.h"
+#include "d3dhal.h"
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+static const IDirectDraw7Vtbl HAL_DirectDraw_VTable;
+
+static DDVERSIONDATA hal_version;
+static DD32BITDRIVERDATA hal_driverdata;
+static HINSTANCE hal_instance;
+
+static const DDDEVICEIDENTIFIER2 hal_device =
+{
+    "display",
+    "DirectDraw HAL",
+    { { 0x00010001, 0x00010001 } },
+    0, 0, 0, 0,
+    /* 40c1b248-9d7d-4a29-b7d7-4cd8109f3d5d */
+    {0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}},
+    0
+};
+
+HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+			      IUnknown* pUnkOuter, BOOL ex);
+HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
+
+static const ddraw_driver hal_driver =
+{
+    &hal_device,
+    100, /* we prefer the HAL */
+    HAL_DirectDraw_Create,
+    HAL_DirectDraw_Initialize
+};
+
+static DDHAL_CALLBACKS dd_cbs;
+static DDRAWI_DIRECTDRAW_GBL dd_gbl;
+
+static D3DHAL_GLOBALDRIVERDATA d3d_hal_data;
+static D3DHAL_D3DEXTENDEDCAPS d3d_hal_extcaps;
+static D3DHAL_CALLBACKS d3d_hal_cbs1;
+static D3DHAL_CALLBACKS2 d3d_hal_cbs2;
+
+/* in real windoze, these entry points are 16-bit, but we can work in 32-bit */
+static BOOL WINAPI set_hal_info(LPDDHALINFO lpDDHalInfo, BOOL reset)
+{
+    dd_cbs.HALDD	= *lpDDHalInfo->lpDDCallbacks;
+    dd_cbs.HALDDSurface	= *lpDDHalInfo->lpDDSurfaceCallbacks;
+    dd_cbs.HALDDPalette	= *lpDDHalInfo->lpDDPaletteCallbacks;
+    if (lpDDHalInfo->lpDDExeBufCallbacks)
+	dd_cbs.HALDDExeBuf	= *lpDDHalInfo->lpDDExeBufCallbacks;
+
+    dd_gbl.lpDDCBtmp = &dd_cbs;
+
+    dd_gbl.ddCaps		 = lpDDHalInfo->ddCaps;
+    dd_gbl.dwMonitorFrequency	 = lpDDHalInfo->dwMonitorFrequency;
+    dd_gbl.vmiData		 = lpDDHalInfo->vmiData;
+    dd_gbl.dwModeIndex		 = lpDDHalInfo->dwModeIndex;
+    dd_gbl.dwNumFourCC	         = lpDDHalInfo->ddCaps.dwNumFourCCCodes;
+    dd_gbl.lpdwFourCC		 = lpDDHalInfo->lpdwFourCC;
+    dd_gbl.dwNumModes		 = lpDDHalInfo->dwNumModes;
+    dd_gbl.lpModeInfo		 = lpDDHalInfo->lpModeInfo;
+    /* FIXME: dwFlags */
+    dd_gbl.dwPDevice		 = (DWORD)lpDDHalInfo->lpPDevice;
+    dd_gbl.hInstance		 = lpDDHalInfo->hInstance;
+    /* DirectX 2 */
+    if (lpDDHalInfo->lpD3DGlobalDriverData)
+	memcpy(&d3d_hal_data, (LPVOID)lpDDHalInfo->lpD3DGlobalDriverData, sizeof(D3DDEVICEDESC_V1));
+    else
+	memset(&d3d_hal_data, 0, sizeof(D3DDEVICEDESC_V1));
+    dd_gbl.lpD3DGlobalDriverData = (ULONG_PTR)&d3d_hal_data;
+
+    if (lpDDHalInfo->lpD3DHALCallbacks)
+	memcpy(&d3d_hal_cbs1, (LPVOID)lpDDHalInfo->lpD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS));
+    else
+	memset(&d3d_hal_cbs1, 0, sizeof(D3DHAL_CALLBACKS));
+    dd_gbl.lpD3DHALCallbacks	 = (ULONG_PTR)&d3d_hal_cbs1;
+
+    if (lpDDHalInfo->dwFlags & DDHALINFO_GETDRIVERINFOSET) {
+	DDHAL_GETDRIVERINFODATA data;
+	data.dwSize = sizeof(DDHAL_GETDRIVERINFODATA);
+	data.dwFlags = 0; /* ? */
+	data.dwContext = hal_driverdata.dwContext; /* ? */
+
+	data.guidInfo = GUID_D3DExtendedCaps;
+	data.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
+	data.lpvData = &d3d_hal_extcaps;
+	data.dwActualSize = 0;
+	data.ddRVal = 0;
+	lpDDHalInfo->GetDriverInfo(&data);
+	d3d_hal_extcaps.dwSize = data.dwActualSize;
+	dd_gbl.lpD3DExtendedCaps = (ULONG_PTR)&d3d_hal_extcaps;
+
+	data.guidInfo = GUID_D3DCallbacks2;
+	data.dwExpectedSize = sizeof(D3DHAL_CALLBACKS2);
+	data.lpvData = &d3d_hal_cbs2;
+	data.dwActualSize = 0;
+	data.ddRVal = 0;
+	lpDDHalInfo->GetDriverInfo(&data);
+	d3d_hal_cbs2.dwSize = data.dwActualSize;
+	dd_gbl.lpD3DHALCallbacks2 = (ULONG_PTR)&d3d_hal_cbs2;
+    }
+
+    if( opengl_initialized && 
+           (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) ) {
+        /*GL_DirectDraw_Init(&dd_gbl);*/
+    }
+
+    return FALSE;
+}
+
+static DDHALDDRAWFNS hal_funcs = {
+    sizeof(DDHALDDRAWFNS),
+    set_hal_info,
+    NULL, /* VidMemAlloc */
+    NULL  /* VidMemFree */
+};
+
+/* Called from DllInit, which is synchronised so there are no threading
+ * concerns. */
+static BOOL initialize(void)
+{
+    DCICMD cmd;
+    INT ncmd = DCICOMMAND;
+    BOOL ret;
+    HDC dc = CreateDCA("DISPLAY", NULL, NULL, NULL);
+    INT ver = Escape(dc, QUERYESCSUPPORT, sizeof(ncmd), (LPVOID)&ncmd, NULL);
+    if (ver != DD_HAL_VERSION) {
+	DeleteDC(dc);
+	TRACE("DirectDraw HAL not available\n");
+	return FALSE;
+    }
+    cmd.dwVersion = DD_VERSION;
+    cmd.dwReserved = 0;
+
+    /* the DDNEWCALLBACKFNS is supposed to give the 16-bit driver entry points
+     * in ddraw16.dll, but since Wine doesn't have or use 16-bit display drivers,
+     * we'll just work in 32-bit, who'll notice... */
+    cmd.dwCommand = DDNEWCALLBACKFNS;
+    cmd.dwParam1 = (DWORD)&hal_funcs;
+    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, 0, NULL);
+
+    /* next, exchange version information */
+    cmd.dwCommand = DDVERSIONINFO;
+    cmd.dwParam1 = DD_RUNTIME_VERSION; /* not sure what should *really* go here */
+    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_version), (LPVOID)&hal_version);
+
+    /* get 32-bit driver data (dll name and entry point) */
+    cmd.dwCommand = DDGET32BITDRIVERNAME;
+    ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_driverdata), (LPVOID)&hal_driverdata);
+    /* we're supposed to load the DLL in hal_driverdata.szName, then GetProcAddress
+     * the hal_driverdata.szEntryPoint, and call it with hal_driverdata.dwContext
+     * as a parameter... but since this is only more remains from the 16-bit world,
+     * we'll ignore it */
+
+    /* finally, initialize the driver object */
+    cmd.dwCommand = DDCREATEDRIVEROBJECT;
+    ret = ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_instance), (LPVOID)&hal_instance);
+    if (ret) {
+	/* the driver should have called our set_hal_info now */
+	if (!dd_gbl.lpDDCBtmp) ret = FALSE;
+    }
+
+    /* init done */
+    DeleteDC(dc);
+
+    TRACE("%s DirectDraw HAL\n", ret ? "enabling" : "disabling");
+
+    return ret;
+}
+
+static void cleanup(void)
+{
+    DDHAL_DESTROYDRIVERDATA data;
+
+    if (!dd_cbs.HALDD.DestroyDriver) return;
+
+    data.lpDD = NULL;
+    data.ddRVal = 0;
+    data.DestroyDriver = dd_cbs.HALDD.DestroyDriver;
+    data.DestroyDriver(&data);
+}
+
+static DWORD choose_mode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
+			 DWORD dwRefreshRate, DWORD dwFlags)
+{
+    int best = -1;
+    unsigned int i;
+
+    if (!dd_gbl.dwNumModes) return 0;
+
+/* let's support HALs that cannot switch depths (XVidMode),
+ * these should return dwBPP == 0 for all their resolutions */
+#define BPP_MATCH(dd, bpp) ((!(dd)) || ((dd) == bpp))
+
+/* FIXME: we should try to match the refresh rate too */
+
+    /* Choose the smallest mode that is large enough. */
+    for (i=0; i < dd_gbl.dwNumModes; i++)
+    {
+	if (dd_gbl.lpModeInfo[i].dwWidth >= dwWidth &&
+	    dd_gbl.lpModeInfo[i].dwHeight >= dwHeight &&
+	    BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
+	{
+	    if (best == -1) best = i;
+	    else
+	    {
+		if (dd_gbl.lpModeInfo[i].dwWidth < dd_gbl.lpModeInfo[best].dwWidth ||
+		    dd_gbl.lpModeInfo[i].dwHeight < dd_gbl.lpModeInfo[best].dwHeight)
+		    best = i;
+	    }
+	}
+    }
+
+    if (best == -1)
+    {
+	TRACE("all modes too small\n");
+	/* ok, let's use the largest */
+
+	for (i=0; i < dd_gbl.dwNumModes; i++)
+	{
+	    if (BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
+	    {
+		if (best == -1) best = i;
+		else
+		{
+		    if (dd_gbl.lpModeInfo[i].dwWidth > dd_gbl.lpModeInfo[best].dwWidth ||
+			dd_gbl.lpModeInfo[i].dwHeight > dd_gbl.lpModeInfo[best].dwHeight)
+			best = i;
+		}
+	    }
+	}
+    }
+#undef BPP_MATCH
+
+    if (best == -1)
+    {
+	ERR("requested color depth (%ld) not available, try reconfiguring X server\n", dwBPP);
+	return dd_gbl.dwModeIndex;
+    }
+
+    TRACE("using mode %d\n", best);
+
+    return best;
+}
+
+static HRESULT set_mode(IDirectDrawImpl *This, DWORD dwMode)
+{
+    HRESULT hr = DD_OK;
+
+    if (dwMode != dd_gbl.dwModeIndex)
+    {
+	DDHAL_SETMODEDATA data;
+	data.lpDD = &dd_gbl;
+	data.dwModeIndex = dwMode;
+	data.ddRVal = 0;
+	data.SetMode = dd_cbs.HALDD.SetMode;
+	data.inexcl = 0;
+	data.useRefreshRate = FALSE;
+	if (data.SetMode)
+	    data.SetMode(&data);
+	hr = data.ddRVal;
+	if (SUCCEEDED(hr))
+	    dd_gbl.dwModeIndex = dwMode;
+    }
+    return hr;
+}
+
+static HRESULT set_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl)
+{
+    DDHAL_SETEXCLUSIVEMODEDATA data;
+
+    data.lpDD = &dd_gbl;
+    data.dwEnterExcl = dwEnterExcl;
+    data.dwReserved = 0;
+    data.ddRVal = 0;
+    data.SetExclusiveMode = dd_cbs.HALDD.SetExclusiveMode;
+    if (data.SetExclusiveMode)
+	data.SetExclusiveMode(&data);
+    return data.ddRVal;
+}
+
+BOOL DDRAW_HAL_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+    if (fdwReason == DLL_PROCESS_ATTACH)
+    {
+	if (initialize())
+	    DDRAW_register_driver(&hal_driver);
+    }
+    else if (fdwReason == DLL_PROCESS_DETACH)
+    {
+	cleanup();
+    }
+
+    return TRUE;
+}
+
+/* Not called from the vtable. */
+HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
+{
+    HRESULT hr;
+
+    TRACE("(%p,%d)\n", This, ex);
+
+    hr = User_DirectDraw_Construct(This, ex);
+    if (FAILED(hr)) return hr;
+
+    This->local.lpGbl = &dd_gbl;
+
+    This->final_release = HAL_DirectDraw_final_release;
+    This->set_exclusive_mode = set_exclusive_mode;
+
+    This->create_palette = HAL_DirectDrawPalette_Create;
+
+    This->create_primary    = HAL_DirectDraw_create_primary;
+    This->create_backbuffer = HAL_DirectDraw_create_backbuffer;
+    This->create_texture    = HAL_DirectDraw_create_texture;
+
+    ICOM_INIT_INTERFACE(This, IDirectDraw7, HAL_DirectDraw_VTable);
+
+    /* merge HAL caps */
+    This->caps.dwCaps |= dd_gbl.ddCaps.dwCaps;
+    This->caps.dwCaps2 |= dd_gbl.ddCaps.dwCaps2;
+    This->caps.dwCKeyCaps |= dd_gbl.ddCaps.dwCKeyCaps;
+    This->caps.dwFXCaps |= dd_gbl.ddCaps.dwFXCaps;
+    This->caps.dwPalCaps |= dd_gbl.ddCaps.dwPalCaps;
+    /* FIXME: merge more caps */
+    This->caps.ddsCaps.dwCaps |= dd_gbl.ddCaps.ddsCaps.dwCaps;
+    This->caps.ddsCaps.dwCaps2 |= dd_gbl.ddsCapsMore.dwCaps2;
+    This->caps.ddsCaps.dwCaps3 |= dd_gbl.ddsCapsMore.dwCaps3;
+    This->caps.ddsCaps.dwCaps4 |= dd_gbl.ddsCapsMore.dwCaps4;
+    This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
+
+    return S_OK;
+}
+
+/* This function is called from DirectDrawCreate(Ex) on the most-derived
+ * class to start construction.
+ * Not called from the vtable. */
+HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+			      IUnknown* pUnkOuter, BOOL ex)
+{
+    HRESULT hr;
+    IDirectDrawImpl* This;
+
+    TRACE("\n");
+
+    assert(pUnkOuter == NULL);
+
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+		     sizeof(IDirectDrawImpl)
+		     + sizeof(HAL_DirectDrawImpl));
+    if (This == NULL) return E_OUTOFMEMORY;
+
+    /* Note that this relation does *not* hold true if the DD object was
+     * CoCreateInstanced then Initialized. */
+    This->private = (HAL_DirectDrawImpl *)(This+1);
+
+    /* Initialize the DDCAPS structure */
+    This->caps.dwSize = sizeof(This->caps);
+
+    hr = HAL_DirectDraw_Construct(This, ex);
+    if (FAILED(hr))
+	HeapFree(GetProcessHeap(), 0, This);
+    else
+	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
+
+    return hr;
+}
+
+/* This function is called from Uninit_DirectDraw_Initialize on the
+ * most-derived-class to start initialization.
+ * Not called from the vtable. */
+HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
+{
+    HRESULT hr;
+
+    TRACE("\n");
+
+    This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+			      sizeof(HAL_DirectDrawImpl));
+    if (This->private == NULL) return E_OUTOFMEMORY;
+
+    /* Initialize the DDCAPS structure */
+    This->caps.dwSize = sizeof(This->caps);
+
+    hr = HAL_DirectDraw_Construct(This, TRUE); /* XXX ex? */
+    if (FAILED(hr))
+    {
+	HeapFree(GetProcessHeap(), 0, This->private);
+	return hr;
+    }
+
+    return DD_OK;
+}
+
+/* Called from an internal function pointer. */
+void HAL_DirectDraw_final_release(IDirectDrawImpl *This)
+{
+    if (dd_gbl.dwFlags & DDRAWI_MODECHANGED) set_mode(This, dd_gbl.dwModeIndexOrig);
+    User_DirectDraw_final_release(This);
+}
+
+HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This,
+				      const DDSURFACEDESC2* pDDSD,
+				      LPDIRECTDRAWSURFACE7* ppSurf,
+				      IUnknown* pUnkOuter)
+{
+    if (This->cooperative_level & DDSCL_EXCLUSIVE)
+	return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+    else
+	return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+}
+
+HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
+					 const DDSURFACEDESC2* pDDSD,
+					 LPDIRECTDRAWSURFACE7* ppSurf,
+					 IUnknown* pUnkOuter,
+					 IDirectDrawSurfaceImpl* primary)
+{
+    if (This->cooperative_level & DDSCL_EXCLUSIVE)
+	return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+    else
+	return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+}
+
+HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
+				      const DDSURFACEDESC2* pDDSD,
+				      LPDIRECTDRAWSURFACE7* ppSurf,
+				      LPUNKNOWN pOuter,
+				      DWORD dwMipMapLevel)
+{
+    return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
+}
+
+HRESULT WINAPI
+HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
+				   LPDDDEVICEIDENTIFIER2 pDDDI,
+				   DWORD dwFlags)
+{
+    *pDDDI = hal_device;
+    return DD_OK;
+}
+
+HRESULT WINAPI
+HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    HRESULT hr;
+
+    TRACE("(%p)\n", iface);
+
+    if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) return DD_OK;
+
+    hr = Main_DirectDraw_RestoreDisplayMode(iface);
+    if (SUCCEEDED(hr)) {
+	hr = set_mode(This, dd_gbl.dwModeIndexOrig);
+	if (SUCCEEDED(hr)) dd_gbl.dwFlags &= ~DDRAWI_MODECHANGED;
+    }
+
+    return hr;
+}
+
+HRESULT WINAPI
+HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+			      DWORD dwHeight, DWORD dwBPP,
+			      DWORD dwRefreshRate, DWORD dwFlags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    HRESULT hr;
+
+    TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
+    hr = User_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP,
+					dwRefreshRate, dwFlags);
+
+    if (SUCCEEDED(hr)) {
+	if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) dd_gbl.dwModeIndexOrig = dd_gbl.dwModeIndex;
+	hr = set_mode(This, choose_mode(dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags));
+	if (SUCCEEDED(hr)) dd_gbl.dwFlags |= DDRAWI_MODECHANGED;
+    }
+
+    return hr;
+}
+
+HRESULT WINAPI
+HAL_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
+			       LPDWORD pCodes)
+{
+    unsigned int i;
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    if (*pNumCodes)
+	*pNumCodes=dd_gbl.dwNumFourCC;
+    if (pCodes && dd_gbl.dwNumFourCC)
+	memcpy(pCodes,dd_gbl.lpdwFourCC,sizeof(pCodes[0])*dd_gbl.dwNumFourCC);
+    FIXME("(%p,%p,%p)\n",This,pNumCodes,pCodes);
+    if (dd_gbl.dwNumFourCC) {
+	if (pCodes && FIXME_ON(ddraw)) {
+	    FIXME("returning: ");
+	    for (i=0;i<dd_gbl.dwNumFourCC;i++) {
+		MESSAGE("%c%c%c%c,",
+			((LPBYTE)(pCodes+i))[0],
+			((LPBYTE)(pCodes+i))[1],
+			((LPBYTE)(pCodes+i))[2],
+			((LPBYTE)(pCodes+i))[3]
+		);
+	    }
+	    MESSAGE("\n");
+	}
+    }
+    return DD_OK;
+}
+
+
+static const IDirectDraw7Vtbl HAL_DirectDraw_VTable =
+{
+    Main_DirectDraw_QueryInterface,
+    Main_DirectDraw_AddRef,
+    Main_DirectDraw_Release,
+    Main_DirectDraw_Compact,
+    Main_DirectDraw_CreateClipper,
+    Main_DirectDraw_CreatePalette,
+    Main_DirectDraw_CreateSurface,
+    Main_DirectDraw_DuplicateSurface,
+    User_DirectDraw_EnumDisplayModes,
+    Main_DirectDraw_EnumSurfaces,
+    Main_DirectDraw_FlipToGDISurface,
+    Main_DirectDraw_GetCaps,
+    Main_DirectDraw_GetDisplayMode,
+    HAL_DirectDraw_GetFourCCCodes,
+    Main_DirectDraw_GetGDISurface,
+    Main_DirectDraw_GetMonitorFrequency,
+    Main_DirectDraw_GetScanLine,
+    Main_DirectDraw_GetVerticalBlankStatus,
+    Main_DirectDraw_Initialize,
+    HAL_DirectDraw_RestoreDisplayMode,
+    Main_DirectDraw_SetCooperativeLevel,
+    HAL_DirectDraw_SetDisplayMode,
+    Main_DirectDraw_WaitForVerticalBlank,
+    Main_DirectDraw_GetAvailableVidMem,
+    Main_DirectDraw_GetSurfaceFromDC,
+    Main_DirectDraw_RestoreAllSurfaces,
+    Main_DirectDraw_TestCooperativeLevel,
+    HAL_DirectDraw_GetDeviceIdentifier,
+    Main_DirectDraw_StartModeTest,
+    Main_DirectDraw_EvaluateMode
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/ddraw/ddraw_thunks.c	2005-06-03 20:50:43.000000000 +0100
@@ -0,0 +1,1032 @@
+/* Direct Draw Thunks and old vtables
+ * Copyright 2000 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 <stdarg.h>
+
+#define CONST_VTABLE
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "ddraw.h"
+#include "ddraw_private.h"
+#include "ddcomimpl.h"
+
+static HRESULT WINAPI
+IDirectDrawImpl_QueryInterface(LPDIRECTDRAW This, REFIID iid, LPVOID *ppObj)
+{
+    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw,
+							  IDirectDraw7, This),
+				       iid, ppObj);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_QueryInterface(LPDIRECTDRAW2 This, REFIID iid, LPVOID *ppObj)
+{
+    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw2,
+							  IDirectDraw7, This),
+				       iid, ppObj);
+}
+
+
+static HRESULT WINAPI
+IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
+{
+    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw4,
+							  IDirectDraw7, This),
+				       iid, ppObj);
+}
+
+static ULONG WINAPI
+IDirectDrawImpl_AddRef(LPDIRECTDRAW This)
+{
+    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
+						  IDirectDraw, IDirectDraw7,
+						  This));
+}
+
+static ULONG WINAPI
+IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 This)
+{
+    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
+						  IDirectDraw2, IDirectDraw7,
+						  This));
+}
+
+static ULONG WINAPI
+IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
+						  IDirectDraw4, IDirectDraw7,
+						  This));
+}
+
+static ULONG WINAPI
+IDirectDrawImpl_Release(LPDIRECTDRAW This)
+{
+    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw, IDirectDraw7,
+						   This));
+}
+
+static ULONG WINAPI
+IDirectDraw2Impl_Release(LPDIRECTDRAW2 This)
+{
+    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw2, IDirectDraw7,
+						   This));
+}
+
+static ULONG WINAPI
+IDirectDraw4Impl_Release(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw4, IDirectDraw7,
+						   This));
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_Compact(LPDIRECTDRAW This)
+{
+    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw, IDirectDraw7,
+						   This));
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_Compact(LPDIRECTDRAW2 This)
+{
+    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw2, IDirectDraw7,
+						   This));
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_Compact(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_Compact(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw4, IDirectDraw7,
+						   This));
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_CreateClipper(LPDIRECTDRAW This, DWORD dwFlags,
+			      LPDIRECTDRAWCLIPPER *ppClipper,
+			      IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, ppClipper, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_CreateClipper(LPDIRECTDRAW2 This, DWORD dwFlags,
+			       LPDIRECTDRAWCLIPPER *ppClipper,
+			       IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw2,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, ppClipper, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_CreateClipper(LPDIRECTDRAW4 This, DWORD dwFlags,
+			       LPDIRECTDRAWCLIPPER *ppClipper,
+			       IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreateClipper(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw4,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, ppClipper, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
+			      LPPALETTEENTRY pEntries,
+			      LPDIRECTDRAWPALETTE *ppPalette,
+			      IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, pEntries, ppPalette, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
+			       LPPALETTEENTRY pEntries,
+			       LPDIRECTDRAWPALETTE *ppPalette,
+			       IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw2,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, pEntries, ppPalette, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
+			       LPPALETTEENTRY pEntries,
+			       LPDIRECTDRAWPALETTE *ppPalette,
+			       IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw4,
+							 IDirectDraw7,
+							 This),
+				      dwFlags, pEntries, ppPalette, pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
+			      LPDIRECTDRAWSURFACE *ppSurface,
+			      IUnknown *pUnkOuter)
+{
+    LPDIRECTDRAWSURFACE7 pSurface7;
+    HRESULT hr;
+
+    /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
+     * since the data layout is the same */
+    hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw,
+						       IDirectDraw7,
+						       This),
+				    (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppSurface = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
+				    IDirectDrawSurface7, IDirectDrawSurface3,
+				    pSurface7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
+			       LPDIRECTDRAWSURFACE *ppSurface,
+			       IUnknown *pUnkOuter)
+{
+    LPDIRECTDRAWSURFACE7 pSurface7;
+    HRESULT hr;
+
+    hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw2,
+						       IDirectDraw7,
+						       This),
+				    (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppSurface = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
+				    IDirectDrawSurface7, IDirectDrawSurface3,
+				    pSurface7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
+			       LPDIRECTDRAWSURFACE4 *ppSurface,
+			       IUnknown *pUnkOuter)
+{
+    return IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw4,
+							 IDirectDraw7,
+							 This),
+				      pSDesc,
+				      (LPDIRECTDRAWSURFACE7 *)ppSurface,
+				      pUnkOuter);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
+				 LPDIRECTDRAWSURFACE *ppDst)
+{
+    LPDIRECTDRAWSURFACE7 pDst7;
+    HRESULT hr;
+
+    hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw,
+							  IDirectDraw7, This),
+				       COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
+							  IDirectDrawSurface3,
+							  IDirectDrawSurface7,
+							  pSrc),
+				       &pDst7);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
+				IDirectDrawSurface3, pDst7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
+				  LPDIRECTDRAWSURFACE *ppDst)
+{
+    LPDIRECTDRAWSURFACE7 pDst7;
+    HRESULT hr;
+
+    hr = IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw2,
+							  IDirectDraw7, This),
+				       COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
+							  IDirectDrawSurface3,
+							  IDirectDrawSurface7,
+							  pSrc),
+				       &pDst7);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppDst = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
+				IDirectDrawSurface3, pDst7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
+				  LPDIRECTDRAWSURFACE4 pSrc,
+				  LPDIRECTDRAWSURFACE4 *ppDst)
+{
+    return IDirectDraw7_DuplicateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw4,
+							    IDirectDraw7,
+							    This),
+					 (LPDIRECTDRAWSURFACE7)pSrc,
+					 (LPDIRECTDRAWSURFACE7 *)ppDst);
+}
+
+struct displaymodescallback_context
+{
+    LPDDENUMMODESCALLBACK func;
+    LPVOID context;
+};
+
+static HRESULT CALLBACK
+EnumDisplayModesCallbackThunk(LPDDSURFACEDESC2 pDDSD2, LPVOID context)
+{
+    DDSURFACEDESC DDSD;
+    struct displaymodescallback_context *cbcontext = context;
+
+    memcpy(&DDSD,pDDSD2,sizeof(DDSD));
+    DDSD.dwSize = sizeof(DDSD);
+
+    return cbcontext->func(&DDSD, cbcontext->context);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_EnumDisplayModes(LPDIRECTDRAW This, DWORD dwFlags,
+				 LPDDSURFACEDESC pDDSD, LPVOID context,
+				 LPDDENUMMODESCALLBACK cb)
+{
+    struct displaymodescallback_context cbcontext;
+
+    cbcontext.func    = cb;
+    cbcontext.context = context;
+
+    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw,
+							    IDirectDraw7,
+							    This),
+					 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
+					 EnumDisplayModesCallbackThunk);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_EnumDisplayModes(LPDIRECTDRAW2 This, DWORD dwFlags,
+				  LPDDSURFACEDESC pDDSD, LPVOID context,
+				  LPDDENUMMODESCALLBACK cb)
+{
+    struct displaymodescallback_context cbcontext;
+
+    cbcontext.func    = cb;
+    cbcontext.context = context;
+
+    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw2,
+							    IDirectDraw7,
+							    This),
+					 dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext,
+					 EnumDisplayModesCallbackThunk);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_EnumDisplayModes(LPDIRECTDRAW4 This, DWORD dwFlags,
+				  LPDDSURFACEDESC2 pDDSD, LPVOID context,
+				  LPDDENUMMODESCALLBACK2 cb)
+{
+    return IDirectDraw7_EnumDisplayModes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw4,
+							    IDirectDraw7,
+							    This),
+					 dwFlags, pDDSD, context, cb);
+}
+
+struct surfacescallback_context
+{
+    LPDDENUMSURFACESCALLBACK func;
+    LPVOID context;
+};
+
+static HRESULT CALLBACK
+EnumSurfacesCallbackThunk(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
+			  LPVOID context)
+{
+    struct surfacescallback_context *cbcontext = context;
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    return cbcontext->func((LPDIRECTDRAWSURFACE)
+                           COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,
+					      IDirectDrawSurface7,
+					      IDirectDrawSurface3, pSurf),
+			   (LPDDSURFACEDESC)pDDSD, cbcontext->context);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_EnumSurfaces(LPDIRECTDRAW This, DWORD dwFlags,
+			     LPDDSURFACEDESC pDDSD, LPVOID context,
+			     LPDDENUMSURFACESCALLBACK cb)
+{
+    struct surfacescallback_context cbcontext;
+
+    cbcontext.func    = cb;
+    cbcontext.context = context;
+
+    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
+							IDirectDraw,
+							IDirectDraw7, This),
+				     dwFlags, (LPDDSURFACEDESC2)pDDSD,
+				     &cbcontext, EnumSurfacesCallbackThunk);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
+			      LPDDSURFACEDESC pDDSD, LPVOID context,
+			      LPDDENUMSURFACESCALLBACK cb)
+{
+    struct surfacescallback_context cbcontext;
+
+    cbcontext.func    = cb;
+    cbcontext.context = context;
+
+    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
+							IDirectDraw2,
+							IDirectDraw7, This),
+				     dwFlags, (LPDDSURFACEDESC2)pDDSD,
+				     &cbcontext, EnumSurfacesCallbackThunk);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_EnumSurfaces(LPDIRECTDRAW4 This, DWORD dwFlags,
+			      LPDDSURFACEDESC2 pDDSD, LPVOID context,
+			      LPDDENUMSURFACESCALLBACK2 cb)
+{
+    return IDirectDraw7_EnumSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
+							IDirectDraw4,
+							IDirectDraw7, This),
+				     dwFlags, pDDSD, context,
+				     (LPDDENUMSURFACESCALLBACK7)cb);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_FlipToGDISurface(LPDIRECTDRAW This)
+{
+    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw,
+							    IDirectDraw7,
+							    This));
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 This)
+{
+    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw2,
+							    IDirectDraw7,
+							    This));
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_FlipToGDISurface(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_FlipToGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw4,
+							    IDirectDraw7,
+							    This));
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetCaps(LPDIRECTDRAW This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
+{
+    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw, IDirectDraw7,
+						   This), pDDC1, pDDC2);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetCaps(LPDIRECTDRAW2 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
+{
+    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw2, IDirectDraw7,
+						   This), pDDC1, pDDC2);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetCaps(LPDIRECTDRAW4 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
+{
+    return IDirectDraw7_GetCaps(COM_INTERFACE_CAST(IDirectDrawImpl,
+						   IDirectDraw4, IDirectDraw7,
+						   This), pDDC1, pDDC2);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetDisplayMode(LPDIRECTDRAW This, LPDDSURFACEDESC pDDSD)
+{
+    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw,
+							  IDirectDraw7, This),
+				       (LPDDSURFACEDESC2)pDDSD);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetDisplayMode(LPDIRECTDRAW2 This, LPDDSURFACEDESC pDDSD)
+{
+    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw2,
+							  IDirectDraw7, This),
+				       (LPDDSURFACEDESC2)pDDSD);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetDisplayMode(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pDDSD)
+{
+    return IDirectDraw7_GetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw4,
+							  IDirectDraw7, This),
+				       pDDSD);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetFourCCCodes(LPDIRECTDRAW This, LPDWORD lpNumCodes,
+			       LPDWORD lpCodes)
+{
+    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw,
+							  IDirectDraw7,
+							  This),
+				       lpNumCodes, lpCodes);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetFourCCCodes(LPDIRECTDRAW2 This, LPDWORD lpNumCodes,
+				LPDWORD lpCodes)
+{
+    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw2,
+							  IDirectDraw7,
+							  This),
+				       lpNumCodes, lpCodes);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetFourCCCodes(LPDIRECTDRAW4 This, LPDWORD lpNumCodes,
+				LPDWORD lpCodes)
+{
+    return IDirectDraw7_GetFourCCCodes(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw4,
+							  IDirectDraw7,
+							  This),
+				       lpNumCodes, lpCodes);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetGDISurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE *ppSurf)
+{
+    LPDIRECTDRAWSURFACE7 pSurf7;
+    HRESULT hr;
+
+    hr = IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw,
+						       IDirectDraw7,
+						       This), &pSurf7);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppSurf = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
+				 IDirectDrawSurface3, pSurf7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE *ppSurf)
+{
+    LPDIRECTDRAWSURFACE7 pSurf7;
+    HRESULT hr;
+
+    hr = IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw2,
+						       IDirectDraw7,
+						       This), &pSurf7);
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    *ppSurf = (LPDIRECTDRAWSURFACE)COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
+				 IDirectDrawSurface3, pSurf7);
+
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetGDISurface(LPDIRECTDRAW4 This,
+			       LPDIRECTDRAWSURFACE4 *ppSurf)
+{
+    return IDirectDraw7_GetGDISurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+							 IDirectDraw4,
+							 IDirectDraw7,
+							 This),
+				      (LPDIRECTDRAWSURFACE7 *)ppSurf);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetMonitorFrequency(LPDIRECTDRAW This, LPDWORD pdwFreq)
+{
+    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw,
+							       IDirectDraw7,
+							       This),
+					    pdwFreq);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetMonitorFrequency(LPDIRECTDRAW2 This, LPDWORD pdwFreq)
+{
+    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw2,
+							       IDirectDraw7,
+							       This),
+					    pdwFreq);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetMonitorFrequency(LPDIRECTDRAW4 This, LPDWORD pdwFreq)
+{
+    return IDirectDraw7_GetMonitorFrequency(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw4,
+							       IDirectDraw7,
+							       This),
+					    pdwFreq);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetScanLine(LPDIRECTDRAW This, LPDWORD pdwLine)
+{
+    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw,
+						       IDirectDraw7,
+						       This), pdwLine);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 This, LPDWORD pdwLine)
+{
+    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw2,
+						       IDirectDraw7,
+						       This), pdwLine);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetScanLine(LPDIRECTDRAW4 This, LPDWORD pdwLine)
+{
+    return IDirectDraw7_GetScanLine(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw4,
+						       IDirectDraw7,
+						       This), pdwLine);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_GetVerticalBlankStatus(LPDIRECTDRAW This, LPBOOL lpbIsInVB)
+{
+    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
+								  IDirectDraw,
+								  IDirectDraw7,
+								  This),
+					       lpbIsInVB);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetVerticalBlankStatus(LPDIRECTDRAW2 This, LPBOOL lpbIsInVB)
+{
+    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
+								  IDirectDraw2,
+								  IDirectDraw7,
+								  This),
+					       lpbIsInVB);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetVerticalBlankStatus(LPDIRECTDRAW4 This, LPBOOL lpbIsInVB)
+{
+    return IDirectDraw7_GetVerticalBlankStatus(COM_INTERFACE_CAST(IDirectDrawImpl,
+								  IDirectDraw4,
+								  IDirectDraw7,
+								  This),
+					       lpbIsInVB);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_Initialize(LPDIRECTDRAW iface, LPGUID pGUID)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
+    HRESULT ret_value;
+
+    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
+    
+    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
+    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
+    
+    return ret_value;
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, LPGUID pGUID)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
+    HRESULT ret_value;
+    
+    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
+
+    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
+    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
+    
+    return ret_value;
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_Initialize(LPDIRECTDRAW4 iface, LPGUID pGUID)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
+    HRESULT ret_value;
+    
+    ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID);
+    
+    /* Overwrite the falsely set 'DIRECTDRAW7' flag */
+    This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7;
+    
+    return ret_value;
+}
+
+
+static HRESULT WINAPI
+IDirectDrawImpl_RestoreDisplayMode(LPDIRECTDRAW This)
+{
+    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw,
+							      IDirectDraw7,
+							      This));
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 This)
+{
+    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw2,
+							      IDirectDraw7,
+							      This));
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_RestoreDisplayMode(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_RestoreDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw4,
+							      IDirectDraw7,
+							      This));
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_SetCooperativeLevel(LPDIRECTDRAW This, HWND hWnd,
+				    DWORD dwFlags)
+{
+    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw,
+							       IDirectDraw7,
+							       This),
+					    hWnd, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_SetCooperativeLevel(LPDIRECTDRAW2 This, HWND hWnd,
+				     DWORD dwFlags)
+{
+    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw2,
+							       IDirectDraw7,
+							       This),
+					    hWnd, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_SetCooperativeLevel(LPDIRECTDRAW4 This, HWND hWnd,
+				     DWORD dwFlags)
+{
+    return IDirectDraw7_SetCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
+							       IDirectDraw4,
+							       IDirectDraw7,
+							       This),
+					    hWnd, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_SetDisplayMode(LPDIRECTDRAW This, DWORD a, DWORD b, DWORD c)
+{
+    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw,
+							  IDirectDraw7,
+							  This),
+				       a, b, c, 0, 0);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_SetDisplayMode(LPDIRECTDRAW2 This, DWORD a, DWORD b, DWORD c,
+				DWORD d, DWORD e)
+{
+    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw2,
+							  IDirectDraw7,
+							  This),
+				       a, b, c, d, e);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_SetDisplayMode(LPDIRECTDRAW4 This, DWORD a, DWORD b, DWORD c,
+				DWORD d, DWORD e)
+{
+    return IDirectDraw7_SetDisplayMode(COM_INTERFACE_CAST(IDirectDrawImpl,
+							  IDirectDraw4,
+							  IDirectDraw7,
+							  This),
+				       a, b, c, d, e);
+}
+
+static HRESULT WINAPI
+IDirectDrawImpl_WaitForVerticalBlank(LPDIRECTDRAW This, DWORD dwFlags,
+				     HANDLE hEvent)
+{
+    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
+								IDirectDraw,
+								IDirectDraw7,
+								This),
+					     dwFlags, hEvent);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_WaitForVerticalBlank(LPDIRECTDRAW2 This, DWORD dwFlags,
+				      HANDLE hEvent)
+{
+    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
+								IDirectDraw2,
+								IDirectDraw7,
+								This),
+					     dwFlags, hEvent);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_WaitForVerticalBlank(LPDIRECTDRAW4 This, DWORD dwFlags,
+				      HANDLE hEvent)
+{
+    return IDirectDraw7_WaitForVerticalBlank(COM_INTERFACE_CAST(IDirectDrawImpl,
+								IDirectDraw4,
+								IDirectDraw7,
+								This),
+					     dwFlags, hEvent);
+}
+
+static HRESULT WINAPI
+IDirectDraw2Impl_GetAvailableVidMem(LPDIRECTDRAW2 This, LPDDSCAPS pCaps,
+				    LPDWORD pdwTotal, LPDWORD pdwFree)
+{
+    DDSCAPS2 Caps2;
+    DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
+
+    return IDirectDraw7_GetAvailableVidMem(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw2,
+							      IDirectDraw7,
+							      This),
+					   &Caps2, pdwTotal, pdwFree);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetAvailableVidMem(LPDIRECTDRAW4 This, LPDDSCAPS2 pCaps,
+				    LPDWORD pdwTotal, LPDWORD pdwFree)
+{
+    return IDirectDraw7_GetAvailableVidMem(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw4,
+							      IDirectDraw7,
+							      This),
+					   pCaps, pdwTotal, pdwFree);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 This, HDC hDC,
+				  LPDIRECTDRAWSURFACE4 *pSurf)
+{
+    return IDirectDraw7_GetSurfaceFromDC(COM_INTERFACE_CAST(IDirectDrawImpl,
+							    IDirectDraw4,
+							    IDirectDraw7,
+							    This),
+					 hDC, (LPDIRECTDRAWSURFACE7 *)pSurf);
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_RestoreAllSurfaces(COM_INTERFACE_CAST(IDirectDrawImpl,
+							      IDirectDraw4,
+							      IDirectDraw7,
+							      This));
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 This)
+{
+    return IDirectDraw7_TestCooperativeLevel(COM_INTERFACE_CAST(IDirectDrawImpl,
+								IDirectDraw4,
+								IDirectDraw7,
+								This));
+}
+
+static HRESULT WINAPI
+IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 This,
+				     LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags)
+{
+    DDDEVICEIDENTIFIER2 DDDI2;
+    HRESULT hr;
+
+    hr = IDirectDraw7_GetDeviceIdentifier(COM_INTERFACE_CAST(IDirectDrawImpl,
+							     IDirectDraw4,
+							     IDirectDraw7,
+							     This),
+					  &DDDI2, dwFlags);
+
+    DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(&DDDI2, pDDDI);
+
+    return hr;
+}
+
+const IDirectDrawVtbl DDRAW_IDirectDraw_VTable =
+{
+    IDirectDrawImpl_QueryInterface,
+    IDirectDrawImpl_AddRef,
+    IDirectDrawImpl_Release,
+    IDirectDrawImpl_Compact,
+    IDirectDrawImpl_CreateClipper,
+    IDirectDrawImpl_CreatePalette,
+    IDirectDrawImpl_CreateSurface,
+    IDirectDrawImpl_DuplicateSurface,
+    IDirectDrawImpl_EnumDisplayModes,
+    IDirectDrawImpl_EnumSurfaces,
+    IDirectDrawImpl_FlipToGDISurface,
+    IDirectDrawImpl_GetCaps,
+    IDirectDrawImpl_GetDisplayMode,
+    IDirectDrawImpl_GetFourCCCodes,
+    IDirectDrawImpl_GetGDISurface,
+    IDirectDrawImpl_GetMonitorFrequency,
+    IDirectDrawImpl_GetScanLine,
+    IDirectDrawImpl_GetVerticalBlankStatus,
+    IDirectDrawImpl_Initialize,
+    IDirectDrawImpl_RestoreDisplayMode,
+    IDirectDrawImpl_SetCooperativeLevel,
+    IDirectDrawImpl_SetDisplayMode,
+    IDirectDrawImpl_WaitForVerticalBlank,
+};
+
+const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable =
+{
+    IDirectDraw2Impl_QueryInterface,
+    IDirectDraw2Impl_AddRef,
+    IDirectDraw2Impl_Release,
+    IDirectDraw2Impl_Compact,
+    IDirectDraw2Impl_CreateClipper,
+    IDirectDraw2Impl_CreatePalette,
+    IDirectDraw2Impl_CreateSurface,
+    IDirectDraw2Impl_DuplicateSurface,
+    IDirectDraw2Impl_EnumDisplayModes,
+    IDirectDraw2Impl_EnumSurfaces,
+    IDirectDraw2Impl_FlipToGDISurface,
+    IDirectDraw2Impl_GetCaps,
+    IDirectDraw2Impl_GetDisplayMode,
+    IDirectDraw2Impl_GetFourCCCodes,
+    IDirectDraw2Impl_GetGDISurface,
+    IDirectDraw2Impl_GetMonitorFrequency,
+    IDirectDraw2Impl_GetScanLine,
+    IDirectDraw2Impl_GetVerticalBlankStatus,
+    IDirectDraw2Impl_Initialize,
+    IDirectDraw2Impl_RestoreDisplayMode,
+    IDirectDraw2Impl_SetCooperativeLevel,
+    IDirectDraw2Impl_SetDisplayMode,
+    IDirectDraw2Impl_WaitForVerticalBlank,
+    IDirectDraw2Impl_GetAvailableVidMem
+};
+
+const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable =
+{
+    IDirectDraw4Impl_QueryInterface,
+    IDirectDraw4Impl_AddRef,
+    IDirectDraw4Impl_Release,
+    IDirectDraw4Impl_Compact,
+    IDirectDraw4Impl_CreateClipper,
+    IDirectDraw4Impl_CreatePalette,
+    IDirectDraw4Impl_CreateSurface,
+    IDirectDraw4Impl_DuplicateSurface,
+    IDirectDraw4Impl_EnumDisplayModes,
+    IDirectDraw4Impl_EnumSurfaces,
+    IDirectDraw4Impl_FlipToGDISurface,
+    IDirectDraw4Impl_GetCaps,
+    IDirectDraw4Impl_GetDisplayMode,
+    IDirectDraw4Impl_GetFourCCCodes,
+    IDirectDraw4Impl_GetGDISurface,
+    IDirectDraw4Impl_GetMonitorFrequency,
+    IDirectDraw4Impl_GetScanLine,
+    IDirectDraw4Impl_GetVerticalBlankStatus,
+    IDirectDraw4Impl_Initialize,
+    IDirectDraw4Impl_RestoreDisplayMode,
+    IDirectDraw4Impl_SetCooperativeLevel,
+    IDirectDraw4Impl_SetDisplayMode,
+    IDirectDraw4Impl_WaitForVerticalBlank,
+    IDirectDraw4Impl_GetAvailableVidMem,
+    IDirectDraw4Impl_GetSurfaceFromDC,
+    IDirectDraw4Impl_RestoreAllSurfaces,
+    IDirectDraw4Impl_TestCooperativeLevel,
+    IDirectDraw4Impl_GetDeviceIdentifier
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/ddraw/ddraw_user.c	2005-06-03 20:51:09.000000000 +0100
@@ -0,0 +1,562 @@
+/*	DirectDraw driver for User-based primary surfaces
+ *
+ * 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 <stdarg.h>
+#include <string.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#define CONST_VTABLE
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "ddraw.h"
+#include "ddraw_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+static const IDirectDraw7Vtbl User_DirectDraw_VTable;
+
+static const DDDEVICEIDENTIFIER2 user_device =
+{
+    "display",
+    "User (and GDI)",
+    { { 0x00010001, 0x00010001 } },
+    0, 0, 0, 0,
+    /* fe38440c-8969-4283-bc73-749e7bc3c2eb */
+    {0xfe38440c,0x8969,0x428e, {0x73,0xbc,0x74,0x9e,0x7b,0xc3,0xc2,0xeb}},
+    0
+};
+
+static const DDPIXELFORMAT pixelformats[] =
+{
+    /* 8bpp paletted */
+    { sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_PALETTEINDEXED8, 0, { 8 } },
+    /* 15bpp 5/5/5 */
+    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0x7C00 }, { 0x3E0 },
+      { 0x1F } },
+    /* 16bpp 5/6/5 */
+    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0xF800 }, { 0x7E0 },
+      { 0x1F } },
+    /* 24bpp 8/8/8 */
+    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 24 }, { 0xFF0000 },
+      { 0x00FF00 }, { 0x0000FF } },
+    /* 32bpp 8/8/8 */
+    { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 32 }, { 0xFF0000 },
+      { 0x00FF00 }, { 0x0000FF } }
+};
+
+HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+				     IUnknown* pUnkOuter, BOOL ex);
+HRESULT User_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
+
+static const ddraw_driver user_driver =
+{
+    &user_device,
+    10,
+    User_DirectDraw_Create,
+    User_DirectDraw_Initialize
+};
+
+BOOL DDRAW_User_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+    if (fdwReason == DLL_PROCESS_ATTACH)
+	DDRAW_register_driver(&user_driver);
+
+    return TRUE;
+}
+
+static const DDPIXELFORMAT* pixelformat_for_depth(DWORD depth)
+{
+    switch (depth)
+    {
+    case  8: return pixelformats + 0;
+    case 15: return pixelformats + 1;
+    case 16: return pixelformats + 2;
+    case 24: return pixelformats + 3;
+    case 32: return pixelformats + 4;
+    default: return NULL;
+    }
+}
+
+/* Not called from the vtable. */
+HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
+{
+    HRESULT hr;
+    DWORD depth;
+    HDC hDC;
+
+    TRACE("(%p,%d)\n",This,ex);
+
+    hr = Main_DirectDraw_Construct(This, ex);
+    if (FAILED(hr)) return hr;
+
+    This->final_release = User_DirectDraw_final_release;
+
+    This->create_primary    = User_DirectDraw_create_primary;
+    This->create_backbuffer = User_DirectDraw_create_backbuffer;
+
+    hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
+    depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
+    DeleteDC(hDC);
+
+    This->width       = GetSystemMetrics(SM_CXSCREEN);
+    This->height      = GetSystemMetrics(SM_CYSCREEN);
+    This->pitch       = DDRAW_width_bpp_to_pitch(This->width, depth);
+    This->pixelformat = *pixelformat_for_depth(depth);
+
+    This->orig_width       = This->width;
+    This->orig_height      = This->height;
+    This->orig_pitch       = This->pitch;
+    This->orig_pixelformat = This->pixelformat;
+
+    ICOM_INIT_INTERFACE(This, IDirectDraw7, User_DirectDraw_VTable);
+
+    /* capabilities */
+#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
+	  | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP	  \
+	  | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY			  \
+	  | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
+#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
+#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT	\
+		| DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90	\
+		| DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN		\
+		| DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN		\
+		| DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN		\
+		| DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
+    This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS;
+    if( opengl_initialized )
+    {
+        /* Hack for D3D code */
+        This->caps.dwCaps |= DDCAPS_3D;
+    }
+    This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED |
+			  DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES;
+    This->caps.dwCKeyCaps |= CKEY_CAPS;
+    This->caps.dwFXCaps |= FX_CAPS;
+    This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
+    This->caps.dwVidMemTotal = 16*1024*1024;
+    This->caps.dwVidMemFree = 16*1024*1024;
+    This->caps.dwSVBCaps |= BLIT_CAPS;
+    This->caps.dwSVBCKeyCaps |= CKEY_CAPS;
+    This->caps.dwSVBFXCaps |= FX_CAPS;
+    This->caps.dwVSBCaps |= BLIT_CAPS;
+    This->caps.dwVSBCKeyCaps |= CKEY_CAPS;
+    This->caps.dwVSBFXCaps |= FX_CAPS;
+    This->caps.dwSSBCaps |= BLIT_CAPS;
+    This->caps.dwSSBCKeyCaps |= CKEY_CAPS;
+    This->caps.dwSSBFXCaps |= FX_CAPS;
+    This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER |
+				 DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
+				 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE |
+				 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
+				 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
+    if( opengl_initialized )
+    {
+        /* Hacks for D3D code */
+        This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
+    }
+    
+    This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
+#undef BLIT_CAPS
+#undef CKEY_CAPS
+#undef FX_CAPS
+
+    return S_OK;
+}
+
+/* This function is called from DirectDrawCreate(Ex) on the most-derived
+ * class to start construction.
+ * Not called from the vtable. */
+HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+			       IUnknown* pUnkOuter, BOOL ex)
+{
+    HRESULT hr;
+    IDirectDrawImpl* This;
+
+    assert(pUnkOuter == NULL);
+
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+		     sizeof(IDirectDrawImpl) + sizeof(User_DirectDrawImpl));
+    if (This == NULL) return E_OUTOFMEMORY;
+
+    /* Note that this relation does *not* hold true if the DD object was
+     * CoCreateInstanced then Initialized. */
+    This->private = (User_DirectDrawImpl *)(This+1);
+
+    /* Initialize the DDCAPS structure */
+    This->caps.dwSize = sizeof(This->caps);
+
+    hr = User_DirectDraw_Construct(This, ex);
+    if (FAILED(hr))
+	HeapFree(GetProcessHeap(), 0, This);
+    else
+	*pIface = ICOM_INTERFACE(This, IDirectDraw7);
+
+    return hr;
+}
+
+/* This function is called from Uninit_DirectDraw_Initialize on the
+ * most-derived-class to start initialization.
+ * Not called from the vtable. */
+HRESULT User_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
+{
+    HRESULT hr;
+    This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+			      sizeof(User_DirectDrawImpl));
+    if (This->private == NULL) return E_OUTOFMEMORY;
+
+    /* Initialize the DDCAPS structure */
+    This->caps.dwSize = sizeof(This->caps);
+
+    hr = User_DirectDraw_Construct(This, TRUE); /* XXX ex? */
+    if (FAILED(hr))
+    {
+	HeapFree(GetProcessHeap(), 0, This->private);
+	return hr;
+    }
+
+    return DD_OK;
+}
+
+/* Called from an internal function pointer. */
+void User_DirectDraw_final_release(IDirectDrawImpl *This)
+{
+    Main_DirectDraw_final_release(This);
+}
+
+/* Compact: generic */
+/* CreateClipper: generic */
+/* CreatePalette: generic (with callback) */
+/* CreateSurface: generic (with callbacks) */
+
+HRESULT
+User_DirectDraw_create_primary(IDirectDrawImpl* This,
+			       const DDSURFACEDESC2* pDDSD,
+			       LPDIRECTDRAWSURFACE7* ppSurf,
+			       IUnknown* pUnkOuter)
+{
+    return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+}
+
+HRESULT
+User_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
+				  const DDSURFACEDESC2* pDDSD,
+				  LPDIRECTDRAWSURFACE7* ppSurf,
+				  IUnknown* pUnkOuter,
+				  IDirectDrawSurfaceImpl* primary)
+{
+    return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
+}
+
+/* DuplicateSurface: generic */
+
+/* Originally derived from Xlib_IDirectDraw2Impl_EnumDisplayModes.
+ *
+ * The depths are whatever DIBsections support on the client side.
+ * Should they be limited by screen depth?
+ */
+HRESULT WINAPI
+User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
+				 LPDDSURFACEDESC2 pDDSD, LPVOID context,
+				 LPDDENUMMODESCALLBACK2 callback)
+{
+    DDSURFACEDESC2 callback_sd;
+    DEVMODEW DevModeW;
+    const DDPIXELFORMAT* pixelformat;
+
+    int i;
+
+    TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",iface,dwFlags,pDDSD,context,callback);
+
+    ZeroMemory(&callback_sd, sizeof(callback_sd));
+    callback_sd.dwSize = sizeof(callback_sd);
+
+    callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS
+	| DDSD_PITCH;
+
+    if (dwFlags & DDEDM_REFRESHRATES)
+	callback_sd.dwFlags |= DDSD_REFRESHRATE;
+
+    callback_sd.u2.dwRefreshRate = 60.0;
+
+    i = 0;
+    while (EnumDisplaySettingsExW(NULL, i, &DevModeW, 0))
+    {
+	callback_sd.dwHeight = DevModeW.dmPelsHeight;
+	callback_sd.dwWidth = DevModeW.dmPelsWidth;
+        if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
+        {
+            callback_sd.u2.dwRefreshRate = DevModeW.dmDisplayFrequency;
+        }
+
+	TRACE("- mode: %ldx%ld\n", callback_sd.dwWidth, callback_sd.dwHeight);
+        
+        pixelformat = pixelformat_for_depth(DevModeW.dmBitsPerPel);
+        callback_sd.u1.lPitch
+            = DDRAW_width_bpp_to_pitch(DevModeW.dmPelsWidth,
+                                       pixelformat->u1.dwRGBBitCount);
+
+        callback_sd.u4.ddpfPixelFormat = *pixelformat;
+
+        callback_sd.ddsCaps.dwCaps = 0;
+        if (pixelformat->dwFlags & DDPF_PALETTEINDEXED8) /* ick */
+            callback_sd.ddsCaps.dwCaps |= DDSCAPS_PALETTE;
+
+        TRACE(" - %2ld bpp, R=%08lx G=%08lx B=%08lx\n",
+            callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
+            callback_sd.u4.ddpfPixelFormat.u2.dwRBitMask,
+            callback_sd.u4.ddpfPixelFormat.u3.dwGBitMask,
+            callback_sd.u4.ddpfPixelFormat.u4.dwBBitMask);
+        if (callback(&callback_sd, context) == DDENUMRET_CANCEL)
+            return DD_OK;
+        i++;
+    }
+
+    return DD_OK;
+}
+
+/* EnumSurfaces: generic */
+/* FlipToGDISurface: ??? */
+
+#if 0
+HRESULT WINAPI
+User_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
+			LPDDCAPS pHELCaps)
+{
+/* Based on my guesses for what is appropriate with some clues from the
+ * NVidia driver. Not everything is actually implemented yet.
+ * NV has but we don't: Overlays, Video Ports, DDCAPS_READSCANLINE,
+ * DDCAPS2_CERTIFIED (heh), DDSCAPS2_NONLOCALVIDMEM, DDSCAPS2_COPYFOURCC.
+ * It actually has no FX alpha caps.
+ * Oddly, it doesn't list DDPCAPS_PRIMARYSURFACE.
+ * And the HEL caps make little sense.
+ */
+#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
+	  | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP	  \
+	  | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY			  \
+	  | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
+
+#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
+
+#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT	\
+		| DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90	\
+		| DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN		\
+		| DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN		\
+		| DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN		\
+		| DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
+
+#if 0
+#define ROPS { SRCCOPY, SRCPAINT, SRCAND, SRCINVERT, SRCERASE, NOTSRCCOPY, \
+	NOTSRCERASE, MERGEPAINT, BLACKNESS, WHITENESS, }
+#else
+#define ROPS { 0, }
+#endif
+
+    static const DDCAPS caps =
+    { sizeof(DDCAPS),
+      DDCAPS_3D | DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS,
+      DDCAPS2_CANMANAGETEXTURE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_CERTIFIED
+      | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA
+      | DDCAPS2_WIDESURFACES,
+      CKEY_CAPS,
+      FX_CAPS,
+      0, /* dwFXAlphaCaps */
+      DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,
+      0, /* dwSVCaps */
+      0, /* ? dwAlphaBitConstBitDepths */
+      0, /* ? dwAlphaBitPixelPitDepths */
+      0, /* ? dwAlphaBltSurfaceBitDepths */
+      0, /* ? dwAlphaOverlayConstBitDepths */
+      0, /* ? dwAlphaOverlayPixelBitDepths */
+      0, /* ? dwAlphaOverlaySurfaceBitDepths */
+      DDBD_16, /* ? dwZBufferBitDepths */
+      16*1024*1024, /* dwVidMemTotal */
+      16*1024*1024, /* dwVidMemFree */
+      0, /* dwMaxVisibleOverlays */
+      0, /* dwCurrVisibleOverlays */
+      0, /* dwNumFourCCCodes */
+      0, /* dwAlignBoundarySrc */
+      0, /* dwAlignSizeSrc */
+      0, /* dwAlignBoundaryDest */
+      0, /* dwAlignSizeDest */
+      0, /* dwAlignStrideAlign */
+      ROPS, /* XXX dwRops[DD_ROP_SPACE] */
+      { 0, }, /* XXX ddsOldCaps */
+      1000, /* dwMinOverlayStretch */
+      1000, /* dwMaxOverlayStretch */
+      1000, /* dwMinLiveVideoStretch */
+      1000, /* dwMaxLiveVideoStretch */
+      1000, /* dwMinHwCodecStretch */
+      1000, /* dwMaxHwCodecStretch */
+      0, 0, 0, /* dwReserved1, 2, 3 */
+      BLIT_CAPS, /* dwSVBCaps */
+      CKEY_CAPS, /* dwSVBCKeyCaps */
+      FX_CAPS, /* dwSVBFXCaps */
+      ROPS, /* dwSVBRops */
+      BLIT_CAPS, /* dwVSBCaps */
+      CKEY_CAPS, /* dwVSBCKeyCaps */
+      FX_CAPS, /* dwVSBFXCaps */
+      ROPS, /* dwVSBRops */
+      BLIT_CAPS, /* dwSSBCaps */
+      CKEY_CAPS, /* dwSSBCKeyCaps */
+      FX_CAPS, /* dwSSBFXCaps */
+      ROPS, /* dwSSBRops */
+      0, /* dwMaxVideoPorts */
+      0, /* dwCurrVideoPorts */
+      0, /* ? dwSVBCaps2 */
+      BLIT_CAPS, /* ? dwNLVBCaps */
+      0, /* ? dwNLVBCaps2 */
+      CKEY_CAPS, /* dwNLVBCKeyCaps */
+      FX_CAPS, /* dwNLVBFXCaps */
+      ROPS, /* dwNLVBRops */
+      { /* ddsCaps */
+	  DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP
+	  | DDSCAPS_FRONTBUFFER | DDSCAPS_MIPMAP | DDSCAPS_OFFSCREENPLAIN
+	  | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
+	  | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE
+	  | DDSCAPS_ZBUFFER,
+	  DDSCAPS2_CUBEMAP,
+	  0,
+	  0
+      }
+    };
+
+#undef BLIT_CAPS
+#undef CKEY_CAPS
+#undef FX_CAPS
+#undef ROPS
+
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)->(%p,%p)\n",This,pDriverCaps,pHELCaps);
+
+    if (pDriverCaps != NULL)
+	DD_STRUCT_COPY_BYSIZE(pDriverCaps,&caps);
+
+    if (pHELCaps != NULL)
+	DD_STRUCT_COPY_BYSIZE(pHELCaps,&caps);
+
+    return DD_OK;
+}
+#endif
+
+HRESULT WINAPI
+User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
+				    LPDDDEVICEIDENTIFIER2 pDDDI,
+				    DWORD dwFlags)
+{
+    TRACE("(%p)->(%p,%08lx)\n",iface,pDDDI,dwFlags);
+    *pDDDI = user_device;
+    return DD_OK;
+}
+
+/* GetDisplayMode: generic */
+/* GetFourCCCodes: generic */
+/* GetGDISurface: ??? */
+/* GetMonitorFrequency: generic */
+/* GetScanLine: generic */
+/* GetSurfaceFromDC: generic */
+/* GetVerticalBlankStatus: generic */
+/* Initialize: generic */
+/* RestoreAllSurfaces: generic */
+/* RestoreDisplayMode: generic */
+/* SetCooperativeLevel: ??? */
+
+HRESULT WINAPI
+User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+			       DWORD dwHeight, DWORD dwBPP,
+			       DWORD dwRefreshRate, DWORD dwFlags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    const DDPIXELFORMAT* pixelformat;
+    DEVMODEW devmode;
+    LONG pitch;
+
+    TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
+    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+    devmode.dmBitsPerPel = dwBPP;
+    devmode.dmPelsWidth  = dwWidth;
+    devmode.dmPelsHeight = dwHeight;
+    /* '0' means default frequency */
+    if (dwRefreshRate != 0) 
+    {
+	devmode.dmFields |= DM_DISPLAYFREQUENCY;
+	devmode.dmDisplayFrequency = dwRefreshRate;
+    }
+    if (ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
+	return DDERR_INVALIDMODE;
+
+    pixelformat = pixelformat_for_depth(dwBPP);
+    if (pixelformat == NULL)
+    {
+	assert(0);
+	return DDERR_GENERIC;
+    }
+
+    pitch = DDRAW_width_bpp_to_pitch(dwWidth, dwBPP);
+    return Main_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, pitch,
+					  dwRefreshRate, dwFlags, pixelformat);
+}
+
+/* StartModeTest: ??? */
+/* TestCooperativeLevel: generic? */
+/* WaitForVerticalBlank: ??? */
+
+static const IDirectDraw7Vtbl User_DirectDraw_VTable =
+{
+    Main_DirectDraw_QueryInterface,
+    Main_DirectDraw_AddRef,
+    Main_DirectDraw_Release,
+    Main_DirectDraw_Compact,
+    Main_DirectDraw_CreateClipper,
+    Main_DirectDraw_CreatePalette,
+    Main_DirectDraw_CreateSurface,
+    Main_DirectDraw_DuplicateSurface,
+    User_DirectDraw_EnumDisplayModes,
+    Main_DirectDraw_EnumSurfaces,
+    Main_DirectDraw_FlipToGDISurface,
+    Main_DirectDraw_GetCaps,
+    Main_DirectDraw_GetDisplayMode,
+    Main_DirectDraw_GetFourCCCodes,
+    Main_DirectDraw_GetGDISurface,
+    Main_DirectDraw_GetMonitorFrequency,
+    Main_DirectDraw_GetScanLine,
+    Main_DirectDraw_GetVerticalBlankStatus,
+    Main_DirectDraw_Initialize,
+    Main_DirectDraw_RestoreDisplayMode,
+    Main_DirectDraw_SetCooperativeLevel,
+    User_DirectDraw_SetDisplayMode,
+    Main_DirectDraw_WaitForVerticalBlank,
+    Main_DirectDraw_GetAvailableVidMem,
+    Main_DirectDraw_GetSurfaceFromDC,
+    Main_DirectDraw_RestoreAllSurfaces,
+    Main_DirectDraw_TestCooperativeLevel,
+    User_DirectDraw_GetDeviceIdentifier,
+    Main_DirectDraw_StartModeTest,
+    Main_DirectDraw_EvaluateMode
+};


More information about the wine-patches mailing list