ddraw: Rewrite most of ddraw using WineD3D.
diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in
index 88a7ff4..3e43491 100644
--- a/dlls/ddraw/Makefile.in
+++ b/dlls/ddraw/Makefile.in
@@ -4,45 +4,31 @@
 VPATH     = @srcdir@
 MODULE    = ddraw.dll
 IMPORTLIB = libddraw.$(IMPLIBEXT)
-IMPORTS   = ole32 user32 gdi32 advapi32 kernel32 ntdll
+IMPORTS   = wined3d ole32 user32 gdi32 advapi32 kernel32 ntdll
 EXTRAINCL = @X_CFLAGS@
 EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ 
 
-OPENGLFILES = \
-	d3d_utils.c \
-	device_main.c \
-	device_opengl.c \
-	direct3d_main.c \
-	direct3d_opengl.c \
+C_SRCS = \
+	clipper.c \
+	ddraw.c \
+	ddraw_thunks.c \
+	device.c \
+	direct3d.c \
 	executebuffer.c \
+	gamma.c \
 	light.c \
+	main.c \
 	material.c \
-	opengl_utils.c \
+	palette.c \
+	parent.c \
+	regsvr.c \
+	surface.c \
+	surface_thunks.c \
 	texture.c \
+	utils.c \
 	vertexbuffer.c \
 	viewport.c
 
-C_SRCS = \
-	@OPENGLFILES@ \
-	clipper.c \
-	ddraw_hal.c \
-	ddraw_main.c \
-	ddraw_thunks.c \
-	ddraw_user.c \
-	ddraw_utils.c \
-	main.c \
-	palette_hal.c \
-	palette_main.c \
-	regsvr.c \
-	surface_dib.c \
-	surface_fakezbuffer.c \
-	surface_gamma.c \
-	surface_hal.c \
-	surface_main.c \
-	surface_thunks.c \
-	surface_user.c \
-	surface_wndproc.c
-
 RC_SRCS = version.rc
 
 SUBDIRS = tests
diff --git a/dlls/ddraw/clipper.c b/dlls/ddraw/clipper.c
index 4f0f6b4..9f643b4 100644
--- a/dlls/ddraw/clipper.c
+++ b/dlls/ddraw/clipper.c
@@ -1,7 +1,8 @@
-/*		DirectDrawClipper implementation
+/* DirectDrawClipper implementation
  *
- * Copyright 2000 Marcus Meissner
- * Copyright 2000 TransGaming Technologies Inc.
+ * Copyright 2000 (c) Marcus Meissner
+ * Copyright 2000 (c) TransGaming Technologies Inc.
+ * Copyright 2006 (c) Stefan Dösinger
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,52 +37,97 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-/******************************************************************************
- *			DirectDrawCreateClipper (DDRAW.@)
- */
+/*****************************************************************************
+ * IUnknown methods
+ *****************************************************************************/
 
-static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable;
-
-HRESULT WINAPI DirectDrawCreateClipper(
-    DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
+/*****************************************************************************
+ * IDirectDrawClipper::QueryInterface
+ *
+ * Can query the IUnknown and IDirectDrawClipper interface from a
+ * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
+ * interface. Can't create other interfaces.
+ *
+ * Arguments:
+ *  riid: Interface id asked for
+ *  ppvObj: Returns the pointer to the interface
+ *
+ * Return values:
+ *  DD_OK on success
+ *  E_NOINTERFACE if the requested interface wasn't found.
+ *
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
+    LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
 ) {
-    IDirectDrawClipperImpl* This;
-    TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
 
-    if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(IDirectDrawClipperImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable);
-    This->ref = 1;
-    This->hWnd = 0;
-    This->ddraw_owner = NULL;
-
-    *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper);
-    return DD_OK;
+    if (IsEqualGUID(&IID_IUnknown, riid)
+	|| IsEqualGUID(&IID_IDirectDrawClipper, riid))
+    {
+	*ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
+	InterlockedIncrement(&This->ref);
+	return S_OK;
+    }
+    else
+    {
+	return E_NOINTERFACE;
+    }
 }
 
-/* This is the classfactory implementation. */
-HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid,
-				      LPVOID* ppObj)
+/*****************************************************************************
+ * IDirectDrawClipper::AddRef
+ *
+ * Increases the reference count of the interface, returns the new count
+ *
+ *****************************************************************************/
+static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
 {
-    HRESULT hr;
-    LPDIRECTDRAWCLIPPER pClip;
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
 
-    hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter);
-    if (FAILED(hr)) return hr;
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
 
-    hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj);
-    IDirectDrawClipper_Release(pClip);
-    return hr;
+    return ref;
 }
 
-/******************************************************************************
- *			IDirectDrawClipper
- */
-HRESULT WINAPI Main_DirectDrawClipper_SetHwnd(
+/*****************************************************************************
+ * IDirectDrawClipper::Release
+ *
+ * Decreases the reference count of the interface, returns the new count
+ * If the refcount is decreased to 0, the interface is destroyed.
+ *
+ *****************************************************************************/
+static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
+
+    if (ref == 0)
+    {
+	HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    else return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::SetHwnd
+ *
+ * Assigns a hWnd to the clipper interface.
+ *
+ * Arguments:
+ *  Flags: Unsupported so far
+ *  hWnd: The hWnd to set
+ *
+ * Return values:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Flags was != 0
+ *
+ *****************************************************************************/
+
+static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
 ) {
     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
@@ -96,52 +142,25 @@
     return DD_OK;
 }
 
-static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This)
-{
-    if (This->ddraw_owner != NULL)
-	Main_DirectDraw_RemoveClipper(This->ddraw_owner, This);
-
-    HeapFree(GetProcessHeap(), 0 ,This);
-}
-
-void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This)
-{
-    WARN("deleting clipper %p with refcnt %lu\n", This, This->ref);
-    Main_DirectDrawClipper_Destroy(This);
-}
-
-ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) {
-    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
-
-    if (ref == 0)
-    {
-	Main_DirectDrawClipper_Destroy(This);
-	return 0;
-    }
-    else return ref;
-}
-
-/***********************************************************************
-*           IDirectDrawClipper::GetClipList
-*
-* Retrieve a copy of the clip list
-*
-* PARAMS
-*  lpRect  Rectangle to be used to clip the clip list or NULL for the
-*          entire clip list
-*  lpClipList structure for the resulting copy of the clip list.
-           If NULL, fills lpdwSize up to the number of bytes necessary to hold
-           the entire clip.
-*  lpdwSize Size of resulting clip list; size of the buffer at lpClipList
-           or, if lpClipList is NULL, receives the required size of the buffer
-           in bytes
-* RETURNS
-*  Either DD_OK or DDERR_*
-*/
-HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
+/*****************************************************************************
+ * IDirectDrawClipper::GetClipList
+ *
+ * Retrieve a copy of the clip list
+ *
+ * Arguments:
+ *  Rect: Rectangle to be used to clip the clip list or NULL for the
+ *        entire clip list
+ *  ClipList: structure for the resulting copy of the clip list.
+ *            If NULL, fills Size up to the number of bytes necessary to hold
+ *            the entire clip.
+ *  Size: Size of resulting clip list; size of the buffer at ClipList
+ *        or, if ClipList is NULL, receives the required size of the buffer
+ *        in bytes
+ *
+ * RETURNS
+ *  Either DD_OK or DDERR_*
+ ************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
     LPDWORD lpdwSize)
 {
@@ -188,18 +207,21 @@
     }
 }
 
-/***********************************************************************
-*           IDirectDrawClipper::SetClipList
-*
-* Sets or deletes (if lprgn is NULL) the clip list
-*
-* PARAMS
-*  lprgn   Pointer to a LRGNDATA structure or NULL
-*  dwFlags not used, must be 0
-* RETURNS
-*  Either DD_OK or DDERR_*
-*/
-HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
+/*****************************************************************************
+ * IDirectDrawClipper::SetClipList
+ *
+ * Sets or deletes (if lprgn is NULL) the clip list
+ *
+ * This implementation is a stup and returns DD_OK always to make the app
+ * happy.
+ *
+ * PARAMS
+ *  lprgn   Pointer to a LRGNDATA structure or NULL
+ *  dwFlags not used, must be 0
+ * RETURNS
+ *  Either DD_OK or DDERR_*
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
 ) {
     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
@@ -209,35 +231,18 @@
     return DD_OK;
 }
 
-HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
-    LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
-) {
-    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
-
-    if (IsEqualGUID(&IID_IUnknown, riid)
-	|| IsEqualGUID(&IID_IDirectDrawClipper, riid))
-    {
-	*ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
-	InterlockedIncrement(&This->ref);
-	return S_OK;
-    }
-    else
-    {
-	return E_NOINTERFACE;
-    }
-}
-
-ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
-{
-    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
-
-    return ref;
-}
-
-HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
+/*****************************************************************************
+ * IDirectDrawClipper::GetHwnd
+ *
+ * Returns the hwnd assigned with SetHwnd
+ *
+ * Arguments:
+ *  hWndPtr: Address to store the HWND at
+ *
+ * Return values:
+ *  Always returns DD_OK;
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
 ) {
     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
@@ -248,7 +253,21 @@
     return DD_OK;
 }
 
-HRESULT WINAPI Main_DirectDrawClipper_Initialize(
+/*****************************************************************************
+ * IDirectDrawClipper::Initialize
+ *
+ * Initializes the interface. Well, there isn't much to do for this
+ * implementation, but it stores the DirectDraw Interface.
+ *
+ * Arguments:
+ *  DD: Pointer to a IDirectDraw interface
+ *  Flags: Unsupported by now
+ *
+ * Return values:
+ *  DD_OK on success
+ *  DDERR_ALREADYINITIALIZED if this interface isn't initialized allready
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
 ) {
     IDirectDrawImpl* pOwner;
@@ -259,12 +278,22 @@
 
     pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
     This->ddraw_owner = pOwner;
-    Main_DirectDraw_AddClipper(pOwner, This);
 
     return DD_OK;
 }
 
-HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
+/*****************************************************************************
+ * IDirectDrawClipper::IsClipListChanged
+ *
+ * This function is a stub
+ *
+ * Arguments:
+ *  Changed:
+ *
+ * Return values:
+ *  DD_OK, because it's a stub
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
 ) {
     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
@@ -276,15 +305,18 @@
     return DD_OK;
 }
 
-static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable =
+/*****************************************************************************
+ * The VTable
+ *****************************************************************************/
+const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl =
 {
-    Main_DirectDrawClipper_QueryInterface,
-    Main_DirectDrawClipper_AddRef,
-    Main_DirectDrawClipper_Release,
-    Main_DirectDrawClipper_GetClipList,
-    Main_DirectDrawClipper_GetHWnd,
-    Main_DirectDrawClipper_Initialize,
-    Main_DirectDrawClipper_IsClipListChanged,
-    Main_DirectDrawClipper_SetClipList,
-    Main_DirectDrawClipper_SetHwnd
+    IDirectDrawClipperImpl_QueryInterface,
+    IDirectDrawClipperImpl_AddRef,
+    IDirectDrawClipperImpl_Release,
+    IDirectDrawClipperImpl_GetClipList,
+    IDirectDrawClipperImpl_GetHWnd,
+    IDirectDrawClipperImpl_Initialize,
+    IDirectDrawClipperImpl_IsClipListChanged,
+    IDirectDrawClipperImpl_SetClipList,
+    IDirectDrawClipperImpl_SetHwnd
 };
diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h
deleted file mode 100644
index 727c3f5..0000000
--- a/dlls/ddraw/d3d_private.h
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * Direct3D private include file
- *
- * Copyright (c) 1998-2004 Lionel Ulmer
- * Copyright (c) 2002-2005 Christian Costa
- *
- * This file contains all the structure that are not exported
- * through d3d.h and all common macros.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __GRAPHICS_WINE_D3D_PRIVATE_H
-#define __GRAPHICS_WINE_D3D_PRIVATE_H
-
-/* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "d3d.h"
-
-#define MAX_TEXTURES 8
-#define MAX_LIGHTS  16
-
-#define HIGHEST_RENDER_STATE         152
-#define HIGHEST_TEXTURE_STAGE_STATE   24
-
-/*****************************************************************************
- * Predeclare the interface implementation structures
- */
-typedef struct IDirect3DLightImpl IDirect3DLightImpl;
-typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl;
-typedef struct IDirect3DViewportImpl IDirect3DViewportImpl;
-typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
-typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl;
-
-#include "ddraw_private.h"
-
-typedef struct STATEBLOCKFLAGS {
-   BOOL render_state[HIGHEST_RENDER_STATE];
-   BOOL texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE];
-} STATEBLOCKFLAGS;
-
-typedef struct STATEBLOCK {
-   STATEBLOCKFLAGS set_flags; 
-   DWORD render_state[HIGHEST_RENDER_STATE];
-   DWORD texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE];
-} STATEBLOCK;
-
-
-/*****************************************************************************
- * IDirect3DLight implementation structure
- */
-struct IDirect3DLightImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DLight);
-    LONG ref;
-    /* IDirect3DLight fields */
-    IDirectDrawImpl *d3d;
-    /* If this light is active for one viewport, put the viewport here */
-    IDirect3DViewportImpl *active_viewport;
-
-    D3DLIGHT2 light;
-    D3DLIGHT7 light7;
-
-    DWORD dwLightIndex;
-
-    /* Chained list used for adding / removing from viewports */
-    IDirect3DLightImpl *next;
-
-    /* Activation function */
-    void (*activate)(IDirect3DLightImpl*);
-    void (*desactivate)(IDirect3DLightImpl*);
-    void (*update)(IDirect3DLightImpl*);
-};
-
-/*****************************************************************************
- * IDirect3DMaterial implementation structure
- */
-struct IDirect3DMaterialImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DMaterial3);
-    ICOM_VFIELD_MULTI(IDirect3DMaterial2);
-    ICOM_VFIELD_MULTI(IDirect3DMaterial);
-    LONG  ref;
-    /* IDirect3DMaterial2 fields */
-    IDirectDrawImpl *d3d;
-    IDirect3DDeviceImpl *active_device;
-
-    D3DMATERIAL mat;
-
-    void (*activate)(IDirect3DMaterialImpl* this);
-};
-
-/*****************************************************************************
- * IDirect3DViewport implementation structure
- */
-struct IDirect3DViewportImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DViewport3);
-    LONG ref;
-    /* IDirect3DViewport fields */
-    IDirectDrawImpl *d3d;
-    /* If this viewport is active for one device, put the device here */
-    IDirect3DDeviceImpl *active_device;
-
-    DWORD num_lights;
-    DWORD map_lights;
-
-    int use_vp2;
-    union {
-        D3DVIEWPORT vp1;
-	D3DVIEWPORT2 vp2;
-    } viewports;
-
-    /* Activation function */
-    void (*activate)(IDirect3DViewportImpl*);
-
-    /* Field used to chain viewports together */
-    IDirect3DViewportImpl *next;
-
-    /* Lights list */
-    IDirect3DLightImpl *lights;
-
-    /* Background material */
-    IDirect3DMaterialImpl *background;
-};
-
-/*****************************************************************************
- * IDirect3DExecuteBuffer implementation structure
- */
-struct IDirect3DExecuteBufferImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DExecuteBuffer);
-    LONG ref;
-    /* IDirect3DExecuteBuffer fields */
-    IDirectDrawImpl *d3d;
-    IDirect3DDeviceImpl* d3ddev;
-
-    D3DEXECUTEBUFFERDESC desc;
-    D3DEXECUTEDATA data;
-
-    /* This buffer will store the transformed vertices */
-    void* vertex_data;
-    WORD* indices;
-    int nb_indices;
-
-    /* This flags is set to TRUE if we allocated ourselves the
-       data buffer */
-    BOOL need_free;
-
-    void (*execute)(IDirect3DExecuteBufferImpl* this,
-                    IDirect3DDeviceImpl* dev,
-                    IDirect3DViewportImpl* vp);
-};
-
-/* Internal structure to store the state of the clipping planes */
-typedef struct d3d7clippingplane 
-{
-    D3DVALUE plane[4];
-} d3d7clippingplane;
-
-/*****************************************************************************
- * IDirect3DDevice implementation structure
- */
-
-#define WORLDMAT_CHANGED (0x00000001 <<  0)
-#define VIEWMAT_CHANGED  (0x00000001 <<  1)
-#define PROJMAT_CHANGED  (0x00000001 <<  2)
-#define TEXMAT0_CHANGED  (0x00000001 <<  3)
-#define TEXMAT1_CHANGED  (0x00000001 <<  4)
-#define TEXMAT2_CHANGED  (0x00000001 <<  5)
-#define TEXMAT3_CHANGED  (0x00000001 <<  6)
-#define TEXMAT4_CHANGED  (0x00000001 <<  7)
-#define TEXMAT5_CHANGED  (0x00000001 <<  8)
-#define TEXMAT6_CHANGED  (0x00000001 <<  9)
-#define TEXMAT7_CHANGED  (0x00000001 << 10)
-
-struct IDirect3DDeviceImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DDevice7);
-    ICOM_VFIELD_MULTI(IDirect3DDevice3);
-    ICOM_VFIELD_MULTI(IDirect3DDevice2);
-    ICOM_VFIELD_MULTI(IDirect3DDevice);
-    LONG  ref;
-
-    /* Version of the Direct3D object from which the device has been created */
-    DWORD version;
-
-    /* IDirect3DDevice fields */
-    IDirectDrawImpl *d3d;
-    IDirectDrawSurfaceImpl *surface;
-
-    IDirect3DViewportImpl *viewport_list;
-    IDirect3DViewportImpl *current_viewport;
-    D3DVIEWPORT7 active_viewport;
-
-    IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES];
-    IDirectDrawSurfaceImpl *current_zbuffer;
-    
-    /* Current transformation matrices */
-    D3DMATRIX *world_mat;
-    D3DMATRIX *view_mat;
-    D3DMATRIX *proj_mat;
-    D3DMATRIX *tex_mat[MAX_TEXTURES];
-    BOOLEAN tex_mat_is_identity[MAX_TEXTURES];
-    
-    /* Current material used in D3D7 mode */
-    D3DMATERIAL7 current_material;
-
-    /* Light state */
-    DWORD material;
-
-    /* Light parameters */
-    DWORD num_set_lights;
-    DWORD max_active_lights;
-    LPD3DLIGHT7 light_parameters;
-    DWORD *active_lights;
-
-    /* Clipping planes */
-    DWORD max_clipping_planes;
-    d3d7clippingplane *clipping_planes;
-    
-    void (*set_context)(IDirect3DDeviceImpl*);
-    HRESULT (*clear)(IDirect3DDeviceImpl *This,
-		     DWORD dwCount,
-		     LPD3DRECT lpRects,
-		     DWORD dwFlags,
-		     DWORD dwColor,
-		     D3DVALUE dvZ,
-		     DWORD dwStencil);
-    void (*matrices_updated)(IDirect3DDeviceImpl *This, DWORD matrices);
-    void (*set_matrices)(IDirect3DDeviceImpl *This, DWORD matrices,
-			 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat);
-    void (*flush_to_framebuffer)(IDirect3DDeviceImpl *This, LPCRECT pRect, IDirectDrawSurfaceImpl *surf);
-
-    STATEBLOCK state_block;
-
-    /* Used to prevent locks and rendering to overlap */
-    CRITICAL_SECTION crit;
-
-    /* Rendering functions */
-    D3DPRIMITIVETYPE primitive_type;
-    DWORD vertex_type;
-    DWORD render_flags;
-    DWORD nb_vertices;
-    LPBYTE vertex_buffer;
-    DWORD vertex_size;
-    DWORD buffer_size;
-};
-
-/*****************************************************************************
- * IDirect3DVertexBuffer implementation structure
- */
-struct IDirect3DVertexBufferImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer7);
-    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer);
-    LONG ref;
-    IDirectDrawImpl *d3d;
-    D3DVERTEXBUFFERDESC desc;
-    LPVOID *vertices;
-    DWORD vertex_buffer_size;
-
-    BOOLEAN processed;
-};
-
-/* Various dump and helper functions */
-#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \
-    (((d3dvtVertexType) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
-
-#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
-    (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
-
-extern const char *_get_renderstate(D3DRENDERSTATETYPE type);
-extern void dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat);
-extern void dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol);
-extern void dump_D3DLIGHT7(LPD3DLIGHT7 lpLight);
-extern void dump_DPFLAGS(DWORD dwFlags);
-extern void dump_D3DMATRIX(D3DMATRIX *mat);
-extern void dump_D3DVECTOR(D3DVECTOR *lpVec);
-extern void dump_flexible_vertex(DWORD d3dvtVertexType);
-extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
-extern void convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided, DWORD dwStartVertex);
-extern void dump_D3DVOP(DWORD dwVertexOp);
-extern void dump_D3DPV(DWORD dwFlags);
-extern void multiply_matrix(LPD3DMATRIX,LPD3DMATRIX,LPD3DMATRIX);
-extern void InitDefaultStateBlock(STATEBLOCK* lpStateBlock, int version);
-
-extern const float id_mat[16];
-
-/*****************************************************************************
- * IDirect3D object methods
- */
-HRESULT WINAPI
-Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
-                                 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
-                                 LPVOID lpUserArg);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE7 lpDDS,
-                                  LPDIRECT3DDEVICE7* lplpD3DDevice);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
-					   LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-					   LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
-					   DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
-                                           REFCLSID riidDevice,
-                                           LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-                                           LPVOID lpContext);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface,
-                                       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-                                       LPVOID lpUserArg);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
-                                       LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                       IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
-					  LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
-					  IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
-					  LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
-					  IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
-				      LPD3DFINDDEVICESEARCH lpD3DDFS,
-				      LPD3DFINDDEVICERESULT lpD3DFDR);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE4 lpDDS,
-                                  LPDIRECT3DDEVICE3* lplpD3DDevice3,
-                                  LPUNKNOWN lpUnk);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface,
-					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-					 LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
-					 DWORD dwFlags,
-					 LPUNKNOWN lpUnk);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface,
-				     LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2,
-				     IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface,
-				     LPDIRECT3DVIEWPORT2* lplpD3DViewport2,
-				     IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE lpDDS,
-                                  LPDIRECT3DDEVICE2* lplpD3DDevice2);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface,
-                                REFIID riid);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface,
-				     LPDIRECT3DMATERIAL* lplpDirect3DMaterial,
-				     IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface,
-				     LPDIRECT3DVIEWPORT* lplpD3DViewport,
-				     IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
-                                LPD3DFINDDEVICESEARCH lpD3DDFS,
-                                LPD3DFINDDEVICERESULT lplpD3DDevice);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_7_QueryInterface(LPDIRECT3D7 iface,
-                                     REFIID riid,
-                                     LPVOID* obp);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface,
-                                     REFIID riid,
-                                     LPVOID* obp);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface,
-                                     REFIID riid,
-                                     LPVOID* obp);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface,
-                                     REFIID riid,
-                                     LPVOID* obp);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_7_AddRef(LPDIRECT3D7 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_7_Release(LPDIRECT3D7 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface,
-                                         REFCLSID riidDevice,
-                                         LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-                                         LPVOID lpContext);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
-                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-                                  LPVOID lpUserArg);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
-                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-                                  LPVOID lpUserArg);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface,
-                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                  IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface,
-                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                  IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
-				 LPD3DFINDDEVICESEARCH lpD3DDFS,
-				 LPD3DFINDDEVICERESULT lplpD3DDevice);
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface,
-				 LPD3DFINDDEVICESEARCH lpD3DDFS,
-				 LPD3DFINDDEVICERESULT lpD3DFDR);
-
-/*****************************************************************************
- * IDirect3DDevice object methods
- */
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface,
-                                                   REFIID riid,
-                                                   LPVOID* obp);
-
-ULONG WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface);
-
-ULONG WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
-                                   LPD3DDEVICEDESC7 lpD3DHELDevDesc);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
-                                                 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
-                                                 LPVOID lpArg);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface,
-						LPDIRECT3D7* lplpDirect3D3);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface,
-						 LPDIRECTDRAWSURFACE7 lpNewRenderTarget,
-						 DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface,
-						 LPDIRECTDRAWSURFACE7* lplpRenderTarget);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface,
-                                 DWORD dwCount,
-                                 LPD3DRECT lpRects,
-                                 DWORD dwFlags,
-                                 D3DCOLOR dwColor,
-                                 D3DVALUE dvZ,
-                                 DWORD dwStencil);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DVIEWPORT7 lpData);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface,
-                                                   D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                                   LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DVIEWPORT7 lpData);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DMATERIAL7 lpMat);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DMATERIAL7 lpMat);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
-                                    DWORD dwLightIndex,
-                                    LPD3DLIGHT7 lpLight);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface,
-                                    DWORD dwLightIndex,
-                                    LPD3DLIGHT7 lpLight);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
-                                                D3DRENDERSTATETYPE dwRenderStateType,
-                                                DWORD dwRenderState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
-                                                D3DRENDERSTATETYPE dwRenderStateType,
-                                                LPDWORD lpdwRenderState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface,
-                                         LPDWORD lpdwBlockHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface,
-                                   LPDIRECTDRAWSURFACE7 lpddsTexture);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
-                                            D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                            DWORD d3dvtVertexType,
-                                            LPVOID lpvVertices,
-                                            DWORD dwVertexCount,
-                                            DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
-                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                   DWORD d3dvtVertexType,
-                                                   LPVOID lpvVertices,
-                                                   DWORD dwVertexCount,
-                                                   LPWORD dwIndices,
-                                                   DWORD dwIndexCount,
-                                                   DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface,
-                                               LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface,
-                                               LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                   DWORD dwVertexType,
-                                                   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                   DWORD dwVertexCount,
-                                                   DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                          DWORD dwVertexType,
-                                                          LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                          DWORD dwVertexCount,
-                                                          LPWORD lpIndex,
-                                                          DWORD dwIndexCount,
-                                                          DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-					      D3DPRIMITIVETYPE d3dptPrimitiveType,
-					      LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-					      DWORD dwStartVertex,
-					      DWORD dwNumVertices,
-					      DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-						     D3DPRIMITIVETYPE d3dptPrimitiveType,
-						     LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-						     DWORD dwStartVertex,
-						     DWORD dwNumVertices,
-						     LPWORD lpwIndices,
-						     DWORD dwIndexCount,
-						     DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface,
-                                                      LPD3DVECTOR lpCenters,
-                                                      LPD3DVALUE lpRadii,
-                                                      DWORD dwNumSpheres,
-                                                      DWORD dwFlags,
-                                                      LPDWORD lpdwReturnValues);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_GetTexture(LPDIRECT3DDEVICE7 iface,
-					 DWORD dwStage,
-					 LPDIRECTDRAWSURFACE7* lpTexture);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
-					 DWORD dwStage,
-					 LPDIRECTDRAWSURFACE7 lpTexture);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface,
-                                                   DWORD dwStage,
-                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                   LPDWORD lpdwState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
-                                                   DWORD dwStage,
-                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                   DWORD dwState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface,
-                                             LPDWORD lpdwPasses);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface,
-                                           DWORD dwBlockHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface,
-                                             DWORD dwBlockHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface,
-                                            DWORD dwBlockHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface,
-                                            D3DSTATEBLOCKTYPE d3dsbType,
-                                            LPDWORD lpdwBlockHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface,
-                                LPDIRECTDRAWSURFACE7 lpDestTex,
-                                LPPOINT lpDestPoint,
-                                LPDIRECTDRAWSURFACE7 lpSrcTex,
-                                LPRECT lprcSrcRect,
-                                DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
-                                       DWORD dwLightIndex,
-                                       BOOL bEnable);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface,
-                                          DWORD dwLightIndex,
-                                          BOOL* pbEnable);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface,
-                                        DWORD dwIndex,
-                                        D3DVALUE* pPlaneEquation);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface,
-                                        DWORD dwIndex,
-                                        D3DVALUE* pPlaneEquation);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface,
-                                   DWORD dwDevInfoID,
-                                   LPVOID pDevInfoStruct,
-                                   DWORD dwSize);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
-                                         LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                         LPD3DDEVICEDESC lpD3DHELDevDesc);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DSTATS lpD3DStats);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface,
-					     LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface,
-						LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface,
-					      LPDIRECT3DVIEWPORT3 lpDirect3DViewport3,
-					      LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3,
-					      DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface,
-						 LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface,
-						 LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface,
-                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                 DWORD dwVertexTypeDesc,
-                                 DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface,
-                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                        DWORD d3dvtVertexType,
-                                        LPVOID lpvVertices,
-                                        DWORD dwNumVertices,
-                                        DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface,
-                                     LPVOID lpVertexType);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface,
-                                    WORD wVertexIndex);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface,
-                                  DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface,
-                                            D3DLIGHTSTATETYPE dwLightStateType,
-                                            LPDWORD lpdwLightState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
-                                            D3DLIGHTSTATETYPE dwLightStateType,
-                                            DWORD dwLightState);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
-                                                 LPDIRECT3DTEXTURE2 lpD3DTex1,
-                                                 LPDIRECT3DTEXTURE2 lpD3DTex2);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
-                                                 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
-                                                 LPVOID lpArg);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface,
-                                 D3DPRIMITIVETYPE d3dpt,
-                                 D3DVERTEXTYPE dwVertexTypeDesc,
-                                 DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface,
-                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                        D3DVERTEXTYPE d3dvtVertexType,
-                                        LPVOID lpvVertices,
-                                        DWORD dwNumVertices,
-                                        DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
-                                         D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                         D3DVERTEXTYPE d3dvtVertexType,
-                                         LPVOID lpvVertices,
-                                         DWORD dwVertexCount,
-                                         DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
-                                                D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                D3DVERTEXTYPE d3dvtVertexType,
-                                                LPVOID lpvVertices,
-                                                DWORD dwVertexCount,
-                                                LPWORD dwIndices,
-                                                DWORD dwIndexCount,
-                                                DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface,
-                                      LPDIRECT3D lpDirect3D,
-                                      LPGUID lpGUID,
-                                      LPD3DDEVICEDESC lpD3DDVDesc);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
-                                               LPD3DEXECUTEBUFFERDESC lpDesc,
-                                               LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
-                                               IUnknown* pUnkOuter);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface,
-                                   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-                                   LPDIRECT3DVIEWPORT lpDirect3DViewport,
-                                   DWORD dwFlags);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface,
-                                LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-                                LPDIRECT3DVIEWPORT lpDirect3DViewport,
-                                DWORD dwFlags,
-                                LPD3DRECT lpRect);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface,
-                                          LPDWORD lpCount,
-                                          LPD3DPICKRECORD lpD3DPickRec);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface,
-                                        LPD3DMATRIXHANDLE lpD3DMatHandle);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface,
-                                     D3DMATRIXHANDLE D3DMatHandle,
-                                     LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface,
-                                     D3DMATRIXHANDLE D3DMatHandle,
-                                     LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface,
-                                        D3DMATRIXHANDLE D3DMatHandle);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface,
-                                           REFIID riid,
-                                           LPVOID* obp);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface,
-                                           REFIID riid,
-                                           LPVOID* obp);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface,
-                                           REFIID riid,
-                                           LPVOID* obp);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface);
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface,
-					LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface,
-					LPDIRECT3DVIEWPORT lpDirect3DViewport);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface,
-					   LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface,
-					   LPDIRECT3DVIEWPORT lpDirect3DViewport);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface,
-					 LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
-					 LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
-					 DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface,
-					 LPDIRECT3DVIEWPORT lpDirect3DViewport,
-					 LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
-					 DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface,
-					LPDIRECT3D3* lplpDirect3D3);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface,
-					LPDIRECT3D2* lplpDirect3D2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface,
-					LPDIRECT3D* lplpDirect3D);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-					       LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-					       LPDIRECT3DVIEWPORT2* lpDirect3DViewport2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface,
-                                               LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
-                                               LPVOID lpArg);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           DWORD dwRenderState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           DWORD dwRenderState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           LPDWORD lpdwRenderState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           LPDWORD lpdwRenderState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface,
-                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                          DWORD d3dvtVertexType,
-                                          LPVOID lpvVertices,
-                                          DWORD dwVertexCount,
-                                          DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface,
-                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                 DWORD d3dvtVertexType,
-                                                 LPVOID lpvVertices,
-                                                 DWORD dwVertexCount,
-                                                 LPWORD dwIndices,
-                                                 DWORD dwIndexCount,
-                                                 DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
-                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                 DWORD dwVertexType,
-                                                 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                 DWORD dwVertexCount,
-                                                 DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
-                                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                        DWORD dwVertexType,
-                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                        DWORD dwVertexCount,
-                                                        LPWORD lpIndex,
-                                                        DWORD dwIndexCount,
-                                                        DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface,
-                                                    LPD3DVECTOR lpCenters,
-                                                    LPD3DVALUE lpRadii,
-                                                    DWORD dwNumSpheres,
-                                                    DWORD dwFlags,
-                                                    LPDWORD lpdwReturnValues);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface,
-                                                 DWORD dwStage,
-                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                 LPDWORD lpdwState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface,
-                                                 DWORD dwStage,
-                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                 DWORD dwState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface,
-                                           LPDWORD lpdwPasses);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface,
-                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                    LPD3DDEVICEDESC lpD3DHELDevDesc);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface,
-                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                    LPD3DDEVICEDESC lpD3DHELDevDesc);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface,
-                                               LPDIRECT3DTEXTURE lpD3Dtex1,
-                                               LPDIRECT3DTEXTURE lpD3DTex2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface,
-                                     LPD3DSTATS lpD3DStats);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface,
-                                     LPD3DSTATS lpD3DStats);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface,
-                                            LPDIRECTDRAWSURFACE4 lpNewRenderTarget,
-                                            DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface,
-                                            LPDIRECTDRAWSURFACE4* lplpRenderTarget);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
-                                            LPDIRECTDRAWSURFACE lpNewRenderTarget,
-                                            DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
-                                            LPDIRECTDRAWSURFACE* lplpRenderTarget);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface,
-                                   LPVOID lpVertexType);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface,
-                                  WORD wVertexIndex);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface,
-                                DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface,
-                                          D3DLIGHTSTATETYPE dwLightStateType,
-                                          LPDWORD lpdwLightState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface,
-                                          D3DLIGHTSTATETYPE dwLightStateType,
-                                          DWORD dwLightState);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface,
-                                               LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
-                                               LPVOID lpArg);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
-				       DWORD dwStage,
-				       LPDIRECT3DTEXTURE2 lpTexture2);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface,
-					    D3DPRIMITIVETYPE d3dptPrimitiveType,
-					    LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
-					    DWORD dwStartVertex,
-					    DWORD dwNumVertices,
-					    DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface,
-						   D3DPRIMITIVETYPE d3dptPrimitiveType,
-						   LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
-						   LPWORD lpwIndices,
-						   DWORD dwIndexCount,
-						   DWORD dwFlags);
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface,
-				       DWORD dwStage,
-				       LPDIRECT3DTEXTURE2* lplpTexture2);
-
-#endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
diff --git a/dlls/ddraw/d3d_utils.c b/dlls/ddraw/d3d_utils.c
deleted file mode 100644
index 27f2df3..0000000
--- a/dlls/ddraw/d3d_utils.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* Direct3D Common functions
- * Copyright (c) 1998 Lionel ULMER
- *
- * This file contains all common miscellaneous code that spans
- * different 'objects'
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#include "windef.h"
-#include "winbase.h"
-#include "objbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-
-#include "d3d_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-const char *_get_renderstate(D3DRENDERSTATETYPE type) {
-    static const char * const states[] = {
-        "ERR",
-	"D3DRENDERSTATE_TEXTUREHANDLE",
-	"D3DRENDERSTATE_ANTIALIAS",
-	"D3DRENDERSTATE_TEXTUREADDRESS",
-	"D3DRENDERSTATE_TEXTUREPERSPECTIVE",
-	"D3DRENDERSTATE_WRAPU",
-	"D3DRENDERSTATE_WRAPV",
-	"D3DRENDERSTATE_ZENABLE",
-	"D3DRENDERSTATE_FILLMODE",
-	"D3DRENDERSTATE_SHADEMODE",
-	"D3DRENDERSTATE_LINEPATTERN",
-	"D3DRENDERSTATE_MONOENABLE",
-	"D3DRENDERSTATE_ROP2",
-	"D3DRENDERSTATE_PLANEMASK",
-	"D3DRENDERSTATE_ZWRITEENABLE",
-	"D3DRENDERSTATE_ALPHATESTENABLE",
-	"D3DRENDERSTATE_LASTPIXEL",
-	"D3DRENDERSTATE_TEXTUREMAG",
-	"D3DRENDERSTATE_TEXTUREMIN",
-	"D3DRENDERSTATE_SRCBLEND",
-	"D3DRENDERSTATE_DESTBLEND",
-	"D3DRENDERSTATE_TEXTUREMAPBLEND",
-	"D3DRENDERSTATE_CULLMODE",
-	"D3DRENDERSTATE_ZFUNC",
-	"D3DRENDERSTATE_ALPHAREF",
-	"D3DRENDERSTATE_ALPHAFUNC",
-	"D3DRENDERSTATE_DITHERENABLE",
-	"D3DRENDERSTATE_ALPHABLENDENABLE",
-	"D3DRENDERSTATE_FOGENABLE",
-	"D3DRENDERSTATE_SPECULARENABLE",
-	"D3DRENDERSTATE_ZVISIBLE",
-	"D3DRENDERSTATE_SUBPIXEL",
-	"D3DRENDERSTATE_SUBPIXELX",
-	"D3DRENDERSTATE_STIPPLEDALPHA",
-	"D3DRENDERSTATE_FOGCOLOR",
-	"D3DRENDERSTATE_FOGTABLEMODE",
-	"D3DRENDERSTATE_FOGTABLESTART",
-	"D3DRENDERSTATE_FOGTABLEEND",
-	"D3DRENDERSTATE_FOGTABLEDENSITY",
-	"D3DRENDERSTATE_STIPPLEENABLE",
-	"D3DRENDERSTATE_EDGEANTIALIAS",
-	"D3DRENDERSTATE_COLORKEYENABLE",
-	"ERR",
-	"D3DRENDERSTATE_BORDERCOLOR",
-	"D3DRENDERSTATE_TEXTUREADDRESSU",
-	"D3DRENDERSTATE_TEXTUREADDRESSV",
-	"D3DRENDERSTATE_MIPMAPLODBIAS",
-	"D3DRENDERSTATE_ZBIAS",
-	"D3DRENDERSTATE_RANGEFOGENABLE",
-	"D3DRENDERSTATE_ANISOTROPY",
-	"D3DRENDERSTATE_FLUSHBATCH",
-	"D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT",
-	"D3DRENDERSTATE_STENCILENABLE",
-	"D3DRENDERSTATE_STENCILFAIL",
-	"D3DRENDERSTATE_STENCILZFAIL",
-	"D3DRENDERSTATE_STENCILPASS",
-	"D3DRENDERSTATE_STENCILFUNC",
-	"D3DRENDERSTATE_STENCILREF",
-	"D3DRENDERSTATE_STENCILMASK",
-	"D3DRENDERSTATE_STENCILWRITEMASK",
-	"D3DRENDERSTATE_TEXTUREFACTOR",
-	"ERR",
-	"ERR",
-	"ERR",
-	"D3DRENDERSTATE_STIPPLEPATTERN00",
-	"D3DRENDERSTATE_STIPPLEPATTERN01",
-	"D3DRENDERSTATE_STIPPLEPATTERN02",
-	"D3DRENDERSTATE_STIPPLEPATTERN03",
-	"D3DRENDERSTATE_STIPPLEPATTERN04",
-	"D3DRENDERSTATE_STIPPLEPATTERN05",
-	"D3DRENDERSTATE_STIPPLEPATTERN06",
-	"D3DRENDERSTATE_STIPPLEPATTERN07",
-	"D3DRENDERSTATE_STIPPLEPATTERN08",
-	"D3DRENDERSTATE_STIPPLEPATTERN09",
-	"D3DRENDERSTATE_STIPPLEPATTERN10",
-	"D3DRENDERSTATE_STIPPLEPATTERN11",
-	"D3DRENDERSTATE_STIPPLEPATTERN12",
-	"D3DRENDERSTATE_STIPPLEPATTERN13",
-	"D3DRENDERSTATE_STIPPLEPATTERN14",
-	"D3DRENDERSTATE_STIPPLEPATTERN15",
-	"D3DRENDERSTATE_STIPPLEPATTERN16",
-	"D3DRENDERSTATE_STIPPLEPATTERN17",
-	"D3DRENDERSTATE_STIPPLEPATTERN18",
-	"D3DRENDERSTATE_STIPPLEPATTERN19",
-	"D3DRENDERSTATE_STIPPLEPATTERN20",
-	"D3DRENDERSTATE_STIPPLEPATTERN21",
-	"D3DRENDERSTATE_STIPPLEPATTERN22",
-	"D3DRENDERSTATE_STIPPLEPATTERN23",
-	"D3DRENDERSTATE_STIPPLEPATTERN24",
-	"D3DRENDERSTATE_STIPPLEPATTERN25",
-	"D3DRENDERSTATE_STIPPLEPATTERN26",
-	"D3DRENDERSTATE_STIPPLEPATTERN27",
-	"D3DRENDERSTATE_STIPPLEPATTERN28",
-	"D3DRENDERSTATE_STIPPLEPATTERN29",
-	"D3DRENDERSTATE_STIPPLEPATTERN30",
-	"D3DRENDERSTATE_STIPPLEPATTERN31"
-    };
-    static const char * const states_2[] = {
-        "D3DRENDERSTATE_WRAP0",
-	"D3DRENDERSTATE_WRAP1",
-	"D3DRENDERSTATE_WRAP2",
-	"D3DRENDERSTATE_WRAP3",
-	"D3DRENDERSTATE_WRAP4",
-	"D3DRENDERSTATE_WRAP5",
-	"D3DRENDERSTATE_WRAP6",
-	"D3DRENDERSTATE_WRAP7",
-	"D3DRENDERSTATE_CLIPPING",
-	"D3DRENDERSTATE_LIGHTING",
-	"D3DRENDERSTATE_EXTENTS",
-	"D3DRENDERSTATE_AMBIENT",
-	"D3DRENDERSTATE_FOGVERTEXMODE",
-	"D3DRENDERSTATE_COLORVERTEX",
-	"D3DRENDERSTATE_LOCALVIEWER",
-	"D3DRENDERSTATE_NORMALIZENORMALS",
-	"D3DRENDERSTATE_COLORKEYBLENDENABLE",
-	"D3DRENDERSTATE_DIFFUSEMATERIALSOURCE",
-	"D3DRENDERSTATE_SPECULARMATERIALSOURCE",
-	"D3DRENDERSTATE_AMBIENTMATERIALSOURCE",
-	"D3DRENDERSTATE_EMISSIVEMATERIALSOURCE",
-	"ERR",
-	"ERR",
-	"D3DRENDERSTATE_VERTEXBLEND",
-	"D3DRENDERSTATE_CLIPPLANEENABLE",
-    };
-    if (type >= D3DRENDERSTATE_WRAP0) {
-        type -= D3DRENDERSTATE_WRAP0;
-	if (type >= (sizeof(states_2) / sizeof(states_2[0]))) return "ERR";
-	return states_2[type];
-    }
-    if (type >= (sizeof(states) / sizeof(states[0]))) return "ERR";
-    return states[type];
-}
-
-void
-dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol)
-{
-    DPRINTF("%f %f %f %f", lpCol->u1.r, lpCol->u2.g, lpCol->u3.b, lpCol->u4.a);
-}
-
-void
-dump_D3DVECTOR(D3DVECTOR *lpVec)
-{
-    DPRINTF("%f %f %f", lpVec->u1.x, lpVec->u2.y, lpVec->u3.z);
-}
-
-void
-dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat)
-{
-    DPRINTF(" - diffuse  : "); dump_D3DCOLORVALUE(&(lpMat->u.diffuse)); DPRINTF("\n");
-    DPRINTF(" - ambient  : "); dump_D3DCOLORVALUE(&(lpMat->u1.ambient)); DPRINTF("\n");
-    DPRINTF(" - specular : "); dump_D3DCOLORVALUE(&(lpMat->u2.specular)); DPRINTF("\n");
-    DPRINTF(" - emissive : "); dump_D3DCOLORVALUE(&(lpMat->u3.emissive)); DPRINTF("\n");
-    DPRINTF(" - power    : %f\n", lpMat->u4.power);
-}
-
-void
-dump_D3DLIGHT7(LPD3DLIGHT7 lpLight)
-{
-    DPRINTF(" - light type : %s\n", (lpLight->dltType == D3DLIGHT_POINT ? "D3DLIGHT_POINT" : 
-				     (lpLight->dltType == D3DLIGHT_SPOT ? "D3DLIGHT_SPOT" : 
-				      (lpLight->dltType == D3DLIGHT_DIRECTIONAL ? "D3DLIGHT_DIRECTIONAL" : 
-				       "UNSUPPORTED"))));
-    DPRINTF(" - diffuse       : "); dump_D3DCOLORVALUE(&(lpLight->dcvDiffuse)); DPRINTF("\n");
-    DPRINTF(" - specular      : "); dump_D3DCOLORVALUE(&(lpLight->dcvSpecular)); DPRINTF("\n");
-    DPRINTF(" - ambient       : "); dump_D3DCOLORVALUE(&(lpLight->dcvAmbient)); DPRINTF("\n");
-    DPRINTF(" - position      : "); dump_D3DVECTOR(&(lpLight->dvPosition)); DPRINTF("\n");
-    DPRINTF(" - direction     : "); dump_D3DVECTOR(&(lpLight->dvDirection)); DPRINTF("\n");
-    DPRINTF(" - dvRange       : %f\n", lpLight->dvRange);
-    DPRINTF(" - dvFalloff     : %f\n", lpLight->dvFalloff);
-    DPRINTF(" - dvAttenuation : %f %f %f\n", lpLight->dvAttenuation0, lpLight->dvAttenuation1, lpLight->dvAttenuation2);
-    DPRINTF(" - dvTheta       : %f\n", lpLight->dvTheta);
-    DPRINTF(" - dvPhi         : %f\n", lpLight->dvPhi);
-}
-
-void
-dump_DPFLAGS(DWORD dwFlags)
-{
-    static const flag_info flags[] =
-    {
-        FE(D3DDP_WAIT),
-	FE(D3DDP_OUTOFORDER),
-	FE(D3DDP_DONOTCLIP),
-	FE(D3DDP_DONOTUPDATEEXTENTS),
-	FE(D3DDP_DONOTLIGHT)
-    };
-
-    DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void
-dump_D3DMATRIX(D3DMATRIX *mat)
-{
-    DPRINTF("  %f %f %f %f\n", mat->_11, mat->_12, mat->_13, mat->_14);
-    DPRINTF("  %f %f %f %f\n", mat->_21, mat->_22, mat->_23, mat->_24);
-    DPRINTF("  %f %f %f %f\n", mat->_31, mat->_32, mat->_33, mat->_34);
-    DPRINTF("  %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44);
-}
-
-DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
-{
-    DWORD size = 0;
-    int i;
-    
-    if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
-    if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
-    if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD);
-    switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
-        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
-	default: TRACE(" matrix weighting not handled yet...\n");
-    }
-    for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) {
-	size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(D3DVALUE);
-    }
-    
-    return size;
-}
-
-void dump_flexible_vertex(DWORD d3dvtVertexType)
-{
-    static const flag_info flags[] = {
-        FE(D3DFVF_NORMAL),
-	FE(D3DFVF_RESERVED1),
-	FE(D3DFVF_DIFFUSE),
-	FE(D3DFVF_SPECULAR)
-    };
-    unsigned int i;
-    
-    if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
-    switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-#define GEN_CASE(a) case a: DPRINTF(#a " "); break
-        GEN_CASE(D3DFVF_XYZ);
-	GEN_CASE(D3DFVF_XYZRHW);
-	GEN_CASE(D3DFVF_XYZB1);
-	GEN_CASE(D3DFVF_XYZB2);
-	GEN_CASE(D3DFVF_XYZB3);
-	GEN_CASE(D3DFVF_XYZB4);
-	GEN_CASE(D3DFVF_XYZB5);
-    }
-    DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
-    switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
-        GEN_CASE(D3DFVF_TEX0);
-	GEN_CASE(D3DFVF_TEX1);
-	GEN_CASE(D3DFVF_TEX2);
-	GEN_CASE(D3DFVF_TEX3);
-	GEN_CASE(D3DFVF_TEX4);
-	GEN_CASE(D3DFVF_TEX5);
-	GEN_CASE(D3DFVF_TEX6);
-	GEN_CASE(D3DFVF_TEX7);
-	GEN_CASE(D3DFVF_TEX8);
-    }
-#undef GEN_CASE
-    for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) {
-        DPRINTF(" T%d-s%ld", i + 1, GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i));
-    }
-    DPRINTF("\n");
-}
-
-void
-convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided, DWORD dwStartVertex)
-{
-    int current_offset = 0;
-    unsigned int tex_index;
-    int size = get_flexible_vertex_size(d3dvtVertexType);
-
-    lpvVertices = ((BYTE *) lpvVertices) + (size * dwStartVertex);
-    
-    if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-        strided->position.lpvData = lpvVertices;
-        current_offset += 3 * sizeof(D3DVALUE);
-    } else {
-        strided->position.lpvData  = lpvVertices;
-        current_offset += 4 * sizeof(D3DVALUE);
-    }
-    if (d3dvtVertexType & D3DFVF_RESERVED1) {
-        current_offset += sizeof(DWORD);
-    }
-    if (d3dvtVertexType & D3DFVF_NORMAL) { 
-        strided->normal.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += 3 * sizeof(D3DVALUE);
-    }
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) { 
-        strided->diffuse.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += sizeof(DWORD);
-    }
-    if (d3dvtVertexType & D3DFVF_SPECULAR) {
-        strided->specular.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += sizeof(DWORD);
-    }
-    for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) {
-        strided->textureCoords[tex_index].lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index) * sizeof(D3DVALUE);
-    }
-    strided->position.dwStride = current_offset;
-    strided->normal.dwStride   = current_offset;
-    strided->diffuse.dwStride  = current_offset;
-    strided->specular.dwStride = current_offset;
-    for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
-        strided->textureCoords[tex_index].dwStride  = current_offset;   
-}
-
-void
-dump_D3DVOP(DWORD dwVertexOp)
-{
-    static const flag_info flags[] =
-    {
-        FE(D3DVOP_LIGHT),
-	FE(D3DVOP_CLIP),
-	FE(D3DVOP_EXTENTS),
-	FE(D3DVOP_TRANSFORM)
-    };
-    DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void
-dump_D3DPV(DWORD dwFlags)
-{
-    if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n");
-    else if (dwFlags != 0) DPRINTF("Unknown !!!\n");
-    else DPRINTF("\n");
-}
-
-void multiply_matrix(LPD3DMATRIX dest, LPD3DMATRIX src1, LPD3DMATRIX src2)
-{
-    D3DMATRIX temp;
-
-    /* Now do the multiplication 'by hand'.
-       I know that all this could be optimised, but this will be done later :-) */
-    temp._11 = (src1->_11 * src2->_11) + (src1->_21 * src2->_12) + (src1->_31 * src2->_13) + (src1->_41 * src2->_14);
-    temp._21 = (src1->_11 * src2->_21) + (src1->_21 * src2->_22) + (src1->_31 * src2->_23) + (src1->_41 * src2->_24);
-    temp._31 = (src1->_11 * src2->_31) + (src1->_21 * src2->_32) + (src1->_31 * src2->_33) + (src1->_41 * src2->_34);
-    temp._41 = (src1->_11 * src2->_41) + (src1->_21 * src2->_42) + (src1->_31 * src2->_43) + (src1->_41 * src2->_44);
-
-    temp._12 = (src1->_12 * src2->_11) + (src1->_22 * src2->_12) + (src1->_32 * src2->_13) + (src1->_42 * src2->_14);
-    temp._22 = (src1->_12 * src2->_21) + (src1->_22 * src2->_22) + (src1->_32 * src2->_23) + (src1->_42 * src2->_24);
-    temp._32 = (src1->_12 * src2->_31) + (src1->_22 * src2->_32) + (src1->_32 * src2->_33) + (src1->_42 * src2->_34);
-    temp._42 = (src1->_12 * src2->_41) + (src1->_22 * src2->_42) + (src1->_32 * src2->_43) + (src1->_42 * src2->_44);
-
-    temp._13 = (src1->_13 * src2->_11) + (src1->_23 * src2->_12) + (src1->_33 * src2->_13) + (src1->_43 * src2->_14);
-    temp._23 = (src1->_13 * src2->_21) + (src1->_23 * src2->_22) + (src1->_33 * src2->_23) + (src1->_43 * src2->_24);
-    temp._33 = (src1->_13 * src2->_31) + (src1->_23 * src2->_32) + (src1->_33 * src2->_33) + (src1->_43 * src2->_34);
-    temp._43 = (src1->_13 * src2->_41) + (src1->_23 * src2->_42) + (src1->_33 * src2->_43) + (src1->_43 * src2->_44);
-
-    temp._14 = (src1->_14 * src2->_11) + (src1->_24 * src2->_12) + (src1->_34 * src2->_13) + (src1->_44 * src2->_14);
-    temp._24 = (src1->_14 * src2->_21) + (src1->_24 * src2->_22) + (src1->_34 * src2->_23) + (src1->_44 * src2->_24);
-    temp._34 = (src1->_14 * src2->_31) + (src1->_24 * src2->_32) + (src1->_34 * src2->_33) + (src1->_44 * src2->_34);
-    temp._44 = (src1->_14 * src2->_41) + (src1->_24 * src2->_42) + (src1->_34 * src2->_43) + (src1->_44 * src2->_44);
-
-    /* And copy the new matrix in the good storage.. */
-    memcpy(dest, &temp, 16 * sizeof(D3DVALUE));    
-}
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
new file mode 100644
index 0000000..f86321e
--- /dev/null
+++ b/dlls/ddraw/ddraw.c
@@ -0,0 +1,3046 @@
+/*
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided);
+static HRESULT WINAPI IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary);
+static HRESULT WINAPI IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT level);
+
+/* Device identifier. Don't relay it to WineD3D */
+static const DDDEVICEIDENTIFIER2 deviceidentifier =
+{
+    "display",
+    "DirectDraw HAL",
+    { { 0x00010001, 0x00010001 } },
+    0, 0, 0, 0,
+    /* a8373c10-7ac4-4deb-849a-009844d08b2d */
+    {0xa8373c10,0x7ac4,0x4deb, {0x84,0x9a,0x00,0x98,0x44,0xd0,0x8b,0x2d}},
+    0
+};
+
+/* This is for cleanup if a broken app doesn't Release its objects */
+IDirectDrawImpl *ddraw_list;
+
+/*****************************************************************************
+ * IUnkown Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDraw7::QueryInterface
+ *
+ * Queries different interfaces of the DirectDraw object. It can return
+ * IDirectDraw interfaces in version 1, 2, 4 and 7, and IDirect3D interfaces
+ * in version 1, 2, 3 and 7. An IDirect3DDevice can be created with this
+ * method.
+ * The returned interface is AddRef() before it's returned
+ *
+ * Rules for QueryInterface:
+ *  http://msdn.microsoft.com/library/default.asp? \
+ *    url=/library/en-us/com/html/6db17ed8-06e4-4bae-bc26-113176cc7e0e.asp
+ *
+ * Used for version 1, 2, 4 and 7
+ *
+ * Params:
+ *  refiid: Interface ID asked for
+ *  obj: Used to return the interface pointer
+ *
+ * Returns:
+ *  S_OK if an interface was found
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
+                               REFIID refiid,
+                               void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, 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(!refiid)
+        return DDERR_INVALIDPARAMS;
+
+    /* Check DirectDraw Interfaces */
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
+         IsEqualGUID( &IID_IDirectDraw7, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirectDraw7);
+        TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirectDraw4);
+        TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirectDraw2);
+        TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirectDraw);
+        TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
+    }
+
+    /* Direct3D */
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        /* Check the surface implementation */
+        if(This->ImplType == SURFACE_UNKNOWN)
+        {
+            /* Apps may create the IDirect3D Interface before the primary surface.
+             * set the surface implementation */
+            This->ImplType = SURFACE_OPENGL;
+            TRACE("(%p) Choosing OpenGL surfaces because a Direct3D interface was requested\n", This);
+        }
+        else if(This->ImplType != SURFACE_OPENGL && DefaultSurfaceType == SURFACE_UNKNOWN)
+        {
+            ERR("(%p) The App is requesting a D3D device, but a non-OpenGL surface type was choosen. Prepare for trouble!\n", This);
+            ERR(" (%p) You may want to contact wine-devel for help\n", This);
+            /* Should I assert(0) here??? */
+        }
+        else if(This->ImplType != SURFACE_OPENGL)
+        {
+            WARN("The app requests a Direct3D interface, but non-opengl surfaces where set in winecfg\n");
+            /* Do not abort here, only reject 3D Device creation */
+        }
+
+        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 if(IsEqualGUID( &IID_IDirect3D7  , refiid ))
+        {
+            *obj = ICOM_INTERFACE(This, IDirect3D7);
+            TRACE(" returning Direct3D7 interface at %p.\n", *obj);
+        }
+    }
+
+    /* Unknown interface */
+    else
+    {
+        ERR("(%p)->(%s, %p): No interface found", This, debugstr_guid(refiid), obj);
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef( (IUnknown *) *obj );
+    return S_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::AddRef
+ *
+ * Increses the interfaces refcount. Used for version 1, 2, 4 and 7
+ *
+ * Returns: The new refcount
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) : incrementing from %lu.\n", This, ref -1);
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_Destroy
+ *
+ * Destroys a ddraw object. This is to share code between normal Release
+ * and the dll unload cleanup code
+ *
+ * Params:
+ *  This: DirectDraw object to destroy
+ *
+ *****************************************************************************/
+void
+IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
+{
+        IDirectDrawImpl *prev;
+
+        TRACE("(%p)\n", This);
+
+        /* Destroy the device window if we created one */
+        if(This->devicewindow != 0)
+        {
+            TRACE(" (%p) Destroying the device window %p\n", This, This->devicewindow);
+            DestroyWindow(This->devicewindow);
+            This->devicewindow = 0;
+        }
+
+        /* Unregister the window class */
+        UnregisterClassA(This->classname, 0);
+
+        /* Unchain it from the ddraw list */
+        if(ddraw_list == This)
+        {
+            ddraw_list = This->next;
+            /* No need to search for a predecessor here */
+        }
+        else
+        {
+            for(prev = ddraw_list; prev; prev = prev->next)
+                if(prev->next == This) break;
+
+            if(prev)
+                prev->next = This->next;
+            else
+                ERR("Didn't find the previous ddraw element in the list\n");
+        }
+
+        /* Release the attached WineD3D stuff */
+        IWineD3DDevice_Release(This->wineD3DDevice);
+        IWineD3D_Release(This->wineD3D);
+
+        /* Now free the object */
+        HeapFree(GetProcessHeap(), 0, This);
+}
+/*****************************************************************************
+ * IDirectDraw7::Release
+ *
+ * Decreses the refcount. If the refcount falls to 0, the object is destroyed
+ *
+ * Returns: The new refcount
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawImpl_Release(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref +1);
+
+    if (ref == 0)
+    {
+        /* No need to restore the display mode - it's done by SetCooperativeLevel */
+
+        IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(This, IDirectDraw7),
+                                         NULL,
+                                         DDSCL_NORMAL);
+
+        /* This is for the dll cleanup code in DllMain() */
+        if(!This->DoNotDestroy)
+            IDirectDrawImpl_Destroy(This);
+    }
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDraw methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDrawImpl_SetupExclusiveWindow
+ *
+ * Helper function that modifies a HWND's Style and ExStyle for proper
+ * fullscreen use.
+ *
+ * Params:
+ *  This: Pointer to the DirectDraw implementation
+ *  HWND: Window to setup
+ *
+ *****************************************************************************/
+static void
+IDirectDrawImpl_SetupFullscreenWindow(IDirectDrawImpl *This,
+                                      HWND window)
+{
+    LONG style, exStyle;
+    /* Don't do anything if an original style is stored.
+     * That shouldn't happen
+     */
+    TRACE("(%p): Setting up window %p for exclusive mode\n", This, window);
+    if( (This->style != 0) && (This->exStyle != 0) )
+    {
+        ERR("(%p) Want to change the window parameters of HWND %p, but \
+             another style is stored for restauration afterwards\n", This, window);
+    }
+
+    /* Get the parameters and save them */
+    style = GetWindowLongW(window, GWL_STYLE);
+    exStyle = GetWindowLongW(window, GWL_EXSTYLE);
+    This->style = style;
+    This->exStyle = exStyle;
+
+    /* Filter out window decorations */
+    style &= ~WS_CAPTION;
+    style &= ~WS_THICKFRAME;
+    exStyle &= ~WS_EX_WINDOWEDGE;
+    exStyle &= ~WS_EX_CLIENTEDGE;
+
+    /* Make sure the window is managed, otherwise we won't get keyboard input */
+    style |= WS_POPUP | WS_SYSMENU;
+
+    TRACE("Old style was %08lx,%08lx, setting to %08lx,%08lx\n",
+          This->style, This->exStyle, style, exStyle);
+
+    SetWindowLongW(window, GWL_STYLE, style);
+    SetWindowLongW(window, GWL_EXSTYLE, exStyle);
+
+    /* Inform the window about the update.
+     * TODO: Should I move it to 0/0 too?
+     */
+    SetWindowPos(window, 0 /* InsertAfter, ignored */,
+                 0, 0, 0, 0, /* Pos, Size, igored */
+                 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_RestoreWindow
+ *
+ * Helper function that restores a windows' properties when taking it out
+ * of fullscreen mode
+ *
+ * Params:
+ *  This: Pointer to the DirectDraw implementation
+ *  HWND: Window to setup
+ *
+ *****************************************************************************/
+static void
+IDirectDrawImpl_RestoreWindow(IDirectDrawImpl *This,
+                              HWND window)
+{
+    if( (This->style == 0) && (This->exStyle == 0) )
+    {
+        /* This could be a DDSCL_NORMAL -> DDSCL_NORMAL
+         * switch, do nothing
+         */
+        return;
+    }
+    TRACE("(%p): Restoring window settings of window %p to %08lx, %08lx\n",
+          This, window, This->style, This->exStyle);
+
+    SetWindowLongW(window, GWL_STYLE, This->style);
+    SetWindowLongW(window, GWL_EXSTYLE, This->exStyle);
+
+    /* Delete the old values */
+    This->style = 0;
+    This->exStyle = 0;
+
+    /* Inform the window about the update */
+    SetWindowPos(window, 0 /* InsertAfter, ignored */,
+                 0, 0, 0, 0, /* Pos, Size, igored */
+                 SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::SetCooperativeLevel
+ *
+ * Sets the cooerative level for the DirectDraw object, and the window
+ * assigned to it. The cooperative level determines the general behavior
+ * of the DirectDraw application
+ *
+ * Warning: This is quite tricky, as it's not really documented which
+ * cooperative levels can be combined with each other. If a game fails
+ * after this function, try to check the cooperative levels passed on
+ * Windows, and if it returns something different.
+ *
+ * If you think that this function caused the failure because it writes a
+ * fixme, be sure to run again with a +ddraw trace.
+ *
+ * What is known about cooperative levels(See the ddraw modes test):
+ * DDSCL_EXCLUSIVE and DDSCL_FULLSCREEN must be used with each other
+ * DDSCL_NORMAL is not compatible with DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN
+ * DDSCL_SETFOCUSWINDOW can be passed only in DDSCL_NORMAL mode, but after that
+ * DDSCL_FULLSCREEN can be activated
+ * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES
+ *
+ * Handled flags: DDSCL_NORMAL, DDSCL_FULLSCREEN, DDSCL_EXCLUSIVE,
+ *                DDSCL_SETFOCUSWINDOW(partially)
+ *
+ * Unhandled flags, which should be implemented
+ *  DDSCL_SETDEVICEWINDOW: Sets a window specially used for rendering(I don't
+ *  expect any difference to a normal window for wine)
+ *  DDSCL_CREATEDEVICEWINDOW: Tells ddraw to create it's own window for
+ *  rendering(Possible test case: Half-life)
+ *
+ * Unsure about these: DDSCL_FPUSETUP DDSCL_FPURESERVE
+ *
+ * These seem not really imporant for wine
+ *  DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX,
+ *  DDSCL_MULTITHREDED
+ *
+ * Returns:
+ *  DD_OK if the cooperative level was set successfully
+ *  DDERR_INVALIDPARAMS if the passed cooperative level combination is invalid
+ *  DDERR_HWNDALLREADYSET if DDSCL_SETFOCUSWINDOW is passed in exclusive mode
+ *   (Propably others too, have to investigate)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
+                                    HWND hwnd,
+                                    DWORD cooplevel)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    HWND window;
+    HRESULT hr;
+
+    FIXME("(%p)->(%p,%08lx)\n",This,hwnd,cooplevel);
+    DDRAW_dump_cooperativelevel(cooplevel);
+
+    /* Get the old window */
+    hr = IWineD3DDevice_GetHWND(This->wineD3DDevice, &window);
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DDevice::GetHWND failed, hr = %08lx\n", hr);
+        return hr;
+    }
+
+    /* Tests suggest that we need one of them: */
+    if(!(cooplevel & (DDSCL_SETFOCUSWINDOW |
+                      DDSCL_NORMAL         |
+                      DDSCL_EXCLUSIVE      )))
+    {
+        TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n");
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* Handle those levels first which set varios hwnds */
+    if(cooplevel & DDSCL_SETFOCUSWINDOW)
+    {
+        /* This isn't compatible with a lot of flags */
+        if(cooplevel & ( DDSCL_MULTITHREADED   |
+                         DDSCL_FPUSETUP        |
+                         DDSCL_FPUPRESERVE     |
+                         DDSCL_ALLOWREBOOT     |
+                         DDSCL_ALLOWMODEX      |
+                         DDSCL_SETDEVICEWINDOW |
+                         DDSCL_NORMAL          |
+                         DDSCL_EXCLUSIVE       |
+                         DDSCL_FULLSCREEN      ) )
+        {
+            TRACE("Called with incompatible flags, returning DDERR_INVALIDPARAMS\n");
+            return DDERR_INVALIDPARAMS;
+        }
+        else if( (This->cooperative_level & DDSCL_FULLSCREEN) && window)
+        {
+            TRACE("Setting DDSCL_SETFOCUSWINDOW with an already set window, returning DDERR_HWNDALREADYSET\n");
+            return DDERR_HWNDALREADYSET;
+        }
+
+        This->focuswindow = hwnd;
+        /* Won't use the hwnd param for anything else */
+        hwnd = NULL;
+
+        /* Use the focus window for drawing too */
+        IWineD3DDevice_SetHWND(This->wineD3DDevice, This->focuswindow);
+
+        /* Destroy the device window, if we have one */
+        if(This->devicewindow)
+        {
+            DestroyWindow(This->devicewindow);
+            This->devicewindow = NULL;
+        }
+    }
+    /* DDSCL_NORMAL or DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE */
+    if(cooplevel & DDSCL_NORMAL)
+    {
+        /* Can't coexist with fullscreen or exclusive */
+        if(cooplevel & (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) )
+        {
+            TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE\n", This);
+            return DDERR_INVALIDPARAMS;
+        }
+
+        /* Switching from fullscreen? */
+        if(This->cooperative_level & DDSCL_FULLSCREEN)
+        {
+            /* Restore the display mode */
+            IDirectDraw7_RestoreDisplayMode(iface);
+
+            if(window)
+                IDirectDrawImpl_RestoreWindow(This, window);
+
+            This->cooperative_level &= ~DDSCL_FULLSCREEN;
+            This->cooperative_level &= ~DDSCL_EXCLUSIVE;
+            This->cooperative_level &= ~DDSCL_ALLOWMODEX;
+        }
+
+        /* Don't override focus windows or private device windows */
+        if( hwnd &&
+            !(This->focuswindow) &&
+            !(This->devicewindow) &&
+            (hwnd != window) )
+        {
+            IWineD3DDevice_SetHWND(This->wineD3DDevice, hwnd);
+        }
+    }
+    else if(cooplevel & DDSCL_FULLSCREEN)
+    {
+        /* Needs DDSCL_EXCLUSIVE */
+        if(!(cooplevel & DDSCL_EXCLUSIVE) )
+        {
+            TRACE("(%p) DDSCL_FULLSCREEN needs DDSCL_EXCLUSIVE\n", This);
+            return DDERR_INVALIDPARAMS;
+        }
+        /* Need a HWND
+        if(hwnd == 0)
+        {
+            TRACE("(%p) DDSCL_FULLSCREEN needs a HWND\n", This);
+            return DDERR_INVALIDPARAMS;
+        }
+        */
+
+        /* Switch from normal to full screen mode? */
+        if(This->cooperative_level & DDSCL_NORMAL)
+        {
+            This->cooperative_level &= ~DDSCL_NORMAL;
+        }
+
+        /* Don't override focus windows or private device windows */
+        if( hwnd &&
+            !(This->focuswindow) &&
+            !(This->devicewindow) &&
+            (hwnd != window) )
+        {
+            /* On a window change, restore the old window and set the new one */
+            if(window != hwnd)
+            {
+                if(window)
+                    IDirectDrawImpl_RestoreWindow(This, window);
+                IDirectDrawImpl_SetupFullscreenWindow(This, hwnd);
+            }
+            IWineD3DDevice_SetHWND(This->wineD3DDevice, hwnd);
+        }
+    }
+    else if(cooplevel & DDSCL_EXCLUSIVE)
+    {
+        TRACE("(%p) DDSCL_EXCLUSIVE needs DDSCL_FULLSCREEN\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(cooplevel & DDSCL_CREATEDEVICEWINDOW)
+    {
+        /* Don't create a device window if a focus window is set */
+        if( !(This->focuswindow) )
+        {
+            HWND devicewindow = CreateWindowExA(0, This->classname, "DDraw device window",
+                                                WS_POPUP, 0, 0,
+                                                GetSystemMetrics(SM_CXSCREEN),
+                                                GetSystemMetrics(SM_CYSCREEN),
+                                                NULL, NULL, GetModuleHandleA(0), NULL);
+
+            ShowWindow(devicewindow, SW_SHOW);   /* Just to be sure */
+            TRACE("(%p) Created a DDraw device window. HWND=%p\n", This, devicewindow);
+
+            IWineD3DDevice_SetHWND(This->wineD3DDevice, devicewindow);
+            This->devicewindow = devicewindow;
+        }
+    }
+
+    /* Unhandled flags */
+    if(cooplevel & DDSCL_ALLOWREBOOT)
+        WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This);
+    if(cooplevel & DDSCL_ALLOWMODEX)
+        WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This);
+    if(cooplevel & DDSCL_MULTITHREADED)
+        FIXME("(%p) Unhandled flag DDSCL_MULTITHREADED, Uh Oh...\n", This);
+    if(cooplevel & DDSCL_FPUSETUP)
+        WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This);
+    if(cooplevel & DDSCL_FPUPRESERVE)
+        WARN("(%p) Unhandled flag DDSCL_FPUPRESERVE, harmless\n", This);
+
+    /* Store the cooperative_level */
+    This->cooperative_level |= cooplevel;
+    TRACE("SetCooperativeLevel retuning DD_OK\n");
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::SetDisplayMode
+ *
+ * Sets the display screen resolution, color depth and refresh frequency
+ * when in fullscreen mode(in theory).
+ * Possible return values listed in the SDK suggest that this method fails
+ * when not in fullscreen mode, but this is wrong. Windows 2000 happily sets
+ * the display mode in DDSCL_NORMAL mode without an hwnd specified.
+ * It seems to be valid to pass 0 for With and Height, this has to be tested
+ * It could mean that the current video mode should be left as-is. (But why
+ * call it then?)
+ *
+ * Params:
+ *  Height, Width: Screen dimension
+ *  BPP: Color depth in Bits per pixel
+ *  Refreshrate: Screen refresh rate
+ *  Flags: Other stuff
+ *
+ * Returns
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface,
+                               DWORD Width,
+                               DWORD Height,
+                               DWORD BPP,
+                               DWORD RefreshRate,
+                               DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    WINED3DDISPLAYMODE Mode;
+    TRACE("(%p)->(%ld,%ld,%ld,%ld,%lx: Relay!\n", This, Width, Height, BPP, RefreshRate, Flags);
+
+    if( !Width || !Height )
+    {
+        ERR("Width=%ld, Height=%ld, what to do?\n", Width, Height);
+        /* It looks like Need for speed Posche Unleashed expects DD_OK here */
+        return DD_OK;
+    }
+
+    /* Check the exclusive mode
+    if(!(This->cooperative_level & DDSCL_EXCLUSIVE))
+        return DDERR_NOEXCLUSIVEMODE;
+     * This is WRONG. Don't know if the SDK is completely
+     * wrong and if there are any coditions when DDERR_NOEXCLUSIVE
+     * is returned, but Half-Life 1.1.1.1(Steam version)
+     * depends on this
+     */
+
+    Mode.Width = Width;
+    Mode.Height = Height;
+    Mode.RefreshRate = RefreshRate;
+    switch(BPP)
+    {
+        case 8:  Mode.Format = WINED3DFMT_P8;       break;
+        case 15: Mode.Format = WINED3DFMT_X1R5G5B5; break;
+        case 16: Mode.Format = WINED3DFMT_R5G6B5;   break;
+        case 24: Mode.Format = WINED3DFMT_R8G8B8;   break;
+        case 32: Mode.Format = WINED3DFMT_A8R8G8B8; break;
+    }
+
+    /* TODO: The possible return values from msdn suggest that
+     * the screen mode can't be changed if a surface is locked
+     * or some drawing is in progress
+     */
+
+    /* TODO: Lose the primary surface */
+    return IWineD3DDevice_SetDisplayMode(This->wineD3DDevice,
+                                         0, /* First swapchain */
+                                         &Mode);
+
+}
+
+/*****************************************************************************
+ * IDirectDraw7::RestoreDisplayMode
+ *
+ * Restores the display mode to what it was at creation time. Basically.
+ *
+ * A problem arises when there are 2 DirectDraw objects using the same hwnd:
+ *  -> DD_1 finds the screen at 1400x1050x32 when created, sets it to 640x480x16
+ *  -> DD_2 is created, finds the screen at 640x480x16, sets it to 1024x768x32
+ *  -> DD_1 is released. The screen should be left at 1024x768x32.
+ *  -> DD_2 is released. The screen should be set to 1400x1050x32
+ * This case is unhandled right now, but Empire Earth does it this way.
+ * (But perhaps there is something in SetCooperativeLevel to prevent this)
+ *
+ * The msdn says that this method resets the display mode to what it was before
+ * SetDisplayMode was called. What if SetDisplayModes is called 2 times??
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_RestoreDisplayMode(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)\n", This);
+
+    return IDirectDraw7_SetDisplayMode(ICOM_INTERFACE(This, IDirectDraw7),
+                                       This->orig_width,
+                                       This->orig_height,
+                                       This->orig_bpp,
+                                       0,
+                                       0);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetCaps
+ *
+ * Returns the drives capatiblities
+ *
+ * Used for version 1, 2, 4 and 7
+ *
+ * Params:
+ *  DriverCaps: Structure to write the Hardware accellerated caps to
+ *  HelCaps: Structure to write the emulation caps to
+ *
+ * Returns
+ *  This implementation returnd DD_OK only
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
+                        DDCAPS *DriverCaps,
+                        DDCAPS *HELCaps)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
+
+    /* One structure must be != NULL */
+    if( (!DriverCaps) && (!HELCaps) )
+    {
+        ERR("(%p) Invalid params to IDirectDrawImpl_GetCaps\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(DriverCaps)
+    {
+        DD_STRUCT_COPY_BYSIZE(DriverCaps, &This->caps);
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("Driver Caps :\n");
+            DDRAW_dump_DDCAPS(DriverCaps);
+        }
+
+    }
+    if(HELCaps)
+    {
+        DD_STRUCT_COPY_BYSIZE(HELCaps, &This->caps);
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("HEL Caps :\n");
+            DDRAW_dump_DDCAPS(HELCaps);
+        }
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::Compact
+ *
+ * No idea what it does, MSDN says it's not implemented.
+ *
+ * Returns
+ *  DD_OK, but this is unchecked
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_Compact(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)\n", This);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetDisplayMode
+ *
+ * Returns information about the current display mode
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  DDSD: Address of a surface description structure to write the info to
+ *
+ * Returns
+ *  DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
+                               DDSURFACEDESC2 *DDSD)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    HRESULT hr;
+    WINED3DDISPLAYMODE Mode;
+    DWORD Size;
+    TRACE("(%p)->(%p): Relay\n", This, DDSD);
+
+    /* This seems sane */
+    if(!DDSD) 
+    {
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* The necessary members of LPDDSURFACEDESC and LPDDSURFACEDESC2 are equal,
+     * so one method can be used for all versions (Hopefully)
+     */
+    hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                      0 /* swapchain 0 */,
+                                      &Mode);
+    if( hr != D3D_OK )
+    {
+        ERR(" (%p) IWineD3DDevice::GetDisplayMode returned %08lx\n", This, hr);
+        return hr;
+    }
+
+    Size = DDSD->dwSize;
+    memset(DDSD, 0, Size);
+
+    DDSD->dwSize = Size;
+    DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE;
+    DDSD->dwWidth = Mode.Width;
+    DDSD->dwHeight = Mode.Height; 
+    DDSD->u2.dwRefreshRate = 60;
+    DDSD->ddsCaps.dwCaps = 0;
+    DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat);
+    PixelFormat_WineD3DtoDD(&DDSD->u4.ddpfPixelFormat, Mode.Format);
+    DDSD->u1.lPitch = Mode.Width * DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount / 8;
+
+    if(TRACE_ON(ddraw))
+    {
+        TRACE("Returning surface desc :\n");
+        DDRAW_dump_surface_desc(DDSD);
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetFourCCCodes
+ *
+ * Returns an array of supported FourCC codes.
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  NumCodes: Contains the number of Codes that Codes can carry. Returns the number
+ *            of enumerated codes
+ *  Codes: Pointer to an array of DWORDs where the supported codes are wriiten
+ *         to
+ *
+ * Returns
+ *  Always returns DD_OK, as it's a stub for now
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface,
+                               DWORD *NumCodes, DWORD *Codes)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    FIXME("(%p)->(%p, %p): Stub!\n", This, NumCodes, Codes);
+
+    if(NumCodes) *NumCodes = 0;
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetMonitorFrequency
+ *
+ * Returns the monitor's frequency
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  Freq: Pointer to a DWORD to write the frequency to
+ *
+ * Returns
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface,
+                                    DWORD *Freq)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%p)\n", This, Freq);
+
+    /* Ideally this should be in WineD3D, as it concernes the screen setup,
+     * but for now this should make the games happy
+     */
+    *Freq = 60;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetVerticalBlankStatus
+ *
+ * Returns the Vertical blank status of the monitor. This should be in WineD3D
+ * too basically, but as it's a semi stub, I didn't create a function there
+ *
+ * Params:
+ *  status: Pointer to a BOOL to be filled with the vertical blank status
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if status is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface,
+                                       BOOL *status)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%p)\n", This, status);
+
+    /* This looks sane, the MSDN suggests it too */
+    if(!status) return DDERR_INVALIDPARAMS;
+
+    *status = This->fake_vblank;
+    This->fake_vblank = !This->fake_vblank;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetAvailableVidMem
+ *
+ * Returns the total and free video memory
+ *
+ * Params:
+ *  Caps: Specifies the memory type asked for
+ *  total: Pointer to a DWORD to be filled with the total memory
+ *  free: Pointer to a DWORD to be filled with the free memory
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS of free and total are NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, DWORD *free)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
+
+    if(TRACE_ON(ddraw))
+    {
+        TRACE("(%p) Asked for memory with description: ", This);
+        DDRAW_dump_DDSCAPS2(Caps);
+        TRACE("\n");
+    }
+
+    /* Todo: System memory vs local video memory vs non-local video memory
+     * The MSDN also mentiones differences between texture memory and other
+     * resources, but that's not important
+     */
+
+    if( (!total) && (!free) ) return DDERR_INVALIDPARAMS;
+
+    if(total) *total = This->total_vidmem;
+    if(free) *free = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::Initialize
+ *
+ * Initializes a DirectDraw interface.
+ *
+ * Params:
+ *  GUID: Interface identifier. Well, don't know what this is really good
+ *   for
+ *
+ * Returns
+ *  Returns DD_OK on the first call,
+ *  DDERR_ALREADYINITIALIZED on repeated calls
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_Initialize(IDirectDraw7 *iface,
+                           GUID *Guid)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%s): No-op\n", This, debugstr_guid(Guid));
+
+    if(This->initialized)
+    {
+        return DDERR_ALREADYINITIALIZED;
+    }
+    else
+    {
+        return DD_OK;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDraw7::FlipToGDISurface
+ *
+ * "Makes the surface that the GDI writes to the primary surface"
+ * Looks like some windows specific thing we don't have to care about.
+ * According to MSDN it permits GDI dialog boxes in FULLSCREEN mode. Good to
+ * show error boxes ;)
+ * Well, just return DD_OK.
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)\n", This);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::WaitForVerticalBlank
+ *
+ * This method allows applications to get in sync with the vertical blank
+ * interval.
+ * The wormhole demo in the DirectX 7 sdk uses this call, and it doesn't
+ * redraw the screen, most likely because of this stub
+ *
+ * Parameters:
+ *  Flags: one of DDWAITVB_BLOCKBEGIN, DDWAITVB_BLOCKBEGINEVENT
+ *         or DDWAITVB_BLOCKEND
+ *  h: Not used, according to MSDN
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
+                                     DWORD Flags,
+                                     HANDLE h)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    FIXME("(%p)->(%lx,%p): Stub\n", This, Flags, h);
+
+    /* MSDN says DDWAITVB_BLOCKBEGINEVENT is not supported */
+    if(Flags & DDWAITVB_BLOCKBEGINEVENT)
+        return DDERR_UNSUPPORTED; /* unchecked */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetScanLine
+ *
+ * Returns the scan line that is beeing drawn on the monitor
+ *
+ * Parameters:
+ *  Scanline: Address to write the scan line value to
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    static BOOL hide = FALSE;
+    WINED3DDISPLAYMODE Mode;
+
+    /* This function is called often, so print the fixme only once */
+    if(!hide)
+    {
+        FIXME("(%p)->(%p): Semi-Stub\n", This, Scanline);
+        hide = TRUE;
+    }
+
+    IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                  0,
+                                  &Mode);
+
+    /* Fake the line sweeping of the monitor */
+    /* FIXME: We should synchronize with a source to keep the refresh rate */ 
+    *Scanline = This->cur_scanline++;
+    /* Assume 20 scan lines in the vertical blank */
+    if (This->cur_scanline >= Mode.Height + 20)
+        This->cur_scanline = 0;
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::TestCooperativeLevel
+ *
+ * Informs the application about the state of the video adapter, depending
+ * on the cooperative level
+ *
+ * Returns:
+ *  DD_OK if the device is in a sane state
+ *  DDERR_NOEXCLUSIVEMODE or DDERR_EXCLUSIVEMODEALREADYSET
+ *  if the state is not correct(See below)
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    HRESULT hr;
+    TRACE("(%p)\n", This);
+
+    /* Description from MSDN:
+     * For fullscreen apps return DDERR_NOEXCLUSIVEMODE if the user switched
+     * away from the app with e.g. alt-tab. Windowed apps receive 
+     * DDERR_EXCLUSIVEMODEALREADYSET if another application created an 
+     * DirectDraw object in exclusive mode. DDERR_WRONGMODE is returned,
+     * when the video mode has changed
+     */
+
+    hr =  IWineD3DDevice_TestCooperativeLevel(This->wineD3DDevice);
+
+    /* Fix the result value. These values are mapped from their
+     * d3d9 counterpart.
+     */
+    switch(hr)
+    {
+        case WINED3DERR_DEVICELOST:
+            if(This->cooperative_level & DDSCL_EXCLUSIVE)
+            {
+                return DDERR_NOEXCLUSIVEMODE;
+            }
+            else
+            {
+                return DDERR_EXCLUSIVEMODEALREADYSET;
+            }
+
+        case WINED3DERR_DEVICENOTRESET:
+            return DD_OK;
+
+        case WINED3D_OK:
+            return DD_OK;
+
+        case WINED3DERR_DRIVERINTERNALERROR:
+        default:
+            ERR("(%p) Unexpected return value %08lx from wineD3D, " \
+                " returning DD_OK\n", This, hr);
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetGDISurface
+ *
+ * Returns the surface that GDI is treating as the primary surface.
+ * For Wine this is the front buffer
+ *
+ * Params:
+ *  GDISurface: Address to write the surface pointer to
+ *
+ * Returns:
+ *  DD_OK if the surface was found
+ *  DDERR_NOTFOUND if the GDI surface wasn't found
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
+                              IDirectDrawSurface7 **GDISurface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    IWineD3DSurface *Surf;
+    IDirectDrawSurface7 *ddsurf;
+    HRESULT hr;
+    DDSCAPS2 ddsCaps;
+    TRACE("(%p)->(%p)\n", This, GDISurface);
+
+    /* Get the back buffer from the wineD3DDevice and search it's
+     * attached surfaces for the front buffer
+     */
+    hr = IWineD3DDevice_GetBackBuffer(This->wineD3DDevice,
+                                      0, /* SwapChain */
+                                      0, /* first back buffer*/
+                                      WINED3DBACKBUFFER_TYPE_MONO,
+                                      &Surf);
+
+    if( (hr != D3D_OK) ||
+        (!Surf) )
+    {
+        ERR("IWineD3DDevice::GetBackBuffer failed\n");
+        return DDERR_NOTFOUND;
+    }
+
+    /* GetBackBuffer AddRef()ed the surface, release it */
+    IWineD3DSurface_Release(Surf);
+
+    IWineD3DSurface_GetParent(Surf,
+                              (IUnknown **) &ddsurf);
+    IDirectDrawSurface7_Release(ddsurf);  /* For the GetParent */
+
+    /* Find the front buffer */
+    ddsCaps.dwCaps = DDSCAPS_FRONTBUFFER;
+    hr = IDirectDrawSurface7_GetAttachedSurface(ddsurf,
+                                                &ddsCaps,
+                                                GDISurface);
+    if(hr != DD_OK)
+    {
+        ERR("IDirectDrawSurface7::GetAttachedSurface failed, hr = %lx\n", hr);
+    }
+
+    /* The AddRef is OK this time */
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_EnumDisplayModesCB
+ *
+ * Callback function for IDirectDraw7::EnumDisplayModes. Translates
+ * the wineD3D values to ddraw values and calls the application callback
+ *
+ * Params:
+ *  device: The IDirectDraw7 interface to the current device
+ *  With, Height, Pixelformat, Refresh: Enumerated display mode
+ *  context: the context pointer passed to IWineD3DDevice::EnumDisplayModes
+ *
+ * Returns:
+ *  The return value from the application callback
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_EnumDisplayModesCB(IUnknown *pDevice,
+                                   UINT Width,
+                                   UINT Height,
+                                   WINED3DFORMAT Pixelformat,
+                                   FLOAT Refresh,
+                                   void *context)
+{
+    DDSURFACEDESC2 callback_sd;
+    EnumDisplayModesCBS *cbs = (EnumDisplayModesCBS *) context;
+
+    memset(&callback_sd, 0, sizeof(callback_sd));
+    callback_sd.dwSize = sizeof(callback_sd);
+    callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+
+    callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
+    if(Refresh > 0.0)
+    {
+        callback_sd.dwFlags |= DDSD_REFRESHRATE;
+        callback_sd.u2.dwRefreshRate = 60.0;
+    }
+
+    callback_sd.dwHeight = Height;
+    callback_sd.dwWidth = Width;
+
+    PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, Pixelformat);
+    return cbs->callback(&callback_sd, cbs->context);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::EnumDisplayModes
+ *
+ * Enumerates the supported Display modes. The modes can be filtered with
+ * the DDSD paramter.
+ *
+ * Params:
+ *  Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES
+ *  DDSD: Surface description to filter the modes
+ *  Context: Pointer passed back to the callback function
+ *  cb: Application-provided callback function
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if the callback wasn't set
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
+                                 DWORD Flags,
+                                 DDSURFACEDESC2 *DDSD,
+                                 void *Context,
+                                 LPDDENUMMODESCALLBACK2 cb)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    UINT Width = 0, Height = 0;
+    WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN;
+    EnumDisplayModesCBS cbs;
+
+    TRACE("(%p)->(%p,%p,%p): Relay\n", This, DDSD, Context, cb);
+
+    /* This looks sane */
+    if(!cb) return DDERR_INVALIDPARAMS;
+
+    /* The private callback structure */
+    cbs.callback = cb;
+    cbs.context = Context;
+
+    if(DDSD)
+    {
+        if (DDSD->dwFlags & DDSD_WIDTH)
+            Width = DDSD->dwWidth;
+        if (DDSD->dwFlags & DDSD_HEIGHT)
+            Width = DDSD->dwHeight;
+        if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) )
+            pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
+    }
+
+    return IWineD3DDevice_EnumDisplayModes(This->wineD3DDevice,
+                                           Flags,
+                                           Width, Height, pixelformat,
+                                           &cbs,
+                                           IDirectDrawImpl_EnumDisplayModesCB);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::EvaluateMode
+ *
+ * Used with IDirectDraw7::StartModeTest to test video modes.
+ * EvaluateMode is used to pass or fail a mode, and continue with the next
+ * mode
+ *
+ * Params:
+ *  Flags: DDEM_MODEPASSED or DDEM_MODEFAILED
+ *  Timeout: Returns the amount of secounds left before the mode would have
+ *           been failed automatically
+ *
+ * Returns:
+ *  This implementation always DD_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_EvaluateMode(IDirectDraw7 *iface,
+                             DWORD Flags,
+                             DWORD *Timeout)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    FIXME("(%p)->(%ld,%p): Stub!\n", This, Flags, Timeout);
+
+    /* When implementing this, implement it in WineD3D */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetDeviceIdentifier
+ *
+ * Returns the device identifier, which gives information about the driver
+ * Our device identifier is defined at the beginning of this file.
+ *
+ * Params:
+ *  DDDI: Address for the returned structure
+ *  Flags: Can be DDGDI_GETHOSTIDENTIFIER
+ *
+ * Returns:
+ *  On success it returns DD_OK
+ *  DDERR_INVALIDPARAMS if DDDI is NULL;
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
+                                    DDDEVICEIDENTIFIER2 *DDDI,
+                                    DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%p,%08lx) \n", This, DDDI, Flags);
+
+    if(!DDDI)
+        return DDERR_INVALIDPARAMS;
+
+    /* The DDGDI_GETHOSTIDENTIFIER returns the information about the 2D
+     * host adapter, if there's a secondary 3D adapter. This doesn't apply
+     * to any modern hardware, nor is it interesting for Wine, so ignore it
+     */
+
+    *DDDI = deviceidentifier;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetSurfaceFromDC
+ *
+ * Returns the Surface for a GDI device context handle.
+ * Is this related to IDirectDrawSurface::GetDC ???
+ *
+ * Params:
+ *  hdc: hdc to return the surface for
+ *  Surface: Address to write the surface pointer to
+ *
+ * Returns:
+ *  Always returns DD_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
+                                 HDC hdc,
+                                 IDirectDrawSurface7 **Surface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface);
+
+    /* Implementation idea if needed: Loop through all surfaces and compare
+     * their hdc with hdc. Implement it in WineD3D! */
+    return DDERR_NOTFOUND;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::RestoreAllSurfaces
+ *
+ * Calls the restore method of all surfaces
+ *
+ * Params:
+ *
+ * Returns:
+ *  Always returns DD_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    FIXME("(%p): Stub\n", This);
+
+    /* This isn't hard to implement: Enumerate all WineD3D surfaces,
+     * get their parent and call their restore method. Do not implement
+     * it in WineD3D, as restoring a surface means re-creating the
+     * WineD3DDSurface
+     */
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::StartModeTest
+ *
+ * Tests the specified video modes to update the system registry with
+ * refresh rate information. StartModeTest starts the mode test,
+ * EvaluateMode is used to fail or pass a mode. If EvaluateMode
+ * isn't called withhin 15 secounds, the mode is failed automatically
+ *
+ * As refresh rates are handled by the X server, I don't think this
+ * Methos is important
+ *
+ * Params:
+ *  Modes: An array of mode specifications
+ *  NumModes: The number of modes in Modes
+ *  Flags: Some flags...
+ *
+ * Returns:
+ *  Returns DDERR_TESTFINISHED if flags contains DDSMT_ISTESTREQUIRED,
+ *  if no modes are passed, DDERR_INVALIDPARAMS is returned,
+ *  otherwise DD_OK;
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_StartModeTest(IDirectDraw7 *iface,
+                              SIZE *Modes,
+                              DWORD NumModes,
+                              DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    WARN("(%p)->(%p, %ld, %lx): Semi-Stub, most likely harmless\n", This, Modes, NumModes, Flags);
+
+    /* This looks sane */
+    if( (!Modes) || (NumModes == 0) ) return DDERR_INVALIDPARAMS;
+
+    /* DDSMT_ISTESTREQUIRED asks if a mode test is necessary.
+     * As it is not, DDERR_TESTFINISHED is returned
+     * (hopefully that's correct
+     *
+    if(Flags & DDSMT_ISTESTREQUIRED) return DDERR_TESTFINISHED;
+     * well, that value doesn't (yet) exist in the wine headers, so ignore it
+     */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_RecreateSurfacesCallback
+ *
+ * Enumeration callback for IDirectDrawImpl_RecreateAllSurfaces.
+ * It re-recreates the WineD3DSurface. It's pretty steightforward
+ *
+ *****************************************************************************/
+HRESULT WINAPI
+IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
+                                         DDSURFACEDESC2 *desc,
+                                         void *Context)
+{
+    IDirectDrawSurfaceImpl *surfImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
+                                                   IDirectDrawSurface7,
+                                                   surf);
+    IDirectDrawImpl *This = surfImpl->ddraw;
+    IUnknown *Parent;
+    IParentImpl *parImpl = NULL;
+    IWineD3DSurface *wineD3DSurface;
+    HRESULT hr;
+    void *tmp;
+
+    WINED3DSURFACE_DESC     Desc;
+    WINED3DFORMAT           Format;
+    WINED3DRESOURCETYPE     Type;
+    DWORD                   Usage;
+    WINED3DPOOL             Pool;
+    UINT                    Size;
+
+    WINED3DMULTISAMPLE_TYPE MultiSampleType;
+    DWORD                   MultiSampleQuality;
+    UINT                    Width;
+    UINT                    Height;
+
+    TRACE("(%p): Enumerated Surface %p\n", This, surfImpl);
+
+    /* For the enumeration */
+    IDirectDrawSurface7_Release(surf);
+
+    if(surfImpl->ImplType == This->ImplType) return DDENUMRET_OK; /* Continue */
+
+    /* Get the objects */
+    wineD3DSurface = surfImpl->WineD3DSurface;
+    IWineD3DSurface_GetParent(wineD3DSurface, &Parent);
+    IUnknown_Release(Parent); /* For the getParent */
+
+    /* Is the parent an IParent interface? */
+    if(IUnknown_QueryInterface(Parent, &IID_IParent, &tmp) == S_OK)
+    {
+        /* It is a IParent interface! */
+        IUnknown_Release(Parent); /* For the QueryInterface */
+        parImpl = ICOM_OBJECT(IParentImpl, IParent, Parent);
+        /* Release the reference the parent interface is holding */
+        IWineD3DSurface_Release(wineD3DSurface);
+    }
+
+
+    /* Get the surface properties */
+    Desc.Format = &Format;
+    Desc.Type = &Type;
+    Desc.Usage = &Usage;
+    Desc.Pool = &Pool;
+    Desc.Size = &Size;
+    Desc.MultiSampleType = &MultiSampleType;
+    Desc.MultiSampleQuality = &MultiSampleQuality;
+    Desc.Width = &Width;
+    Desc.Height = &Height;
+
+    hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc);
+    if(hr != D3D_OK) return hr;
+
+    /* Create the new surface */
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
+                                      Width, Height, Format,
+                                      TRUE /* Lockable */,
+                                      FALSE /* Discard */,
+                                      surfImpl->mipmap_level,
+                                      &surfImpl->WineD3DSurface,
+                                      Type,
+                                      Usage,
+                                      Pool,
+                                      MultiSampleType,
+                                      MultiSampleQuality,
+                                      0 /* SharedHandle */,
+                                      This->ImplType,
+                                      Parent);
+
+    if(hr != D3D_OK)
+        return hr;
+
+    /* Update the IParent if it exists */
+    if(parImpl)
+    {
+        parImpl->child = (IUnknown *) surfImpl->WineD3DSurface;
+        /* Add a reference for the IParent */
+        IWineD3DSurface_AddRef(surfImpl->WineD3DSurface);
+    }
+    /* TODO: Copy the surface content, except for render targets */
+
+    if(IWineD3DSurface_Release(wineD3DSurface) == 0)
+        TRACE("Surface released successfull, next surface\n");
+    else
+        ERR("Something's still holding the old WineD3DSurface\n");
+
+    surfImpl->ImplType = This->ImplType;
+
+    return DDENUMRET_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_RecreateAllSurfaces
+ *
+ * A function, that converts all wineD3DSurfaces to the new implementation type
+ * It enumerates all surfaces with IWineD3DDevice::EnumSurfaces, creates a
+ * new WineD3DSurface, copys the content and releases the old surface
+ *
+ *****************************************************************************/
+static HRESULT
+IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This)
+{
+    DDSURFACEDESC2 desc;
+    TRACE("(%p): Switch to implementation %d\n", This, This->ImplType);
+
+    if(This->ImplType != SURFACE_OPENGL && This->d3d_initialized)
+    {
+        /* Should happen almost never */
+        FIXME("(%p) Switching to non-opengl surfaces with d3d started. Is this a bug?\n", This);
+        /* Shutdown d3d */
+        IWineD3DDevice_Uninit3D(This->wineD3DDevice);
+    }
+    /* Contrary: D3D starting is handled by the caller, because it knows the render target */
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+
+    return IDirectDraw7_EnumSurfaces(ICOM_INTERFACE(This, IDirectDraw7),
+                                     0,
+                                     &desc,
+                                     This,
+                                     IDirectDrawImpl_RecreateSurfacesCallback);
+}
+
+/*****************************************************************************
+ * D3D7CB_CreateSurface
+ *
+ * Callback function for IDirect3DDevice_CreateTexture. It searches for the
+ * correct mipmap sublevel, and returns it to WineD3D.
+ * The surfaces are created already by IDirectDraw7::CreateSurface
+ *
+ * Params:
+ *  With, Height: With and height of the surface
+ *  Format: The requested format
+ *  Usage, Pool: D3DUSAGE and D3DPOOL of the surface
+ *  level: The mipmap level
+ *  Surface: Pointer to pass the created surface back at
+ *  SharedHandle: NULL
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+D3D7CB_CreateSurface(IUnknown *device,
+                     UINT Width, UINT Height,
+                     WINED3DFORMAT Format,
+                     DWORD Usage, WINED3DPOOL Pool, UINT level,
+                     IWineD3DSurface **Surface,
+                     HANDLE *SharedHandle)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device);
+    IDirectDrawSurfaceImpl *surf = This->tex_root;
+    int i;
+    TRACE("(%p) call back. surf=%p\n", device, surf);
+
+    /* Find the wanted mipmap. There are enought mipmaps in the chain */
+    for(i = 0; i < level; i++)
+        surf = surf->next_complex;
+
+    /* Return the surface */
+    *Surface = surf->WineD3DSurface;
+
+    TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *Surface, surf);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_CreateNewSurface
+ *
+ * A helper function for IDirectDraw7::CreateSurface. It creates a new surface
+ * with the passed parameters.
+ *
+ * Params:
+ *  DDSD: Description of the surface to create
+ *  Surf: Address to store the interface pointer at
+ *
+ * Returns:
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
+                                 DDSURFACEDESC2 *pDDSD,
+                                 IDirectDrawSurfaceImpl **ppSurf,
+                                 UINT level)
+{
+    HRESULT hr;
+    UINT Width = 0, Height = 0;
+    WINED3DFORMAT Format = WINED3DFMT_UNKNOWN;
+    WINED3DRESOURCETYPE ResType = WINED3DRTYPE_SURFACE;
+    DWORD Usage = 0;
+    WINED3DSURFTYPE ImplType = This->ImplType;
+    WINED3DSURFACE_DESC Desc;
+    IUnknown *Parent;
+    IParentImpl *parImpl = NULL;
+    WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
+
+    /* Dummies for GetDesc */
+    WINED3DPOOL dummy_d3dpool;
+    WINED3DMULTISAMPLE_TYPE dummy_mst;
+    UINT dummy_uint;
+    DWORD dummy_dword;
+
+    if (TRACE_ON(ddraw))
+    {
+        TRACE(" (%p) Requesting surface desc :\n", This);
+        DDRAW_dump_surface_desc(pDDSD);
+    }
+
+    /* Select the surface type, if it wasn't choosen yet */
+    if(ImplType == SURFACE_UNKNOWN)
+    {
+        /* Use GL Surfaces if a D3DDEVICE Surface is requested */
+        if(pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
+        {
+            TRACE("(%p) Choosing GL surfaces because a 3DDEVICE Surface was requested\n", This);
+            ImplType = SURFACE_OPENGL;
+        }
+
+        /* Otherwise use GDI surfaces for now */
+        else
+        {
+            TRACE("(%p) Choosing GDI surfaces for 2D rendering\n", This);
+            ImplType = SURFACE_GDI;
+        }
+
+        /* Policy if all surface implementations are available:
+         * First, check if a default type was set with winecfg. If not,
+         * try Xrender surfaces, and use them if they work. Next, check if
+         * accellerated OpenGL is available, and use GL surfaces in this
+         * case. If all fails, use GDI surfaces. If a 3DDEVICE surface
+         * was created, always use OpenGL surfaces.
+         *
+         * (Note: Xrender surfaces are not implemented by now, the
+         * unaccellerated implementation uses GDI to render in Software)
+         */
+
+        /* Store the type. If it needs to be changed, all WineD3DSurfaces have to
+         * be re-created. This could be done with IDirectDrawSurface7::Restore
+         */
+        This->ImplType = ImplType;
+    }
+    else
+    {
+         if((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE ) && 
+            (This->ImplType != SURFACE_OPENGL ) && DefaultSurfaceType == SURFACE_UNKNOWN)
+        {
+            /* We have to change to OpenGL,
+             * and re-create all WineD3DSurfaces
+             */
+            ImplType = SURFACE_OPENGL;
+            This->ImplType = ImplType;
+            TRACE("(%p) Re-creating all surfaces\n", This);
+            IDirectDrawImpl_RecreateAllSurfaces(This);
+            TRACE("(%p) Done recreating all surfaces\n", This);
+        }
+        else if(This->ImplType != SURFACE_OPENGL)
+        {
+            WARN("The application requests a 3D capable surface, but a non-opengl surface was set in the registry\n");
+            /* Do not fail surface creation, only fail 3D device creation */
+        }
+    }
+
+    /* Get the surface parameters */
+    if ( pDDSD->dwFlags & DDSD_LPSURFACE)
+    {
+        ERR("(%p) Using a passed surface pointer is not yet supported\n", This);
+	assert(0);
+    }
+
+    /* Get the correct wined3d usage */
+    if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
+                                 DDSCAPS_BACKBUFFER     |
+                                 DDSCAPS_3DDEVICE       ) )
+    {
+        Usage |= WINED3DUSAGE_RENDERTARGET;
+    }
+    if(This->depthstencil)
+    {
+        /* The depth stencil creation callback sets this flag.
+         * Set the WineD3D usage to let it know that it's a depth
+         * Stencil surface.
+         */
+        Usage |= WINED3DUSAGE_DEPTHSTENCIL;
+    }
+    if(pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
+    {
+        Pool = WINED3DPOOL_SYSTEMMEM;
+    }
+
+    Format = PixelFormat_DD2WineD3D(&pDDSD->u4.ddpfPixelFormat);
+    if(Format == WINED3DFMT_UNKNOWN)
+    {
+        ERR("Unsupported / Unknown pixelformat\n");
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
+    /* Create the Surface object */
+    *ppSurf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
+    if(!*ppSurf)
+    {
+        ERR("(%p) Error allocating memory for a surface\n", This);
+        return DDERR_OUTOFVIDEOMEMORY;
+    }
+    ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawSurface7, IDirectDrawSurface7_Vtbl);
+    ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawSurface3, IDirectDrawSurface3_Vtbl);
+    ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawGammaControl, IDirectDrawGammaControl_Vtbl);
+    ICOM_INIT_INTERFACE(*ppSurf, IDirect3DTexture2, IDirect3DTexture2_Vtbl);
+    ICOM_INIT_INTERFACE(*ppSurf, IDirect3DTexture, IDirect3DTexture1_Vtbl);
+    (*ppSurf)->ref = 1;
+    (*ppSurf)->version = 7;
+    (*ppSurf)->ddraw = This;
+    (*ppSurf)->surface_desc.dwSize = sizeof(DDSURFACEDESC2);
+    (*ppSurf)->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+    DD_STRUCT_COPY_BYSIZE(&(*ppSurf)->surface_desc, pDDSD);
+
+    /* Surface attachments */
+    (*ppSurf)->next_attached = NULL;
+    (*ppSurf)->first_attached = *ppSurf;
+
+    (*ppSurf)->next_complex = NULL;
+    (*ppSurf)->first_complex = *ppSurf;
+
+    /* Needed to re-create the surface on an implementation change */
+    (*ppSurf)->ImplType = ImplType;
+
+    /* For D3DDevice creation */
+    (*ppSurf)->isRenderTarget = FALSE;
+
+    /* A trace message for debugging */
+    TRACE("(%p) Created IDirectDrawSurface implementation structure at %p\n", This, *ppSurf);
+
+    if(pDDSD->ddsCaps.dwCaps & ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE) )
+    {
+        /* Render targets and textures need a IParent interface,
+         * because WineD3D will destroy them when the swapchain
+         * is released
+         */
+        parImpl = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl));
+        if(!parImpl)
+        {
+            ERR("Out of memory when allocating memory for a IParent implementation\n");
+            return DDERR_OUTOFMEMORY;
+        }
+        parImpl->ref = 1;
+        ICOM_INIT_INTERFACE(parImpl, IParent, IParent_Vtbl);
+        Parent = (IUnknown *) ICOM_INTERFACE(parImpl, IParent);
+        TRACE("Using IParent interface %p as parent\n", parImpl);
+    }
+    else
+    {
+        /* Use the surface as parent */
+        Parent = (IUnknown *) ICOM_INTERFACE(*ppSurf, IDirectDrawSurface7);
+        TRACE("Using Surface interface %p as parent\n", *ppSurf);
+    }
+
+    /* Now create the WineD3D Surface */
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
+                                      pDDSD->dwWidth,
+                                      pDDSD->dwHeight,
+                                      Format,
+                                      TRUE /* Lockable */,
+                                      FALSE /* Discard */,
+                                      level,
+                                      &(*ppSurf)->WineD3DSurface,
+                                      ResType, Usage,
+                                      Pool,
+                                      WINED3DMULTISAMPLE_NONE,
+                                      0 /* MultiSampleQuality */,
+                                      0 /* SharedHandle */,
+                                      ImplType,
+                                      Parent);
+
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DDevice::CreateSurface failed. hr = %08lx\n", hr);
+        return hr;
+    }
+
+    /* Set the child of the parent implementation if it exists */
+    if(parImpl)
+    {
+        parImpl->child = (IUnknown *) (*ppSurf)->WineD3DSurface;
+        /* The IParent releases the WineD3DSurface, and
+         * the ddraw surface does that too. Hold an reference
+         */
+        IWineD3DSurface_AddRef((*ppSurf)->WineD3DSurface);
+    }
+
+    /* Increase the surface counter, and attach the surface */
+    InterlockedIncrement(&This->surfaces);
+    if(This->surface_list)
+    {
+        This->surface_list->prev = *ppSurf;
+    }
+    (*ppSurf)->next = This->surface_list;
+    This->surface_list = *ppSurf;
+
+    /* Here we could store all created surfaces in the DirectDrawImpl structure,
+     * But this could also be delegated to WineDDraw, as it keeps track of all it's
+     * resources. Not implemented for now, as there are more important things ;)
+     */
+
+    /* Get the pixel format of the WineD3DSurface and store it.
+     * Don't use the Format choosen above, WineD3D might have
+     * changed it
+     */
+    Desc.Format = &Format;
+    Desc.Type = &ResType;
+    Desc.Usage = &Usage;
+    Desc.Pool = &dummy_d3dpool;
+    Desc.Size = &dummy_uint;
+    Desc.MultiSampleType = &dummy_mst;
+    Desc.MultiSampleQuality = &dummy_dword;
+    Desc.Width = &Width;
+    Desc.Height = &Height;
+
+    (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
+    hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc);
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DSurface::GetDesc failed\n");
+        IDirectDrawSurface7_Release( (IDirectDrawSurface7 *) *ppSurf);
+        return hr;
+    }
+
+    if(Format == WINED3DFMT_UNKNOWN)
+    {
+        FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n");
+    }
+    PixelFormat_WineD3DtoDD( &(*ppSurf)->surface_desc.u4.ddpfPixelFormat, Format);
+
+    /* Anno 1602 stores the pitch right after surface creation, so make sure it's there.
+     * I can't LockRect() the surface here because if OpenGL surfaces are in use, the
+     * WineD3DDevice might not be useable for 3D yet, so an extra method was created
+     */
+    (*ppSurf)->surface_desc.dwFlags |= DDSD_PITCH;
+    (*ppSurf)->surface_desc.u1.lPitch = IWineD3DSurface_GetPitch((*ppSurf)->WineD3DSurface);
+
+    /* Application passed a color key? Set it! */
+    if(pDDSD->dwFlags & DDSD_CKDESTOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_DESTOVERLAY,
+                                    &pDDSD->u3.ddckCKDestOverlay);
+    }
+    if(pDDSD->dwFlags & DDSD_CKDESTBLT)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_DESTBLT,
+                                    &pDDSD->ddckCKDestBlt);
+    }
+    if(pDDSD->dwFlags & DDSD_CKSRCOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_SRCOVERLAY,
+                                    &pDDSD->ddckCKSrcOverlay);
+    }
+    if(pDDSD->dwFlags & DDSD_CKSRCBLT)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_SRCBLT,
+                                    &pDDSD->ddckCKSrcBlt);
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::CreateSurface
+ *
+ * Creates a new IDirectDrawSurface object and returns it's interface.
+ *
+ * The surface connections with wined3d are a bit tricky. Basically it works
+ * like this:
+ *
+ * |------------------------|               |-----------------|
+ * | DDraw surface          |               | WineD3DSurface  |
+ * |                        |               |                 |
+ * |        WineD3DSurface  |-------------->|                 |
+ * |        Child           |<------------->| Parent          |
+ * |------------------------|               |-----------------|
+ *
+ * The DDraw surface is the parent of the wined3d surface, and it releases
+ * the WineD3DSurface when the ddraw surface is destroyed.
+ *
+ * However, for all surfaces which can be in a container in WineD3D,
+ * we have to do this. These surfaces are ususally compley surfaces,
+ * so this concernes primary surfaces with a front and a back buffer,
+ * and textures textures.
+ *
+ * |------------------------|               |-----------------|
+ * | DDraw surface          |               | Containter      |
+ * |                        |               |                 |
+ * |                  Child |<------------->| Parent          |
+ * |                Texture |<------------->|                 |
+ * |         WineD3DSurface |<----|         |          Levels |<--|
+ * | Complex connection     |     |         |                 |   |
+ * |------------------------|     |         |-----------------|   |
+ *  ^                             |                               |
+ *  |                             |                               |
+ *  |                             |                               |
+ *  |    |------------------|     |         |-----------------|   |
+ *  |    | IParent          |     |-------->| WineD3DSurface  |   |
+ *  |    |                  |               |                 |   |
+ *  |    |            Child |<------------->| Parent          |   |
+ *  |    |                  |               |       Container |<--|
+ *  |    |------------------|               |-----------------|   |
+ *  |                                                             |
+ *  |   |----------------------|                                  |
+ *  |   | DDraw surface 2      |                                  |
+ *  |   |                      |                                  |
+ *  |<->| Complex root   Child |                                  |
+ *  |   |              Texture |                                  |
+ *  |   |       WineD3DSurface |<----|                            |
+ *  |   |----------------------|     |                            |
+ *  |                                |                            |
+ *  |    |---------------------|     |      |-----------------|   |
+ *  |    | IParent             |     |----->| WineD3DSurface  |   |
+ *  |    |                     |            |                 |   |
+ *  |    |               Child |<---------->| Parent          |   |
+ *  |    |---------------------|            |       Container |<--|
+ *  |                                       |-----------------|   |
+ *  |                                                             |
+ *  |             ---More surfaces can follow---                  |
+ *
+ * The reason is that the IWineD3DSwapchain(render target container)
+ * and the IWineD3DTexure(Texture container) release the parents
+ * of their surface's children, but by releasing the complex root
+ * the surfaces which are complexly attached to it are destroyed
+ * too. See IDirectDrawSurface::Release for a more detailed
+ * explanation.
+ *
+ * Params:
+ *  DDSD: Description of the surface to create
+ *  Surf: Address to store the interface pointer at
+ *  UnkOuter: Basically for aggregation support, but ddraw doesn't support
+ *            aggregation, so it has to be NULL
+ *
+ * Returns:
+ *  DD_OK on success
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *  DDERR_* if an error occurs
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
+                              DDSURFACEDESC2 *DDSD,
+                              IDirectDrawSurface7 **Surf,
+                              IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    IDirectDrawSurfaceImpl *object = NULL;
+    HRESULT hr;
+    LONG extra_surfaces = 0, i;
+    DDSURFACEDESC2 desc2;
+    UINT level = 0;
+    WINED3DDISPLAYMODE Mode;
+
+    TRACE("(%p)->(%p,%p,%p)\n", This, DDSD, Surf, UnkOuter);
+
+    /* Some checks before we start */
+    if (TRACE_ON(ddraw))
+    {
+        TRACE(" (%p) Requesting surface desc :\n", This);
+        DDRAW_dump_surface_desc(DDSD);
+    }
+
+    if (UnkOuter != NULL)
+    {
+        FIXME("(%p) : outer != NULL?\n", This);
+        return CLASS_E_NOAGGREGATION; /* unchecked */
+    }
+
+    if (!(DDSD->dwFlags & DDSD_CAPS))
+    {
+        /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
+        DDSD->dwFlags |= DDSD_CAPS;
+    }
+    if (DDSD->ddsCaps.dwCaps == 0)
+    {
+        /* This has been checked on real Windows */
+        DDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+    }
+
+    if (DDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD)
+    {
+        /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
+        DDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if ((DDSD->dwFlags & DDSD_LPSURFACE) && (DDSD->lpSurface == NULL))
+    {
+        /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */
+        WARN("(%p) Null surface pointer specified, ignore it!\n", This);
+        DDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if (Surf == NULL)
+    {
+        FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This);
+        return E_POINTER; /* unchecked */
+    }
+
+    /* Modify some flags */
+    memset(&desc2, 0, sizeof(desc2));
+    desc2.dwSize = sizeof(desc2);   /*For the struct copy */
+    DD_STRUCT_COPY_BYSIZE(&desc2, DDSD);
+    desc2.dwSize = sizeof(desc2);   /* To override a possibly smaller size */
+    desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */
+
+    /* Get the video mode from WineD3D - we will need it */
+    hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                       0, /* Swapchain 0 */
+                                       &Mode);
+    if(FAILED(hr))
+    {
+        ERR("Failed to read display mode from wined3d\n");
+        switch(This->orig_bpp)
+        {
+            case 8:
+                Mode.Format = WINED3DFMT_P8;
+                break;
+
+            case 15:
+                Mode.Format = WINED3DFMT_X1R5G5B5;
+                break;
+
+            case 16:
+                Mode.Format = WINED3DFMT_R5G6B5;
+                break;
+
+            case 24:
+                Mode.Format = WINED3DFMT_R8G8B8;
+                break;
+
+            case 32:
+                Mode.Format = WINED3DFMT_X8R8G8B8;
+                break;
+        }
+        Mode.Width = This->orig_width;
+        Mode.Height = This->orig_height;
+    }
+
+    /* No pixelformat given? Use the current screen format */
+    if(!(desc2.dwFlags & DDSD_PIXELFORMAT))
+    {
+        desc2.dwFlags |= DDSD_PIXELFORMAT;
+        desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
+
+        /* Wait: It could be a Z buffer */
+        if(desc2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
+        {
+            switch(desc2.u2.dwMipMapCount) /* Who had this glourious idea? */
+            {
+                case 15:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D15S1);
+                    break;
+                case 16:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D16);
+                    break;
+                case 24:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D24X8);
+                    break;
+                case 32:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D32);
+                    break;
+                default:
+                    ERR("Unknown Z buffer bit depth\n");
+            }
+        }
+        else
+        {
+            PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, Mode.Format);
+        }
+    }
+
+    /* No Width or no Height? Use the current window size or
+     * the original screen size
+     */
+    if(!(desc2.dwFlags & DDSD_WIDTH) ||
+       !(desc2.dwFlags & DDSD_HEIGHT) )
+    {
+        HWND window;
+
+        /* Fallback: From WineD3D / original mode */
+        desc2.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+        desc2.dwWidth = Mode.Width;
+        desc2.dwHeight = Mode.Height;
+
+        hr = IWineD3DDevice_GetHWND(This->wineD3DDevice,
+                                    &window);
+        if( (hr == D3D_OK) && (window != 0) )
+        {
+            RECT rect;
+            if(GetWindowRect(window, &rect) )
+            {
+                /* This is a hack until I find a better solution */
+                if( (rect.right - rect.left) <= 1 ||
+                    (rect.bottom - rect.top) <= 1 )
+                {
+                    FIXME("Wanted to get surface dimensions from window %p, but it has only \
+                           a size of %ldx%ld. Using full screen dimensions\n",
+                           window, rect.right - rect.left, rect.bottom - rect.top);
+                }
+                else
+                {
+                    /* Not sure if this is correct */
+                    desc2.dwWidth = rect.right - rect.left;
+                    desc2.dwHeight = rect.bottom - rect.top;
+                    TRACE("Using window %p's dimensions: %ldx%ld\n", window, desc2.dwWidth, desc2.dwHeight);
+                }
+            }
+        }
+    }
+
+    /* Mipmap count fixes */
+    if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+    {
+        if(desc2.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
+        {
+            if(desc2.dwFlags & DDSD_MIPMAPCOUNT)
+            {
+                /* Mipmap count is given, nothing to do */
+            }
+            else
+            {
+                /* Undocumented feature: Create sublevels until
+                 * eighter the width or the height is 1
+                 */
+                DWORD min = desc2.dwWidth < desc2.dwHeight ?
+                            desc2.dwWidth : desc2.dwHeight;
+                desc2.u2.dwMipMapCount = 0;
+                while( min )
+                {
+                    desc2.u2.dwMipMapCount += 1;
+                    min >>= 1;
+                }
+            }
+        }
+        else
+        {
+            /* Not-complex mipmap -> Mipmapcount = 1 */
+            desc2.u2.dwMipMapCount = 1;
+        }
+        extra_surfaces = desc2.u2.dwMipMapCount - 1;
+
+        /* There's a mipmap count in the created surface in any case */
+        desc2.dwFlags |= DDSD_MIPMAPCOUNT;
+    }
+    /* If no mipmap is given, the texture has only one level */
+
+    /* The first surface is a front buffer, the back buffer is created afterwards */
+    if( (desc2.dwFlags & DDSD_CAPS) && (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
+    {
+        desc2.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
+    }
+
+    /* Create the first surface */
+    hr = IDirectDrawImpl_CreateNewSurface(This, &desc2, &object, 0);
+    if( hr != DD_OK)
+    {
+        ERR("IDirectDrawImpl_CreateNewSurface failed with %08lx\n", hr);
+        return hr;
+    }
+
+    *Surf = ICOM_INTERFACE(object, IDirectDrawSurface7);
+
+    /* Create Additional surfaces if necessary
+     * This applies to Primary surfaces which have a back buffer count
+     * set, but not to mipmap textures. In case of Mipmap textures,
+     * wineD3D takes care of the creation of additional surfaces
+     */
+    if(DDSD->dwFlags & DDSD_BACKBUFFERCOUNT)
+    {
+        extra_surfaces = DDSD->dwBackBufferCount;
+        desc2.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; /* It's not a front buffer */
+        desc2.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+    }
+
+    for(i = 0; i < extra_surfaces; i++)
+    {
+        IDirectDrawSurfaceImpl *object2 = NULL;
+        IDirectDrawSurfaceImpl *iterator;
+
+        /* increase the mipmap level, but only if a mipmap is created
+         * In this case, also half the size
+         */
+        if(DDSD->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+        {
+            level++;
+            desc2.dwWidth /= 2;
+            desc2.dwHeight /= 2;
+        }
+
+        hr = IDirectDrawImpl_CreateNewSurface(This,
+                                              &desc2,
+                                              &object2,
+                                              level);
+        if(hr != DD_OK)
+        {
+            /* This destroys and possibly created surfaces too */
+            IDirectDrawSurface_Release( ICOM_INTERFACE(object, IDirectDrawSurface7) );
+            return hr;
+        }
+
+        /* Add the new surface to the complex attachment list */
+        object2->first_complex = object;
+        object2->next_complex = NULL;
+        iterator = object;
+        while(iterator->next_complex) iterator = iterator->next_complex;
+        iterator->next_complex = object2;
+
+        /* Remove the (possible) back buffer cap from the new surface description,
+         * because only one surface in the flipping chain is a back buffer, one
+         * is a front buffer, the others are just primary surfaces.
+         */
+        desc2.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
+    }
+
+    /* Addref the ddraw interface to keep an reference for each surface */
+    IDirectDraw7_AddRef(iface);
+
+    /* If the implementation is OpenGL and there's no d3ddevice, attach a d3ddevice
+     * But attach the d3ddevice only if the currently created surface was
+     * a primary surface(2D app in 3D mode) or a 3DDEVICE surface(3D app)
+     * The only case I can think of where this doesn't apply is when a
+     * 2D app was configured by the user to run with OpenGL and it didn't create
+     * the render target as first surface. In this case the render target creation
+     * will cause the 3D init.
+     */
+    if( (This->ImplType == SURFACE_OPENGL) && !(This->d3d_initialized) &&
+        desc2.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) )
+    {
+        IDirectDrawSurfaceImpl *target = This->surface_list;
+
+        /* Search for the primary to use as render target */
+        while(target)
+        {
+            if(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+            {
+                /* found */
+                TRACE("Using primary %p as render target\n", target);
+                break;
+            }
+            target = target->next;
+        }
+        /* If it's not found, use the just created DDSCAPS_3DDEVICE surface */
+        if(!target)
+        {
+            target = object;
+        }
+
+        TRACE("(%p) Attaching a D3DDevice, rendertarget = %p\n", This, target);
+        hr = IDirectDrawImpl_AttachD3DDevice(This, target->first_complex);
+        if(hr != D3D_OK)
+        {
+            ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %lx\n", hr);
+        }
+    }
+
+    /* Create a WineD3DTexture if a texture was requested */
+    if(DDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
+    {
+        UINT levels;
+        WINED3DFORMAT Format;
+        WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
+
+        This->tex_root = object;
+
+        if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+        {
+            /* a mipmap is created, create enought levels */
+            levels = desc2.u2.dwMipMapCount;
+        }
+        else
+        {
+            /* No mipmap is created, create one level */
+            levels = 1;
+        }
+
+        /* DDSCAPS_SYSTEMMEMORY textures are in WINED3DPOOL_SYSTEMMEM */
+        if(DDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
+        {
+            Pool = WINED3DPOOL_SYSTEMMEM;
+        }
+        /* Should I forward the MANEGED cap to the managed pool ? */
+
+        /* Get the format. It's set already by CreateNewSurface */
+        Format = PixelFormat_DD2WineD3D(&object->surface_desc.u4.ddpfPixelFormat);
+
+        /* The surfaces are already created, the callback only
+         * passes the IWineD3DSurface to WineD3D
+         */
+        hr = IWineD3DDevice_CreateTexture( This->wineD3DDevice,
+                                           DDSD->dwWidth, DDSD->dwHeight,
+                                           levels, /* MipMapCount = Levels */
+                                           0, /* usage */
+                                           Format,
+                                           Pool,
+                                           &object->wineD3DTexture,
+                                           0, /* SharedHandle */
+                                           (IUnknown *) ICOM_INTERFACE(object, IDirectDrawSurface7),
+                                           D3D7CB_CreateSurface );
+        This->tex_root = NULL;
+    }
+
+    return hr;
+}
+
+#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
+#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
+
+static 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;
+}
+
+static BOOL
+IDirectDrawImpl_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;
+}
+
+#undef DDENUMSURFACES_SEARCHTYPE
+#undef DDENUMSURFACES_MATCHTYPE
+
+/*****************************************************************************
+ * IDirectDraw7::EnumSurfaces
+ *
+ * Loops through all surfaces attached to this device and calls the
+ * application callback. This can't be relayed to WineD3DDevice,
+ * because some WineD3DSurfaces' parents are IParent objects
+ *
+ * Params:
+ *  Flags: Some filtering flags. See IDirectDrawImpl_EnumSurfacesCallback
+ *  DDSD: Description to filter for
+ *  Context: Application-provided pointer, it's passed unmodified to the
+ *           Callback function
+ *  Callback: Address to call for each surface
+ *
+ * Returns:
+ *  DDERR_INVALIDPARAMS if the callback is NULL
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface,
+                             DWORD Flags,
+                             DDSURFACEDESC2 *DDSD,
+                             void *Context,
+                             LPDDENUMSURFACESCALLBACK7 Callback)
+{
+    /* The surface enumeration is handled by WineDDraw,
+     * because it keeps track of all surfaces attached to
+     * it. The filtering is done by our callback function,
+     * because WineDDraw doesn't handle ddraw-like surface
+     * caps structures
+     */
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    IDirectDrawSurfaceImpl *surf;
+    BOOL all, nomatch;
+    DDSURFACEDESC2 desc;
+
+    all = Flags & DDENUMSURFACES_ALL;
+    nomatch = Flags & DDENUMSURFACES_NOMATCH;
+
+    TRACE("(%p)->(%lx,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);
+
+    if(!Callback)
+        return DDERR_INVALIDPARAMS;
+
+    for(surf = This->surface_list; surf; surf = surf->next)
+    {
+        if (all || (nomatch != IDirectDrawImpl_DDSD_Match(DDSD, &surf->surface_desc)))
+        {
+            desc = surf->surface_desc;
+            IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7));
+            if(Callback( ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, Context) != DDENUMRET_OK)
+                return DD_OK;
+        }
+    }
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * D3D7CB_CreateRenderTarget
+ *
+ * Callback called by WineD3D to create Surfaces for render target usage
+ * This function takes the D3D target from the IDirectDrawImpl structure,
+ * and returns the WineD3DSurface. To avoid double usage, the surface
+ * is marked as render target afterwards
+ *
+ * Params
+ *  device: The WineD3DDevice's parent
+ *  Width, Height, Format: Dimesions and pixelformat of the render target
+ *                         Ignored, because the surface already exists
+ *  MultiSample, MultisampleQuality, Lockable: Ignored for the same reason
+ *  Lockable: ignored
+ *  ppSurface: Address to pass the surface pointer back at
+ *  pSharedHandle: Ignored
+ *
+ * Returns:
+ *  Always returns D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+D3D7CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
+                          WINED3DFORMAT Format,
+                          WINED3DMULTISAMPLE_TYPE MultiSample,
+                          DWORD MultisampleQuality,
+                          BOOL Lockable,
+                          IWineD3DSurface** ppSurface,
+                          HANDLE* pSharedHandle)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device);
+    IDirectDrawSurfaceImpl *d3dSurface = (IDirectDrawSurfaceImpl *) This->d3d_target->first_complex;
+    TRACE("(%p) call back\n", device);
+
+    /* Loop through the complex chain and try to find unused primary surfaces */
+    while(d3dSurface->isRenderTarget)
+    {
+        d3dSurface = d3dSurface->next_complex;
+        if(!d3dSurface) break;
+    }
+    if(!d3dSurface)
+    {
+        d3dSurface = This->d3d_target;
+        ERR(" (%p) : No DirectDrawSurface found to create the back buffer. Using the front buffer as back buffer. Uncertain consequences\n", This);
+    }
+
+    /* TODO: Return failure if the dimensions do not match, but this shouldn't happen */
+
+    *ppSurface = d3dSurface->WineD3DSurface;
+    d3dSurface->isRenderTarget = TRUE;
+    TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *ppSurface, d3dSurface);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+D3D7CB_CreateDepthStencilSurface(IUnknown *device,
+                                 UINT Width,
+                                 UINT Height,
+                                 WINED3DFORMAT Format,
+                                 WINED3DMULTISAMPLE_TYPE MultiSample,
+                                 DWORD MultisampleQuality,
+                                 BOOL Discard,
+                                 IWineD3DSurface** ppSurface,
+                                 HANDLE* pSharedHandle)
+{
+    /* Create a Depth Stencil surface to make WineD3D happy */
+    HRESULT hr = D3D_OK;
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device);
+    DDSURFACEDESC2 ddsd;
+
+    TRACE("(%p) call back\n", device);
+
+    *ppSurface = NULL;
+
+    /* Create a DirectDraw surface */
+    memset(&ddsd, 0, sizeof(ddsd));
+    ddsd.dwSize = sizeof(ddsd);
+    ddsd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+    ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
+    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    ddsd.dwHeight = Height;
+    ddsd.dwWidth = Width;
+    if(Format != 0)
+    {
+      PixelFormat_WineD3DtoDD(&ddsd.u4.ddpfPixelFormat, Format);
+    }
+    else
+    {
+      ddsd.dwFlags ^= DDSD_PIXELFORMAT;
+    }
+
+    This->depthstencil = TRUE;
+    hr = IDirectDraw7_CreateSurface((IDirectDraw7 *) This,
+                                    &ddsd,
+                                    (IDirectDrawSurface7 **) &This->DepthStencilBuffer,
+                                    NULL);
+    This->depthstencil = FALSE;
+    if(FAILED(hr))
+    {
+        ERR(" (%p) Creating a DepthStencil Surface failed, result = %lx\n", This, hr);
+        return hr;
+    }
+    *ppSurface = This->DepthStencilBuffer->WineD3DSurface;
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * D3D7CB_CreateAdditionalSwapChain
+ *
+ * Callback function for WineD3D which creates a new WineD3DSwapchain
+ * interface. It also creates a IParent interface to store that pointer,
+ * so the WineD3DSwapchain has a parent and can be released when the D3D
+ * device is destroyed
+ *****************************************************************************/
+HRESULT WINAPI
+D3D7CB_CreateAdditionalSwapChain(IUnknown *device,
+                                 WINED3DPRESENT_PARAMETERS* pPresentationParameters,
+                                 IWineD3DSwapChain ** ppSwapChain)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device);
+    IParentImpl *object = NULL;
+    HRESULT res = D3D_OK;
+    IWineD3DSwapChain *swapchain;
+    TRACE("(%p) call back\n", device);
+
+    object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(IParentImpl));
+    if (NULL == object)
+    {
+        FIXME("Allocation of memory failed\n");
+        *ppSwapChain = NULL;
+        return DDERR_OUTOFVIDEOMEMORY;
+    }
+
+    ICOM_INIT_INTERFACE(object, IParent, IParent_Vtbl);
+    object->ref = 1;
+
+    res = IWineD3DDevice_CreateAdditionalSwapChain(This->wineD3DDevice,
+                                                   pPresentationParameters, 
+                                                   &swapchain, 
+                                                   (IUnknown*) ICOM_INTERFACE(object, IParent),
+                                                   D3D7CB_CreateRenderTarget,
+                                                   D3D7CB_CreateDepthStencilSurface);
+    if (res != D3D_OK)
+    {
+        FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This);
+        HeapFree(GetProcessHeap(), 0 , object);
+        *ppSwapChain = NULL;
+    }
+    else
+    {
+        *ppSwapChain = swapchain;
+        object->child = (IUnknown *) swapchain;
+    }
+
+    return res;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_AttachD3DDevice
+ *
+ * Initializes the D3D capatiblities of WineD3D
+ *
+ * Params:
+ *  primary: The primary surface for D3D
+ *
+ * Returns
+ *  DD_OK on success,
+ *  DDERR_* otherwise
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This,
+                                IDirectDrawSurfaceImpl *primary)
+{
+    HRESULT hr;
+    UINT                  BackBufferCount = 0;
+    HWND                  window;
+
+    WINED3DPRESENT_PARAMETERS localParameters;
+    BOOL isWindowed, EnableAutoDepthStencil;
+    WINED3DFORMAT AutoDepthStencilFormat;
+    WINED3DMULTISAMPLE_TYPE MultiSampleType;
+    WINED3DSWAPEFFECT  SwapEffect;
+    DWORD Flags, MultiSampleQuality;
+    UINT FullScreen_RefreshRateInHz, PresentationInterval;
+    WINED3DDISPLAYMODE Mode;
+
+    TRACE("(%p)->(%p)\n", This, primary);
+
+    /* Get the window */
+    hr = IWineD3DDevice_GetHWND(This->wineD3DDevice,
+                                &window);
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DDevice::GetHWND failed\n");
+        return hr;
+    }
+
+    /* If there's no window, create a hidden window. WineD3D needs it */
+    if(window == 0)
+    {
+        window = CreateWindowExA(0, This->classname, "Hidden D3D Window",
+                                 WS_DISABLED, 0, 0,
+                                 GetSystemMetrics(SM_CXSCREEN),
+                                 GetSystemMetrics(SM_CYSCREEN),
+                                 NULL, NULL, GetModuleHandleA(0), NULL);
+
+        ShowWindow(window, SW_HIDE);   /* Just to be sure */
+        WARN("(%p) No window for the Direct3DDevice, created a hidden window. HWND=%p\n", This, window);
+        This->d3d_window = window;
+    }
+    else
+    {
+        TRACE("(%p) Using existing window %p for Direct3D rendering\n", This, window);
+    }
+
+    /* use the surface description for the device parameters, not the
+     * Device settings. The app might render to an offscreen surface
+     */
+    Mode.Width = primary->surface_desc.dwWidth;
+    Mode.Height = primary->surface_desc.dwHeight;
+    Mode.Format = PixelFormat_DD2WineD3D(&primary->surface_desc.u4.ddpfPixelFormat);
+
+    if(primary->surface_desc.dwFlags & DDSD_BACKBUFFERCOUNT)
+    {
+        BackBufferCount = primary->surface_desc.dwBackBufferCount;
+    }
+
+    /* Store the future Render Target surface */
+    This->d3d_target = primary;
+
+    isWindowed = !(This->cooperative_level & DDSCL_FULLSCREEN);
+    EnableAutoDepthStencil = FALSE;
+    AutoDepthStencilFormat = WINED3DFMT_D16;
+    MultiSampleType = WINED3DMULTISAMPLE_NONE;
+    SwapEffect = WINED3DSWAPEFFECT_COPY;
+    Flags = 0;
+    MultiSampleQuality = 0;
+    FullScreen_RefreshRateInHz = WINED3DPRESENT_RATE_DEFAULT; /* Default rate: It's allready set */
+    PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT;
+
+    TRACE("Passing mode %d\n", Mode.Format);
+
+    localParameters.BackBufferWidth                = &Mode.Width;
+    localParameters.BackBufferHeight               = &Mode.Height;
+    localParameters.BackBufferFormat               = (WINED3DFORMAT *) &Mode.Format;
+    localParameters.BackBufferCount                = (UINT *) &BackBufferCount;
+    localParameters.MultiSampleType                = &MultiSampleType;
+    localParameters.MultiSampleQuality             = &MultiSampleQuality;
+    localParameters.SwapEffect                     = &SwapEffect;
+    localParameters.hDeviceWindow                  = &window;
+    localParameters.Windowed                       = &isWindowed;
+    localParameters.EnableAutoDepthStencil         = &EnableAutoDepthStencil;
+    localParameters.AutoDepthStencilFormat         = &AutoDepthStencilFormat;
+    localParameters.Flags                          = &Flags;
+    localParameters.FullScreen_RefreshRateInHz     = &FullScreen_RefreshRateInHz;
+    localParameters.PresentationInterval           = &PresentationInterval;
+
+    /* Set this NOW, otherwise creating the depth stencil surface will cause an
+     * recursive loop until ram or emulated video memory is full
+     */
+    This->d3d_initialized = TRUE;
+
+    hr = IWineD3DDevice_Init3D(This->wineD3DDevice,
+                               &localParameters,
+                               D3D7CB_CreateAdditionalSwapChain);
+    if(FAILED(hr))
+    {
+        This->wineD3DDevice = NULL;
+        return hr;
+    }
+
+    /* Create an Index Buffer parent */
+    TRACE("(%p) Successfully initialized 3D\n", This);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * DirectDrawCreateClipper (DDRAW.@)
+ *
+ * Creates a new IDirectDrawClipper object.
+ *
+ * Params:
+ *  Clipper: Address to write the interface pointer to
+ *  UnkOuter: For aggregation support, which ddraw doesn't have. Has to be
+ *            NULL
+ *
+ * Returns:
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *  E_OUTOFMEMORY if allocating the object failed
+ *
+ *****************************************************************************/
+HRESULT WINAPI
+DirectDrawCreateClipper(DWORD Flags,
+                        IDirectDrawClipper **Clipper,
+                        IUnknown *UnkOuter)
+{
+    IDirectDrawClipperImpl* object;
+    TRACE("(%08lx,%p,%p)\n", Flags, Clipper, UnkOuter);
+
+    if (UnkOuter != NULL) return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                     sizeof(IDirectDrawClipperImpl));
+    if (object == NULL) return E_OUTOFMEMORY;
+
+    ICOM_INIT_INTERFACE(object, IDirectDrawClipper, IDirectDrawClipper_Vtbl);
+    object->ref = 1;
+    object->hWnd = 0;
+    object->ddraw_owner = NULL;
+
+    *Clipper = (IDirectDrawClipper *) object;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::CreateClipper
+ *
+ * Creates a DDraw clipper. See DirectDrawCreateClipper for details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_CreateClipper(IDirectDraw7 *iface,
+                              DWORD Flags,
+                              IDirectDrawClipper **Clipper,
+                              IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    TRACE("(%p)->(%lx,%p,%p)\n", This, Flags, Clipper, UnkOuter);
+    return DirectDrawCreateClipper(Flags, Clipper, UnkOuter);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::CreatePalette
+ *
+ * Creates a new IDirectDrawPalette object
+ *
+ * Params:
+ *  Flags: The flags for the new clipper
+ *  ColorTable: Color table to assign to the new clipper
+ *  Palette: Address to write the interface pointer to
+ *  UnkOuter: For aggregation support, which ddraw doesn't have. Has to be
+ *            NULL
+ *
+ * Returns:
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *  E_OUTOFMEMORY if allocating the object failed
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_CreatePalette(IDirectDraw7 *iface,
+                              DWORD Flags,
+                              PALETTEENTRY *ColorTable,
+                              IDirectDrawPalette **Palette,
+                              IUnknown *pUnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    IDirectDrawPaletteImpl *object;
+    HRESULT hr = DDERR_GENERIC;
+    TRACE("(%p)->(%lx,%p,%p,%p)\n", This, Flags, ColorTable, Palette, pUnkOuter);
+
+    if(pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */
+
+    object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
+    if(!object) return E_OUTOFMEMORY;
+
+    ICOM_INIT_INTERFACE(object, IDirectDrawPalette, IDirectDrawPalette_Vtbl);
+    object->ref = 1;
+
+    hr = IWineD3DDevice_CreatePalette(This->wineD3DDevice, Flags, ColorTable, &object->wineD3DPalette, (IUnknown *) ICOM_INTERFACE(object, IDirectDrawPalette) );
+    if(hr != DD_OK)
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    *Palette = ICOM_INTERFACE(object, IDirectDrawPalette);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::DuplicateSurface
+ *
+ * Duplicates a surface. The surface memory points to the same memory as
+ * the original surface, and it's released when the last surface referring
+ * it is released. I guess that's beyond Wines surface management right now
+ * (Idea: create a new DDraw surface with the same WineD3DSurface. I need a
+ * test application to implement this)
+ *
+ * Params:
+ *  Src: Address of the source surface
+ *  Dest: Address to write the new surface pointer to
+ *
+ * Returns:
+ *  See IDirectDraw7::CreateSurface
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_DuplicateSurface(IDirectDraw7 *iface,
+                                 IDirectDrawSurface7 *Src,
+                                 IDirectDrawSurface7 **Dest)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
+    IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Src);
+
+    FIXME("(%p)->(%p,%p)\n", This, Surf, Dest);
+
+    /* For now, simply create a new, independent surface */
+    return IDirectDraw7_CreateSurface(iface,
+                                      &Surf->surface_desc,
+                                      Dest,
+                                      NULL);
+}
+
+/*****************************************************************************
+ * IDirectDraw7 VTable
+ *****************************************************************************/
+const IDirectDraw7Vtbl IDirectDraw7_Vtbl =
+{
+    /*** IUnkown ***/
+    IDirectDrawImpl_QueryInterface,
+    IDirectDrawImpl_AddRef,
+    IDirectDrawImpl_Release,
+    /*** IDirectDraw ***/
+    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,
+    /*** IDirectDraw2 ***/
+    IDirectDrawImpl_GetAvailableVidMem,
+    /*** IDirectDraw7 ***/
+    IDirectDrawImpl_GetSurfaceFromDC,
+    IDirectDrawImpl_RestoreAllSurfaces,
+    IDirectDrawImpl_TestCooperativeLevel,
+    IDirectDrawImpl_GetDeviceIdentifier,
+    /*** IDirectDraw7 ***/
+    IDirectDrawImpl_StartModeTest,
+    IDirectDrawImpl_EvaluateMode
+};
diff --git a/dlls/ddraw/ddraw.spec b/dlls/ddraw/ddraw.spec
index 7575091..0cd1d0f 100644
--- a/dlls/ddraw/ddraw.spec
+++ b/dlls/ddraw/ddraw.spec
@@ -8,8 +8,8 @@
 @ stdcall DirectDrawCreateEx(ptr ptr ptr ptr)
 @ stdcall DirectDrawEnumerateA(ptr ptr)
 @ stdcall DirectDrawEnumerateExA(ptr ptr long)
-@ stdcall DirectDrawEnumerateExW(ptr ptr long)
-@ stdcall DirectDrawEnumerateW(ptr ptr)
+@ stub DirectDrawEnumerateExW
+@ stub DirectDrawEnumerateW
 @ stdcall -private DllCanUnloadNow()
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllRegisterServer()
diff --git a/dlls/ddraw/ddraw_hal.c b/dlls/ddraw/ddraw_hal.c
deleted file mode 100644
index 59908a0..0000000
--- a/dlls/ddraw/ddraw_hal.c
+++ /dev/null
@@ -1,578 +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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#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
-};
diff --git a/dlls/ddraw/ddraw_main.c b/dlls/ddraw/ddraw_main.c
deleted file mode 100644
index 4ec8be3..0000000
--- a/dlls/ddraw/ddraw_main.c
+++ /dev/null
@@ -1,1787 +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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
-
-#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 "opengl_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 isurf = ICOM_INTERFACE(surf, IDirectDrawSurface7);
-	    DDSURFACEDESC2 desc;
-
-	    if (TRACE_ON(ddraw)) {
-		TRACE("  => enumerating surface %p (priv. %p) with description:\n", isurf, surf);
-		DDRAW_dump_surface_desc(&surf->surface_desc);
-	    }
-
-	    IDirectDrawSurface7_AddRef(isurf);
-
-	    desc = surf->surface_desc;
-	    if (callback(isurf, &desc, context)	== DDENUMRET_CANCEL)
-		break;
-	}
-    }
-    TRACE(" end of enumeration.\n");
-    
-    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 (TRACE_ON(ddraw)) {
-	TRACE(" flags: "); DDRAW_dump_DDENUMSURFACES(dwFlags);
-    }
-    
-    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)->(%p,%p)\n", This, 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 = This->fake_vblank;
-    This->fake_vblank = !This->fake_vblank;
-    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)->(%p,%08lx)\n",This,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.
-     * This seems to be true at least for DDSCL_SETFOCUSWINDOW
-     * It looks like Windows doesn't store the HWND in all cases,
-     * probably if DDSCL_NORMAL is specified, but that's not sure
-    if (This->window)
-	return DDERR_HWNDALREADYSET;
-    */
-
-    /* DDSCL_EXCLUSIVE or DDSCL_NORMAL or DDSCL_SETFOCUSWINDOW must be given */
-    if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW)))
-    {
-        ERR("(%p) : Call to SetCooperativeLevel failed: cooplevel  != DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This);
-        return DDERR_INVALIDPARAMS;
-    }
-    /* Device window and focus Window. They only really matter in a
-     * Multi-Monitor application, but some games specify them and we
-     * have to react correctly. */
-    if(cooplevel & DDSCL_SETFOCUSWINDOW)
-    {
-        /* This flag is a biest: It is only valid when DDSCL_NORMAL has been set
-         * or no hwnd is set and no other flags are allowed, except DDSCL_NOWINDOWCHANGES
-         */
-        if(This->window)
-            if(!(This->cooperative_level & DDSCL_NORMAL))
-            {
-                ERR("(%p) : Call to SetCooperativeLevel failed: DDSCL_SETFOCUSWINDOW may not be used in Cooplevel %08lx, returning DDERR_HWNDALREADYSET\n",
-                            This, This->cooperative_level);
-                return DDERR_HWNDALREADYSET;
-            }
-        if((cooplevel != DDSCL_SETFOCUSWINDOW))
-            if(cooplevel != (DDSCL_SETFOCUSWINDOW | DDSCL_NOWINDOWCHANGES) )
-            {
-                ERR("(%p) : Call to SetCooperativeLevel failed: Invalid use of DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This);
-                return DDERR_INVALIDPARAMS;
-            }
-
-        /* Don't know what exactly to do, but it's perfectly valid
-         * to pass DDSCL_SETFOCUSWINDOW only */
-        FIXME("(%p) : Poorly handled flag DDSCL_SETFOCUSWINDOW\n", This);
-
-        /* Store the flag in the cooperative level. I don't think that all other
-         * flags should be overwritten, so just add it 
-         * (In the most cases this will be DDSCL_SETFOCUSWINDOW | DDSCL_NORMAL) */
-        cooplevel |= DDSCL_SETFOCUSWINDOW;
-
-        return DD_OK;
-    }
-
-    /* DDSCL_EXCLUSE mode requires  DDSCL_FULLSCREEN and vice versa */
-    if((cooplevel & DDSCL_EXCLUSIVE) && !(cooplevel & DDSCL_FULLSCREEN))
-        return DDERR_INVALIDPARAMS;
-    /* The other case is checked above */
-
-    /* Unhandled flags. Give a warning */
-    if(cooplevel & DDSCL_SETDEVICEWINDOW)
-        FIXME("(%p) : Unhandled flag DDSCL_SETDEVICEWINDOW.\n", This);
-    if(cooplevel & DDSCL_CREATEDEVICEWINDOW)
-        FIXME("(%p) : Unhandled flag DDSCL_CREATEDEVICEWINDOW.\n", This);
-
-    /* Perhaps the hwnd is only set in DDSCL_EXLUSIVE and DDSCL_FULLSCREEN mode. Not sure */
-    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
-};
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index a35ba6b..66ce166 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,54 +30,57 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "ddraw.h"
-#include "d3d.h"
-#include "ddcomimpl.h"
 #include "ddrawi.h"
+#include "d3d.h"
 
-/* XXX Put this somewhere proper. */
-#define DD_STRUCT_INIT(x)			\
-	do {					\
-		memset((x), 0, sizeof(*(x)));	\
-		(x)->dwSize = sizeof(*x);	\
-	} while (0)
+#include "ddcomimpl.h"
 
-#define DD_STRUCT_COPY_BYSIZE(to,from)			\
-	do {						\
-	    	DWORD __size = (to)->dwSize;		\
-	    	DWORD __copysize = __size;		\
-	    	DWORD __resetsize = __size;		\
-		assert(to != from);                     \
-	        if (__resetsize > sizeof(*to))		\
-		    __resetsize = sizeof(*to);		\
-	    	memset(to,0,__resetsize);               \
-	        if ((from)->dwSize < __size) 		\
-		    __copysize = (from)->dwSize;	\
-		memcpy(to,from,__copysize);		\
-		(to)->dwSize = __size;/*restore size*/	\
-	} while (0)
+#include "wine/wined3d_interface.h"
 
-#define MAKE_FOURCC(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 24))
+/*****************************************************************************
+ * IParent - a helper interface
+ *****************************************************************************/
+DEFINE_GUID(IID_IParent, 0xc20e4c88, 0x74e7, 0x4940, 0xba, 0x9f, 0x2e, 0x32, 0x3f, 0x9d, 0xc9, 0x81);
+typedef struct IParent *LPPARENT, *PPARENT;
+
+#define INTERFACE IParent
+DECLARE_INTERFACE_(IParent,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IParent_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IParent_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IParent_Release(p)            (p)->lpVtbl->Release(p)
+#endif
+
+
+/* Typdef the interfaces */
+typedef struct IDirectDrawImpl            IDirectDrawImpl;
+typedef struct IDirectDrawSurfaceImpl     IDirectDrawSurfaceImpl;
+typedef struct IDirectDrawClipperImpl     IDirectDrawClipperImpl;
+typedef struct IDirectDrawPaletteImpl     IDirectDrawPaletteImpl;
+typedef struct IDirect3DDeviceImpl        IDirect3DDeviceImpl;
+typedef struct IDirect3DLightImpl         IDirect3DLightImpl;
+typedef struct IDirect3DViewportImpl      IDirect3DViewportImpl;
+typedef struct IDirect3DMaterialImpl      IDirect3DMaterialImpl;
+typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
+typedef struct IDirect3DVertexBufferImpl  IDirect3DVertexBufferImpl;
+typedef struct IParentImpl                IParentImpl;
 
 /*****************************************************************************
  * IDirectDraw implementation structure
- */
-
-typedef struct IDirectDrawImpl IDirectDrawImpl;
-typedef struct IDirectDrawPaletteImpl IDirectDrawPaletteImpl;
-typedef struct IDirectDrawClipperImpl IDirectDrawClipperImpl;
-typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl;
-typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
-
-typedef void (*pixel_convert_func)(void *src, void *dst, DWORD width,
-				   DWORD height, LONG pitch,
-				   IDirectDrawPaletteImpl *palette);
-
-typedef void (*palette_convert_func)(LPPALETTEENTRY palent,
-				     void *screen_palette, DWORD start,
-				     DWORD count);
+ *****************************************************************************/
 
 struct IDirectDrawImpl
 {
+    /* IUnknown fields */
     ICOM_VFIELD_MULTI(IDirectDraw7);
     ICOM_VFIELD_MULTI(IDirectDraw4);
     ICOM_VFIELD_MULTI(IDirectDraw2);
@@ -87,144 +90,256 @@
     ICOM_VFIELD_MULTI(IDirect3D2);
     ICOM_VFIELD_MULTI(IDirect3D);
 
-    LONG ref;
+    LONG              ref;
 
-    /* TRUE if created via DirectDrawCreateEx or CoCreateInstance,
-     * FALSE if created via DirectDrawCreate. */
-    BOOL ex;
+    /* WineD3D linkage */
+    IWineD3D                *wineD3D;
+    IWineD3DDevice          *wineD3DDevice;
+    IDirectDrawSurfaceImpl  *DepthStencilBuffer;
+    BOOL                    d3d_initialized;
 
-    /* Linked list of surfaces, joined by next_ddraw in IDirectSurfaceImpl. */
-    IDirectDrawSurfaceImpl* surfaces;
-    /* Linked list of palettes, joined by next_ddraw. */
-    IDirectDrawPaletteImpl* palettes;
-    /* Linked list of clippers, joined by next_ddraw. */
-    IDirectDrawClipperImpl* clippers;
+    /* misc ddraw fields */
+    UINT                    total_vidmem;
+    DWORD                   cur_scanline;
+    BOOL                    fake_vblank;
+    BOOL                    initialized;
 
-    IDirectDrawSurfaceImpl* primary_surface;
+    /* DirectDraw things, which are not handled by WineD3D */
+    DWORD                   cooperative_level;
 
-    DDRAWI_DIRECTDRAW_LCL local;
-    DDCAPS caps;
+    DWORD                   orig_width, orig_height;
+    DWORD                   orig_bpp;
 
-    HWND window;
-    DWORD cooperative_level;
-    WNDPROC original_wndproc;
+    DDCAPS                  caps;
 
-    DWORD width, height;
-    LONG pitch;
-    DDPIXELFORMAT pixelformat;
-    DWORD cur_scanline;
+    LONG                    style;
+    LONG                    exStyle;
 
-    BOOL fake_vblank;
-    
-    /* Should each of these go into some structure? */
-    DWORD orig_width, orig_height;
-    LONG orig_pitch;
-    DDPIXELFORMAT orig_pixelformat;
+    /* D3D things */
+    IDirectDrawSurfaceImpl  *d3d_target;
+    HWND                    d3d_window;
+    IDirect3DDeviceImpl     *d3ddevice;
 
-    /* Called when the refcount goes to 0. */
-    void (*final_release)(IDirectDrawImpl *This);
+    /* Varios HWNDs */
+    HWND                    focuswindow;
+    HWND                    devicewindow;
 
-    HRESULT (*set_exclusive_mode)(IDirectDrawImpl *This, DWORD dwExcl);
+    /* The surface type to request */
+    WINED3DSURFTYPE ImplType;
 
-    HRESULT (*create_palette)(IDirectDrawImpl* This, DWORD dwFlags,
-			      LPDIRECTDRAWPALETTE* ppPalette,
-			      LPUNKNOWN pUnkOuter);
+    /* The surface list - can't relay this to WineD3D
+     * because of IParent
+     */
+    IDirectDrawSurfaceImpl *surface_list;
 
-    /* Surface creation functions. For all of these, pOuter == NULL. */
+    /* Our private window class */
+    char classname[32];
+    WNDCLASSA wnd_class;
 
-    /* Do not create any backbuffers or the flipping chain. */
-    HRESULT (*create_primary)(IDirectDrawImpl* This,
-			      const DDSURFACEDESC2* pDDSD,
-			      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);
+    /* Helpers for surface creation */
+    IDirectDrawSurfaceImpl *tex_root;
+    BOOL                    depthstencil;
 
-    /* Primary may be NULL if we are creating an unattached backbuffer. */
-    HRESULT (*create_backbuffer)(IDirectDrawImpl* This,
-				 const DDSURFACEDESC2* pDDSD,
-				 LPDIRECTDRAWSURFACE7* ppSurf,
-				 LPUNKNOWN pOuter,
-				 IDirectDrawSurfaceImpl* primary);
+    /* For the dll unload cleanup code */
+    IDirectDrawImpl *next;
+    BOOL DoNotDestroy;
+    LONG surfaces;
+};
 
-    /* shiny happy offscreenplain surfaces */
-    HRESULT (*create_offscreen)(IDirectDrawImpl* This,
-				const DDSURFACEDESC2* pDDSD,
-				LPDIRECTDRAWSURFACE7* ppSurf,
-				LPUNKNOWN pOuter);
+/* Declare the VTables. They can be found ddraw.c */
+const IDirectDraw7Vtbl IDirectDraw7_Vtbl;
+const IDirectDraw4Vtbl IDirectDraw4_Vtbl;
+const IDirectDraw2Vtbl IDirectDraw2_Vtbl;
+const IDirectDrawVtbl  IDirectDraw1_Vtbl;
 
-    /* dwMipMapLevel is specified as per OpenGL. (i.e. 0 is base) */
-    HRESULT (*create_texture)(IDirectDrawImpl* This,
-			      const DDSURFACEDESC2* pDDSD,
-			      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,
-			      DWORD dwMipMapLevel);
+/* Helper structures */
+typedef struct EnumDisplayModesCBS
+{
+    void *context;
+    LPDDENUMMODESCALLBACK2 callback;
+} EnumDisplayModesCBS;
 
-    HRESULT (*create_zbuffer)(IDirectDrawImpl* This,
-			      const DDSURFACEDESC2* pDDSD,
-			      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);
+typedef struct EnumSurfacesCBS
+{
+    void *context;
+    LPDDENUMSURFACESCALLBACK7 callback;
+    LPDDSURFACEDESC2 pDDSD;
+    DWORD Flags;
+} EnumSurfacesCBS;
 
-    LPVOID	private;
+/* Utility functions */
+void
+DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn,
+                             DDSCAPS2* pOut);
+void
+DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn,
+                                        DDDEVICEIDENTIFIER* pOut);
+void
+IDirectDrawImpl_Destroy(IDirectDrawImpl *This);
 
-    /* Everything below here is still questionable. */
+HRESULT WINAPI
+IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
+                                         DDSURFACEDESC2 *desc,
+                                         void *Context);
+/* The cleanup list */
+extern IDirectDrawImpl *ddraw_list;
 
-    DDPIXELFORMAT screen_pixelformat;
+/* The default surface type */
+extern WINED3DSURFTYPE DefaultSurfaceType;
 
-    int           pixmap_depth;
-    pixel_convert_func pixel_convert;
-    palette_convert_func palette_convert;
+/*****************************************************************************
+ * IDirectDrawSurface implementation structure
+ *****************************************************************************/
 
-    /* Use to fool some too strict games */
-    INT32 (*allocate_memory)(IDirectDrawImpl *This, DWORD mem);
-    void (*free_memory)(IDirectDrawImpl *This, DWORD mem);
-    DWORD total_vidmem, available_vidmem;
-    
-    /* IDirect3D fields */
-    LPVOID d3d_private;
+struct IDirectDrawSurfaceImpl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD_MULTI(IDirectDrawSurface7);
+    ICOM_VFIELD_MULTI(IDirectDrawSurface3);
+    ICOM_VFIELD_MULTI(IDirectDrawGammaControl);
+    ICOM_VFIELD_MULTI(IDirect3DTexture2);
+    ICOM_VFIELD_MULTI(IDirect3DTexture);
 
-    /* Used as a callback function to create a texture */
-    HRESULT (*d3d_create_texture)(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main);
+    LONG                     ref;
 
-    /* Used as a callback for Devices to tell to the D3D object it's been created */
-    HRESULT (*d3d_added_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device);
-    HRESULT (*d3d_removed_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device);
+    int                     version;
 
-    /* This is needed for delayed texture creation and Z buffer blits */
-    IDirect3DDeviceImpl *current_device;
+    /* Connections to other Objects */
+    IDirectDrawImpl         *ddraw;
+    IWineD3DSurface         *WineD3DSurface;
+    IWineD3DTexture         *wineD3DTexture;
 
-    /* This is for the fake mainWindow */
-    ATOM	winclass;
-    PAINTSTRUCT	ps;
-    BOOL	paintable;
+    /* This implementation handles attaching surfaces to other surfaces */
+    IDirectDrawSurfaceImpl  *next_attached;
+    IDirectDrawSurfaceImpl  *first_attached;
+    IDirectDrawSurfaceImpl  *next_complex;
+    IDirectDrawSurfaceImpl  *first_complex;
+
+    /* Surface description, for GetAttachedSurface */
+    DDSURFACEDESC2          surface_desc;
+
+    /* Misc things */
+    DWORD                   uniqueness_value;
+    UINT                    mipmap_level;
+    WINED3DSURFTYPE         ImplType;
+
+    /* For D3DDevice creation */
+    BOOL                    isRenderTarget;
+
+    /* Clipper objects */
+    IDirectDrawClipperImpl  *clipper;
+
+    /* For the ddraw surface list */
+    IDirectDrawSurfaceImpl *next;
+    IDirectDrawSurfaceImpl *prev;
+};
+
+/* VTable declaration. It's located in surface.c / surface_thunks.c */
+const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl;
+const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl;
+const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl;
+const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl;
+const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl;
+
+/* Get the number of bytes per pixel for a given surface */
+#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8))
+#define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
+
+/*****************************************************************************
+ * IParent Implementation
+ *****************************************************************************/
+struct IParentImpl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD_MULTI(IParent);
+    LONG                    ref;
+
+    /* IParentImpl fields */
+    IUnknown      *child;
+
+};
+
+const IParentVtbl IParent_Vtbl;
+
+/*****************************************************************************
+ * IDirect3DDevice implementation
+ *****************************************************************************/
+struct IDirect3DDeviceImpl
+{
+    /* IUnknown */
+    ICOM_VFIELD_MULTI(IDirect3DDevice7);
+    ICOM_VFIELD_MULTI(IDirect3DDevice3);
+    ICOM_VFIELD_MULTI(IDirect3DDevice2);
+    ICOM_VFIELD_MULTI(IDirect3DDevice);
+    LONG                    ref;
+
+    /* Other object connections */
+    IWineD3DDevice          *wineD3DDevice;
+    IDirectDrawImpl         *ddraw;
+    IWineD3DIndexBuffer     *indexbuffer;
+    IDirectDrawSurfaceImpl  *target;
+    BOOL                    OffScreenTarget;
+
+    /* Viewport management */
+    IDirect3DViewportImpl *viewport_list;
+    IDirect3DViewportImpl *current_viewport;
+    D3DVIEWPORT7 active_viewport;
+
+    /* Light state */
+    DWORD material;
+
+    /* Rendering functions to wrap D3D(1-3) to D3D7 */
+    D3DPRIMITIVETYPE primitive_type;
+    DWORD vertex_type;
+    DWORD render_flags;
+    DWORD nb_vertices;
+    LPBYTE vertex_buffer;
+    DWORD vertex_size;
+    DWORD buffer_size;
+};
+
+/* Vtables in various versions */
+const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl;
+const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl;
+const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl;
+const IDirect3DDeviceVtbl  IDirect3DDevice1_Vtbl;
+
+/* The IID */
+const GUID IID_D3DDEVICE_WineD3D;
+
+/* Helper functions */
+HRESULT IDirect3DImpl_GetCaps(IWineD3D *WineD3D, D3DDEVICEDESC *Desc123, D3DDEVICEDESC7 *Desc7);
+
+/* Structures */
+struct EnumTextureFormatsCBS
+{
+    LPD3DENUMTEXTUREFORMATSCALLBACK cbv2;
+    LPD3DENUMPIXELFORMATSCALLBACK cbv7;
+    void *Context;
 };
 
 /*****************************************************************************
- * IDirectDrawPalette implementation structure
- */
-struct IDirectDrawPaletteImpl
+ * IDirect3D implementation
+ *****************************************************************************/
+
+/* No implementation structure as this is only another interface to DirectDraw */
+
+/* the Vtables */
+const IDirect3DVtbl  IDirect3D1_Vtbl;
+const IDirect3D2Vtbl IDirect3D2_Vtbl;
+const IDirect3D3Vtbl IDirect3D3_Vtbl;
+const IDirect3D7Vtbl IDirect3D7_Vtbl;
+
+/* Structure for EnumZBufferFormats */
+struct EnumZBufferFormatsData
 {
-    /* IUnknown fields */
-    ICOM_VFIELD_MULTI(IDirectDrawPalette);
-    LONG ref;
-
-    DDRAWI_DDRAWPALETTE_LCL local;
-    DDRAWI_DDRAWPALETTE_GBL global;
-
-    /* IDirectDrawPalette fields */
-    HPALETTE		hpal;
-    WORD		palVersion, palNumEntries; /* LOGPALETTE */
-    PALETTEENTRY	palents[256];
-    /* This is to store the palette in 'screen format' */
-    int			screen_palents[256];
-
-    VOID (*final_release)(IDirectDrawPaletteImpl* This);
-
-    IDirectDrawImpl* ddraw_owner;
-    IDirectDrawPaletteImpl* prev_ddraw;
-    IDirectDrawPaletteImpl* next_ddraw;
-
-    LPVOID		private;
+    LPD3DENUMPIXELFORMATSCALLBACK Callback;
+    void *Context;
 };
 
 /*****************************************************************************
  * IDirectDrawClipper implementation structure
- */
+ *****************************************************************************/
 struct IDirectDrawClipperImpl
 {
     /* IUnknown fields */
@@ -235,191 +350,235 @@
     HWND hWnd;
 
     IDirectDrawImpl* ddraw_owner;
-    IDirectDrawClipperImpl* prev_ddraw;
-    IDirectDrawClipperImpl* next_ddraw;
+    struct IDirectDrawClipperImpl* prev_ddraw;
+    struct IDirectDrawClipperImpl* next_ddraw;
 };
 
-/*****************************************************************************
- * IDirectDrawSurface implementation structure
- */
+const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl;
 
-struct IDirectDrawSurfaceImpl
+/*****************************************************************************
+ * IDirectDrawPalette implementation structure
+ *****************************************************************************/
+struct IDirectDrawPaletteImpl
 {
     /* IUnknown fields */
-    ICOM_VFIELD_MULTI(IDirectDrawSurface7);
-    ICOM_VFIELD_MULTI(IDirectDrawSurface3);
-    ICOM_VFIELD_MULTI(IDirectDrawGammaControl);
-    ICOM_VFIELD_MULTI(IDirect3DTexture2);
-    ICOM_VFIELD_MULTI(IDirect3DTexture);
+    ICOM_VFIELD_MULTI(IDirectDrawPalette);
     LONG ref;
 
-    struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */
+    /* WineD3D uplink */
+    IWineD3DPalette           *wineD3DPalette;
 
-    struct IDirectDrawSurfaceImpl* next_ddraw; /* ddraw surface chain */
-    struct IDirectDrawSurfaceImpl* prev_ddraw;
-    struct IDirectDrawSurfaceImpl* next_attached; /* attached surface chain */
-    struct IDirectDrawSurfaceImpl* prev_attached;
+    /* IDirectDrawPalette fields */
+    IDirectDrawImpl           *ddraw_owner;
+};
+const IDirectDrawPaletteVtbl IDirectDrawPalette_Vtbl;
 
-    IDirectDrawImpl* ddraw_owner;
-    IDirectDrawSurfaceImpl* surface_owner;
+/******************************************************************************
+ * DirectDraw ClassFactory Implementation - incomplete
+ ******************************************************************************/
+typedef struct
+{
+    ICOM_VFIELD_MULTI(IClassFactory);
 
-    IDirectDrawPaletteImpl* palette; /* strong ref */
-    IDirectDrawClipperImpl* clipper; /* strong ref */
+    LONG ref;
+    HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj);
+} IClassFactoryImpl;
 
-    DDRAWI_DDRAWSURFACE_LCL local;
-    DDRAWI_DDRAWSURFACE_MORE more;
-    /* FIXME: since Flip should swap the GBL structures, they should
-     * probably not be embedded into the IDirectDrawSurfaceImpl structure... */
-    LPDDRAWI_DDRAWSURFACE_GBL_MORE gmore;
-    DDRAWI_DDRAWSURFACE_GBL global;
-    DDRAWI_DDRAWSURFACE_GBL_MORE global_more;
-
-    DDSURFACEDESC2 surface_desc;
-
-    HDC hDC;
-    RECT lastlockrect;
-    DWORD lastlocktype;
-    BOOL dc_in_use;
-    BOOL locked;
-
-    HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src,
-				 LPDIRECTDRAWSURFACE7* dst);
-    void (*final_release)(IDirectDrawSurfaceImpl *This);
-    HRESULT (*late_allocate)(IDirectDrawSurfaceImpl *This);
-    BOOL (*attach)(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *to);
-    BOOL (*detach)(IDirectDrawSurfaceImpl *This);
-    void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
-    void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
-    void (*lose_surface)(IDirectDrawSurfaceImpl* This);
-    BOOL (*flip_data)(IDirectDrawSurfaceImpl* front,
-		      IDirectDrawSurfaceImpl* back,
-		      DWORD dwFlags);
-    void (*flip_update)(IDirectDrawSurfaceImpl* front, DWORD dwFlags);
-    HRESULT (*get_dc)(IDirectDrawSurfaceImpl* This, HDC* phDC);
-    HRESULT (*release_dc)(IDirectDrawSurfaceImpl* This, HDC hDC);
-    void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal);
-    void (*update_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal,
-			   DWORD dwStart, DWORD dwCount, LPPALETTEENTRY palent);
-    HWND (*get_display_window)(IDirectDrawSurfaceImpl *This);
-    HRESULT (*get_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp);
-    HRESULT (*set_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp);
-
-    struct PrivateData* private_data;
-
-    DWORD max_lod;
-    DWORD priority;
-
-    BOOL lost;
-
-    DWORD uniqueness_value;
-
-    LPVOID private;
-
-    /* Everything below here is dodgy. */
-    /* For Direct3D use */
-    LPVOID aux_ctx, aux_data;
-    void (*aux_release)(LPVOID ctx, LPVOID data);
-    BOOL (*aux_flip)(LPVOID ctx, LPVOID data);
-    void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);
-    HRESULT (*aux_blt)(struct IDirectDrawSurfaceImpl *This, LPRECT rdst, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD dwFlags, LPDDBLTFX lpbltfx);
-    HRESULT (*aux_bltfast)(struct IDirectDrawSurfaceImpl *This, DWORD dstx, DWORD dsty, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD trans);
-    HRESULT (*aux_setcolorkey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey );
-    /* This is to get the D3DDevice object associated to this surface */
-    struct IDirect3DDeviceImpl *d3ddevice;
-    /* This is for texture */
-    IDirectDrawSurfaceImpl *mip_main;
-    int mipmap_level;
-    LPVOID tex_private;
-    void (*lock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
-    void (*unlock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
-    BOOLEAN (*get_dirty_status)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
+/* Helper structures */
+struct object_creation_info
+{
+    const CLSID *clsid;
+    HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid,
+                                 void **ppObj);
 };
 
+/******************************************************************************
+ * IDirect3DLight implementation structure - Wraps to D3D7
+ ******************************************************************************/
+struct IDirect3DLightImpl
+{
+    ICOM_VFIELD_MULTI(IDirect3DLight);
+    LONG ref;
+
+    /* IDirect3DLight fields */
+    IDirectDrawImpl           *ddraw;
+
+    /* If this light is active for one viewport, put the viewport here */
+    IDirect3DViewportImpl     *active_viewport;
+
+    D3DLIGHT2 light;
+    D3DLIGHT7 light7;
+
+    DWORD dwLightIndex;
+
+    /* Chained list used for adding / removing from viewports */
+    IDirect3DLightImpl        *next;
+
+    /* Activation function */
+    void                      (*activate)(IDirect3DLightImpl*);
+    void                      (*desactivate)(IDirect3DLightImpl*);
+    void                      (*update)(IDirect3DLightImpl*);
+};
+
+/* Vtable */
+const IDirect3DLightVtbl IDirect3DLight_Vtbl;
+
+/* Helper functions */
+void light_update(IDirect3DLightImpl* This);
+void light_activate(IDirect3DLightImpl* This);
+void light_desactivate(IDirect3DLightImpl* This);
+
+/******************************************************************************
+ * IDirect3DMaterial implementation structure - Wraps to D3D7
+ ******************************************************************************/
+struct IDirect3DMaterialImpl
+{
+    ICOM_VFIELD_MULTI(IDirect3DMaterial3);
+    ICOM_VFIELD_MULTI(IDirect3DMaterial2);
+    ICOM_VFIELD_MULTI(IDirect3DMaterial);
+    LONG  ref;
+
+    /* IDirect3DMaterial2 fields */
+    IDirectDrawImpl               *ddraw;
+    IDirect3DDeviceImpl           *active_device;
+
+    D3DMATERIAL mat;
+
+    void (*activate)(IDirect3DMaterialImpl* this);
+};
+
+/* VTables in varios versions */
+const IDirect3DMaterialVtbl IDirect3DMaterial_Vtbl;
+const IDirect3DMaterial2Vtbl IDirect3DMaterial2_Vtbl;
+const IDirect3DMaterial3Vtbl IDirect3DMaterial3_Vtbl;
+
+/* Helper functions */
+void material_activate(IDirect3DMaterialImpl* This);
+
 /*****************************************************************************
- * Driver initialisation functions.
- */
-BOOL DDRAW_HAL_Init(HINSTANCE, DWORD, LPVOID);
-BOOL DDRAW_User_Init(HINSTANCE, DWORD, LPVOID);
+ * IDirect3DViewport - Wraps to D3D7
+ *****************************************************************************/
+struct IDirect3DViewportImpl
+{
+    ICOM_VFIELD_MULTI(IDirect3DViewport3);
+    LONG ref;
 
-typedef struct {
-    const DDDEVICEIDENTIFIER2* info;
-    int	preference;	/* how good we are. dga might get 100, xlib 50*/
-    HRESULT (*create)(const GUID*, LPDIRECTDRAW7*, LPUNKNOWN, BOOL ex);
+    /* IDirect3DViewport fields */
+    IDirectDrawImpl           *ddraw;
 
-    /* For IDirectDraw7::Initialize. */
-    HRESULT (*init)(IDirectDrawImpl *, const GUID*);
-} ddraw_driver;
+    /* If this viewport is active for one device, put the device here */
+    IDirect3DDeviceImpl       *active_device;
 
-void DDRAW_register_driver(const ddraw_driver*);
+    DWORD                     num_lights;
+    DWORD                     map_lights;
 
-const ddraw_driver* DDRAW_FindDriver(const GUID* guid);
+    int                       use_vp2;
 
-/******************************************************************************
- * Random utilities
- */
+    union
+    {
+        D3DVIEWPORT vp1;
+        D3DVIEWPORT2 vp2;
+    } viewports;
 
-/* Get DDSCAPS of surface (shortcutmacro) */
-#define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
-/* Get the number of bytes per pixel for a given surface */
-#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.u1.dwRGBBitCount+7)/8))
-#define GET_BPP(desc) PFGET_BPP(desc.u4.ddpfPixelFormat)
+    /* Activation function */
+    void                      (*activate)(IDirect3DViewportImpl*);
 
-LONG DDRAW_width_bpp_to_pitch(DWORD width, DWORD bpp);
+    /* Field used to chain viewports together */
+    IDirect3DViewportImpl     *next;
 
-typedef struct {
-    unsigned short	bpp,depth;
-    unsigned int	rmask,gmask,bmask;
-} ConvertMode;
+    /* Lights list */
+    IDirect3DLightImpl        *lights;
 
-typedef struct {
-    void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
-    void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
-} ConvertFuncs;
+    /* Background material */
+    IDirect3DMaterialImpl     *background;
+};
 
-typedef struct {
-    ConvertMode screen, dest;
-    ConvertFuncs funcs;
-} Convert;
+/* Vtable */
+const IDirect3DViewport3Vtbl IDirect3DViewport3_Vtbl;
 
-extern Convert ModeEmulations[8];
-extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw);
-extern BOOL opengl_initialized;
-extern BOOL s3tc_initialized;
+/* Helper functions */
+void viewport_activate(IDirect3DViewportImpl* This);
 
-typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT1)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
-typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT3)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
-typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT5)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
+/*****************************************************************************
+ * IDirect3DExecuteBuffer - Wraps to D3D7
+ *****************************************************************************/
+struct IDirect3DExecuteBufferImpl
+{
+    /* IUnknown */
+    ICOM_VFIELD_MULTI(IDirect3DExecuteBuffer);
+    LONG                 ref;
 
-extern FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1;
-extern FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3;
-extern FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5;
+    /* IDirect3DExecuteBuffer fields */
+    IDirectDrawImpl      *ddraw;
+    IDirect3DDeviceImpl  *d3ddev;
 
-/******************************************************************************
- * Structure conversion (for thunks)
- */
-void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut);
-void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn,
-					     DDDEVICEIDENTIFIER* pOut);
+    D3DEXECUTEBUFFERDESC desc;
+    D3DEXECUTEDATA       data;
 
-/******************************************************************************
- * Debugging / Flags output functions
- */
-extern void DDRAW_dump_DDBLTFX(DWORD flagmask);
-extern void DDRAW_dump_DDBLTFAST(DWORD flagmask);
-extern void DDRAW_dump_DDBLT(DWORD flagmask);
-extern void DDRAW_dump_DDSCAPS(const DDSCAPS *in);
-extern void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in);
-extern void DDRAW_dump_pixelformat_flag(DWORD flagmask);
-extern void DDRAW_dump_paletteformat(DWORD dwFlags);
-extern void DDRAW_dump_pixelformat(const DDPIXELFORMAT *in);
-extern void DDRAW_dump_colorkeyflag(DWORD ck);
-extern void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd);
-extern void DDRAW_dump_cooperativelevel(DWORD cooplevel);
-extern void DDRAW_dump_lockflag(DWORD lockflag);
-extern void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *in);
-extern void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps);
-extern void DDRAW_dump_DDENUMSURFACES(DWORD flagmask);
-extern void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale) ;
+    /* This buffer will store the transformed vertices */
+    void                 *vertex_data;
+    WORD                 *indices;
+    int                  nb_indices;
+
+    /* This flags is set to TRUE if we allocated ourselves the
+     * data buffer
+     */
+    BOOL                 need_free;
+};
+
+/* The VTable */
+const IDirect3DExecuteBufferVtbl IDirect3DExecuteBuffer_Vtbl;
+
+/* The execute function */
+void
+IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
+                                   IDirect3DDeviceImpl *Device,
+                                   IDirect3DViewportImpl *ViewportImpl);
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer
+ *****************************************************************************/
+struct IDirect3DVertexBufferImpl
+{
+    /*** IUnknown Methods ***/
+    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer7);
+    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer);
+    LONG                 ref;
+
+    /*** WineD3D link ***/
+    IWineD3DVertexBuffer *wineD3DVertexBuffer;
+
+    /*** Storage for D3D7 specific things ***/
+    DWORD                Caps;
+};
+
+/* The Vtables */
+const IDirect3DVertexBuffer7Vtbl IDirect3DVertexBuffer7_Vtbl;
+const IDirect3DVertexBufferVtbl IDirect3DVertexBuffer1_Vtbl;
+
+/*****************************************************************************
+ * Helper functions from utils.c
+ *****************************************************************************/
+
+#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \
+    (((d3dvtVertexType) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
+
+#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
+    (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
+
+void PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, WINED3DFORMAT WineD3DFormat);
+WINED3DFORMAT PixelFormat_DD2WineD3D(DDPIXELFORMAT *DDPixelFormat);
+void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd);
+void DDRAW_dump_pixelformat(const DDPIXELFORMAT *PixelFormat);
+void dump_D3DMATRIX(D3DMATRIX *mat);
+void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps);
+DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
+void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in);
+void DDRAW_dump_cooperativelevel(DWORD cooplevel);
+
+/* This only needs to be here as long the processvertices functionality of
+ * IDirect3DExecuteBuffer isn't in WineD3D */
+void multiply_matrix(LPD3DMATRIX dest, LPD3DMATRIX src1, LPD3DMATRIX src2);
 
 /* Used for generic dumping */
 typedef struct
@@ -438,701 +597,26 @@
     ptrdiff_t offset;
 } member_info;
 
+/* Structure copy */
 #define DDRAW_dump_flags(flags,names,num_names) DDRAW_dump_flags_(flags, names, num_names, 1)
 #define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) }
 
-extern void DDRAW_dump_flags_(DWORD flags, const flag_info* names, size_t num_names, int newline);
-extern void DDRAW_dump_members(DWORD flags, const void* data, const member_info* mems, size_t num_mems);
+#define DD_STRUCT_COPY_BYSIZE(to,from)                  \
+        do {                                            \
+                DWORD __size = (to)->dwSize;            \
+                DWORD __copysize = __size;              \
+                DWORD __resetsize = __size;             \
+                assert(to != from);                     \
+                if (__resetsize > sizeof(*to))          \
+                    __resetsize = sizeof(*to);          \
+                memset(to,0,__resetsize);               \
+                if ((from)->dwSize < __size)            \
+                    __copysize = (from)->dwSize;        \
+                memcpy(to,from,__copysize);             \
+                (to)->dwSize = __size;/*restore size*/  \
+        } while (0)
 
-void DirectDrawSurface_RegisterClass(void);
-void DirectDrawSurface_UnregisterClass(void);
 
-extern const IDirectDrawSurface3Vtbl DDRAW_IDDS3_Thunk_VTable;
+#endif
 
-/*****************************************************************************
- * IDirectDrawClipper declarations
- */
-HRESULT DDRAW_CreateClipper(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppObj);
-void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This);
-
-HRESULT WINAPI
-Main_DirectDrawClipper_SetHwnd(LPDIRECTDRAWCLIPPER iface, DWORD dwFlags,
-			       HWND hWnd);
-ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface);
-HRESULT WINAPI
-Main_DirectDrawClipper_GetClipList(LPDIRECTDRAWCLIPPER iface, LPRECT lpRect,
-				   LPRGNDATA lpClipList, LPDWORD lpdwSize);
-HRESULT WINAPI
-Main_DirectDrawClipper_SetClipList(LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,
-				   DWORD dwFlag);
-HRESULT WINAPI
-Main_DirectDrawClipper_QueryInterface(LPDIRECTDRAWCLIPPER iface, REFIID riid,
-				      LPVOID* ppvObj);
-ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface );
-HRESULT WINAPI
-Main_DirectDrawClipper_GetHWnd(LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr);
-HRESULT WINAPI
-Main_DirectDrawClipper_Initialize(LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD,
-				  DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawClipper_IsClipListChanged(LPDIRECTDRAWCLIPPER iface,
-					 BOOL* lpbChanged);
-
-/*****************************************************************************
- * IDirectDrawPalette MAIN declarations
- */
-HRESULT Main_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
-					 IDirectDrawImpl* pDD, DWORD dwFlags);
-void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This);
-
-HRESULT Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
-				      LPDIRECTDRAWPALETTE* ppPalette,
-				      LPUNKNOWN pUnkOuter);
-void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This);
-
-DWORD Main_DirectDrawPalette_Size(DWORD dwFlags);
-
-HRESULT WINAPI
-Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				  DWORD dwStart, DWORD dwCount,
-				  LPPALETTEENTRY palent);
-HRESULT WINAPI
-Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				  DWORD dwStart, DWORD dwCount,
-				  LPPALETTEENTRY palent);
-ULONG WINAPI
-Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface);
-ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface);
-HRESULT WINAPI
-Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface,
-				  LPDIRECTDRAW ddraw, DWORD dwFlags,
-				  LPPALETTEENTRY palent);
-HRESULT WINAPI
-Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps);
-HRESULT WINAPI
-Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface,
-				      REFIID refiid, LPVOID *obj);
-
-/*****************************************************************************
- * IDirectDrawPalette HAL declarations
- */
-HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
-					 IDirectDrawImpl* pDD, DWORD dwFlags);
-void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This);
-
-HRESULT HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
-				     LPDIRECTDRAWPALETTE* ppPalette,
-				     LPUNKNOWN pUnkOuter);
-
-HRESULT WINAPI
-HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				 DWORD dwStart, DWORD dwCount,
-				 LPPALETTEENTRY palent);
-
-/*****************************************************************************
- * IDirectDraw MAIN declarations
- */
-/* internal virtual functions */
-void Main_DirectDraw_final_release(IDirectDrawImpl* This);
-HRESULT Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
-			      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);
-HRESULT Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
-			    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,
-			    DWORD dwMipMapLevel);
-HRESULT Main_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
-			    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);
-
-/* internal functions */
-HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex);
-void Main_DirectDraw_AddSurface(IDirectDrawImpl* This,
-				IDirectDrawSurfaceImpl* surface);
-void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This,
-				   IDirectDrawSurfaceImpl* surface);
-void Main_DirectDraw_AddClipper(IDirectDrawImpl* This,
-				IDirectDrawClipperImpl* clipper);
-void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This,
-				   IDirectDrawClipperImpl* clipper);
-void Main_DirectDraw_AddPalette(IDirectDrawImpl* This,
-				IDirectDrawPaletteImpl* palette);
-void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This,
-				   IDirectDrawPaletteImpl* palette);
-
-/* interface functions */
-ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface);
-ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface);
-HRESULT WINAPI Main_DirectDraw_QueryInterface(LPDIRECTDRAW7 iface,
-					      REFIID refiid,LPVOID *obj);
-HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface);
-HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface,
-					     DWORD dwFlags,
-					     LPDIRECTDRAWCLIPPER *ppClipper,
-					     IUnknown *pUnkOuter);
-HRESULT WINAPI
-Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			      LPPALETTEENTRY palent,
-			      LPDIRECTDRAWPALETTE* ppPalette,
-			      LPUNKNOWN pUnknown);
-HRESULT WINAPI
-Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
-			      LPDIRECTDRAWSURFACE7 *ppSurf,
-			      IUnknown *pUnkOuter);
-HRESULT WINAPI
-Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
-				 LPDIRECTDRAWSURFACE7* dst);
-HRESULT WINAPI
-Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
-			     LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
-			     LPDDENUMSURFACESCALLBACK7 callback);
-HRESULT WINAPI
-Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b);
-HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface);
-HRESULT WINAPI
-Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
-			LPDDCAPS pHELCaps);
-HRESULT WINAPI
-Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes,
-			       LPDWORD pCodes);
-HRESULT WINAPI
-Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
-			      LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface);
-HRESULT WINAPI
-Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq);
-HRESULT WINAPI
-Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine);
-HRESULT WINAPI
-Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
-				 LPDIRECTDRAWSURFACE7 *lpDDS);
-HRESULT WINAPI
-Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status);
-HRESULT WINAPI
-Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid);
-HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface);
-HRESULT WINAPI
-Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
-				    DWORD cooplevel);
-HRESULT WINAPI
-Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-			       DWORD dwHeight, LONG lPitch,
-			       DWORD dwRefreshRate, DWORD dwFlags,
-			       const DDPIXELFORMAT* pixelformat);
-HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface);
-HRESULT WINAPI
-Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				     HANDLE h);
-HRESULT WINAPI
-Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD);
-HRESULT WINAPI
-Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface,LPDDSCAPS2 ddscaps,
-				   LPDWORD total, LPDWORD free);
-HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface);
-HRESULT WINAPI
-Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
-			      DWORD dwNumModes, DWORD dwFlags);
-
-/*****************************************************************************
- * IDirectDraw USER object declarations
- */
-#define USER_DDRAW_PRIV(ddraw) ((User_DirectDrawImpl*)((ddraw)->private))
-#define USER_DDRAW_PRIV_VAR(name,ddraw) \
-	User_DirectDrawImpl* name = USER_DDRAW_PRIV(ddraw)
-
-typedef struct
-{
-    int empty;
-    /* empty */
-} User_DirectDrawImpl_Part;
-
-typedef struct
-{
-    User_DirectDrawImpl_Part user;
-} User_DirectDrawImpl;
-
-void User_DirectDraw_final_release(IDirectDrawImpl* This);
-HRESULT User_DirectDraw_create_primary(IDirectDrawImpl* This,
-				       const DDSURFACEDESC2* pDDSD,
-				       LPDIRECTDRAWSURFACE7* ppSurf,
-				       LPUNKNOWN pOuter);
-HRESULT User_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
-					  const DDSURFACEDESC2* pDDSD,
-					  LPDIRECTDRAWSURFACE7* ppSurf,
-					  LPUNKNOWN pOuter,
-					  IDirectDrawSurfaceImpl* primary);
-HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex);
-HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-			       IUnknown* pUnkOuter, BOOL ex);
-
-HRESULT WINAPI
-User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
-				 LPDDSURFACEDESC2 pDDSD, LPVOID context,
-				 LPDDENUMMODESCALLBACK2 callback);
-HRESULT WINAPI
-User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
-				    LPDDDEVICEIDENTIFIER2 pDDDI,
-				    DWORD dwFlags);
-HRESULT WINAPI
-User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-			       DWORD dwHeight, DWORD dwBPP,
-			       DWORD dwRefreshRate, DWORD dwFlags);
-
-/*****************************************************************************
- * IDirectDraw HAL declarations
- */
-#define HAL_DDRAW_PRIV(ddraw) \
-	((HAL_DirectDrawImpl*)((ddraw)->private))
-#define HAL_DDRAW_PRIV_VAR(name,ddraw) \
-	HAL_DirectDrawImpl* name = HAL_DDRAW_PRIV(ddraw)
-
-typedef struct
-{
-    DWORD next_vofs;
-} HAL_DirectDrawImpl_Part;
-
-typedef struct
-{
-    User_DirectDrawImpl_Part user;
-    HAL_DirectDrawImpl_Part hal;
-} HAL_DirectDrawImpl;
-
-void HAL_DirectDraw_final_release(IDirectDrawImpl* This);
-HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This,
-				      const DDSURFACEDESC2* pDDSD,
-				      LPDIRECTDRAWSURFACE7* ppSurf,
-				      LPUNKNOWN pOuter);
-HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
-					 const DDSURFACEDESC2* pDDSD,
-					 LPDIRECTDRAWSURFACE7* ppSurf,
-					 LPUNKNOWN pOuter,
-					 IDirectDrawSurfaceImpl* primary);
-HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
-				      const DDSURFACEDESC2* pDDSD,
-				      LPDIRECTDRAWSURFACE7* ppSurf,
-				      LPUNKNOWN pOuter,
-				      DWORD dwMipMapLevel);
-
-HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex);
-HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
-				   IUnknown* pUnkOuter, BOOL ex);
-
-HRESULT WINAPI
-HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
-					LPDDDEVICEIDENTIFIER2 pDDDI,
-					DWORD dwFlags);
-HRESULT WINAPI
-HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
-				   DWORD dwHeight, DWORD dwBPP,
-				   DWORD dwRefreshRate, DWORD dwFlags);
-HRESULT WINAPI HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface);
-
-/*****************************************************************************
- * IDirectDrawSurface MAIN declarations
- */
-/* Support for IDirectDrawSurface7::Set/Get/FreePrivateData. I don't think
- * anybody uses it for much so a good implementation is optional. */
-typedef struct PrivateData
-{
-    struct PrivateData* next;
-    struct PrivateData* prev;
-
-    GUID tag;
-    DWORD flags; /* DDSPD_* */
-    DWORD uniqueness_value;
-
-    union
-    {
-	LPVOID data;
-	LPUNKNOWN object;
-    } ptr;
-
-    DWORD size;
-} PrivateData;
-
-extern const IDirectDrawGammaControlVtbl DDRAW_IDDGC_VTable;
-
-/* Non-interface functions */
-HRESULT Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-					 IDirectDrawImpl* pDD,
-					 const DDSURFACEDESC2* pDDSD);
-void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This);
-
-void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
-HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This);
-BOOL Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
-				   IDirectDrawSurfaceImpl *to);
-BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This);
-void Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
-					LPCRECT pRect, DWORD dwFlags);
-void Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-					  LPCRECT pRect);
-void Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This);
-void Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-					IDirectDrawPaletteImpl* pal);
-void Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					   IDirectDrawPaletteImpl* pal,
-					   DWORD dwStart, DWORD dwCount,
-			                   LPPALETTEENTRY palent);
-HWND Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This);
-
-HRESULT Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp);
-HRESULT Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp);
-
-BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				      IDirectDrawSurfaceImpl* back,
-				      DWORD dwFlags);
-
-#define CHECK_LOST(This)					\
-	do {							\
-		if (This->lost) return DDERR_SURFACELOST;	\
-	} while (0)
-
-#define CHECK_TEXTURE(This)					\
-	do {							\
-		if (!(This->surface_desc.ddsCaps.dwCaps2	\
-		      & DDSCAPS2_TEXTUREMANAGE))		\
-			return DDERR_INVALIDOBJECT;		\
-	} while (0)
-
-#define LOCK_OBJECT(This) do { } while (0)
-#define UNLOCK_OBJECT(This) do { } while (0)
-
-/* IDirectDrawSurface7 (partial) implementation */
-ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface);
-ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface);
-HRESULT WINAPI
-Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
-				      LPVOID* ppObj);
-HRESULT WINAPI
-Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					  LPDIRECTDRAWSURFACE7 pAttach);
-HRESULT WINAPI
-Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
-					   LPRECT pRect);
-HRESULT WINAPI
-Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
-				LPDDBLTBATCH pBatch, DWORD dwCount,
-				DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface);
-HRESULT WINAPI
-Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					     DWORD dwFlags,
-					     LPDIRECTDRAWSURFACE7 pAttach);
-HRESULT WINAPI
-Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
-					    LPVOID context,
-					    LPDDENUMSURFACESCALLBACK7 cb);
-HRESULT WINAPI
-Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
-					  DWORD dwFlags, LPVOID context,
-					  LPDDENUMSURFACESCALLBACK7 cb);
-HRESULT WINAPI
-Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
-			    LPDIRECTDRAWSURFACE7 override, DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface,
-				       REFGUID tag);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					  LPDDSCAPS2 pCaps,
-					  LPDIRECTDRAWSURFACE7* ppSurface);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface,
-				    DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface,
-			       LPDDSCAPS2 pCaps);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWCLIPPER* ppClipper);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface,
-				   DWORD dwFlags, LPDDCOLORKEY pCKey);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface,
-				      LPVOID* pDD);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface,
-				     DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface,
-			      LPDWORD pdwMaxLOD);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
-					  LPLONG pX, LPLONG pY);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWPALETTE* ppPalette);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
-				      LPDDPIXELFORMAT pDDPixelFormat);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
-				   LPDWORD pdwPriority);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag,
-				      LPVOID pBuffer, LPDWORD pcbBufferSize);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
-				      LPDDSURFACEDESC2 pDDSD);
-HRESULT WINAPI
-Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
-					  LPDWORD pValue);
-HRESULT WINAPI
-Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD);
-HRESULT WINAPI
-Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface);
-HRESULT WINAPI
-Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
-			    LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h);
-HRESULT WINAPI
-Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWCLIPPER pDDClipper);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
-				   DWORD dwFlags, LPDDCOLORKEY pCKey);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
-					  LONG X, LONG Y);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWPALETTE pPalette);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
-				   DWORD dwPriority);
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
-				      REFGUID tag, LPVOID pData,
-				      DWORD cbSize, DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect);
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
-				     LPRECT pSrcRect,
-				     LPDIRECTDRAWSURFACE7 pDstSurface,
-				     LPRECT pDstRect, DWORD dwFlags,
-				     LPDDOVERLAYFX pFX);
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
-					    DWORD dwFlags);
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
-					   DWORD dwFlags,
-					   LPDIRECTDRAWSURFACE7 pDDSRef);
-
-/*****************************************************************************
- * IDirectDrawSurface DIB declarations
- */
-#define DIB_PRIV(surf) ((DIB_DirectDrawSurfaceImpl*)((surf)->private))
-
-#define DIB_PRIV_VAR(name, surf) \
-	DIB_DirectDrawSurfaceImpl* name = DIB_PRIV(surf)
-
-struct DIB_DirectDrawSurfaceImpl_Part
-{
-    HBITMAP DIBsection;
-    void* bitmap_data;
-    HGDIOBJ holdbitmap;
-    BOOL client_memory;
-    DWORD d3d_data[4]; /* room for Direct3D driver data */
-};
-
-typedef struct
-{
-    struct DIB_DirectDrawSurfaceImpl_Part dib;
-} DIB_DirectDrawSurfaceImpl;
-
-HRESULT
-DIB_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
-				IDirectDrawImpl *pDD,
-				const DDSURFACEDESC2 *pDDSD);
-HRESULT
-DIB_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-			     const DDSURFACEDESC2 *pDDSD,
-			     LPDIRECTDRAWSURFACE7 *ppSurf,
-			     IUnknown *pUnkOuter);
-
-void DIB_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
-BOOL DIB_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				     IDirectDrawSurfaceImpl* back,
-				     DWORD dwFlags);
-
-void DIB_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-				       IDirectDrawPaletteImpl* pal);
-void DIB_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					  IDirectDrawPaletteImpl* pal,
-					  DWORD dwStart, DWORD dwCount,
-					  LPPALETTEENTRY palent);
-
-HRESULT DIB_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC);
-HRESULT DIB_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This,HDC hDC);
-
-HRESULT DIB_DirectDrawSurface_alloc_dc(IDirectDrawSurfaceImpl* This,HDC* phDC);
-HRESULT DIB_DirectDrawSurface_free_dc(IDirectDrawSurfaceImpl* This, HDC hDC);
-
-HRESULT WINAPI
-DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT prcDest,
-			  LPDIRECTDRAWSURFACE7 pSrcSurf, LPRECT prcSrc,
-			  DWORD dwFlags, LPDDBLTFX pBltFx);
-HRESULT WINAPI
-DIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dwX,
-			      DWORD dwY, LPDIRECTDRAWSURFACE7 pSrcSurf,
-			      LPRECT prcSrc, DWORD dwTrans);
-HRESULT WINAPI DIB_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface);
-HRESULT WINAPI
-DIB_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
-				     LPDDSURFACEDESC2 pDDSD, DWORD dwFlags);
-
-/*****************************************************************************
- * IDirectDrawSurface USER declarations
- */
-#define USER_PRIV(surf) ((User_DirectDrawSurfaceImpl*)((surf)->private))
-
-#define USER_PRIV_VAR(name,surf) \
-	User_DirectDrawSurfaceImpl* name = USER_PRIV(surf)
-
-struct User_DirectDrawSurfaceImpl_Part
-{
-    HWND window;
-    HDC cached_dc;
-    HANDLE update_thread, update_event, refresh_event;
-    volatile int wait_count, in_refresh;
-    CRITICAL_SECTION crit;
-};
-
-typedef struct
-{
-    struct DIB_DirectDrawSurfaceImpl_Part dib;
-    struct User_DirectDrawSurfaceImpl_Part user;
-} User_DirectDrawSurfaceImpl;
-
-HRESULT User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-					 IDirectDrawImpl* pDD,
-					 const DDSURFACEDESC2* pDDSD);
-
-HRESULT User_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-				      const DDSURFACEDESC2 *pDDSD,
-				      LPDIRECTDRAWSURFACE7 *ppSurf,
-				      IUnknown *pUnkOuter);
-
-void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
-
-void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
-					LPCRECT pRect, DWORD dwFlags);
-void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-					  LPCRECT pRect);
-void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-					IDirectDrawPaletteImpl* pal);
-void User_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					   IDirectDrawPaletteImpl* pal,
-					   DWORD dwStart, DWORD dwCount,
-					   LPPALETTEENTRY palent);
-HRESULT User_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						 LPDIRECTDRAWSURFACE7* ppDup);
-BOOL User_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				      IDirectDrawSurfaceImpl* back,
-				      DWORD dwFlags);
-void User_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This,
-					DWORD dwFlags);
-HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This);
-
-HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC);
-HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This,
-					  HDC hDC);
-
-HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp);
-HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp);
-
-/*****************************************************************************
- * IDirectDrawSurface HAL declarations
- */
-#define HAL_PRIV(surf) ((HAL_DirectDrawSurfaceImpl*)((surf)->private))
-
-#define HAL_PRIV_VAR(name,surf) \
-	HAL_DirectDrawSurfaceImpl* name = HAL_PRIV(surf)
-
-struct HAL_DirectDrawSurfaceImpl_Part
-{
-    DWORD need_late;
-    LPVOID fb_addr;
-    DWORD fb_pitch, fb_vofs;
-};
-
-typedef struct
-{
-    struct DIB_DirectDrawSurfaceImpl_Part dib;
-    struct User_DirectDrawSurfaceImpl_Part user;
-    struct HAL_DirectDrawSurfaceImpl_Part hal;
-} HAL_DirectDrawSurfaceImpl;
-
-HRESULT HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-					IDirectDrawImpl* pDD,
-					const DDSURFACEDESC2* pDDSD);
-
-HRESULT HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-				     const DDSURFACEDESC2 *pDDSD,
-				     LPDIRECTDRAWSURFACE7 *ppSurf,
-				     IUnknown *pUnkOuter);
-
-void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
-HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This);
-
-void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-				       IDirectDrawPaletteImpl* pal);
-void HAL_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					  IDirectDrawPaletteImpl* pal,
-					  DWORD dwStart, DWORD dwCount,
-					  LPPALETTEENTRY palent);
-HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						LPDIRECTDRAWSURFACE7* ppDup);
-void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
-				       LPCRECT pRect, DWORD dwFlags);
-void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-					 LPCRECT pRect);
-BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				     IDirectDrawSurfaceImpl* back,
-				     DWORD dwFlags);
-void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This,
-				       DWORD dwFlags);
-HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This);
-
-/*****************************************************************************
- * IDirectDrawSurface FAKEZBUFFER declarations
- */
-typedef struct
-{
-    BOOLEAN in_memory;
-} FakeZBuffer_DirectDrawSurfaceImpl;
-
-HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-						IDirectDrawImpl* pDD,
-						const DDSURFACEDESC2* pDDSD);
-
-HRESULT FakeZBuffer_DirectDrawSurface_Create(IDirectDrawImpl* pDD,
-					     const DDSURFACEDESC2* pDDSD,
-					     LPDIRECTDRAWSURFACE7* ppSurf,
-					     IUnknown* pUnkOuter);
-
-void FakeZBuffer_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
-
-HRESULT FakeZBuffer_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-							LPDIRECTDRAWSURFACE7* ppDup);
-
-#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */
+HRESULT hr_ddraw_from_wined3d(HRESULT hr);
diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c
index ac93f72..8834113 100644
--- a/dlls/ddraw/ddraw_thunks.c
+++ b/dlls/ddraw/ddraw_thunks.c
@@ -15,6 +15,9 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
+
+#include "config.h"
+
 #include <stdarg.h>
 
 #include "windef.h"
@@ -205,6 +208,7 @@
 			      IUnknown *pUnkOuter)
 {
     LPDIRECTDRAWSURFACE7 pSurface7;
+    IDirectDrawSurfaceImpl *impl;
     HRESULT hr;
 
     /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
@@ -221,6 +225,12 @@
 				    IDirectDrawSurface7, IDirectDrawSurface3,
 				    pSurface7);
 
+    impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
+    if(impl)
+    {
+        impl->version = 1;
+    }
+
     return hr;
 }
 
@@ -230,6 +240,7 @@
 			       IUnknown *pUnkOuter)
 {
     LPDIRECTDRAWSURFACE7 pSurface7;
+    IDirectDrawSurfaceImpl *impl;
     HRESULT hr;
 
     hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
@@ -244,6 +255,12 @@
 				    IDirectDrawSurface7, IDirectDrawSurface3,
 				    pSurface7);
 
+    impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
+    if(impl)
+    {
+        impl->version = 2;
+    }
+
     return hr;
 }
 
@@ -252,13 +269,22 @@
 			       LPDIRECTDRAWSURFACE4 *ppSurface,
 			       IUnknown *pUnkOuter)
 {
-    return IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
-							 IDirectDraw4,
-							 IDirectDraw7,
-							 This),
-				      pSDesc,
-				      (LPDIRECTDRAWSURFACE7 *)ppSurface,
-				      pUnkOuter);
+    HRESULT hr;
+    IDirectDrawSurfaceImpl *impl;
+
+    hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
+						       IDirectDraw4,
+						       IDirectDraw7,
+						        This),
+				    pSDesc,
+				    (LPDIRECTDRAWSURFACE7 *)ppSurface,
+				    pUnkOuter);
+    impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurface);
+    if(impl)
+    {
+        impl->version = 4;
+    }
+    return hr;
 }
 
 static HRESULT WINAPI
@@ -709,10 +735,7 @@
     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;
 }
 
@@ -721,12 +744,9 @@
 {
     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;
 }
 
@@ -735,12 +755,9 @@
 {
     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;
 }
 
@@ -942,7 +959,7 @@
     return hr;
 }
 
-const IDirectDrawVtbl DDRAW_IDirectDraw_VTable =
+const IDirectDrawVtbl IDirectDraw1_Vtbl =
 {
     IDirectDrawImpl_QueryInterface,
     IDirectDrawImpl_AddRef,
@@ -969,7 +986,7 @@
     IDirectDrawImpl_WaitForVerticalBlank,
 };
 
-const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable =
+const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
 {
     IDirectDraw2Impl_QueryInterface,
     IDirectDraw2Impl_AddRef,
@@ -997,7 +1014,7 @@
     IDirectDraw2Impl_GetAvailableVidMem
 };
 
-const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable =
+const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
 {
     IDirectDraw4Impl_QueryInterface,
     IDirectDraw4Impl_AddRef,
diff --git a/dlls/ddraw/ddraw_user.c b/dlls/ddraw/ddraw_user.c
deleted file mode 100644
index ddf3d6c..0000000
--- a/dlls/ddraw/ddraw_user.c
+++ /dev/null
@@ -1,575 +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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#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);
-
-    if (pDDSD && TRACE_ON(ddraw))
-    {
-	TRACE("Enumerate modes matching:\n");
-	DDRAW_dump_surface_desc(pDDSD);
-    }
-
-    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;
-
-    for (i = 0; EnumDisplaySettingsExW(NULL, i, &DevModeW, 0); i++)
-    {
-	if (pDDSD)
-	{
-	    if ((pDDSD->dwFlags & DDSD_WIDTH) && (pDDSD->dwWidth != DevModeW.dmPelsWidth))
-		continue; 
-	    if ((pDDSD->dwFlags & DDSD_HEIGHT) && (pDDSD->dwHeight != DevModeW.dmPelsHeight))
-		continue; 
-	    if ((pDDSD->dwFlags & DDSD_PIXELFORMAT) && (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) &&
-		(pDDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount != DevModeW.dmBitsPerPel))
-		    continue; 
-	}
-
-	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;
-    }
-
-    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
-};
diff --git a/dlls/ddraw/ddraw_utils.c b/dlls/ddraw/ddraw_utils.c
deleted file mode 100644
index 327dd2f..0000000
--- a/dlls/ddraw/ddraw_utils.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * DirectDraw helper functions
- *
- * Copyright 1997-2000 Marcus Meissner
- * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "wine/debug.h"
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-/* *************************************
-      16 / 15 bpp to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
-    unsigned char  *c_src = (unsigned char  *) src;
-    unsigned short *c_dst = (unsigned short *) dst;
-    int y;
-
-    if (palette != NULL) {
-	const unsigned int * pal = (unsigned int *) palette->screen_palents;
-
-	for (y = height; y--; ) {
-#if defined(__i386__) && defined(__GNUC__)
-	    /* gcc generates slightly inefficient code for the the copy/lookup,
-	     * it generates one excess memory access (to pal) per pixel. Since
-	     * we know that pal is not modified by the memory write we can
-	     * put it into a register and reduce the number of memory accesses
-	     * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
-	     * stalls. (This is not guaranteed to be the fastest method.)
-	     */
-	    __asm__ __volatile__(
-	    "xor %%eax,%%eax\n"
-	    "1:\n"
-	    "    lodsb\n"
-	    "    movw (%%edx,%%eax,4),%%ax\n"
-	    "    stosw\n"
-	    "	   xor %%eax,%%eax\n"
-	    "    loop 1b\n"
-	    : "=S" (c_src), "=D" (c_dst)
-	    : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
-	    : "eax", "cc", "memory"
-	    );
-	    c_src+=(pitch-width);
-#else
-	    unsigned char * srclineend = c_src+width;
-	    while (c_src < srclineend)
-		*c_dst++ = pal[*c_src++];
-	    c_src+=(pitch-width);
-#endif
-	}
-    } else {
-	FIXME("No palette set...\n");
-	memset(dst, 0, width * height * 2);
-    }
-}
-static void palette_convert_16_to_8(
-	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
-) {
-    unsigned int i;
-    unsigned int *pal = (unsigned int *) screen_palette;
-
-    for (i = 0; i < count; i++)
-	pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
-			  ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
-			  ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
-}
-
-static void palette_convert_15_to_8(
-	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
-) {
-    unsigned int i;
-    unsigned int *pal = (unsigned int *) screen_palette;
-
-    for (i = 0; i < count; i++)
-	pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
-			  ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
-			  ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
-}
-
-/* *************************************
-      24 to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_24_to_8(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned char  *c_src = (unsigned char  *) src;
-    unsigned char *c_dst = (unsigned char *) dst;
-    int y;
-
-    if (palette != NULL) {
-	const unsigned int *pal = (unsigned int *) palette->screen_palents;
-
-	for (y = height; y--; ) {
-	    unsigned char * srclineend = c_src+width;
-	    while (c_src < srclineend ) {
-		register long pixel = pal[*c_src++];
-		*c_dst++ = pixel;
-		*c_dst++ = pixel>>8;
-		*c_dst++ = pixel>>16;
-	    }
-	    c_src+=(pitch-width);
-	}
-    } else {
-	FIXME("No palette set...\n");
-	memset(dst, 0, width * height * 3);
-    }
-}
-
-/* *************************************
-      32 bpp to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_32_to_8(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned char  *c_src = (unsigned char  *) src;
-    unsigned int *c_dst = (unsigned int *) dst;
-    int y;
-
-    if (palette != NULL) {
-	const unsigned int *pal = (unsigned int *) palette->screen_palents;
-
-	for (y = height; y--; ) {
-#if defined(__i386__) && defined(__GNUC__)
-	    /* See comment in pixel_convert_16_to_8 */
-	    __asm__ __volatile__(
-	    "xor %%eax,%%eax\n"
-	    "1:\n"
-	    "    lodsb\n"
-	    "    movl (%%edx,%%eax,4),%%eax\n"
-	    "    stosl\n"
-	    "	   xor %%eax,%%eax\n"
-	    "    loop 1b\n"
-	    : "=S" (c_src), "=D" (c_dst)
-	    : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
-	    : "eax", "cc", "memory"
-	    );
-	    c_src+=(pitch-width);
-#else
-	    unsigned char * srclineend = c_src+width;
-	    while (c_src < srclineend )
-		*c_dst++ = pal[*c_src++];
-	    c_src+=(pitch-width);
-#endif
-	}
-    } else {
-	FIXME("No palette set...\n");
-	memset(dst, 0, width * height * 4);
-    }
-}
-
-static void palette_convert_24_to_8(
-	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
-) {
-    unsigned int i;
-    unsigned int *pal = (unsigned int *) screen_palette;
-
-    for (i = 0; i < count; i++)
-	pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
-			  (((unsigned int) palent[i].peGreen) << 8) |
-			   ((unsigned int) palent[i].peBlue));
-}
-
-/* *************************************
-      16 bpp to 15 bpp
-   ************************************* */
-static void pixel_convert_15_to_16(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned short *c_src = (unsigned short *) src;
-    unsigned short *c_dst = (unsigned short *) dst;
-    int y;
-
-    for (y = height; y--; ) {
-	unsigned short * srclineend = c_src+width;
-	while (c_src < srclineend ) {
-	    unsigned short val = *c_src++;
-	    *c_dst++=((val&0xFFC0)>>1)|(val&0x001f);
-	}
-	c_src+=((pitch/2)-width);
-    }
-}
-
-/* *************************************
-      32 bpp to 16 bpp
-   ************************************* */
-static void pixel_convert_32_to_16(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned short *c_src = (unsigned short *) src;
-    unsigned int *c_dst = (unsigned int *) dst;
-    int y;
-
-    for (y = height; y--; ) {
-	unsigned short * srclineend = c_src+width;
-	while (c_src < srclineend ) {
-	    *c_dst++ = (((*c_src & 0xF800) << 8) |
-			((*c_src & 0x07E0) << 5) |
-			((*c_src & 0x001F) << 3));
-	    c_src++;
-	}
-	c_src+=((pitch/2)-width);
-    }
-}
-
-/* *************************************
-      32 bpp to 24 bpp
-   ************************************* */
-static void pixel_convert_32_to_24(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned char *c_src = (unsigned char *) src;
-    unsigned int *c_dst = (unsigned int *) dst;
-    int y;
-
-    for (y = height; y--; ) {
-	unsigned char * srclineend = c_src+width*3;
-	while (c_src < srclineend ) {
-	    /* FIXME: wrong for big endian */
-	    memcpy(c_dst,c_src,3);
-	    c_src+=3;
-	    c_dst++;
-	}
-	c_src+=pitch-width*3;
-    }
-}
-
-/* *************************************
-      16 bpp to 32 bpp
-   ************************************* */
-static void pixel_convert_16_to_32(
-	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
-	IDirectDrawPaletteImpl* palette
-) {
-    unsigned int *c_src = (unsigned int *) src;
-    unsigned short *c_dst = (unsigned short *) dst;
-    int y;
-
-    for (y = height; y--; ) {
-	unsigned int * srclineend = c_src+width;
-	while (c_src < srclineend ) {
-	    *c_dst++ = (((*c_src & 0xF80000) >> 8) |
-			((*c_src & 0x00FC00) >> 5) |
-			((*c_src & 0x0000F8) >> 3));
-	    c_src++;
-	}
-	c_src+=((pitch/4)-width);
-    }
-}
-
-Convert ModeEmulations[8] = {
-  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { pixel_convert_32_to_24, NULL } },
-  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
-  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8,  palette_convert_24_to_8 } },
-  { { 24, 24,   0xFF0000,   0x00FF00,   0x0000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8,  palette_convert_24_to_8 } },
-  { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  16,16, 0xf800, 0x07e0, 0x001f }, { pixel_convert_15_to_16,  NULL } },
-  { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_16_to_8 } },
-  { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_15_to_8 } },
-  { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { pixel_convert_16_to_32, NULL } }
-};
-
-void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut)
-{
-    /* 2 adds three additional caps fields to the end. Both versions
-     * are unversioned. */
-    pOut->dwCaps = pIn->dwCaps;
-    pOut->dwCaps2 = 0;
-    pOut->dwCaps3 = 0;
-    pOut->dwCaps4 = 0;
-}
-
-void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn,
-					     DDDEVICEIDENTIFIER* pOut)
-{
-    /* 2 adds a dwWHQLLevel field to the end. Both structures are
-     * unversioned. */
-    memcpy(pOut, pIn, sizeof(*pOut));
-}
-
-/******************************************************************************
- *		debug output functions
- */
-void DDRAW_dump_flags_(DWORD flags, const flag_info* names,
-		       size_t num_names, int newline)
-{
-    unsigned int	i;
-
-    for (i=0; i < num_names; i++)
-        if ((flags & names[i].val) ||      /* standard flag value */
-	    ((!flags) && (!names[i].val))) /* zero value only */
-	    DPRINTF("%s ", names[i].name);
-
-    if (newline)
-        DPRINTF("\n");
-}
-
-void DDRAW_dump_members(DWORD flags, const void* data,
-			const member_info* mems, size_t num_mems)
-{
-    unsigned int i;
-
-    for (i=0; i < num_mems; i++)
-    {
-	if (mems[i].val & flags)
-	{
-	    DPRINTF(" - %s : ", mems[i].name);
-	    mems[i].func((const char *)data + mems[i].offset);
-	    DPRINTF("\n");
-	}
-    }
-}
-
-void DDRAW_dump_DDBLTFX(DWORD flagmask)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDBLTFX_ARITHSTRETCHY),
-	    FE(DDBLTFX_MIRRORLEFTRIGHT),
-	    FE(DDBLTFX_MIRRORUPDOWN),
-	    FE(DDBLTFX_NOTEARING),
-	    FE(DDBLTFX_ROTATE180),
-	    FE(DDBLTFX_ROTATE270),
-	    FE(DDBLTFX_ROTATE90),
-	    FE(DDBLTFX_ZBUFFERRANGE),
-	    FE(DDBLTFX_ZBUFFERBASEDEST)
-	};
-
-    DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void DDRAW_dump_DDBLTFAST(DWORD flagmask)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDBLTFAST_NOCOLORKEY),
-	    FE(DDBLTFAST_SRCCOLORKEY),
-	    FE(DDBLTFAST_DESTCOLORKEY),
-	    FE(DDBLTFAST_WAIT)
-	};
-
-    DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void DDRAW_dump_DDBLT(DWORD flagmask)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDBLT_ALPHADEST),
-	    FE(DDBLT_ALPHADESTCONSTOVERRIDE),
-	    FE(DDBLT_ALPHADESTNEG),
-	    FE(DDBLT_ALPHADESTSURFACEOVERRIDE),
-	    FE(DDBLT_ALPHAEDGEBLEND),
-	    FE(DDBLT_ALPHASRC),
-	    FE(DDBLT_ALPHASRCCONSTOVERRIDE),
-	    FE(DDBLT_ALPHASRCNEG),
-	    FE(DDBLT_ALPHASRCSURFACEOVERRIDE),
-	    FE(DDBLT_ASYNC),
-	    FE(DDBLT_COLORFILL),
-	    FE(DDBLT_DDFX),
-	    FE(DDBLT_DDROPS),
-	    FE(DDBLT_KEYDEST),
-	    FE(DDBLT_KEYDESTOVERRIDE),
-	    FE(DDBLT_KEYSRC),
-	    FE(DDBLT_KEYSRCOVERRIDE),
-	    FE(DDBLT_ROP),
-	    FE(DDBLT_ROTATIONANGLE),
-	    FE(DDBLT_ZBUFFER),
-	    FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE),
-	    FE(DDBLT_ZBUFFERDESTOVERRIDE),
-	    FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE),
-	    FE(DDBLT_ZBUFFERSRCOVERRIDE),
-	    FE(DDBLT_WAIT),
-	    FE(DDBLT_DEPTHFILL),
-	    FE(DDBLT_DONOTWAIT)
-    };
-
-    DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
-{
-    static const flag_info flags[] = {
-        FE(DDSCAPS_RESERVED1),
-        FE(DDSCAPS_ALPHA),
-        FE(DDSCAPS_BACKBUFFER),
-        FE(DDSCAPS_COMPLEX),
-        FE(DDSCAPS_FLIP),
-        FE(DDSCAPS_FRONTBUFFER),
-        FE(DDSCAPS_OFFSCREENPLAIN),
-        FE(DDSCAPS_OVERLAY),
-        FE(DDSCAPS_PALETTE),
-        FE(DDSCAPS_PRIMARYSURFACE),
-        FE(DDSCAPS_PRIMARYSURFACELEFT),
-        FE(DDSCAPS_SYSTEMMEMORY),
-        FE(DDSCAPS_TEXTURE),
-        FE(DDSCAPS_3DDEVICE),
-        FE(DDSCAPS_VIDEOMEMORY),
-        FE(DDSCAPS_VISIBLE),
-        FE(DDSCAPS_WRITEONLY),
-        FE(DDSCAPS_ZBUFFER),
-        FE(DDSCAPS_OWNDC),
-        FE(DDSCAPS_LIVEVIDEO),
-        FE(DDSCAPS_HWCODEC),
-        FE(DDSCAPS_MODEX),
-        FE(DDSCAPS_MIPMAP),
-        FE(DDSCAPS_RESERVED2),
-        FE(DDSCAPS_ALLOCONLOAD),
-        FE(DDSCAPS_VIDEOPORT),
-        FE(DDSCAPS_LOCALVIDMEM),
-        FE(DDSCAPS_NONLOCALVIDMEM),
-        FE(DDSCAPS_STANDARDVGAMODE),
-        FE(DDSCAPS_OPTIMIZED)
-    };
-    static const flag_info flags2[] = {
-        FE(DDSCAPS2_HARDWAREDEINTERLACE),
-        FE(DDSCAPS2_HINTDYNAMIC),
-        FE(DDSCAPS2_HINTSTATIC),
-        FE(DDSCAPS2_TEXTUREMANAGE),
-        FE(DDSCAPS2_RESERVED1),
-        FE(DDSCAPS2_RESERVED2),
-        FE(DDSCAPS2_OPAQUE),
-        FE(DDSCAPS2_HINTANTIALIASING),
-        FE(DDSCAPS2_CUBEMAP),
-        FE(DDSCAPS2_CUBEMAP_POSITIVEX),
-        FE(DDSCAPS2_CUBEMAP_NEGATIVEX),
-        FE(DDSCAPS2_CUBEMAP_POSITIVEY),
-        FE(DDSCAPS2_CUBEMAP_NEGATIVEY),
-        FE(DDSCAPS2_CUBEMAP_POSITIVEZ),
-        FE(DDSCAPS2_CUBEMAP_NEGATIVEZ),
-        FE(DDSCAPS2_MIPMAPSUBLEVEL),
-        FE(DDSCAPS2_D3DTEXTUREMANAGE),
-        FE(DDSCAPS2_DONOTPERSIST),
-        FE(DDSCAPS2_STEREOSURFACELEFT)
-    };
- 
-    DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0);
-    DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0);
-}
-
-void DDRAW_dump_DDSCAPS(const DDSCAPS *in) {
-    DDSCAPS2 in_bis;
-
-    in_bis.dwCaps = in->dwCaps;
-    in_bis.dwCaps2 = 0;
-    in_bis.dwCaps3 = 0;
-    in_bis.dwCaps4 = 0;
-
-    DDRAW_dump_DDSCAPS2(&in_bis);
-}
-
-void DDRAW_dump_pixelformat_flag(DWORD flagmask)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDPF_ALPHAPIXELS),
-	    FE(DDPF_ALPHA),
-	    FE(DDPF_FOURCC),
-	    FE(DDPF_PALETTEINDEXED4),
-	    FE(DDPF_PALETTEINDEXEDTO8),
-	    FE(DDPF_PALETTEINDEXED8),
-	    FE(DDPF_RGB),
-	    FE(DDPF_COMPRESSED),
-	    FE(DDPF_RGBTOYUV),
-	    FE(DDPF_YUV),
-	    FE(DDPF_ZBUFFER),
-	    FE(DDPF_PALETTEINDEXED1),
-	    FE(DDPF_PALETTEINDEXED2),
-	    FE(DDPF_ZPIXELS)
-    };
-
-    DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0);
-}
-
-void DDRAW_dump_paletteformat(DWORD dwFlags)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDPCAPS_4BIT),
-	    FE(DDPCAPS_8BITENTRIES),
-	    FE(DDPCAPS_8BIT),
-	    FE(DDPCAPS_INITIALIZE),
-	    FE(DDPCAPS_PRIMARYSURFACE),
-	    FE(DDPCAPS_PRIMARYSURFACELEFT),
-	    FE(DDPCAPS_ALLOW256),
-	    FE(DDPCAPS_VSYNC),
-	    FE(DDPCAPS_1BIT),
-	    FE(DDPCAPS_2BIT),
-	    FE(DDPCAPS_ALPHA)
-    };
-
-    DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) {
-    DPRINTF("( ");
-    DDRAW_dump_pixelformat_flag(pf->dwFlags);
-    if (pf->dwFlags & DDPF_FOURCC) {
-	DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
-		(unsigned char)( pf->dwFourCC     &0xff),
-		(unsigned char)((pf->dwFourCC>> 8)&0xff),
-		(unsigned char)((pf->dwFourCC>>16)&0xff),
-		(unsigned char)((pf->dwFourCC>>24)&0xff),
-		pf->dwFourCC,
-		pf->u1.dwYUVBitCount
-	);
-    }
-    if (pf->dwFlags & DDPF_RGB) {
-	const char *cmd;
-	DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount);
-	switch (pf->u1.dwRGBBitCount) {
-	case 4: cmd = "%1lx"; break;
-	case 8: cmd = "%02lx"; break;
-	case 16: cmd = "%04lx"; break;
-	case 24: cmd = "%06lx"; break;
-	case 32: cmd = "%08lx"; break;
-	default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
-	}
-	DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask);
-	DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask);
-	DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask);
-	if (pf->dwFlags & DDPF_ALPHAPIXELS) {
-	    DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask);
-	}
-	if (pf->dwFlags & DDPF_ZPIXELS) {
-	    DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask);
-	}
-    }
-    if (pf->dwFlags & DDPF_ZBUFFER) {
-	DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth);
-    }
-    if (pf->dwFlags & DDPF_ALPHA) {
-	DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth);
-    }
-    DPRINTF(")");
-}
-
-void DDRAW_dump_colorkeyflag(DWORD ck)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDCKEY_COLORSPACE),
-	    FE(DDCKEY_DESTBLT),
-	    FE(DDCKEY_DESTOVERLAY),
-	    FE(DDCKEY_SRCBLT),
-	    FE(DDCKEY_SRCOVERLAY)
-    };
-
-    DDRAW_dump_flags(ck, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-void DDRAW_dump_lockflag(DWORD lockflag)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDLOCK_SURFACEMEMORYPTR),
-	    FE(DDLOCK_WAIT),
-	    FE(DDLOCK_EVENT),
-	    FE(DDLOCK_READONLY),
-	    FE(DDLOCK_WRITEONLY),
-	    FE(DDLOCK_NOSYSLOCK),
-	    FE(DDLOCK_DISCARDCONTENTS),
-	    FE(DDLOCK_NOOVERWRITE)
-	};
-
-    DDRAW_dump_flags(lockflag, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-static void DDRAW_dump_DWORD(const void *in) {
-    DPRINTF("%ld", *((const DWORD *) in));
-}
-static void DDRAW_dump_PTR(const void *in) {
-    DPRINTF("%p", *((const void * const*) in));
-}
-void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) {
-    DPRINTF(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
-}
-
-void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
-{
-#define STRUCT DDSURFACEDESC2
-    static const member_info members[] =
-        {
-            ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight),
-            ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth),
-            ME(DDSD_PITCH, DDRAW_dump_DWORD, u1.lPitch),
-            ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize),
-            ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
-            ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount),
-	    ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2.dwMipMapCount), /* This is for 'old-style' D3D */
-            ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate),
-            ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
-            ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),
-            ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3.ddckCKDestOverlay),
-            ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt),
-            ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay),
-            ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt),
-            ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4.ddpfPixelFormat)
-        };
-    static const member_info members_caps[] =
-        {
-            ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps)
-        };
-    static const member_info members_caps2[] =
-        {
-            ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps)
-        };
-#undef STRUCT
-
-    if (NULL == lpddsd) {
-        DPRINTF("(null)\n");
-    } else {
-      if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) {
-          DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1);
-      } else {
-          DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
-      }
-      DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
-			 sizeof(members)/sizeof(members[0]));
-    }
-}
-
-void DDRAW_dump_cooperativelevel(DWORD cooplevel)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDSCL_FULLSCREEN),
-	    FE(DDSCL_ALLOWREBOOT),
-	    FE(DDSCL_NOWINDOWCHANGES),
-	    FE(DDSCL_NORMAL),
-	    FE(DDSCL_ALLOWMODEX),
-	    FE(DDSCL_EXCLUSIVE),
-	    FE(DDSCL_SETFOCUSWINDOW),
-	    FE(DDSCL_SETDEVICEWINDOW),
-	    FE(DDSCL_CREATEDEVICEWINDOW)
-    };
-
-    if (TRACE_ON(ddraw))
-    {
-	DPRINTF(" - ");
-	DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
-    }
-}
-
-void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) {
-    static const flag_info flags1[] = {
-      FE(DDCAPS_3D),
-      FE(DDCAPS_ALIGNBOUNDARYDEST),
-      FE(DDCAPS_ALIGNSIZEDEST),
-      FE(DDCAPS_ALIGNBOUNDARYSRC),
-      FE(DDCAPS_ALIGNSIZESRC),
-      FE(DDCAPS_ALIGNSTRIDE),
-      FE(DDCAPS_BLT),
-      FE(DDCAPS_BLTQUEUE),
-      FE(DDCAPS_BLTFOURCC),
-      FE(DDCAPS_BLTSTRETCH),
-      FE(DDCAPS_GDI),
-      FE(DDCAPS_OVERLAY),
-      FE(DDCAPS_OVERLAYCANTCLIP),
-      FE(DDCAPS_OVERLAYFOURCC),
-      FE(DDCAPS_OVERLAYSTRETCH),
-      FE(DDCAPS_PALETTE),
-      FE(DDCAPS_PALETTEVSYNC),
-      FE(DDCAPS_READSCANLINE),
-      FE(DDCAPS_STEREOVIEW),
-      FE(DDCAPS_VBI),
-      FE(DDCAPS_ZBLTS),
-      FE(DDCAPS_ZOVERLAYS),
-      FE(DDCAPS_COLORKEY),
-      FE(DDCAPS_ALPHA),
-      FE(DDCAPS_COLORKEYHWASSIST),
-      FE(DDCAPS_NOHARDWARE),
-      FE(DDCAPS_BLTCOLORFILL),
-      FE(DDCAPS_BANKSWITCHED),
-      FE(DDCAPS_BLTDEPTHFILL),
-      FE(DDCAPS_CANCLIP),
-      FE(DDCAPS_CANCLIPSTRETCHED),
-      FE(DDCAPS_CANBLTSYSMEM)
-    };
-    static const flag_info flags2[] = {
-      FE(DDCAPS2_CERTIFIED),
-      FE(DDCAPS2_NO2DDURING3DSCENE),
-      FE(DDCAPS2_VIDEOPORT),
-      FE(DDCAPS2_AUTOFLIPOVERLAY),
-      FE(DDCAPS2_CANBOBINTERLEAVED),
-      FE(DDCAPS2_CANBOBNONINTERLEAVED),
-      FE(DDCAPS2_COLORCONTROLOVERLAY),
-      FE(DDCAPS2_COLORCONTROLPRIMARY),
-      FE(DDCAPS2_CANDROPZ16BIT),
-      FE(DDCAPS2_NONLOCALVIDMEM),
-      FE(DDCAPS2_NONLOCALVIDMEMCAPS),
-      FE(DDCAPS2_NOPAGELOCKREQUIRED),
-      FE(DDCAPS2_WIDESURFACES),
-      FE(DDCAPS2_CANFLIPODDEVEN),
-      FE(DDCAPS2_CANBOBHARDWARE),
-      FE(DDCAPS2_COPYFOURCC),
-      FE(DDCAPS2_PRIMARYGAMMA),
-      FE(DDCAPS2_CANRENDERWINDOWED),
-      FE(DDCAPS2_CANCALIBRATEGAMMA),
-      FE(DDCAPS2_FLIPINTERVAL),
-      FE(DDCAPS2_FLIPNOVSYNC),
-      FE(DDCAPS2_CANMANAGETEXTURE),
-      FE(DDCAPS2_TEXMANINNONLOCALVIDMEM),
-      FE(DDCAPS2_STEREO),
-      FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL)
-    };
-    static const flag_info flags3[] = {
-      FE(DDCKEYCAPS_DESTBLT),
-      FE(DDCKEYCAPS_DESTBLTCLRSPACE),
-      FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV),
-      FE(DDCKEYCAPS_DESTBLTYUV),
-      FE(DDCKEYCAPS_DESTOVERLAY),
-      FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE),
-      FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV),
-      FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE),
-      FE(DDCKEYCAPS_DESTOVERLAYYUV),
-      FE(DDCKEYCAPS_SRCBLT),
-      FE(DDCKEYCAPS_SRCBLTCLRSPACE),
-      FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV),
-      FE(DDCKEYCAPS_SRCBLTYUV),
-      FE(DDCKEYCAPS_SRCOVERLAY),
-      FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE),
-      FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV),
-      FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE),
-      FE(DDCKEYCAPS_SRCOVERLAYYUV),
-      FE(DDCKEYCAPS_NOCOSTOVERLAY)
-    };
-    static const flag_info flags4[] = {
-      FE(DDFXCAPS_BLTALPHA),
-      FE(DDFXCAPS_OVERLAYALPHA),
-      FE(DDFXCAPS_BLTARITHSTRETCHYN),
-      FE(DDFXCAPS_BLTARITHSTRETCHY),
-      FE(DDFXCAPS_BLTMIRRORLEFTRIGHT),
-      FE(DDFXCAPS_BLTMIRRORUPDOWN),
-      FE(DDFXCAPS_BLTROTATION),
-      FE(DDFXCAPS_BLTROTATION90),
-      FE(DDFXCAPS_BLTSHRINKX),
-      FE(DDFXCAPS_BLTSHRINKXN),
-      FE(DDFXCAPS_BLTSHRINKY),
-      FE(DDFXCAPS_BLTSHRINKYN),
-      FE(DDFXCAPS_BLTSTRETCHX),
-      FE(DDFXCAPS_BLTSTRETCHXN),
-      FE(DDFXCAPS_BLTSTRETCHY),
-      FE(DDFXCAPS_BLTSTRETCHYN),
-      FE(DDFXCAPS_OVERLAYARITHSTRETCHY),
-      FE(DDFXCAPS_OVERLAYARITHSTRETCHYN),
-      FE(DDFXCAPS_OVERLAYSHRINKX),
-      FE(DDFXCAPS_OVERLAYSHRINKXN),
-      FE(DDFXCAPS_OVERLAYSHRINKY),
-      FE(DDFXCAPS_OVERLAYSHRINKYN),
-      FE(DDFXCAPS_OVERLAYSTRETCHX),
-      FE(DDFXCAPS_OVERLAYSTRETCHXN),
-      FE(DDFXCAPS_OVERLAYSTRETCHY),
-      FE(DDFXCAPS_OVERLAYSTRETCHYN),
-      FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT),
-      FE(DDFXCAPS_OVERLAYMIRRORUPDOWN)
-    };
-    static const flag_info flags5[] = {
-      FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND),
-      FE(DDFXALPHACAPS_BLTALPHAPIXELS),
-      FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG),
-      FE(DDFXALPHACAPS_BLTALPHASURFACES),
-      FE(DDFXALPHACAPS_BLTALPHASURFACESNEG),
-      FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND),
-      FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS),
-      FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG),
-      FE(DDFXALPHACAPS_OVERLAYALPHASURFACES),
-      FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG)
-    };
-    static const flag_info flags6[] = {
-      FE(DDPCAPS_4BIT),
-      FE(DDPCAPS_8BITENTRIES),
-      FE(DDPCAPS_8BIT),
-      FE(DDPCAPS_INITIALIZE),
-      FE(DDPCAPS_PRIMARYSURFACE),
-      FE(DDPCAPS_PRIMARYSURFACELEFT),
-      FE(DDPCAPS_ALLOW256),
-      FE(DDPCAPS_VSYNC),
-      FE(DDPCAPS_1BIT),
-      FE(DDPCAPS_2BIT),
-      FE(DDPCAPS_ALPHA),
-    };
-    static const flag_info flags7[] = {
-      FE(DDSVCAPS_RESERVED1),
-      FE(DDSVCAPS_RESERVED2),
-      FE(DDSVCAPS_RESERVED3),
-      FE(DDSVCAPS_RESERVED4),
-      FE(DDSVCAPS_STEREOSEQUENTIAL),
-    };
-
-    DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize);
-    DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
-    DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
-    DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
-    DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
-    DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
-    DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
-    DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
-    DPRINTF("...\n");
-    DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes);
-    DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays);
-    DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch);
-    DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
-    DPRINTF("...\n");
-    DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
-}
-
-void DDRAW_dump_DDENUMSURFACES(DWORD flagmask)
-{
-    static const flag_info flags[] =
-	{
-	    FE(DDENUMSURFACES_ALL),
-	    FE(DDENUMSURFACES_MATCH),
-	    FE(DDENUMSURFACES_NOMATCH),
-	    FE(DDENUMSURFACES_CANBECREATED),
-	    FE(DDENUMSURFACES_DOESEXIST)
-	};
-    DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
-}
-
-/* Debug function that can be helpful to debug various surface-related problems */
-static int get_shift(DWORD color_mask) {
-    int shift = 0;
-    while (color_mask > 0xFF) {
-        color_mask >>= 1;
-	shift += 1;
-    }
-    while ((color_mask & 0x80) == 0) {
-        color_mask <<= 1;
-	shift -= 1;
-    }
-    return shift;
-}
-
-void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale)
-{
-    int rwidth, rheight, x, y;
-    static char *output = NULL;
-    static int size = 0;
-
-    rwidth  = (surface->surface_desc.dwWidth  + scale - 1) / scale;
-    rheight = (surface->surface_desc.dwHeight + scale - 1) / scale;
-
-    if (rwidth > size) {
-	output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rwidth * 3);
-	size = rwidth;
-    }
-    
-    fprintf(f, "P6\n%d %d\n255\n", rwidth, rheight);
-
-    if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-        unsigned char table[256][3];
-	int i;
-	
-	if (surface->palette == NULL) {
-	    fclose(f);
-	    return;
-	}
-	for (i = 0; i < 256; i++) {
-	    table[i][0] = surface->palette->palents[i].peRed;
-	    table[i][1] = surface->palette->palents[i].peGreen;
-	    table[i][2] = surface->palette->palents[i].peBlue;
-	}
-	for (y = 0; y < rheight; y++) {
-	    unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
-	    for (x = 0; x < rwidth; x++) {
-		unsigned char color = *src;
-		src += scale;
-
-		output[3 * x + 0] = table[color][0];
-		output[3 * x + 1] = table[color][1];
-		output[3 * x + 2] = table[color][2];
-	    }
-	    fwrite(output, 3 * rwidth, 1, f);
-	}
-    } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
-        int red_shift, green_shift, blue_shift, pix_width;
-	
-	if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
-	    pix_width = 1;
-	} else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-	    pix_width = 2;
-	} else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-	    pix_width = 4;
-	} else {
-	    pix_width = 3;
-	}
-	
-	red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask);
-	green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask);
-	blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask);
-
-	for (y = 0; y < rheight; y++) {
-	    unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
-	    for (x = 0; x < rwidth; x++) {	    
-		unsigned int color;
-		unsigned int comp;
-		int i;
-
-		color = 0;
-		for (i = 0; i < pix_width; i++) {
-		    color |= src[i] << (8 * i);
-		}
-		src += scale * pix_width;
-		
-		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
-		output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
-		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
-		output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
-		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
-		output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
-	    }
-	    fwrite(output, 3 * rwidth, 1, f);
-	}
-    }
-    fclose(f);
-}
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
new file mode 100644
index 0000000..f0eb86c
--- /dev/null
+++ b/dlls/ddraw/device.c
@@ -0,0 +1,4574 @@
+/*
+ * Copyright (c) 1998-2004 Lionel Ulmer
+ * Copyright (c) 2002-2005 Christian Costa
+ * Copyright (c) 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
+ * to WineD3D, some minimal DirectDraw specific management is handled here.
+ * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
+ * is initialized when DirectDraw creates the primary surface.
+ * Some type management is necessary, because some D3D types changed between
+ * D3D7 and D3D9.
+ *
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
+WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
+
+/* The device ID */
+const GUID IID_D3DDEVICE_WineD3D = {
+  0xaef72d43,
+  0xb09a,
+  0x4b7b,
+  { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
+};
+
+/*****************************************************************************
+ * IUnknown Methods. Common for Version 1, 2, 3 and 7 
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DDevice7::QueryInterface
+ *
+ * Used to query other interfaces from a Direct3DDevice interface.
+ * It can return interface pointers to all Direct3DDevice versions as well
+ * as IDirectDraw and IDirect3D. For a link for QueryInterface
+ * rules see ddraw.c, IDirectDraw7::QueryInterface
+ *
+ * Exists in Version 1, 2, 3 and 7
+ *
+ * Params:
+ *  refiid: Interface ID queried for
+ *  obj: Used to return the interface pointer
+ *
+ * Returns:
+ *  D3D_OK or E_NOINTERFACE
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
+                                     REFIID refiid,
+                                     void **obj)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, 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(!refiid)
+        return DDERR_INVALIDPARAMS;
+
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
+    }
+
+    /* Check DirectDraw Interfacs */
+    else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
+        TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
+        TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
+        TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
+    }
+    else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
+        TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
+    }
+
+    /* Direct3D */
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
+        TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
+        TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
+        TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
+        TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
+    }
+
+    /* Direct3DDevice */
+    else if ( IsEqualGUID( &IID_IDirect3DDevice  , refiid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IDirect3DDevice);
+        TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3DDevice2  , refiid ) ) {
+        *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
+        TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3DDevice3  , refiid ) ) {
+        *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
+        TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3DDevice7  , refiid ) ) {
+        *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
+        TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
+    }
+
+    /* Unknown interface */
+    else
+    {
+        ERR("(%p)->(%s, %p): No interface found", This, debugstr_guid(refiid), obj);
+        return E_NOINTERFACE;
+    }
+
+    /* AddRef the returned interface */
+    IUnknown_AddRef( (IUnknown *) *obj);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
+                                           REFIID riid,
+                                           void **obj)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
+    return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           riid,
+                                           obj);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
+                                           REFIID riid,
+                                           void **obj)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
+    return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           riid,
+                                           obj);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
+                                           REFIID riid,
+                                           void **obp)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
+    return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           riid,
+                                           obp);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::AddRef
+ *
+ * Increases the refcount....
+ * The most exciting Method, definitly
+ *
+ * Exists in Version 1, 2, 3 and 7
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) : incrementing from %lu.\n", This, ref -1);
+
+    return ref;
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
+{
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::Release
+ *
+ * Decreases the refcount of the interface
+ * When the refcount is reduced to 0, the object is destroyed.
+ *
+ * Exists in Version 1, 2, 3 and 7
+ *
+ * Returns:d
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref +1);
+
+    /* This method doesn't destroy the WineD3DDevice, because it's still in use for
+     * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
+     * when the render target is released
+     */
+    if (ref == 0)
+    {
+        IParent *IndexBufferParent;
+        /* Free the index buffer */
+        IWineD3DDevice_SetIndices(This->wineD3DDevice,
+                                  NULL,
+                                  0);
+        IWineD3DIndexBuffer_GetParent(This->indexbuffer,
+                                      (IUnknown **) &IndexBufferParent);
+        IParent_Release(IndexBufferParent); /* Once for the getParent */
+        if( IParent_Release(IndexBufferParent) != 0)  /* And now to destroy it */
+        {
+            ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
+        }
+
+        /* Restore the render targets */
+        if(This->OffScreenTarget)
+        {
+            /* This->target is the offscreen target.
+             * This->ddraw->d3d_target is the target used by DDraw
+             */
+            TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
+            IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
+                                               This->ddraw->d3d_target->WineD3DSurface,
+                                               NULL);
+        }
+
+        /* Release the WineD3DDevice. This won't destroy it */
+        if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
+        {
+            ERR(" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble\n", This, This->wineD3DDevice);
+        }
+
+        /* Release the render target and the WineD3D render target
+         * (See IDirect3D7::CreateDevice for more comments on this)
+         */
+        IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
+        IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
+
+        This->ddraw->d3ddevice = NULL;
+
+        /* Now free the structure */
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DDevice::Initialize
+ *
+ * Initializes a Direct3DDevice. This implementation is a no-op, as all
+ * initialization is done at create time.
+ *
+ * Exists in Version 1
+ *
+ * Parameters:
+ *  No idea what they mean, as the MSDN page is gone
+ *
+ * Returns: DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
+                                 IDirect3D *Direct3D, GUID *guid,
+                                 D3DDEVICEDESC *Desc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+
+    /* It shouldn't be crucial, but print a FIXME, I'm interested if
+     * any game calls it and when
+     */
+    FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetCaps
+ *
+ * Retrieves the device's capatiblities
+ *
+ * This implementation is used for Version 7 only, the older versions have
+ * their own implementation.
+ *
+ * Parameters:
+ *  Desc: Pointer to a D3DDEVICEDESC7 structure to fill
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_* if a problem occurs. See WineD3D
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
+                              D3DDEVICEDESC7 *Desc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    D3DDEVICEDESC OldDesc;
+    TRACE("(%p)->(%p)\n", This, Desc);
+
+    /* Call the same function used by IDirect3D, this saves code */
+    return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::GetCaps
+ *
+ * Retrieves the capatiblities of the hardware device and the emulation
+ * device. For Wine, hardware and emulation are the same(it's all HW).
+ *
+ * This implementation is used for Version 1, 2, and 3. Version 7 has its own
+ *
+ * Parameters:
+ *  HWDesc: Structure to fill with the HW caps
+ *  HelDesc: Structure to fill with the hardare emulation caps
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_* if a problem occurs. See WineD3D
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
+                              D3DDEVICEDESC *HWDesc,
+                              D3DDEVICEDESC *HelDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    D3DDEVICEDESC7 newDesc;
+    HRESULT hr;
+    TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
+
+    hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
+    if(hr != D3D_OK) return hr;
+
+    *HelDesc = *HWDesc;
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
+                                    D3DDEVICEDESC *D3DHWDevDesc,
+                                    D3DDEVICEDESC *D3DHELDevDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
+    return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                    D3DHWDevDesc,
+                                    D3DHELDevDesc);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
+                                    D3DDEVICEDESC *D3DHWDevDesc,
+                                    D3DDEVICEDESC *D3DHELDevDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
+    return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                    D3DHWDevDesc,
+                                    D3DHELDevDesc);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice2::SwapTextureHandles
+ *
+ * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
+ *
+ * Parameters:
+ *  Tex1, Tex2: The 2 Textures to swap
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
+                                         IDirect3DTexture2 *Tex1,
+                                         IDirect3DTexture2 *Tex2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IWineD3DTexture *tmp;
+    IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
+    IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
+    FIXME("(%p)->(%p,%p)\n", This, surf1, surf2);
+
+
+    /* The texture handle is simply the interface address of the WineD3DTexture
+     * interface. Swap the interface pointers.
+     */
+    tmp = surf1->wineD3DTexture;
+    surf1->wineD3DTexture = surf2->wineD3DTexture;
+    surf2->wineD3DTexture = tmp;
+
+    /* What about the parent? Does it have to change too? This could cause a
+     * problem when Releasing the surfaces, Therefore the fixme
+     */
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
+                                               IDirect3DTexture *D3DTex1,
+                                               IDirect3DTexture *D3DTex2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
+    IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
+    return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
+                                               ICOM_INTERFACE(surf1, IDirect3DTexture2),
+                                               ICOM_INTERFACE(surf2, IDirect3DTexture2));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::GetStats
+ *
+ * This method seems to retrieve some stats from the device.
+ * The MSDN documentation doesn't exist any more, but the D3DSTATS
+ * structure suggests that the amout of drawn primitives and processed
+ * vertices is returned.
+ *
+ * Exists in Version 1, 2 and 3
+ *
+ * Parameters:
+ *  Stats: Pointer to a D3DSTATS structure to be filled
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Stats == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
+                               D3DSTATS *Stats)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p)->(%p): Stub!\n", This, Stats);
+
+    if(!Stats)
+        return DDERR_INVALIDPARAMS;
+
+    /* Fill the Stats with 0 */
+    Stats->dwTrianglesDrawn = 0;
+    Stats->dwLinesDrawn = 0;
+    Stats->dwPointsDrawn = 0;
+    Stats->dwSpansDrawn = 0;
+    Stats->dwVerticesProcessed = 0;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
+                                     D3DSTATS *Stats)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
+    return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                     Stats);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
+                                     D3DSTATS *Stats)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
+    return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                     Stats);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::CreateExecuteBuffer
+ *
+ * Creates an IDirect3DExecuteBuffer, used for rendering with a
+ * Direct3DDevice.
+ *
+ * Version 1 only.
+ *
+ * Params:
+ *  Desc: Buffer description
+ *  ExecuteBuffer: Address to return the Interface pointer at
+ *  UnkOuter: Must be NULL. Basically for aggreation, which ddraw doesn't
+ *            support
+ *
+ * Returns:
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *  DDERR_OUTOFMEMORY if we ran out of memory
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
+                                          D3DEXECUTEBUFFERDESC *Desc,
+                                          IDirect3DExecuteBuffer **ExecuteBuffer,
+                                          IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DExecuteBufferImpl* object;
+    TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
+
+    if(UnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    /* Allocate the new Execute Buffer */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
+    if(!object)
+    {
+        ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
+        return DDERR_OUTOFMEMORY;
+    }
+
+    ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
+
+    object->ref = 1;
+    object->d3ddev = This;
+
+    /* Initializes memory */
+    memcpy(&object->desc, Desc, Desc->dwSize);
+
+    /* No buffer given */
+    if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
+        object->desc.lpData = NULL;
+
+    /* No buffer size given */
+    if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
+        object->desc.dwBufferSize = 0;
+
+    /* Create buffer if asked */
+    if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
+    {
+        object->need_free = TRUE;
+        object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
+        if(!object->desc.lpData)
+        {
+            ERR("Out of memory when allocating the execute buffer data\n");
+            HeapFree(GetProcessHeap(), 0, object);
+            return DDERR_OUTOFMEMORY;
+        }
+    }
+    else
+    {
+        object->need_free = FALSE;
+    }
+
+    /* No vertices for the moment */
+    object->vertex_data = NULL;
+
+    object->desc.dwFlags |= D3DDEB_LPDATA;
+
+    object->indices = NULL;
+    object->nb_indices = 0;
+
+    *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
+
+    TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::Execute
+ *
+ * Executes all the stuff in an execute buffer.
+ *
+ * Params:
+ *  ExecuteBuffer: The buffer to execute
+ *  Viewport: The viewport used for rendering
+ *  Flags: Some flags
+ *
+ * Returns:
+ *  DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
+ *  D3D_OK on sucess
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
+                              IDirect3DExecuteBuffer *ExecuteBuffer,
+                              IDirect3DViewport *Viewport,
+                              DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
+    IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
+
+    TRACE("(%p)->(%p,%p,%08lx)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
+
+    if(!Direct3DExecuteBufferImpl)
+        return DDERR_INVALIDPARAMS;
+
+    /* Execute... */
+    IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::AddViewport
+ *
+ * Add a Direct3DViewport to the device's viewport list. These viewports
+ * are wrapped to IDirect3DDevice7 viewports in viewport.c
+ *
+ * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
+ * are the same interfaces.
+ *
+ * Params:
+ *  Viewport: The viewport to add
+ *
+ * Returns:
+ *  DDERR_INVALIDPARAMS if Viewport == NULL
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
+                                  IDirect3DViewport3 *Viewport)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
+
+    TRACE("(%p)->(%p)\n", This, vp);
+
+    /* Sanity check */
+    if(!vp)
+        return DDERR_INVALIDPARAMS;
+
+    vp->next = This->viewport_list;
+    This->viewport_list = vp;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
+                                        IDirect3DViewport2 *Direct3DViewport2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
+    return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                        ICOM_INTERFACE(vp, IDirect3DViewport3));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
+                                        IDirect3DViewport *Direct3DViewport)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
+    return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                        ICOM_INTERFACE(vp, IDirect3DViewport3));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::DeleteViewport
+ *
+ * Deletes a Direct3DViewport from the device's viewport list.
+ *
+ * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
+ * are equal.
+ *
+ * Params:
+ *  Viewport: The viewport to delete
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the viewport wasn't found in the list
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
+                                     IDirect3DViewport3 *Viewport)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
+    IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
+
+    TRACE("(%p)->(%p)\n", This, vp);
+
+    cur_viewport = This->viewport_list;
+    while (cur_viewport != NULL)
+    {
+        if (cur_viewport == vp)
+        {
+            if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
+            else prev_viewport->next = cur_viewport->next;
+            /* TODO : add desactivate of the viewport and all associated lights... */
+            return D3D_OK;
+        }
+        prev_viewport = cur_viewport;
+        cur_viewport = cur_viewport->next;
+    }
+
+    return DDERR_INVALIDPARAMS;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
+                                           IDirect3DViewport2 *Direct3DViewport2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
+    return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                           ICOM_INTERFACE(vp, IDirect3DViewport3));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
+                                           IDirect3DViewport *Direct3DViewport2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
+    return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                           ICOM_INTERFACE(vp, IDirect3DViewport3));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::NextViewport
+ *
+ * Returns an viewport from the viewport list, depending on the
+ * passed viewport and the flags.
+ *
+ * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
+ * are equal.
+ *
+ * Params:
+ *  Viewport: Viewport to use for beginning the search
+ *  Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the flags were wrong, ir Viewport was NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
+                                   IDirect3DViewport3 *Viewport3,
+                                   IDirect3DViewport3 **lplpDirect3DViewport3,
+                                   DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
+    IDirect3DViewportImpl *res = NULL;
+
+    TRACE("(%p)->(%p,%p,%08lx)\n", This, vp, lplpDirect3DViewport3, Flags);
+
+    if(!vp)
+    {
+        return DDERR_INVALIDPARAMS;
+        *lplpDirect3DViewport3 = NULL;
+    }
+
+
+    switch (Flags)
+    {
+        case D3DNEXT_NEXT:
+        {
+            res = vp->next;
+        }
+        break;
+        case D3DNEXT_HEAD:
+        {
+            res = This->viewport_list;
+        }
+        break;
+        case D3DNEXT_TAIL:
+        {
+            IDirect3DViewportImpl *cur_viewport = This->viewport_list;
+            if (cur_viewport != NULL)
+            {
+                while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
+            }
+            res = cur_viewport;
+        }
+        break;
+        default:
+            *lplpDirect3DViewport3 = NULL;
+            return DDERR_INVALIDPARAMS;
+    }
+
+    *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
+                                         IDirect3DViewport2 *Viewport2,
+                                         IDirect3DViewport2 **lplpDirect3DViewport2,
+                                         DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
+    IDirect3DViewport3 *res;
+    HRESULT hr;
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
+    hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                       ICOM_INTERFACE(vp, IDirect3DViewport3),
+                                       &res,
+                                       Flags);
+    *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
+    return hr;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
+                                         IDirect3DViewport *Viewport,
+                                         IDirect3DViewport **lplpDirect3DViewport,
+                                         DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
+    IDirect3DViewport3 *res;
+    HRESULT hr;
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
+    hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                       ICOM_INTERFACE(vp, IDirect3DViewport3),
+                                       &res,
+                                       Flags);
+    *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::Pick
+ *
+ * Executes an execute buffer without performing rendering. Instead, a
+ * list of primitives that intersect with (x1,y1) of the passed rectangle
+ * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
+ * this list.
+ *
+ * Version 1 only
+ *
+ * Params:
+ *  ExecuteBuffer: Buffer to execute
+ *  Viewport: Viewport to use for execution
+ *  Flags: None are defined, according to the SDK
+ *  Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
+ *        x2 and y2 are ignored.
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
+                           IDirect3DExecuteBuffer *ExecuteBuffer,
+                           IDirect3DViewport *Viewport,
+                           DWORD Flags,
+                           D3DRECT *Rect)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
+    FIXME("(%p)->(%p,%p,%08lx,%p): stub!\n", This, execbuf, vp, Flags, Rect);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::GetPickRecords
+ *
+ * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
+ *
+ * Version 1 only
+ *
+ * Params:
+ *  Count: Pointer to a DWORD containing the numbers of pick records to
+ *         retrieve
+ *  D3DPickRec: Address to store the resulting D3DPICKRECORD arry.
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
+                                     DWORD *Count,
+                                     D3DPICKRECORD *D3DPickRec)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * EnumTextureFormatsCB
+ *
+ * Callback called by WineD3D for each enumerated Texture format. It
+ * translates the WineD3DFormat into a ddraw pixel format and calls
+ * the application callback
+ *
+ * Params:
+ *  Device: The WineD3DDevice's parents = The IDirect3DDevice7 interface
+ *          of our device
+ *  fmt: An enumerated pixel format
+ *  Context: Data pointer passed to WineD3D by
+ *           IDirect3DDevice7::EnumTexureformats
+ *
+ * Returns:
+ *  The return value of the application-provided callback
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+EnumTextureFormatsCB(IUnknown *Device,
+                     WINED3DFORMAT fmt,
+                     void *Context)
+{
+    struct EnumTextureFormatsCBS *cbs = (struct EnumTextureFormatsCBS *) Context;
+
+    DDSURFACEDESC sdesc;
+    DDPIXELFORMAT *pformat;
+
+    memset(&sdesc, 0, sizeof(DDSURFACEDESC));
+    sdesc.dwSize = sizeof(DDSURFACEDESC);
+    sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
+    sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    pformat = &(sdesc.ddpfPixelFormat);
+    pformat->dwSize = sizeof(DDPIXELFORMAT);
+
+    PixelFormat_WineD3DtoDD(pformat, fmt);
+
+    if( ( fmt == WINED3DFMT_UYVY)        ||
+        ( fmt == WINED3DFMT_YUY2)        ||
+        ( fmt == WINED3DFMT_DXT1)        ||
+        ( fmt == WINED3DFMT_DXT2)        ||
+        ( fmt == WINED3DFMT_DXT3)        ||
+        ( fmt == WINED3DFMT_DXT4)        ||
+        ( fmt == WINED3DFMT_DXT5)        ||
+        ( fmt == WINED3DFMT_MULTI2_ARGB) ||
+        ( fmt == WINED3DFMT_G8R8_G8B8)   ||
+        ( fmt == WINED3DFMT_R8G8_B8G8)   ||
+        ( fmt == WINED3DFMT_L8)          ||
+        ( fmt == WINED3DFMT_A8L8)        ||
+        ( fmt == WINED3DFMT_A4L4)        ||
+        ( fmt == WINED3DFMT_V8U8)        ||
+        ( fmt == WINED3DFMT_L6V5U5)      )
+    {
+        /* These formats exist exist in D3D3 and D3D7 only,
+         * so do not call the older callback
+         */
+        if(cbs->cbv7) return cbs->cbv7(pformat, cbs->Context);
+    }
+    else
+    {
+        /* Only one of these should be passed */
+        if(cbs->cbv2) return cbs->cbv2(&sdesc, cbs->Context);
+        if(cbs->cbv7) return cbs->cbv7(pformat, cbs->Context);
+    }
+
+    return DDENUMRET_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::EnumTextureformats
+ *
+ * Enumerates the supported texture formats. This is relayed to WineD3D,
+ * and a EnumTextureFormatsCB translated the WineD3DFormats to DDraw
+ * formats and calls the application callback.
+ *
+ * This is for Version 7 and 3, the older versions have a different
+ * callback function and their own implementation
+ *
+ * Params:
+ *  Callback: Callback to call for each enumerated format
+ *  Arg: Argument to pass to the callback
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Callback == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
+                                         LPD3DENUMPIXELFORMATSCALLBACK Callback,
+                                         void *Arg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    struct EnumTextureFormatsCBS cbs = { NULL, Callback, Arg };
+    TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
+
+    if(!Callback)
+        return DDERR_INVALIDPARAMS;
+
+    hr = IWineD3DDevice_EnumTextureFormats(This->wineD3DDevice,
+                                           EnumTextureFormatsCB,
+                                           &cbs);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
+                                               LPD3DENUMPIXELFORMATSCALLBACK Callback,
+                                               void *Arg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
+    return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                               Callback,
+                                               Arg);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice2::EnumTextureformats
+ *
+ * EnumTextureFormats for Version 1 and 2, see
+ * IDirect3DDevice7::EnumTexureFormats for a more detailed description
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
+                                         LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
+                                         void *Arg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    HRESULT hr;
+    struct EnumTextureFormatsCBS cbs = { Callback, NULL, Arg };
+    TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
+
+    hr = IWineD3DDevice_EnumTextureFormats(This->wineD3DDevice,
+                                           EnumTextureFormatsCB,
+                                           &cbs);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
+                                               LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
+                                               void *Arg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
+    return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
+                                               Callback,
+                                               Arg);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::CreateMatrix
+ *
+ * Creates a matrix handle. In Wine, Matrix handles are simply pointers
+ * to a D3DMATRIX structure
+ *
+ * Version 1 only
+ *
+ * Params
+ *  D3DMatHandle: Address to return the handle at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if D3DMatHandle = NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p)->(%p)\n", This, D3DMatHandle);
+
+    if(!D3DMatHandle)
+        return DDERR_INVALIDPARAMS;
+
+    *D3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
+    TRACE(" returning matrix handle %p\n", (void *) *D3DMatHandle);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::SetMatrix
+ *
+ * Sets a matrix for a matrix handle. As matrix handles are pointers to
+ * a D3DMATRIX structure, the matrix is simply copied into the allocated
+ * memory.
+ *
+ * Version 1 only
+ *
+ * Params:
+ *  D3DMatHandle: Handle to set the matrix to
+ *  D3DMatrix: Matrix to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the handle of the matrix is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
+                                D3DMATRIXHANDLE D3DMatHandle,
+                                D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p)->(%08lx,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix);
+
+    if( (!D3DMatHandle) || (!D3DMatrix) )
+        return DDERR_INVALIDPARAMS;
+
+    if (TRACE_ON(d3d7))
+        dump_D3DMATRIX(D3DMatrix);
+
+    *((D3DMATRIX *) D3DMatHandle) = *D3DMatrix;
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::SetMatrix
+ *
+ * Returns the content of a D3DMATRIX handle
+ *
+ * Version 1 only
+ *
+ * Params:
+ *  D3DMatHandle: Matrix handle to read the content from
+ *  D3DMatrix: Address to store the content at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if D3DMatHandle or D3DMatrix are NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
+                                D3DMATRIXHANDLE D3DMatHandle,
+                                D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p)->(%08lx,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix);
+
+    if(!D3DMatrix)
+        return DDERR_INVALIDPARAMS;
+    if(!(D3DMATRIX *) D3DMatHandle)
+        return DDERR_INVALIDPARAMS;
+
+    /* The handle is simply a pointer to a D3DMATRIX structure */
+    *D3DMatrix = *((D3DMATRIX *) D3DMatHandle);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::DeleteMatrix
+ *
+ * Destroys a Matrix handle.
+ *
+ * Version 1 only
+ *
+ * Params:
+ *  D3DMatHandle: Handle to destroy
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if D3DMatHandle is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
+                                   D3DMATRIXHANDLE D3DMatHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p)->(%08lx)\n", This, (DWORD) D3DMatHandle);
+
+    if(!(D3DMATRIX *) D3DMatHandle)
+        return DDERR_INVALIDPARAMS;
+
+    HeapFree(GetProcessHeap(), 0, (void *) D3DMatHandle);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::BeginScene
+ *
+ * This method must be called before any rendering is performed.
+ * IDirect3DDevice::EndScene has to be called after the scene is complete
+ *
+ * Version 1, 2, 3 and 7
+ *
+ * Returns:
+ *  D3D_OK on sucess, for details see IWineD3DDevice::BeginScene
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p): Relay\n", This);
+
+    return IWineD3DDevice_BeginScene(This->wineD3DDevice);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::EndScene
+ *
+ * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
+ * This method must be called after rendering is finished.
+ *
+ * Version 1, 2, 3 and 7
+ *
+ * Returns:
+ *  D3D_OK on success, for details see IWineD3DDevice::EndScene
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p): Relay\n", This);
+
+    IWineD3DDevice_EndScene(This->wineD3DDevice);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
+    return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetDirect3D
+ *
+ * Returns the IDirect3D(= interface to the DirectDraw object) used to create
+ * this device.
+ *
+ * Params:
+ *  Direct3D7: Address to store the interface pointer at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Direct3D7 == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
+                                  IDirect3D7 **Direct3D7)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%p)\n", This, Direct3D7);
+
+    if(!Direct3D7)
+        return DDERR_INVALIDPARAMS;
+
+    *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
+    IDirect3D7_AddRef(*Direct3D7);
+
+    TRACE(" returning interface %p\n", *Direct3D7);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
+                                        IDirect3D3 **Direct3D3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    HRESULT ret;
+    IDirect3D7 *ret_ptr;
+
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
+    ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                       &ret_ptr);
+    if(ret != D3D_OK)
+        return ret;
+    *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
+    TRACE(" returning interface %p\n", *Direct3D3);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
+                                        IDirect3D2 **Direct3D2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    HRESULT ret;
+    IDirect3D7 *ret_ptr;
+
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
+    ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                       &ret_ptr);
+    if(ret != D3D_OK)
+        return ret;
+    *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
+    TRACE(" returning interface %p\n", *Direct3D2);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
+                                        IDirect3D **Direct3D)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    HRESULT ret;
+    IDirect3D7 *ret_ptr;
+
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
+    ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                       &ret_ptr);
+    if(ret != D3D_OK)
+        return ret;
+    *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
+    TRACE(" returning interface %p\n", *Direct3D);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::SetCurrentViewport
+ *
+ * Sets a Direct3DViewport as the current viewport.
+ * For the thunks note that all viewport interface versions are equal
+ *
+ * Params:
+ *  Direct3DViewport3: The viewport to set
+ *
+ * Version 2 and 3
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  (Is a NULL viewport valid?)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
+                                         IDirect3DViewport3 *Direct3DViewport3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
+    TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
+
+    /* Do nothing if the specified viewport is the same as the current one */
+    if (This->current_viewport == vp )
+      return D3D_OK;
+
+    /* Should check if the viewport was added or not */
+
+    /* Release previous viewport and AddRef the new one */
+    if (This->current_viewport)
+    {
+        TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
+        IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
+    }
+    IDirect3DViewport3_AddRef(Direct3DViewport3);
+
+    /* Set this viewport as the current viewport */
+    This->current_viewport = vp;
+
+    /* Activate this viewport */
+    This->current_viewport->active_device = This;
+    This->current_viewport->activate(This->current_viewport);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
+                                               IDirect3DViewport2 *Direct3DViewport2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
+    return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                               ICOM_INTERFACE(vp, IDirect3DViewport3));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::GetCurrentViewport
+ *
+ * Returns the currently active viewport.
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  Direct3DViewport3: Address to return the interface pointer at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Direct3DViewport == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
+                                         IDirect3DViewport3 **Direct3DViewport3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
+
+    if(!Direct3DViewport3)
+        return DDERR_INVALIDPARAMS;
+
+    *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
+
+    /* AddRef the returned viewport */
+    IDirect3DViewport3_AddRef(*Direct3DViewport3);
+
+    TRACE(" returning interface %p\n", *Direct3DViewport3);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
+                                               IDirect3DViewport2 **Direct3DViewport2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    HRESULT hr;
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
+    hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                            (IDirect3DViewport3 **) Direct3DViewport2);
+    if(hr != D3D_OK) return hr;
+    *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, Direct3DViewport2);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetRenderTarget
+ *
+ * Sets the render target for the Direct3DDevice.
+ * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
+ * IDirectDrawSurface3 == IDirectDrawSurface
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
+ *             render target
+ *  Flags: Some flags
+ *
+ * Returns:
+ *  D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
+                                      IDirectDrawSurface7 *NewTarget,
+                                      DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
+    TRACE("(%p)->(%p,%08lx): Relay\n", This, NewTarget, Flags);
+
+    /* Flags: Not used */
+
+    return IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
+                                          0,
+                                          Target ? Target->WineD3DSurface : NULL);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
+                                            IDirectDrawSurface4 *NewRenderTarget,
+                                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
+    return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                            ICOM_INTERFACE(Target, IDirectDrawSurface7),
+                                            Flags);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
+                                            IDirectDrawSurface *NewRenderTarget,
+                                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
+    return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                            ICOM_INTERFACE(Target, IDirectDrawSurface7),
+                                            Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetRenderTarget
+ *
+ * Returns the current render target.
+ * This is handled locally, because the WineD3D render target's parent
+ * is an IParent
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  RenderTarget: Address to store the surface interface pointer
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if RenderTarget == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
+                                      IDirectDrawSurface7 **RenderTarget)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
+
+    if(!RenderTarget)
+        return DDERR_INVALIDPARAMS;
+
+    *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
+    IDirectDrawSurface7_AddRef(*RenderTarget);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
+                                            IDirectDrawSurface4 **RenderTarget)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    HRESULT hr;
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
+    hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          (IDirectDrawSurface7 **) RenderTarget);
+    if(hr != D3D_OK) return hr;
+    *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, RenderTarget);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
+                                            IDirectDrawSurface **RenderTarget)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    HRESULT hr;
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
+    hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          (IDirectDrawSurface7 **) RenderTarget);
+    if(hr != D3D_OK) return hr;
+    *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, RenderTarget);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::Begin
+ *
+ * Begins a description block of vertices. This is simmilar to glBegin()
+ * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
+ * described with IDirect3DDevice::Vertex are drawn.
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  PrimitiveType: The type of primitives to draw
+ *  VertexTypeDesc: A flexible vertex format description of the vertices
+ *  Flags: Some flags..
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
+                            D3DPRIMITIVETYPE PrimitiveType,
+                            DWORD VertexTypeDesc,
+                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p)->(%d,%ld,%08lx)\n", This, PrimitiveType, VertexTypeDesc, Flags);
+
+    This->primitive_type = PrimitiveType;
+    This->vertex_type = VertexTypeDesc;
+    This->render_flags = Flags;
+    This->vertex_size = get_flexible_vertex_size(This->vertex_type);
+    This->nb_vertices = 0;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
+                                  D3DPRIMITIVETYPE d3dpt,
+                                  D3DVERTEXTYPE dwVertexTypeDesc,
+                                  DWORD dwFlags)
+{
+    DWORD FVF;
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08lx): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
+
+    switch(dwVertexTypeDesc)
+    {
+        case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
+        case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
+        case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
+        default:
+            assert(0);  /* Should never happen */
+    };
+
+    return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                  d3dpt,
+                                  FVF,
+                                  dwFlags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::BeginIndexed
+ *
+ * Draws primitives based on vertices in a vertex array which are specified
+ * by indices.
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  PrimitiveType: Primitive type to draw
+ *  VertexType: A FVF description of the vertex format
+ *  Vertices: pointer to an array containg the vertices
+ *  NumVertices: The number of vertices in the vertex array
+ *  Flags: Some flags ...
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
+                                   D3DPRIMITIVETYPE PrimitiveType,
+                                   DWORD VertexType,
+                                   void *Vertices,
+                                   DWORD NumVertices,
+                                   DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
+    return D3D_OK;
+}
+
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
+                                         D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                         D3DVERTEXTYPE d3dvtVertexType,
+                                         void *lpvVertices,
+                                         DWORD dwNumVertices,
+                                         DWORD dwFlags)
+{
+    DWORD FVF;
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
+
+    switch(d3dvtVertexType)
+    {
+        case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
+        case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
+        case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
+        default:
+            assert(0);  /* Should never happen */
+    };
+
+    return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
+                                         d3dptPrimitiveType,
+                                         FVF,
+                                         lpvVertices,
+                                         dwNumVertices,
+                                         dwFlags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::Vertex
+ *
+ * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
+ * drawn vertices in an vertex buffer. If the buffer is to small, its
+ * size is increased.
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  Vertex: Pointer to the vertex
+ *
+ * Returns:
+ *  D3D_OK, on success
+ *  DDERR_INVALIDPARAMS if Vertex is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
+                             void *Vertex)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p)->(%p)\n", This, Vertex);
+
+    if(!Vertex)
+        return DDERR_INVALIDPARAMS;
+
+    if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
+    {
+        BYTE *old_buffer;
+        This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
+        old_buffer = This->vertex_buffer;
+        This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
+        if (old_buffer)
+        {
+            CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
+            HeapFree(GetProcessHeap(), 0, old_buffer);
+        }
+    }
+
+    CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
+                                   void *lpVertexType)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
+    return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                                  lpVertexType);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::Index
+ *
+ * Specifies an index to an vertex to be drawn. The vertex array has to
+ * be specified with BeginIndexed first.
+ *
+ * Parameters:
+ *  VertexIndex: The index of the vertex to draw
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
+                            WORD VertexIndex)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
+                                  WORD wVertexIndex)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
+    return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                  wVertexIndex);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::End
+ *
+ * Ends a draw begun with IDirect3DDevice3::Begin or
+ * IDirect3DDevice::BeginIndexed. The vertices specified with
+ * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
+ * the IDirect3DDevice7::DrawPrimitive method. So far only
+ * non-indexed mode is supported
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  Flags: Some flags, as usual. Don't know which are defined
+ *
+ * Returns:
+ *  The return value of IDirect3DDevice7::DrawPrimitive
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
+                          DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p)->(%08lx)\n", This, Flags);
+
+    return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          This->primitive_type, This->vertex_type,
+                                          This->vertex_buffer, This->nb_vertices,
+                                          This->render_flags);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
+                                DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08lx) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
+    return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                dwFlags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetRenderState
+ *
+ * Returns the value of a render state. The possible render states are
+ * defined in include/d3dtypes.h
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  RenderStateType: Render state to return the current setting of
+ *  Value: Address to store the value at
+ *
+ * Returns:
+ *  D3D_OK on success, for details see IWineD3DDevice::GetRenderState
+ *  DDERR_INVALIDPARAMS if Value == NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
+                                     D3DRENDERSTATETYPE RenderStateType,
+                                     DWORD *Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
+
+    if(!Value)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_GetRenderState(This->wineD3DDevice,
+                                         RenderStateType,
+                                         Value);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD *lpdwRenderState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
+    return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           dwRenderStateType,
+                                           lpdwRenderState);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD *lpdwRenderState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
+    return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           dwRenderStateType,
+                                           lpdwRenderState);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetRenderState
+ *
+ * Sets a render state. The possible render states are defined in
+ * include/d3dtypes.h
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  RenderStateType: State to set
+ *  Value: Value to assign to that state
+ *
+ * Returns:
+ *  D3D_OK on success,
+ *  for details see IWineD3DDevice::SetRenderState
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
+                                     D3DRENDERSTATETYPE RenderStateType,
+                                     DWORD Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08x,%ld): Relay\n", This, RenderStateType, Value);
+
+    /* Some render states need special care */
+    switch(RenderStateType)
+    {
+        case D3DRENDERSTATE_TEXTUREHANDLE:
+            return IWineD3DDevice_SetTexture(This->wineD3DDevice,
+                                             0,
+                                             (IWineD3DBaseTexture *) Value);
+
+        case D3DRENDERSTATE_TEXTUREMAG:
+        {
+            WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
+
+            switch ((D3DTEXTUREFILTER) Value)
+            {
+                case D3DFILTER_NEAREST:
+                    tex_mag = WINED3DTEXF_POINT;
+                    break;
+                case D3DFILTER_LINEAR:
+                    tex_mag = WINED3DTEXF_LINEAR;
+                    break;
+                default:
+                    ERR("Unhandled texture mag %ld !\n",Value);
+            }
+
+            return IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+                                                  0, WINED3DSAMP_MAGFILTER,
+                                                  tex_mag);
+        }
+
+        case D3DRENDERSTATE_TEXTUREMIN:
+        {
+            WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
+
+            switch ((D3DTEXTUREFILTER) Value)
+            {
+                case D3DFILTER_NEAREST:
+                    tex_min = WINED3DTEXF_POINT;
+                    break;
+                case D3DFILTER_LINEAR:
+                    tex_min = WINED3DTEXF_LINEAR;
+                    break;
+                default:
+                    ERR("Unhandled texture mag %ld !\n",Value);
+            }
+
+            return IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+                                                  0, WINED3DSAMP_MINFILTER,
+                                                  tex_min);
+        }
+
+        case D3DRENDERSTATE_TEXTUREADDRESSU:
+        case D3DRENDERSTATE_TEXTUREADDRESSV:
+        case D3DRENDERSTATE_TEXTUREADDRESS:
+        {
+            WINED3DTEXTURESTAGESTATETYPE TexStageStateType;
+
+            if (RenderStateType == D3DRENDERSTATE_TEXTUREADDRESS)
+            {
+                TexStageStateType = WINED3DTSS_ADDRESS;
+            }
+            else if (RenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU)
+            {
+                TexStageStateType = WINED3DTSS_ADDRESSU;
+            }
+            else
+            {
+                TexStageStateType = WINED3DTSS_ADDRESSV;
+            }
+
+            return IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
+                                                       0, TexStageStateType,
+                                                       Value);
+        }
+
+        default:
+            return IWineD3DDevice_SetRenderState(This->wineD3DDevice,
+                                                 RenderStateType,
+                                                 Value);
+    }
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
+                                           D3DRENDERSTATETYPE RenderStateType,
+                                           DWORD Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
+    return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           RenderStateType,
+                                           Value);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
+                                           D3DRENDERSTATETYPE RenderStateType,
+                                           DWORD Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
+    return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           RenderStateType,
+                                           Value);
+}
+
+/*****************************************************************************
+ * Direct3DDevice3::SetLightState
+ *
+ * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
+ * light states are forwarded to Direct3DDevice7 render states
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  LightStateType: The light state to change
+ *  Value: The value to assign to that light state
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the paramters were incorrect
+ *  Also check IDirect3DDevice7::SetRenderState
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
+                                    D3DLIGHTSTATETYPE LightStateType,
+                                    DWORD Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+
+    TRACE("(%p)->(%08x,%08lx)\n", This, LightStateType, Value);
+
+    if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
+    {
+        TRACE("Unexpected Light State Type\n");
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
+    {
+        IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) Value;
+
+        if (mat != NULL)
+        {
+            TRACE(" activating material %p.\n", mat);
+            mat->activate(mat);
+        }
+        else
+        {
+            FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
+        }
+        This->material = Value;
+    }
+    else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
+    {
+        switch (Value)
+        {
+            case D3DCOLOR_MONO:
+                ERR("DDCOLOR_MONO should not happen!\n");
+                break;
+            case D3DCOLOR_RGB:
+                /* We are already in this mode */
+                TRACE("Setting color model to RGB (no-op).\n");
+                break;
+            default:
+                ERR("Unknown color model!\n");
+                return DDERR_INVALIDPARAMS;
+        }
+    }
+    else
+    {
+        D3DRENDERSTATETYPE rs;
+        switch (LightStateType)
+        {
+            case D3DLIGHTSTATE_AMBIENT:       /* 2 */
+                rs = D3DRENDERSTATE_AMBIENT;
+                break;		
+            case D3DLIGHTSTATE_FOGMODE:       /* 4 */
+                rs = D3DRENDERSTATE_FOGVERTEXMODE;
+                break;
+            case D3DLIGHTSTATE_FOGSTART:      /* 5 */
+                rs = D3DRENDERSTATE_FOGSTART;
+                break;
+            case D3DLIGHTSTATE_FOGEND:        /* 6 */
+                rs = D3DRENDERSTATE_FOGEND;
+                break;
+            case D3DLIGHTSTATE_FOGDENSITY:    /* 7 */
+                rs = D3DRENDERSTATE_FOGDENSITY;
+                break;
+            case D3DLIGHTSTATE_COLORVERTEX:   /* 8 */
+                rs = D3DRENDERSTATE_COLORVERTEX;
+                break;
+            default:
+                ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
+                return DDERR_INVALIDPARAMS;
+        }
+
+        return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), 
+                                               rs,
+                                               Value);
+    }
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
+                                          D3DLIGHTSTATETYPE LightStateType,
+                                          DWORD Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
+    return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                          LightStateType,
+                                          Value);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice3::GetLightState
+ *
+ * Returns the current setting of a light state. The state is read from
+ * the Direct3DDevice7 render state.
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ *  LightStateType: The light state to return
+ *  Value: The address to store the light state setting at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDDERR_INVALIDPARAMS if the parameters were incorrect
+ *  Also see IDirect3DDevice7::GetRenderState
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
+                                    D3DLIGHTSTATETYPE LightStateType,
+                                    DWORD *Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+
+    TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
+
+    if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
+    {
+        TRACE("Unexpected Light State Type\n");
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(!Value)
+        return DDERR_INVALIDPARAMS;
+
+    if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
+    {
+        *Value = This->material;
+    }
+    else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
+    {
+        *Value = D3DCOLOR_RGB;
+    }
+    else
+    {
+        D3DRENDERSTATETYPE rs;
+        switch (LightStateType)
+        {
+            case D3DLIGHTSTATE_AMBIENT:       /* 2 */
+                rs = D3DRENDERSTATE_AMBIENT;
+                break;		
+            case D3DLIGHTSTATE_FOGMODE:       /* 4 */
+                rs = D3DRENDERSTATE_FOGVERTEXMODE;
+                break;
+            case D3DLIGHTSTATE_FOGSTART:      /* 5 */
+                rs = D3DRENDERSTATE_FOGSTART;
+                break;
+            case D3DLIGHTSTATE_FOGEND:        /* 6 */
+                rs = D3DRENDERSTATE_FOGEND;
+                break;
+            case D3DLIGHTSTATE_FOGDENSITY:    /* 7 */
+                rs = D3DRENDERSTATE_FOGDENSITY;
+                break;
+            case D3DLIGHTSTATE_COLORVERTEX:   /* 8 */
+                rs = D3DRENDERSTATE_COLORVERTEX;
+                break;
+            default:
+                ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
+                return DDERR_INVALIDPARAMS;
+        }
+
+        return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                               rs,
+                                               Value);
+    }
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
+                                          D3DLIGHTSTATETYPE LightStateType,
+                                          DWORD *Value)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
+    return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
+                                          LightStateType,
+                                          Value);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetTransform
+ *
+ * Assignes a D3DMATRIX to a transform type. The transform types are defined
+ * in include/d3dtypes.h.
+ * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
+ * (=255) for wined3d, because the 1 transform state was removed in d3d8
+ * and WineD3D allready understands the replacement D3DTS_WORLDMATRIX(0)
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  TransformStateType: transform state to set
+ *  Matrix: Matrix to assign to the state
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Matrix == NULL
+ *  For details see IWineD3DDevice::SetTransform
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
+                                   D3DTRANSFORMSTATETYPE TransformStateType,
+                                   D3DMATRIX *Matrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    D3DTRANSFORMSTATETYPE type = TransformStateType;
+    TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
+
+    if(!Matrix)
+        return DDERR_INVALIDPARAMS;
+
+    /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D,
+     * use D3DTS_WORLDMATRIX(0) instead
+     * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256)
+     */
+    if(TransformStateType == D3DTRANSFORMSTATE_WORLD)
+        type = (D3DTRANSFORMSTATETYPE)(0 + 256);
+
+    return IWineD3DDevice_SetTransform(This->wineD3DDevice,
+                                       type,
+                                       Matrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
+                                         D3DTRANSFORMSTATETYPE TransformStateType,
+                                         D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                         TransformStateType,
+                                         D3DMatrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
+                                         D3DTRANSFORMSTATETYPE TransformStateType,
+                                         D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                         TransformStateType,
+                                         D3DMatrix);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetTransform
+ *
+ * Returns the matrix assigned to a transform state
+ * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
+ * SetTransform
+ *
+ * Params:
+ *  TransformStateType: State to read the matrix from
+ *  Matrix: Address to store the matrix at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Matrix == NULL
+ *  For details, see IWineD3DDevice::GetTransform
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
+                                   D3DTRANSFORMSTATETYPE TransformStateType,
+                                   D3DMATRIX *Matrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    D3DTRANSFORMSTATETYPE type = TransformStateType;
+    TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
+
+    if(!Matrix)
+        return DDERR_INVALIDPARAMS;
+
+    /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D,
+     * use D3DTS_WORLDMATRIX(0) instead
+     * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256)
+     */
+    if(TransformStateType == D3DTRANSFORMSTATE_WORLD)
+        type = (D3DTRANSFORMSTATETYPE)(0 + 256);
+
+    return IWineD3DDevice_GetTransform(This->wineD3DDevice, type, Matrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
+                                         D3DTRANSFORMSTATETYPE TransformStateType,
+                                         D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                         TransformStateType,
+                                         D3DMatrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
+                                         D3DTRANSFORMSTATETYPE TransformStateType,
+                                         D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                         TransformStateType,
+                                         D3DMatrix);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::MultiplyTransform
+ *
+ * Multiplies the already-set transform matrix of a transform state
+ * with another matrix. For the world matrix, see SetTransform
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  TransformStateType: Transform state to multiply
+ *  D3DMatrix Matrix to multiply with.
+ *
+ * Returns
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if D3DMatrix is NULL
+ *  For details, see IWineD3DDevice::MultiplyTransform
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
+                                        D3DTRANSFORMSTATETYPE TransformStateType,
+                                        D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
+
+    /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D,
+     * use D3DTS_WORLDMATRIX(0) instead
+     * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256)
+     */
+    if(TransformStateType == D3DTRANSFORMSTATE_WORLD)
+        TransformStateType = (D3DTRANSFORMSTATETYPE)(0 + 256);
+
+    return IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
+                                            TransformStateType,
+                                            D3DMatrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
+                                              D3DTRANSFORMSTATETYPE TransformStateType,
+                                              D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                              TransformStateType,
+                                              D3DMatrix);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
+                                              D3DTRANSFORMSTATETYPE TransformStateType,
+                                              D3DMATRIX *D3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
+    return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                              TransformStateType,
+                                              D3DMatrix);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::DrawPrimitive
+ *
+ * Draws primitves based on vertices in an application-provided pointer
+ *
+ * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
+ * an FVF format for D3D7
+ *
+ * Params:
+ *  PrimitiveType: The type of the primitives to draw
+ *  Vertex type: Flexible vertex format vertex description
+ *  Vertices: Pointer to the vertex array
+ *  VertexCount: The number of vertices to draw
+ *  Flags: As usual a few flags
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Vertices is NULL
+ *  For details, see IWineD3DDevice::DrawPrimitiveUP
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
+                                    D3DPRIMITIVETYPE PrimitiveType,
+                                    DWORD VertexType,
+                                    void *Vertices,
+                                    DWORD VertexCount,
+                                    DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    UINT PrimitiveCount, stride;
+    HRESULT hr;
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
+
+    if(!Vertices)
+        return DDERR_INVALIDPARAMS;
+
+    /* Get the vertex count */
+    switch(PrimitiveType)
+    {
+      case D3DPT_POINTLIST: 
+        PrimitiveCount = VertexCount;
+        break;
+
+      case D3DPT_LINELIST: 
+        PrimitiveCount = VertexCount / 2;
+        break;
+
+      case D3DPT_LINESTRIP:
+        PrimitiveCount = VertexCount - 1;
+        break;
+
+      case D3DPT_TRIANGLELIST:
+        PrimitiveCount = VertexCount / 3;
+        break;
+
+      case D3DPT_TRIANGLESTRIP:
+        PrimitiveCount = VertexCount - 2;
+        break;
+
+      case D3DPT_TRIANGLEFAN:
+        PrimitiveCount = VertexCount - 2;
+        break;
+
+      default: return DDERR_INVALIDPARAMS;
+    }
+
+    /* Get the stride */
+    stride = get_flexible_vertex_size(VertexType);
+
+    /* Set the FVF */
+    hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, VertexType);
+    if(hr != D3D_OK) return hr;
+
+    /* This method translates to the user pointer draw of WineD3D */
+    return IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
+                                          PrimitiveType,
+                                          PrimitiveCount,
+                                          Vertices,
+                                          stride);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
+                                          D3DPRIMITIVETYPE PrimitiveType,
+                                          DWORD VertexType,
+                                          void *Vertices,
+                                          DWORD VertexCount,
+                                          DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
+    return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          PrimitiveType,
+                                          VertexType,
+                                          Vertices,
+                                          VertexCount,
+                                          Flags);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
+                                          D3DPRIMITIVETYPE PrimitiveType,
+                                          D3DVERTEXTYPE VertexType,
+                                          void *Vertices,
+                                          DWORD VertexCount,
+                                          DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    DWORD FVF;
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
+
+    switch(VertexType)
+    {
+        case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
+        case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
+        case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
+        default:
+            assert(0);  /* Should never happen */
+    }
+
+    return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          PrimitiveType,
+                                          FVF,
+                                          Vertices,
+                                          VertexCount,
+                                          Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::DrawIndexedPrimitive
+ *
+ * Draws vertices from an application-provided pointer, based on the index
+ * numbers in a WORD array.
+ *
+ * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
+ * an FVF format for D3D7
+ *
+ * Params:
+ *  PrimitiveType: The primitive type to draw
+ *  VertexType: The FVF vertex description
+ *  Vertices: Pointer to the vertex array
+ *  VertexCount: ?
+ *  Indices: Pointer to the index array
+ *  IndexCount: Number of indices = Number of vertices to draw
+ *  Flags: As usual, some flags
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Vertices or Indices is NULL
+ *  For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
+                                           D3DPRIMITIVETYPE PrimitiveType,
+                                           DWORD VertexType,
+                                           void *Vertices,
+                                           DWORD VertexCount,
+                                           WORD *Indices,
+                                           DWORD IndexCount,
+                                           DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    UINT PrimitiveCount = 0;
+    HRESULT hr;
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
+    /* Get the primitive number */
+    switch(PrimitiveType)
+    {
+      case D3DPT_POINTLIST: 
+        PrimitiveCount = IndexCount;
+        break;
+
+      case D3DPT_LINELIST: 
+        PrimitiveCount = IndexCount / 2;
+        break;
+
+      case D3DPT_LINESTRIP:
+        PrimitiveCount = IndexCount - 1;
+        break;
+
+      case D3DPT_TRIANGLELIST:
+        PrimitiveCount = IndexCount / 3;
+        break;
+
+      case D3DPT_TRIANGLESTRIP:
+        PrimitiveCount = IndexCount - 2;
+        break;
+
+      case D3DPT_TRIANGLEFAN:
+        PrimitiveCount = IndexCount - 2;
+        break;
+
+      default: return DDERR_INVALIDPARAMS;
+    }
+
+    /* Set the D3DDevice's FVF */
+    hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, VertexType);
+    if(FAILED(hr))
+    {
+        ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr);
+        return hr;
+    }
+
+    return IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
+                                                 PrimitiveType,
+                                                 0 /* MinVertexIndex */,
+                                                 VertexCount /* UINT NumVertexIndex */,
+                                                 PrimitiveCount,
+                                                 Indices,
+                                                 WINED3DFMT_INDEX16,
+                                                 Vertices,
+                                                 get_flexible_vertex_size(VertexType));
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
+                                                 D3DPRIMITIVETYPE PrimitiveType,
+                                                 DWORD VertexType,
+                                                 void *Vertices,
+                                                 DWORD VertexCount,
+                                                 WORD *Indices,
+                                                 DWORD IndexCount,
+                                                 DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
+    return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                 PrimitiveType,
+                                                 VertexType,
+                                                 Vertices,
+                                                 VertexCount,
+                                                 Indices,
+                                                 IndexCount,
+                                                 Flags);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
+                                                 D3DPRIMITIVETYPE PrimitiveType,
+                                                 D3DVERTEXTYPE VertexType,
+                                                 void *Vertices,
+                                                 DWORD VertexCount,
+                                                 WORD *Indices,
+                                                 DWORD IndexCount,
+                                                 DWORD Flags)
+{
+    DWORD FVF;
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
+
+    switch(VertexType)
+    {
+        case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
+        case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
+        case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
+        default:
+            assert(0);  /* Should never happen */
+    }
+
+    return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                 PrimitiveType,
+                                                 FVF,
+                                                 Vertices,
+                                                 VertexCount,
+                                                 Indices,
+                                                 IndexCount,
+                                                 Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetClipStatus
+ *
+ * Sets the clip status. This defines things as clipping conditions and
+ * the extents of the clipping region.
+ *
+ * Version 2, 3 and 7
+ *
+ * Params:
+ *  ClipStatus:
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *  (DDERR_INVALIDPARAMS if ClipStatus == NULL)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
+                                    D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
+
+    /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
+     * Perhaps this needs a new data type and an additional IWineD3DDevice method
+     */
+    /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
+                                          D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
+    return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          ClipStatus);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
+                                          D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
+    return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          ClipStatus);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetClipStatus
+ *
+ * Returns the clip status
+ *
+ * Params:
+ *  ClipStatus: Address to write the clip status to
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
+                                    D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
+
+    /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
+    /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
+                                          D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
+    return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          ClipStatus);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
+                                          D3DCLIPSTATUS *ClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
+    return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                          ClipStatus);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::DrawPrimitiveStrided
+ *
+ * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  PrimitiveType: The primitive type to draw
+ *  VertexType: The FVF description of the vertices to draw(for the stride??)
+ *  D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
+ *                         the vertex data locations
+ *  VertexCount: The number of vertices to draw
+ *  Flags: Some flags
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *  (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
+ *  (For details, see IWineD3DDevice::DrawPrimitiveStrided)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
+                                           D3DPRIMITIVETYPE PrimitiveType,
+                                           DWORD VertexType,
+                                           D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
+                                           DWORD VertexCount,
+                                           DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    WineDirect3DVertexStridedData WineD3DStrided;
+    int i;
+    UINT PrimitiveCount;
+
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
+
+    /* Get the strided data right. the wined3d structure is a bit bigger
+     * Watch out: The contents of the strided data are determined by the fvf,
+     * not by the members set in D3DDrawPrimStrideData. So it's valid
+     * to have diffuse.lpvData set to 0xdeadbeef and not setting the diffuse
+     * flag in the fvf.
+     */
+    if(VertexType & D3DFVF_POSITION_MASK)
+    {
+        memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
+        WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
+        WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
+        WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
+        if (VertexType & D3DFVF_XYZRHW)
+        {
+            WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
+        }
+    }
+
+    if(VertexType & D3DFVF_NORMAL)
+    {
+        WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
+        WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
+        WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
+    }
+
+    if(VertexType & D3DFVF_DIFFUSE)
+    {
+        WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
+        WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
+        WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4;
+    }
+
+    if(VertexType & D3DFVF_SPECULAR)
+    {
+        WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
+        WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
+        WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4;
+    }
+
+    for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
+    {
+        WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
+        WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
+        switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
+        {
+            case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
+            case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
+            case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
+            case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
+            default: ERR("Unexpected texture coordinate size %ld\n",
+                         GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
+        }
+    }
+
+    /* Get the primitive count */
+    switch(PrimitiveType)
+    {
+        case D3DPT_POINTLIST: 
+          PrimitiveCount = VertexCount;
+          break;
+
+        case D3DPT_LINELIST: 
+          PrimitiveCount = VertexCount / 2;
+          break;
+
+        case D3DPT_LINESTRIP:
+          PrimitiveCount = VertexCount - 1;
+          break;
+
+        case D3DPT_TRIANGLELIST:
+          PrimitiveCount = VertexCount / 3;
+          break;
+
+        case D3DPT_TRIANGLESTRIP:
+          PrimitiveCount = VertexCount - 2;
+          break;
+
+        case D3DPT_TRIANGLEFAN:
+          PrimitiveCount = VertexCount - 2;
+          break;
+
+        default: return DDERR_INVALIDPARAMS;
+    }
+
+    IWineD3DDevice_SetFVF(This->wineD3DDevice,
+                          VertexType);
+
+    return IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
+                                               PrimitiveType,
+                                               PrimitiveCount,
+                                               &WineD3DStrided);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
+                                                 D3DPRIMITIVETYPE PrimitiveType,
+                                                 DWORD VertexType,
+                                                 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
+                                                 DWORD VertexCount,
+                                                 DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
+    return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                 PrimitiveType,
+                                                 VertexType,
+                                                 D3DDrawPrimStrideData,
+                                                 VertexCount,
+                                                 Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::DrawIndexedPrimitiveStrided
+ *
+ * Draws primitives specified by strided data locations based on indices
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  PrimitiveType:
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *  (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
+ *  (DDERR_INVALIDPARAMS if Indices is NULL)
+ *  (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
+                                                  D3DPRIMITIVETYPE PrimitiveType,
+                                                  DWORD VertexType,
+                                                  D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
+                                                  DWORD VertexCount,
+                                                  WORD *Indices,
+                                                  DWORD IndexCount,
+                                                  DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
+
+    /* I'll implement it as soon as I find a app to test it.
+     * This needs an additional method in IWineD3DDevice.
+     */
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
+                                                        D3DPRIMITIVETYPE PrimitiveType,
+                                                        DWORD VertexType,
+                                                        D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
+                                                        DWORD VertexCount,
+                                                        WORD *Indices,
+                                                        DWORD IndexCount,
+                                                        DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
+    return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                        PrimitiveType,
+                                                        VertexType,
+                                                        D3DDrawPrimStrideData,
+                                                        VertexCount,
+                                                        Indices,
+                                                        IndexCount,
+                                                        Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::DrawPrimitiveVB
+ *
+ * Draws primitives from a vertex buffer to the screen.
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  PrimitiveType: Type of primitive to be rendered.
+ *  D3DVertexBuf: Source Vertex Buffer
+ *  StartVertex: Index of the first vertex from the buffer to be rendered
+ *  NumVertices: Number of vertices to be rendered
+ *  Flags: Can be D3DDP_WAIT to wait until rendering has finished
+ *
+ * Return values
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
+                                      D3DPRIMITIVETYPE PrimitiveType,
+                                      IDirect3DVertexBuffer7 *D3DVertexBuf,
+                                      DWORD StartVertex,
+                                      DWORD NumVertices,
+                                      DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
+    UINT PrimitiveCount;
+    HRESULT hr;
+    DWORD stride;
+    WINED3DVERTEXBUFFER_DESC Desc;
+
+    TRACE("(%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
+
+    /* Sanity checks */
+    if(!vb)
+    {
+        ERR("(%p) No Vertex buffer specified\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* Get the primitive count */
+    switch(PrimitiveType)
+    {
+        case D3DPT_POINTLIST: 
+          PrimitiveCount = NumVertices;
+          break;
+
+        case D3DPT_LINELIST: 
+          PrimitiveCount = NumVertices / 2;
+          break;
+
+        case D3DPT_LINESTRIP:
+          PrimitiveCount = NumVertices - 1;
+          break;
+
+        case D3DPT_TRIANGLELIST:
+          PrimitiveCount = NumVertices / 3;
+          break;
+
+        case D3DPT_TRIANGLESTRIP:
+          PrimitiveCount = NumVertices - 2;
+          break;
+
+        case D3DPT_TRIANGLEFAN:
+          PrimitiveCount = NumVertices - 2;
+          break;
+
+        default: return DDERR_INVALIDPARAMS;
+    }
+
+    /* Get the FVF of the vertex buffer, and its stride */
+    hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
+                                      &Desc);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+    stride = get_flexible_vertex_size(Desc.FVF);
+
+    hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, Desc.FVF);
+    if(FAILED(hr))
+    {
+        ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr);
+        return hr;
+    }
+
+    /* Set the vertex stream souce */
+    hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
+                                        0 /* StreamNumber */,
+                                        vb->wineD3DVertexBuffer,
+                                        0 /* StartVertex - we pass this to DrawPrimitive */,
+                                        stride);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+
+    /* Now draw the primitives */
+    return IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
+                                        PrimitiveType,
+                                        StartVertex,
+                                        PrimitiveCount);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
+                                            D3DPRIMITIVETYPE PrimitiveType,
+                                            IDirect3DVertexBuffer *D3DVertexBuf,
+                                            DWORD StartVertex,
+                                            DWORD NumVertices,
+                                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08lx,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This,  PrimitiveType, vb, StartVertex, NumVertices, Flags);
+    return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                            PrimitiveType,
+                                            ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
+                                            StartVertex,
+                                            NumVertices,
+                                            Flags);
+}
+
+
+/*****************************************************************************
+ * IDirect3DDevice7::DrawIndexedPrimitiveVB
+ *
+ * Draws primitives from a vertex buffer to the screen
+ *
+ * Params:
+ *  PrimitiveType: Type of primitive to be rendered.
+ *  D3DVertexBuf: Source Vertex Buffer
+ *  StartVertex: Index of the first vertex from the buffer to be rendered
+ *  NumVertices: Number of vertices to be rendered
+ *  Indices: Array of DWORDs used to index into the Vertices
+ *  IndexCount: Number of indices in Indices
+ *  Flags: Can be D3DDP_WAIT to wait until rendering has finished
+ *
+ * Return values
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
+                                             D3DPRIMITIVETYPE PrimitiveType,
+                                             IDirect3DVertexBuffer7 *D3DVertexBuf,
+                                             DWORD StartVertex,
+                                             DWORD NumVertices,
+                                             WORD *Indices,
+                                             DWORD IndexCount,
+                                             DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
+    DWORD stride;
+    UINT PrimitiveCount;
+    WORD *LockedIndices;
+    HRESULT hr;
+    WINED3DVERTEXBUFFER_DESC Desc;
+
+    TRACE("(%p)->(%08x,%p,%ld,%ld,%p,%ld,%08lx)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
+
+    /* Steps:
+     * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
+     * 2) Upload the Indices to the index buffer
+     * 3) Set the index source
+     * 4) Set the Vertex Buffer as the Stream source
+     * 5) Call IWineD3DDevice::DrawIndexedPrimitive
+     */
+
+    /* Get the primitive count */
+    switch(PrimitiveType)
+    {
+        case D3DPT_POINTLIST: 
+          PrimitiveCount = IndexCount;
+          break;
+
+        case D3DPT_LINELIST: 
+          PrimitiveCount = IndexCount / 2;
+          break;
+
+        case D3DPT_LINESTRIP:
+          PrimitiveCount = IndexCount - 1;
+          break;
+
+        case D3DPT_TRIANGLELIST:
+          PrimitiveCount = IndexCount / 3;
+          break;
+
+        case D3DPT_TRIANGLESTRIP:
+          PrimitiveCount = IndexCount - 2;
+          break;
+
+        case D3DPT_TRIANGLEFAN:
+          PrimitiveCount = IndexCount - 2;
+          break;
+
+        default: return DDERR_INVALIDPARAMS;
+    }
+
+    /* Get the FVF of the vertex buffer, and its stride */
+    hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
+                                      &Desc);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+    stride = get_flexible_vertex_size(Desc.FVF);
+    TRACE("Vertex buffer FVF = %08lx, stride=%ld\n", Desc.FVF, stride);
+
+    hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, Desc.FVF);
+    if(FAILED(hr))
+    {
+        ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr);
+        return hr;
+    }
+
+    /* copy the index stream into the index buffer.
+     * A new IWineD3DDevice method could be created
+     * which takes an user pointer containing the indices
+     * or a SetData-Method for the index buffer, which
+     * overrides the index buffer data with our pointer.
+     */
+    hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
+                                  0 /* OffSetToLock */,
+                                  0 /* SizeToLock - doesn't matter */,
+                                  (BYTE **) &LockedIndices,
+                                  0 /* Flags */);
+    assert(IndexCount < 0x100000);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+    memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
+    hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+
+    /* Set the index stream */
+    hr = IWineD3DDevice_SetIndices(This->wineD3DDevice,
+                                   This->indexbuffer,
+                                   0);
+
+    /* Set the vertex stream souce */
+    hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
+                                        0 /* StreamNumber */,
+                                        vb->wineD3DVertexBuffer,
+                                        0 /* offset, we pass this to DrawIndexedPrimitive */,
+                                        stride);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08lx\n", This, hr);
+        return hr;
+    }
+
+
+    hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
+                                             PrimitiveType,
+                                             StartVertex,
+                                             0 /* minIndex */,
+                                             NumVertices,
+                                             0 /* StartIndex */,
+                                             PrimitiveCount);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
+                                                   D3DPRIMITIVETYPE PrimitiveType,
+                                                   IDirect3DVertexBuffer *D3DVertexBuf,
+                                                   WORD *Indices,
+                                                   DWORD IndexCount,
+                                                   DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
+    TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
+
+    return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                   PrimitiveType,
+                                                   ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
+                                                   0,
+                                                   IndexCount,
+                                                   Indices,
+                                                   IndexCount,
+                                                   Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::ComputeSphereVisibility
+ *
+ * Calculates the visibility of spheres in the current viewport. The spheres
+ * are passed in the Centers and Radii arrays, the results are passed back
+ * in the ReturnValues array. Return values are eighter completely visible,
+ * partially visible or completely invisible.
+ * The return value consist of a combination of D3DCLIP_* flags, or it's
+ * 0 if the sphere is completely visible(according to the SDK, not checked)
+ *
+ * Sounds like an overdose math ;)
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Centers: Array containing the sphere centers
+ *  Radii: Array containing the sphere radis
+ *  NumSpheres: The number of centers and radiis in the arrays
+ *  Flags: Some flags
+ *  ReturnValues: Array to write the results to
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *  (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
+ *  (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
+ *  is singular)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
+                                              D3DVECTOR *Centers,
+                                              D3DVALUE *Radii,
+                                              DWORD NumSpheres,
+                                              DWORD Flags,
+                                              DWORD *ReturnValues)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p)->(%p,%p,%08lx,%08lx,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
+
+    /* the DirectX 7 sdk says that the visibility is computed by
+     * back-transforming the viewing frustum to model space
+     * using the inverse of the combined world, view and projection
+     * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
+     * is returned.
+     *
+     * Basic implementation idea:
+     * 1) Check if the center is in the viewing frustum
+     * 2) Cut the sphere with the planes of the viewing
+     *    frustum
+     *
+     * ->Center inside the frustum, no intersections:
+     *    Fully visible
+     * ->Center outside the frustum, no intersections:
+     *    Not visible
+     * ->Some intersections: Partially visible
+     *
+     * Implement this call in WineD3D. Eighter implement the
+     * matrix and vector stuff in WineD3D, or use some external
+     * math library.
+     */
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
+                                                    D3DVECTOR *Centers,
+                                                    D3DVALUE *Radii,
+                                                    DWORD NumSpheres,
+                                                    DWORD Flags,
+                                                    DWORD *ReturnValues)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx,%08lx,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
+    return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                    Centers,
+                                                    Radii,
+                                                    NumSpheres,
+                                                    Flags,
+                                                    ReturnValues);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetTexture
+ *
+ * Returns the texture interface handle assigned to a texture stage.
+ * The returned texture is AddRefed. This is taken from old ddraw,
+ * not checked in Windows.
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Stage: Texture stage to read the texture from
+ *  Texture: Address to store the interface pointer at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Texture is NULL
+ *  For details, see IWineD3DDevice::GetTexture
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
+                                 DWORD Stage,
+                                 IDirectDrawSurface7 **Texture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IWineD3DBaseTexture *Surf;
+    HRESULT hr;
+    TRACE("(%p)->(%ld,%p): Relay\n", This, Stage, Texture);
+
+    if(!Texture)
+    {
+        TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
+        return DDERR_INVALIDPARAMS;
+    }
+
+    hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, (IWineD3DBaseTexture **) &Surf);
+    if( (hr != D3D_OK) || (!Surf) ) 
+    {
+        *Texture = NULL;
+        return hr;
+    }
+
+    /* GetParent AddRef()s, which is perfectly OK.
+     * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
+     */
+    return IWineD3DBaseTexture_GetParent(Surf,
+                                         (IUnknown **) Texture);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
+                                       DWORD Stage,
+                                       IDirect3DTexture2 **Texture2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    HRESULT ret;
+    IDirectDrawSurface7 *ret_val;
+
+    TRACE_(ddraw_thunk)("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
+    ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                      Stage,
+                                      &ret_val);
+
+    *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
+
+    TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetTexture
+ *
+ * Assignes a texture to a texture stage. Is the texture AddRefed?
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Stage: The stage to assign the texture to
+ *  Texture: Interface pointer to the texture surface
+ *
+ * Returns
+ * D3D_OK on success
+ * For details, see IWineD3DDevice::SetTexture
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
+                                 DWORD Stage,
+                                 IDirectDrawSurface7 *Texture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
+    TRACE("(%p)->(%08lx,%p): Relay!\n", This, Stage, surf);
+
+    /* Texture may be NULL here */
+    return IWineD3DDevice_SetTexture(This->wineD3DDevice,
+                                     Stage,
+                                     surf ? (IWineD3DBaseTexture * ) surf->wineD3DTexture : NULL);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
+                                       DWORD Stage,
+                                       IDirect3DTexture2 *Texture2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
+    TRACE_(ddraw_thunk)("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex);
+    return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                       Stage,
+                                       ICOM_INTERFACE(tex, IDirectDrawSurface7));
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetTextureStageState
+ *
+ * Retrieves a state from a texture stage.
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Stage: The stage to retrieve the state from
+ *  TexStageStateType: The state type to retrieve
+ *  State: Address to store the state's value at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if State is NULL
+ *  For details, see IWineD3DDevice::GetTextureStageState
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
+                                           DWORD Stage,
+                                           D3DTEXTURESTAGESTATETYPE TexStageStateType,
+                                           DWORD *State)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
+
+    if(!State)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
+                                               Stage,
+                                               TexStageStateType,
+                                               State);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
+                                                 DWORD Stage,
+                                                 D3DTEXTURESTAGESTATETYPE TexStageStateType,
+                                                 DWORD *State)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08lx,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
+    return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                 Stage,
+                                                 TexStageStateType,
+                                                 State);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetTextureStageState
+ *
+ * Sets a texture stage state. Some stage types need to be handled specially,
+ * because they do not exist in WineD3D and were moved to another place
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Stage: The stage to modify
+ *  TexStageStateType: The state to change
+ *  State: The new value for the state
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For details, see IWineD3DDevice::SetTextureStageState
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
+                                           DWORD Stage,
+                                           D3DTEXTURESTAGESTATETYPE TexStageStateType,
+                                           DWORD State)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx,%08x,%08lx): Relay!\n", This, Stage, TexStageStateType, State);
+    switch(TexStageStateType)
+    {
+        /* Mipfilter is a sampler state with different values */
+        case D3DTSS_MIPFILTER:
+        {
+            WINED3DTEXTUREFILTERTYPE value;
+            switch(State)
+            {
+                case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
+                case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
+                case 0: /* Unchecked */
+                case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
+                default:
+                    ERR("Unexpected mipfilter value %ld\n", State);
+                    value = WINED3DTEXF_NONE;
+            }
+            return IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+                                                  Stage,
+                                                  WINED3DSAMP_MIPFILTER,
+                                                  value);
+        }
+
+        /* Minfilter is a sampler state too, equal values */
+        case D3DTSS_MINFILTER:
+            return IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+                                                  Stage,
+                                                  WINED3DSAMP_MINFILTER,
+                                                  State);
+        /* Same for MAGFILTER */
+        case D3DTSS_MAGFILTER:
+            return IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+                                                  Stage,
+                                                  WINED3DSAMP_MAGFILTER,
+                                                  State);
+
+        default:
+
+            return IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
+                                                      Stage,
+                                                      TexStageStateType,
+                                                      State);
+    }
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
+                                                 DWORD Stage,
+                                                 D3DTEXTURESTAGESTATETYPE TexStageStateType,
+                                                 DWORD State)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08lx,%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
+    return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                                 Stage,
+                                                 TexStageStateType,
+                                                 State);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::ValidateDevice
+ *
+ * SDK: "Reports the device's ability to render the currently set
+ * texture-blending operations in a single pass". Whatever that means
+ * exactly...
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  NumPasses: Address to write the number of neccessary passes for the
+ *             desired effect to.
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  See IWineD3DDevice::ValidateDevice for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
+                                     DWORD *NumPasses)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%p): Relay\n", This, NumPasses);
+
+    return IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
+                                           DWORD *Passes)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
+    return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
+                                           Passes);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::Clear
+ *
+ * Fills the render target, the z buffer and the stencil buffer with a
+ * clear color / value
+ *
+ * Version 7 only
+ *
+ * Params:
+ *  Count: Number of rectangles in Rects must be 0 if Rects is NULL
+ *  Rects: Rectangles to clear. If NULL, the whole surface is cleared
+ *  Flags: Some flags, as usual
+ *  Color: Clear color for the render target
+ *  Z: Clear value for the Z buffer
+ *  Stencil: Clear value to store in each stencil buffer entry
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For details, see IWineD3DDevice::Clear
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
+                            DWORD Count,
+                            D3DRECT *Rects,
+                            DWORD Flags,
+                            D3DCOLOR Color,
+                            D3DVALUE Z,
+                            DWORD Stencil)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): Relay\n", This, Count, Rects, Flags, (DWORD) Color, Z, Stencil);
+
+    return IWineD3DDevice_Clear(This->wineD3DDevice, Count, Rects, Flags, Color, Z, Stencil);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetViewport
+ *
+ * Sets the current viewport.
+ *
+ * Version 7 only, but IDirect3DViewport uses this call for older
+ * versions
+ *
+ * Params:
+ *  Data: The new viewport to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *  For more details, see IWineDDDevice::SetViewport
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
+                                  D3DVIEWPORT7 *Data)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%p) Relay!\n", This, Data);
+
+    if(!Data)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_SetViewport(This->wineD3DDevice,
+                                      Data);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice::GetViewport
+ *
+ * Returns the current viewport
+ *
+ * Version 7
+ *
+ * Params:
+ *  Data: D3D7Viewport structure to write the viewport information to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *  For more details, see IWineD3DDevice::GetViewport
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
+                                  D3DVIEWPORT7 *Data)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%p) Relay!\n", This, Data);
+
+    if(!Data)
+        return DDERR_INVALIDPARAMS;
+
+    hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
+                                    Data);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetMaterial
+ *
+ * Sets the Material
+ *
+ * Version 7
+ *
+ * Params:
+ *  Mat: The material to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Mat is NULL.
+ *  For more details, see IWineD3DDevice::SetMaterial
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
+                                  D3DMATERIAL7 *Mat)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%p): Relay!\n", This, Mat);
+
+    hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
+                                    Mat);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetMaterial
+ *
+ * Returns the current material
+ *
+ * Version 7
+ *
+ * Params:
+ *  Mat: D3DMATERIAL7 structure to write the material paramters to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Mat is NULL
+ *  For more details, see IWineD3DDevice::GetMaterial
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
+                                  D3DMATERIAL7 *Mat)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%p): Relay!\n", This, Mat);
+
+    hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
+                                    Mat);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetLight
+ *
+ * Assigns a light to a light index, but doesn't activate it yet.
+ *
+ * Version 7, IDirect3DLight uses this method for older versions
+ *
+ * Params:
+ *  LightIndex: The index of the new light
+ *  Light: A D3DLIGHT7 structure describing the light
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For more details, see IWineD3DDevice::SetLight
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
+                               DWORD LightIndex,
+                               D3DLIGHT7 *Light)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08lx,%p): Relay!\n", This, LightIndex, Light);
+
+    hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
+                                 LightIndex,
+                                 Light);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetLight
+ *
+ * Returns the light assigned to a light index
+ *
+ * Params:
+ *  Light: Structure to write the light information to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Light is NULL
+ *  For details, see IWineD3DDevice::GetLight
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
+                               DWORD LightIndex,
+                               D3DLIGHT7 *Light)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT rc;
+    TRACE("(%p)->(%08lx,%p): Relay!\n", This, LightIndex, Light);
+
+    rc =  IWineD3DDevice_GetLight(This->wineD3DDevice,
+                                  LightIndex,
+                                  Light);
+
+    /* Translate the result. WineD3D returns other values than D3D7 */
+    return hr_ddraw_from_wined3d(rc);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::BeginStateBlock
+ *
+ * Begins recording to a stateblock
+ *
+ * Version 7
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For details see IWineD3DDevice::BeginStateBlock
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(): Relay!\n", This);
+
+    hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::EndStateBlock
+ *
+ * Stops recording to a state block and returns the created stateblock
+ * handle. The d3d7 stateblock handles are the interface pointers of the
+ * IWineD3DStateBlock interface
+ *
+ * Version 7
+ *
+ * Params:
+ *  BlockHandle: Address to store the stateblock's handle to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if BlockHandle is NULL
+ *  See IWineD3DDevice::EndStateBlock for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
+                                    DWORD *BlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
+
+    if(!BlockHandle)
+        return DDERR_INVALIDPARAMS;
+
+    hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
+                                      (IWineD3DStateBlock **) BlockHandle);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::PreLoad
+ *
+ * Allows the app to signal that a texture will be used soon, to allow
+ * the Direct3DDevice to load it to the video card in the meantime.
+ *
+ * Version 7
+ *
+ * Params:
+ *  Texture: The texture to preload
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Texture is NULL
+ *  See IWineD3DSurface::PreLoad for details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
+                              IDirectDrawSurface7 *Texture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
+
+    TRACE("(%p)->(%p): Relay!\n", This, surf);
+
+    if(!Texture)
+        return DDERR_INVALIDPARAMS;
+
+    IWineD3DSurface_PreLoad(surf->WineD3DSurface);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::ApplyStateBlock
+ *
+ * Activates the state stored in a state block handle.
+ *
+ * Params:
+ *  BlockHandle: The stateblock handle to activate
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
+                                      DWORD BlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle);
+
+    if(!BlockHandle)
+        return D3DERR_INVALIDSTATEBLOCK;
+
+    hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) BlockHandle);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::CaptureStateBlock
+ *
+ * Updates a stateblock's values to the values currently set for the device
+ *
+ * Version 7
+ *
+ * Params:
+ *  BlockHandle: Stateblock to update
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
+ *  See IWineD3DDevice::CaptureStateBlock for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
+                                        DWORD BlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle);
+
+    if(BlockHandle == 0)
+        return D3DERR_INVALIDSTATEBLOCK;
+
+    hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) BlockHandle);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::DeleteStateBlock
+ *
+ * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
+ *
+ * Version 7
+ *
+ * Params:
+ *  BlockHandle: Stateblock handle to delete
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
+                                       DWORD BlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle);
+
+    if(BlockHandle == 0)
+        return D3DERR_INVALIDSTATEBLOCK;
+
+    IWineD3DStateBlock_Release((IWineD3DStateBlock *) BlockHandle);
+
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::CreateStateBlock
+ *
+ * Creates a new state block handle.
+ *
+ * Version 7
+ *
+ * Params:
+ *  Type: The state block type
+ *  BlockHandle: Address to write the created handle to
+ *
+ * Returns:
+ *   D3D_OK on success
+ *   DDERR_INVALIDPARAMS if BlockHandle is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
+                                       D3DSTATEBLOCKTYPE Type,
+                                       DWORD *BlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
+
+    if(!BlockHandle)
+        return DDERR_INVALIDPARAMS;
+
+    /* The D3DSTATEBLOCKTYPE enum is fine here */
+    hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
+                                         Type,
+                                         (IWineD3DStateBlock **) BlockHandle,
+                                         NULL /* Parent, hope that works */);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::Load
+ *
+ * Loads an rectangular area from the source into the destination texture.
+ * It can also copy the source to the faces of a cubic environment map
+ *
+ * Version 7
+ *
+ * Params:
+ *  DestTex: Destination texture
+ *  DestPoint: Point in the destination where the source image should be
+ *             written to
+ *  SrcTex: Source texture
+ *  SrcRect: Source rectangle
+ *  Flags: Some flags
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL
+ *  See IDirect3DTexture2::Load for details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
+                           IDirectDrawSurface7 *DestTex,
+                           POINT *DestPoint,
+                           IDirectDrawSurface7 *SrcTex,
+                           RECT *SrcRect,
+                           DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
+    IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
+    FIXME("(%p)->(%p,%p,%p,%p,%08lx): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags);
+
+    if( (!src) || (!dest) )
+        return DDERR_INVALIDPARAMS;
+
+    IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2),
+                           ICOM_INTERFACE(src, IDirect3DTexture2));
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::LightEnable
+ *
+ * Enables or disables a light
+ *
+ * Version 7, IDirect3DLight uses this method too.
+ *
+ * Params:
+ *  LightIndex: The index of the light to enable / disable
+ *  Enable: Enable or disable the light
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For more details, see IWineD3DDevice::SetLightEnable
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
+                                  DWORD LightIndex,
+                                  BOOL Enable)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08lx,%d): Relay!\n", This, LightIndex, Enable);
+
+    hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetLightEnable
+ *
+ * Retrieves if the light with the given index is enables or not
+ *
+ * Version 7
+ *
+ * Params:
+ *  LightIndex: Index of desired light
+ *  Enable: Pointer to a BOOL which contains the result
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Enable is NULL
+ *  See IWineD3DDevice::GetLightEnable for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
+                                     DWORD LightIndex,
+                                     BOOL* Enable)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%08lx,%p): Relay\n", This, LightIndex, Enable);
+
+    if(!Enable)
+        return DDERR_INVALIDPARAMS;
+
+    hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
+    return hr_ddraw_from_wined3d(hr);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::SetClipPlane
+ *
+ * Sets custom clipping plane
+ *
+ * Version 7
+ *
+ * Params:
+ *  Index: The index of the clipping plane
+ *  PlaneEquation: An equation defining the clipping plane
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if PlaneEquation is NULL
+ *  See IWineD3DDevice::SetClipPlane for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
+                                   DWORD Index,
+                                   D3DVALUE* PlaneEquation)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx,%p): Relay!\n", This, Index, PlaneEquation);
+
+    if(!PlaneEquation)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetClipPlane
+ *
+ * Returns the clipping plane with a specific index
+ *
+ * Params:
+ *  Index: The index of the desired plane
+ *  PlaneEquation: Address to store the plane equation to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if PlaneEquation is NULL
+ *  See IWineD3DDevice::GetClipPlane for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
+                                   DWORD Index,
+                                   D3DVALUE* PlaneEquation)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%ld,%p): Relay!\n", This, Index, PlaneEquation);
+
+    if(!PlaneEquation)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
+}
+
+/*****************************************************************************
+ * IDirect3DDevice7::GetInfo
+ *
+ * Retrieves some information about the device. The DirectX sdk says that
+ * this version returnes S_FALSE for all retail build of DirectX, that's
+ * this implementation does.
+ *
+ * Params:
+ *  DevInfoID: Information type requested
+ *  DevInfoStruct: Pointer to a structure to store the info to
+ *  Size: Size of the structure
+ *
+ * Returns:
+ *  S_FALSE, because it's a non-debug driver
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
+                              DWORD DevInfoID,
+                              void *DevInfoStruct,
+                              DWORD Size)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p)->(%08lx,%p,%08lx)\n", This, DevInfoID, DevInfoStruct, Size);
+
+    if (TRACE_ON(d3d7))
+    {
+        TRACE(" info requested : ");
+        switch (DevInfoID)
+        {
+            case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
+            case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
+            case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
+            default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
+        }
+    }
+
+    return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
+}
+
+const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    IDirect3DDeviceImpl_7_QueryInterface,
+    IDirect3DDeviceImpl_7_AddRef,
+    IDirect3DDeviceImpl_7_Release,
+    /*** IDirect3DDevice7 ***/
+    IDirect3DDeviceImpl_7_GetCaps,
+    IDirect3DDeviceImpl_7_EnumTextureFormats,
+    IDirect3DDeviceImpl_7_BeginScene,
+    IDirect3DDeviceImpl_7_EndScene,
+    IDirect3DDeviceImpl_7_GetDirect3D,
+    IDirect3DDeviceImpl_7_SetRenderTarget,
+    IDirect3DDeviceImpl_7_GetRenderTarget,
+    IDirect3DDeviceImpl_7_Clear,
+    IDirect3DDeviceImpl_7_SetTransform,
+    IDirect3DDeviceImpl_7_GetTransform,
+    IDirect3DDeviceImpl_7_SetViewport,
+    IDirect3DDeviceImpl_7_MultiplyTransform,
+    IDirect3DDeviceImpl_7_GetViewport,
+    IDirect3DDeviceImpl_7_SetMaterial,
+    IDirect3DDeviceImpl_7_GetMaterial,
+    IDirect3DDeviceImpl_7_SetLight,
+    IDirect3DDeviceImpl_7_GetLight,
+    IDirect3DDeviceImpl_7_SetRenderState,
+    IDirect3DDeviceImpl_7_GetRenderState,
+    IDirect3DDeviceImpl_7_BeginStateBlock,
+    IDirect3DDeviceImpl_7_EndStateBlock,
+    IDirect3DDeviceImpl_7_PreLoad,
+    IDirect3DDeviceImpl_7_DrawPrimitive,
+    IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
+    IDirect3DDeviceImpl_7_SetClipStatus,
+    IDirect3DDeviceImpl_7_GetClipStatus,
+    IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
+    IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
+    IDirect3DDeviceImpl_7_DrawPrimitiveVB,
+    IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
+    IDirect3DDeviceImpl_7_ComputeSphereVisibility,
+    IDirect3DDeviceImpl_7_GetTexture,
+    IDirect3DDeviceImpl_7_SetTexture,
+    IDirect3DDeviceImpl_7_GetTextureStageState,
+    IDirect3DDeviceImpl_7_SetTextureStageState,
+    IDirect3DDeviceImpl_7_ValidateDevice,
+    IDirect3DDeviceImpl_7_ApplyStateBlock,
+    IDirect3DDeviceImpl_7_CaptureStateBlock,
+    IDirect3DDeviceImpl_7_DeleteStateBlock,
+    IDirect3DDeviceImpl_7_CreateStateBlock,
+    IDirect3DDeviceImpl_7_Load,
+    IDirect3DDeviceImpl_7_LightEnable,
+    IDirect3DDeviceImpl_7_GetLightEnable,
+    IDirect3DDeviceImpl_7_SetClipPlane,
+    IDirect3DDeviceImpl_7_GetClipPlane,
+    IDirect3DDeviceImpl_7_GetInfo
+};
+
+const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DDeviceImpl_3_QueryInterface,
+    Thunk_IDirect3DDeviceImpl_3_AddRef,
+    Thunk_IDirect3DDeviceImpl_3_Release,
+    /*** IDirect3DDevice3 ***/
+    IDirect3DDeviceImpl_3_GetCaps,
+    IDirect3DDeviceImpl_3_GetStats,
+    IDirect3DDeviceImpl_3_AddViewport,
+    IDirect3DDeviceImpl_3_DeleteViewport,
+    IDirect3DDeviceImpl_3_NextViewport,
+    Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
+    Thunk_IDirect3DDeviceImpl_3_BeginScene,
+    Thunk_IDirect3DDeviceImpl_3_EndScene,
+    Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
+    IDirect3DDeviceImpl_3_SetCurrentViewport,
+    IDirect3DDeviceImpl_3_GetCurrentViewport,
+    Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
+    Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
+    IDirect3DDeviceImpl_3_Begin,
+    IDirect3DDeviceImpl_3_BeginIndexed,
+    IDirect3DDeviceImpl_3_Vertex,
+    IDirect3DDeviceImpl_3_Index,
+    IDirect3DDeviceImpl_3_End,
+    Thunk_IDirect3DDeviceImpl_3_GetRenderState,
+    Thunk_IDirect3DDeviceImpl_3_SetRenderState,
+    IDirect3DDeviceImpl_3_GetLightState,
+    IDirect3DDeviceImpl_3_SetLightState,
+    Thunk_IDirect3DDeviceImpl_3_SetTransform,
+    Thunk_IDirect3DDeviceImpl_3_GetTransform,
+    Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
+    Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
+    Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
+    Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
+    Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
+    Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
+    Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
+    Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
+    Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
+    Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
+    Thunk_IDirect3DDeviceImpl_3_GetTexture,
+    Thunk_IDirect3DDeviceImpl_3_SetTexture,
+    Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
+    Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
+    Thunk_IDirect3DDeviceImpl_3_ValidateDevice
+};
+
+const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DDeviceImpl_2_QueryInterface,
+    Thunk_IDirect3DDeviceImpl_2_AddRef,
+    Thunk_IDirect3DDeviceImpl_2_Release,
+    /*** IDirect3DDevice2 ***/
+    Thunk_IDirect3DDeviceImpl_2_GetCaps,
+    IDirect3DDeviceImpl_2_SwapTextureHandles,
+    Thunk_IDirect3DDeviceImpl_2_GetStats,
+    Thunk_IDirect3DDeviceImpl_2_AddViewport,
+    Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
+    Thunk_IDirect3DDeviceImpl_2_NextViewport,
+    IDirect3DDeviceImpl_2_EnumTextureFormats,
+    Thunk_IDirect3DDeviceImpl_2_BeginScene,
+    Thunk_IDirect3DDeviceImpl_2_EndScene,
+    Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
+    Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
+    Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
+    Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
+    Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
+    Thunk_IDirect3DDeviceImpl_2_Begin,
+    Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
+    Thunk_IDirect3DDeviceImpl_2_Vertex,
+    Thunk_IDirect3DDeviceImpl_2_Index,
+    Thunk_IDirect3DDeviceImpl_2_End,
+    Thunk_IDirect3DDeviceImpl_2_GetRenderState,
+    Thunk_IDirect3DDeviceImpl_2_SetRenderState,
+    Thunk_IDirect3DDeviceImpl_2_GetLightState,
+    Thunk_IDirect3DDeviceImpl_2_SetLightState,
+    Thunk_IDirect3DDeviceImpl_2_SetTransform,
+    Thunk_IDirect3DDeviceImpl_2_GetTransform,
+    Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
+    Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
+    Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
+    Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
+    Thunk_IDirect3DDeviceImpl_2_GetClipStatus
+};
+
+const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DDeviceImpl_1_QueryInterface,
+    Thunk_IDirect3DDeviceImpl_1_AddRef,
+    Thunk_IDirect3DDeviceImpl_1_Release,
+    /*** IDirect3DDevice1 ***/
+    IDirect3DDeviceImpl_1_Initialize,
+    Thunk_IDirect3DDeviceImpl_1_GetCaps,
+    Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
+    IDirect3DDeviceImpl_1_CreateExecuteBuffer,
+    Thunk_IDirect3DDeviceImpl_1_GetStats,
+    IDirect3DDeviceImpl_1_Execute,
+    Thunk_IDirect3DDeviceImpl_1_AddViewport,
+    Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
+    Thunk_IDirect3DDeviceImpl_1_NextViewport,
+    IDirect3DDeviceImpl_1_Pick,
+    IDirect3DDeviceImpl_1_GetPickRecords,
+    Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
+    IDirect3DDeviceImpl_1_CreateMatrix,
+    IDirect3DDeviceImpl_1_SetMatrix,
+    IDirect3DDeviceImpl_1_GetMatrix,
+    IDirect3DDeviceImpl_1_DeleteMatrix,
+    Thunk_IDirect3DDeviceImpl_1_EndScene,
+    Thunk_IDirect3DDeviceImpl_1_BeginScene,
+    Thunk_IDirect3DDeviceImpl_1_GetDirect3D
+};
diff --git a/dlls/ddraw/device_main.c b/dlls/ddraw/device_main.c
deleted file mode 100644
index 55ee51f..0000000
--- a/dlls/ddraw/device_main.c
+++ /dev/null
@@ -1,2241 +0,0 @@
-/*
- * Direct3D Device
- *
- * Copyright (c) 1998-2004 Lionel Ulmer
- * Copyright (c) 2002-2005 Christian Costa
- *
- * This file contains all the common stuff for D3D devices.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <string.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "objbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-
-#include "d3d_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-DWORD InitRenderStateTab[] = {
-    D3DRENDERSTATE_TEXTUREHANDLE,           (DWORD)NULL,
-    D3DRENDERSTATE_ANTIALIAS,               D3DANTIALIAS_NONE,
-    /* FIXME: D3DRENDERSTATE_TEXTUREADDRESS */
-    D3DRENDERSTATE_TEXTUREPERSPECTIVE,      TRUE,
-    /* FIXME: D3DRENDERSTATE_WRAPU */
-    /* FIXME: D3DRENDERSTATE_WRAPV */
-    D3DRENDERSTATE_ZENABLE,                 D3DZB_TRUE, /* This needs to be set differently according to the Z buffer status */
-    D3DRENDERSTATE_FILLMODE,                D3DFILL_SOLID,
-    D3DRENDERSTATE_SHADEMODE,               D3DSHADE_GOURAUD,
-    D3DRENDERSTATE_LINEPATTERN,             0,
-    D3DRENDERSTATE_MONOENABLE,              FALSE,
-    D3DRENDERSTATE_ROP2,                    R2_COPYPEN,
-    D3DRENDERSTATE_PLANEMASK,               0xFFFFFFFF,
-    D3DRENDERSTATE_ZWRITEENABLE,            TRUE,
-    D3DRENDERSTATE_ALPHATESTENABLE,         FALSE,
-    D3DRENDERSTATE_LASTPIXEL,               TRUE,
-    D3DRENDERSTATE_TEXTUREMAG,              D3DFILTER_NEAREST,
-    D3DRENDERSTATE_TEXTUREMIN,              D3DFILTER_NEAREST,
-    D3DRENDERSTATE_SRCBLEND,                D3DBLEND_ONE,
-    D3DRENDERSTATE_DESTBLEND,               D3DBLEND_ZERO,
-    D3DRENDERSTATE_TEXTUREMAPBLEND,         D3DTBLEND_MODULATE,
-    D3DRENDERSTATE_CULLMODE,                D3DCULL_CCW,
-    D3DRENDERSTATE_ZFUNC,                   D3DCMP_LESSEQUAL,
-    D3DRENDERSTATE_ALPHAREF,                0,
-    D3DRENDERSTATE_ALPHAFUNC,               D3DCMP_ALWAYS,
-    D3DRENDERSTATE_DITHERENABLE,            FALSE,
-    D3DRENDERSTATE_ALPHABLENDENABLE,        FALSE,
-    D3DRENDERSTATE_FOGENABLE,               FALSE,
-    D3DRENDERSTATE_SPECULARENABLE,          FALSE,
-    D3DRENDERSTATE_ZVISIBLE,                FALSE,
-    D3DRENDERSTATE_SUBPIXEL,                FALSE,
-    D3DRENDERSTATE_SUBPIXELX,               FALSE,
-    D3DRENDERSTATE_STIPPLEDALPHA,           FALSE,
-    D3DRENDERSTATE_FOGCOLOR,                D3DRGBA(0,0,0,0),
-    D3DRENDERSTATE_FOGTABLEMODE,            D3DFOG_NONE,
-    /* FIXME: D3DRENDERSTATE_FOGTABLESTART (same as D3DRENDERSTATE_FOGSTART) */
-    /* FIXME: D3DRENDERSTATE_FOGTABLEEND (same as D3DRENDERSTATE_FOGEND) */
-    D3DRENDERSTATE_FOGTABLEDENSITY,         0x3F80000, /* 1.0f (same as D3DRENDERSTATE_FOGDENSITY) */
-    /* FIXME: D3DRENDERSTATE_STIPPLEENABLE */
-    D3DRENDERSTATE_EDGEANTIALIAS,           FALSE,
-    D3DRENDERSTATE_COLORKEYENABLE,          FALSE,
-    /* FIXME: D3DRENDERSTATE_BORDERCOLOR */
-    D3DRENDERSTATE_TEXTUREADDRESSU,         D3DTADDRESS_WRAP,
-    D3DRENDERSTATE_TEXTUREADDRESSV,         D3DTADDRESS_WRAP,
-    D3DRENDERSTATE_MIPMAPLODBIAS,           0x00000000, /* 0.0f */
-    D3DRENDERSTATE_ZBIAS,                   0,
-    D3DRENDERSTATE_RANGEFOGENABLE,          FALSE,    
-    /* FIXME: D3DRENDERSTATE_ANISOTROPY */
-    /* FIXME: D3DRENDERSTATE_FLUSHBATCH */
-    /* FIXME: D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT */
-    D3DRENDERSTATE_STENCILENABLE,           FALSE,
-    D3DRENDERSTATE_STENCILFAIL,             D3DSTENCILOP_KEEP,
-    D3DRENDERSTATE_STENCILZFAIL,            D3DSTENCILOP_KEEP,
-    D3DRENDERSTATE_STENCILPASS,             D3DSTENCILOP_KEEP,
-    D3DRENDERSTATE_STENCILFUNC,             D3DCMP_ALWAYS,
-    D3DRENDERSTATE_STENCILREF,              0,
-    D3DRENDERSTATE_STENCILMASK,             0xFFFFFFFF,
-    D3DRENDERSTATE_STENCILWRITEMASK,        0xFFFFFFFF,
-    /* FIXME: D3DRENDERSTATE_TEXTUREFACTOR */
-    /* FIXME: D3DRENDERSTATE_STIPPLEPATTERN00..31 */
-    D3DRENDERSTATE_WRAP0,                   0,
-    D3DRENDERSTATE_WRAP1,                   0,
-    D3DRENDERSTATE_WRAP2,                   0,
-    D3DRENDERSTATE_WRAP3,                   0,
-    D3DRENDERSTATE_WRAP4,                   0,
-    D3DRENDERSTATE_WRAP5,                   0,
-    D3DRENDERSTATE_WRAP6,                   0,
-    D3DRENDERSTATE_WRAP7,                   0,
-    D3DRENDERSTATE_CLIPPING,                FALSE,
-    D3DRENDERSTATE_LIGHTING,                TRUE,
-    D3DRENDERSTATE_EXTENTS,                 FALSE,
-    D3DRENDERSTATE_AMBIENT,                 D3DRGBA(0,0,0,0),
-    D3DRENDERSTATE_FOGVERTEXMODE,           D3DFOG_NONE,
-    D3DRENDERSTATE_COLORVERTEX,             TRUE,
-    D3DRENDERSTATE_LOCALVIEWER,             TRUE,
-    D3DRENDERSTATE_NORMALIZENORMALS,        FALSE,
-    /* FIXME: D3DRENDER_STATE_COLORKEYBLENDENABLE */
-    D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,   D3DMCS_COLOR1,
-    D3DRENDERSTATE_SPECULARMATERIALSOURCE,  D3DMCS_COLOR2,
-    D3DRENDERSTATE_AMBIENTMATERIALSOURCE,   D3DMCS_COLOR2,
-    D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,  D3DMCS_MATERIAL,
-    D3DRENDERSTATE_VERTEXBLEND,             D3DVBLEND_DISABLE,
-    D3DRENDERSTATE_CLIPPLANEENABLE,         0
-};
-
-DWORD InitLightStateTab[] = {
-    D3DLIGHTSTATE_MATERIAL,           (DWORD)NULL,
-    D3DLIGHTSTATE_AMBIENT,            D3DRGBA(0,0,0,0),
-    D3DLIGHTSTATE_COLORMODEL,         D3DCOLOR_RGB,
-    D3DLIGHTSTATE_FOGMODE,            D3DFOG_NONE,
-    D3DLIGHTSTATE_FOGSTART,           0x3F80000, /* 1.0f */
-    D3DLIGHTSTATE_FOGEND,             0x42C8000, /* 100.0f */
-    D3DLIGHTSTATE_FOGDENSITY,         0x3F80000  /* 1.0f */
-    /* FIXME: D3DLIGHTSTATE_COLORVERTEX */
-};
-
-DWORD InitTextureStageStateTab[] = {
-    D3DTSS_COLOROP,          D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */
-    D3DTSS_COLORARG1,        D3DTA_TEXTURE,
-    D3DTSS_COLORARG2,        D3DTA_CURRENT,
-    D3DTSS_ALPHAOP,          D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */
-    D3DTSS_ALPHAARG1,        D3DTA_TEXTURE,
-    D3DTSS_ALPHAARG2,        D3DTA_CURRENT,
-    /* FIXME: D3DTSS_BUMPENVMAT00,01,10,11 */
-    /* D3DTSS_TEXCOORDINDEX is set manually */
-    D3DTSS_ADDRESS,          D3DTADDRESS_WRAP,
-    D3DTSS_ADDRESSU,         D3DTADDRESS_WRAP,
-    D3DTSS_ADDRESSV,         D3DTADDRESS_WRAP,
-    D3DTSS_BORDERCOLOR,      0x00000000,
-    D3DTSS_MAGFILTER,        D3DTFG_POINT,
-    D3DTSS_MINFILTER,        D3DTFN_POINT,
-    D3DTSS_MIPFILTER,        D3DTFP_NONE,
-    D3DTSS_MIPMAPLODBIAS,    0x00000000, /* 0.0f */
-    D3DTSS_MAXMIPLEVEL,      0,
-    /* D3DTSS_MAXANISOTROPY,    1, */ /* This is to prevent warnings :-) */
-    /* FIXME: D3DTSS_BUMPENVLSCALE */
-    /* FIXME: D3DTSS_NUMPENVLOFFSET */
-    /* FIXME: D3DTSS_TEXTURETRANSFORMFLAGS */
-};
-
-	
-void InitDefaultStateBlock(STATEBLOCK* lpStateBlock, int version)
-{
-    unsigned int i, j;  
-    TRACE("(%p,%d)\n", lpStateBlock, version);    
-    memset(lpStateBlock, 0, sizeof(STATEBLOCK));
-    
-    /* Initialize render states */
-    for (i = 0; i < sizeof(InitRenderStateTab) / sizeof(InitRenderStateTab[0]); i += 2)
-    {
-        lpStateBlock->render_state[InitRenderStateTab[i] - 1] = InitRenderStateTab[i + 1];
-	lpStateBlock->set_flags.render_state[InitRenderStateTab[i] - 1] = TRUE;
-    }
-
-    /* Initialize texture stages states */
-    for (i = 0; i < MAX_TEXTURES; i++)
-    {
-       for (j = 0; j < sizeof(InitTextureStageStateTab) / sizeof(InitTextureStageStateTab[0]); j += 2)
-       {
-           lpStateBlock->texture_stage_state[i][InitTextureStageStateTab[j] - 1] = InitTextureStageStateTab[j + 1];
-           lpStateBlock->set_flags.texture_stage_state[i][InitTextureStageStateTab[j] - 1] = TRUE;
-       }
-       /* Map texture coords 0 to stage 0, 1 to stage 1, etc... */
-       lpStateBlock->texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = i;
-       lpStateBlock->set_flags.texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = TRUE;
-    }
-    
-    /* The first texture is particular, update it consequently */
-    lpStateBlock->texture_stage_state[0][D3DTSS_COLOROP - 1] = D3DTOP_MODULATE;
-    lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAOP - 1] = D3DTOP_SELECTARG1;
-    lpStateBlock->texture_stage_state[0][D3DTSS_COLORARG2 - 1] = D3DTA_DIFFUSE;
-    lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAARG2 - 1] = D3DTA_DIFFUSE;
-    
-    /* Updates for particular versions */
-    if ((version == 1) || (version==2))
-       lpStateBlock->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] = TRUE;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface,
-                                                   REFIID riid,
-                                                   LPVOID* obp)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
-
-    *obp = NULL;
-
-    /* Note: We cannot get an interface whose version is higher than the
-     *       Direct3D object that created the device */
-
-    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
-        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
-	*obp = iface;
-	TRACE("  Creating IUnknown interface at %p.\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DDevice, riid ) ) {
-        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
-        *obp = ICOM_INTERFACE(This, IDirect3DDevice);
-	TRACE("  Creating IDirect3DDevice interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DDevice2, riid ) && (This->version >= 2)) {
-        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
-        *obp = ICOM_INTERFACE(This, IDirect3DDevice2);
-	TRACE("  Creating IDirect3DDevice2 interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DDevice3, riid ) && (This->version >= 3)) {
-        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
-        *obp = ICOM_INTERFACE(This, IDirect3DDevice3);
-	TRACE("  Creating IDirect3DDevice3 interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DDevice7, riid ) && (This->version >= 7)) {
-        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
-        *obp = ICOM_INTERFACE(This, IDirect3DDevice7);
-	TRACE("  Creating IDirect3DDevice7 interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirectDrawSurface, riid ) ||
-         IsEqualGUID( &IID_IDirectDrawSurface2, riid ) ||
-         IsEqualGUID( &IID_IDirectDrawSurface3, riid ) ) {
-        IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7));
-        *obp = ICOM_INTERFACE(This->surface, IDirectDrawSurface3);
-	TRACE("  Return IDirectDrawSurface3 interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirectDrawSurface4, riid ) ||
-         IsEqualGUID( &IID_IDirectDrawSurface7, riid ) ) {
-        IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7));
-        *obp = ICOM_INTERFACE(This->surface, IDirectDrawSurface7);
-	TRACE("  Return IDirectDrawSurface7 interface %p\n", *obp);
-	return S_OK;
-    }
-    FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
-}
-
-ULONG WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
-
-    return ref;
-}
-
-ULONG WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
-
-    if (!ref) {
-        int i;
-	/* Release texture associated with the device */
-	for (i = 0; i < MAX_TEXTURES; i++) {
-	    if (This->current_texture[i] != NULL)
-	        IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[i], IDirect3DTexture2));
-	}
-	HeapFree(GetProcessHeap(), 0, This->vertex_buffer);
-	HeapFree(GetProcessHeap(), 0, This);
-	return 0;
-    }
-    return ref;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
-                                   LPD3DDEVICEDESC7 lpD3DHELDevDesc)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DHELDevDesc);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
-                                                 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
-                                                 LPVOID lpArg)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumPixelProc, lpArg);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->()\n", This, iface);
-    /* Nothing to do */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->()\n", This, iface);
-    /* Nothing to do */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface,
-						LPDIRECT3D7* lplpDirect3D7)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3D7);
-
-    *lplpDirect3D7 = ICOM_INTERFACE(This->d3d, IDirect3D7);
-    IDirect3D7_AddRef(ICOM_INTERFACE(This->d3d, IDirect3D7));
-    
-    TRACE(" returning interface %p\n", *lplpDirect3D7);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface,
-						 LPDIRECTDRAWSURFACE7 lpNewRenderTarget,
-						 DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirectDrawSurfaceImpl *target_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpNewRenderTarget);
-
-    TRACE("(%p/%p)->(%p,%08lx)\n", This, iface, lpNewRenderTarget, dwFlags);
-    if (target_impl != This->surface) {
-        WARN(" Change of rendering target not handled yet !\n");
-    }
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface,
-						 LPDIRECTDRAWSURFACE7* lplpRenderTarget)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lplpRenderTarget);
-
-    *lplpRenderTarget = ICOM_INTERFACE(This->surface, IDirectDrawSurface7);
-    IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7));
-    
-    TRACE(" returning surface at %p.\n", *lplpRenderTarget);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface,
-                                 DWORD dwCount,
-                                 LPD3DRECT lpRects,
-                                 DWORD dwFlags,
-                                 D3DCOLOR dwColor,
-                                 D3DVALUE dvZ,
-                                 DWORD dwStencil)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, (DWORD) dwColor, dvZ, dwStencil);
-    return This->clear(This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    DWORD matrix_changed = 0x00000000;
-
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
-
-    switch (dtstTransformStateType) {
-        case D3DTRANSFORMSTATE_WORLD: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" D3DTRANSFORMSTATE_WORLD :\n"); dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	    memcpy(This->world_mat, lpD3DMatrix, 16 * sizeof(float));
-	    matrix_changed = WORLDMAT_CHANGED;
-	} break;
-
-	case D3DTRANSFORMSTATE_VIEW: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" D3DTRANSFORMSTATE_VIEW :\n");  dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	    memcpy(This->view_mat, lpD3DMatrix, 16 * sizeof(float));
-	    matrix_changed = VIEWMAT_CHANGED;
-	} break;
-
-	case D3DTRANSFORMSTATE_PROJECTION: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");  dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	    memcpy(This->proj_mat, lpD3DMatrix, 16 * sizeof(float));
-	    matrix_changed = PROJMAT_CHANGED;
-	} break;
-
-	case D3DTRANSFORMSTATE_TEXTURE0:
-	case D3DTRANSFORMSTATE_TEXTURE1:
-	case D3DTRANSFORMSTATE_TEXTURE2:
-	case D3DTRANSFORMSTATE_TEXTURE3:
-	case D3DTRANSFORMSTATE_TEXTURE4:
-	case D3DTRANSFORMSTATE_TEXTURE5:
-	case D3DTRANSFORMSTATE_TEXTURE6:
-	case D3DTRANSFORMSTATE_TEXTURE7: {
-	    DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0;
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" D3DTRANSFORMSTATE_TEXTURE%ld :\n", mat_num);  dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	    memcpy(This->tex_mat[mat_num], lpD3DMatrix, 16 * sizeof(float));
-	    matrix_changed = TEXMAT0_CHANGED << mat_num;
-	} break;
-	  
-	default:
-	    ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
-	    break;
-    }
-
-    if (matrix_changed != 0x00000000) This->matrices_updated(This, matrix_changed);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
-
-    switch (dtstTransformStateType) {
-        case D3DTRANSFORMSTATE_WORLD: {
-	    memcpy(lpD3DMatrix, This->world_mat, 16 * sizeof(D3DVALUE));
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" returning D3DTRANSFORMSTATE_WORLD :\n");
-		dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	} break;
-
-	case D3DTRANSFORMSTATE_VIEW: {
-	    memcpy(lpD3DMatrix, This->view_mat, 16 * sizeof(D3DVALUE));
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" returning D3DTRANSFORMSTATE_VIEW :\n");
-		dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	} break;
-
-	case D3DTRANSFORMSTATE_PROJECTION: {
-	    memcpy(lpD3DMatrix, This->proj_mat, 16 * sizeof(D3DVALUE));
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" returning D3DTRANSFORMSTATE_PROJECTION :\n");
-		dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	} break;
-
-	case D3DTRANSFORMSTATE_TEXTURE0:
-	case D3DTRANSFORMSTATE_TEXTURE1:
-	case D3DTRANSFORMSTATE_TEXTURE2:
-	case D3DTRANSFORMSTATE_TEXTURE3:
-	case D3DTRANSFORMSTATE_TEXTURE4:
-	case D3DTRANSFORMSTATE_TEXTURE5:
-	case D3DTRANSFORMSTATE_TEXTURE6:
-	case D3DTRANSFORMSTATE_TEXTURE7: {
-	    DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0;
-	    memcpy(lpD3DMatrix, This->tex_mat[mat_num], 16 * sizeof(D3DVALUE));
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" returning D3DTRANSFORMSTATE_TEXTURE%ld :\n", mat_num);
-		dump_D3DMATRIX(lpD3DMatrix);
-	    }
-	} break;
-	  
-	default:
-	    ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
-	    return DDERR_INVALIDPARAMS;
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface,
-                                                   D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                                   LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    LPD3DMATRIX mat;
-    DWORD matrix_changed = 0x00000000;
-
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
-    
-    if (TRACE_ON(ddraw)) {
-        TRACE(" Multiplying by :\n"); dump_D3DMATRIX(lpD3DMatrix);
-    }
-    
-    switch (dtstTransformStateType) {
-        case D3DTRANSFORMSTATE_WORLD: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" Resulting D3DTRANSFORMSTATE_WORLD matrix is :\n");
-	    }
-	    mat = This->world_mat;
-	    matrix_changed = WORLDMAT_CHANGED;
-	} break;
-
-        case D3DTRANSFORMSTATE_VIEW: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" Resulting D3DTRANSFORMSTATE_VIEW matrix is :\n");
-	    }
-	    mat = This->view_mat;
-	    matrix_changed = VIEWMAT_CHANGED;
-	} break;
-
-        case D3DTRANSFORMSTATE_PROJECTION: {
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" Resulting D3DTRANSFORMSTATE_PROJECTION matrix is :\n");
-	    }
-	    mat = This->proj_mat;
-	    matrix_changed = PROJMAT_CHANGED;
-	} break;
-
-	case D3DTRANSFORMSTATE_TEXTURE0:
-	case D3DTRANSFORMSTATE_TEXTURE1:
-	case D3DTRANSFORMSTATE_TEXTURE2:
-	case D3DTRANSFORMSTATE_TEXTURE3:
-	case D3DTRANSFORMSTATE_TEXTURE4:
-	case D3DTRANSFORMSTATE_TEXTURE5:
-	case D3DTRANSFORMSTATE_TEXTURE6:
-	case D3DTRANSFORMSTATE_TEXTURE7: {
-	    DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0;
-	    if (TRACE_ON(ddraw)) {
-	        TRACE(" Resulting D3DTRANSFORMSTATE_TEXTURE%ld matrix is :\n", mat_num);
-	    }
-	    mat = This->tex_mat[mat_num];
-	    matrix_changed = TEXMAT0_CHANGED << mat_num;
-	} break;
-
-	default:
-	    ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
-	    return DDERR_INVALIDPARAMS;
-    }
-
-    multiply_matrix(mat,mat,lpD3DMatrix);
-    
-    if (TRACE_ON(ddraw)) {
-        dump_D3DMATRIX(mat);
-    }
-    
-    if (matrix_changed != 0x00000000) This->matrices_updated(This, matrix_changed);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DVIEWPORT7 lpData)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
-
-    *lpData = This->active_viewport;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" returning viewport :\n");
-	TRACE("    - dwX = %ld   dwY = %ld\n",
-	      lpData->dwX, lpData->dwY);
-	TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
-	      lpData->dwWidth, lpData->dwHeight);
-	TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
-	      lpData->dvMinZ, lpData->dvMaxZ);
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DMATERIAL7 lpMat)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpMat);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface,
-                                       LPD3DMATERIAL7 lpMat)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
-    
-    *lpMat = This->current_material;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" returning material :\n");
-	dump_D3DMATERIAL7(lpMat);
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
-                                    DWORD dwLightIndex,
-                                    LPD3DLIGHT7 lpLight)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwLightIndex, lpLight);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface,
-                                    DWORD dwLightIndex,
-                                    LPD3DLIGHT7 lpLight)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
-
-    if (dwLightIndex >= This->num_set_lights)
-        return DDERR_INVALIDPARAMS;
-
-    *lpLight = This->light_parameters[dwLightIndex];
-
-    /* If dltType is zero, then this light has never been set, either
-       by calling SetLight or implicitely by calling EnableLight without
-       calling SetLight first. */
-    if (lpLight->dltType == 0)
-        return DDERR_INVALIDPARAMS;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" returning light :\n");
-	dump_D3DLIGHT7(lpLight);
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
-                                                D3DRENDERSTATETYPE dwRenderStateType,
-                                                DWORD dwRenderState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwRenderStateType, dwRenderState);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
-                                                D3DRENDERSTATETYPE dwRenderStateType,
-                                                LPDWORD lpdwRenderState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dwRenderStateType, lpdwRenderState);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(): stub!\n", This, iface);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface,
-                                         LPDWORD lpdwBlockHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpdwBlockHandle);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface,
-                                   LPDIRECTDRAWSURFACE7 lpddsTexture)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpddsTexture);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
-                                            D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                            DWORD d3dvtVertexType,
-                                            LPVOID lpvVertices,
-                                            DWORD dwVertexCount,
-                                            DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
-                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                   DWORD d3dvtVertexType,
-                                                   LPVOID lpvVertices,
-                                                   DWORD dwVertexCount,
-                                                   LPWORD dwIndices,
-                                                   DWORD dwIndexCount,
-                                                   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface,
-                                               LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface,
-                                               LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                   DWORD dwVertexType,
-                                                   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                   DWORD dwVertexCount,
-                                                   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                          DWORD dwVertexType,
-                                                          LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                          DWORD dwVertexCount,
-                                                          LPWORD lpIndex,
-                                                          DWORD dwIndexCount,
-                                                          DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-					      D3DPRIMITIVETYPE d3dptPrimitiveType,
-					      LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-					      DWORD dwStartVertex,
-					      DWORD dwNumVertices,
-					      DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-						     D3DPRIMITIVETYPE d3dptPrimitiveType,
-						     LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-						     DWORD dwStartVertex,
-						     DWORD dwNumVertices,
-						     LPWORD lpwIndices,
-						     DWORD dwIndexCount,
-						     DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface,
-                                                      LPD3DVECTOR lpCenters,
-                                                      LPD3DVALUE lpRadii,
-                                                      DWORD dwNumSpheres,
-                                                      DWORD dwFlags,
-                                                      LPDWORD lpdwReturnValues)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx,%08lx,%p): stub!\n", This, iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_GetTexture(LPDIRECT3DDEVICE7 iface,
-					 DWORD dwStage,
-					 LPDIRECTDRAWSURFACE7* lpTexture)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture);
-
-    if (This->current_texture[dwStage] != NULL) {
-        *lpTexture = ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7);
-        IDirectDrawSurface7_AddRef(*lpTexture);
-    } else {
-        *lpTexture = NULL;
-    }
-
-    TRACE(" returning interface at %p (for implementation at %p).\n", *lpTexture, This->current_texture[dwStage]);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
-					 DWORD dwStage,
-					 LPDIRECTDRAWSURFACE7 lpTexture)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lpTexture);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface,
-                                                   DWORD dwStage,
-                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                   LPDWORD lpdwState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%08x,%p)\n", This, iface, dwStage, d3dTexStageStateType, lpdwState);
-    if (lpdwState && (dwStage < 8) && d3dTexStageStateType && (d3dTexStageStateType <= HIGHEST_TEXTURE_STAGE_STATE) ) {
-        *lpdwState = This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1];
-	return DD_OK;
-    }
-    return DDERR_INVALIDPARAMS;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
-                                                   DWORD dwStage,
-                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                   DWORD dwState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%08x,%08lx): stub!\n", This, iface, dwStage, d3dTexStageStateType, dwState);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface,
-                                             LPDWORD lpdwPasses)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p): semi-stub!\n", This, iface, lpdwPasses);
-
-    /* For the moment, we have a VERY good hardware which does everything in one pass :-) */
-    *lpdwPasses = 1;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface,
-                                           DWORD dwBlockHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface,
-                                             DWORD dwBlockHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface,
-                                            DWORD dwBlockHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface,
-                                            D3DSTATEBLOCKTYPE d3dsbType,
-                                            LPDWORD lpdwBlockHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, d3dsbType, lpdwBlockHandle);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface,
-                                LPDIRECTDRAWSURFACE7 lpDestTex,
-                                LPPOINT lpDestPoint,
-                                LPDIRECTDRAWSURFACE7 lpSrcTex,
-                                LPRECT lprcSrcRect,
-                                DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%p,%p,%p,%p,%08lx): Partially Implemented!\n", This, iface, lpDestTex, lpDestPoint, lpSrcTex, lprcSrcRect, dwFlags);
-    IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpDestTex),
-			   COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpSrcTex));
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
-                                       DWORD dwLightIndex,
-                                       BOOL bEnable)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%d): stub!\n", This, iface, dwLightIndex, bEnable);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface,
-                                          DWORD dwLightIndex,
-                                          BOOL* pbEnable)
-{
-    int i;
-
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, pbEnable);
-
-    *pbEnable = 0;
-    if (dwLightIndex >= This->num_set_lights)
-        return DDERR_INVALIDPARAMS;
-
-    /* If dltType is zero, then this light has never been set, either
-       by calling SetLight or implicitely by calling EnableLight without
-       calling SetLight first. */
-    if (This->light_parameters[dwLightIndex].dltType == 0)
-        return DDERR_INVALIDPARAMS;
-
-    for (i = 0; i < This->max_active_lights; i++)
-        if (This->active_lights[i] == dwLightIndex)
-            *pbEnable = TRUE;
-
-    TRACE(" returning %d.\n", *pbEnable);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface,
-                                        DWORD dwIndex,
-                                        D3DVALUE* pPlaneEquation)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwIndex, pPlaneEquation);
-    return DD_OK;
-}
-
-HRESULT  WINAPI  
-Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, D3DVALUE* pPlaneEquation)
-{
-    IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
-
-    TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
-
-    if (dwIndex>=This->max_clipping_planes) {
-	return DDERR_INVALIDPARAMS;
-    }
-
-    memcpy( pPlaneEquation, This->clipping_planes[dwIndex].plane, sizeof(D3DVALUE[4]));
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface,
-                                   DWORD dwDevInfoID,
-                                   LPVOID pDevInfoStruct,
-                                   DWORD dwSize)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" info requested : ");
-	switch (dwDevInfoID) {
-	    case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
-	    case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
-	    case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
-	    default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
-	}
-    }
-
-    return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
-                                         LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                         LPD3DDEVICEDESC lpD3DHELDevDesc)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DSTATS lpD3DStats)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DStats);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface,
-					     LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
-    
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
-
-    lpDirect3DViewportImpl->next = This->viewport_list;
-    This->viewport_list = lpDirect3DViewportImpl;
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface,
-						LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
-    IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
-  
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
-
-    cur_viewport = This->viewport_list;
-    while (cur_viewport != NULL) {
-        if (cur_viewport == lpDirect3DViewportImpl) {
-	    if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
-	    else prev_viewport->next = cur_viewport->next;
-	    /* TODO : add desactivate of the viewport and all associated lights... */
-	    return DD_OK;
-	}
-	prev_viewport = cur_viewport;
-	cur_viewport = cur_viewport->next;
-    }
-    
-    return DDERR_INVALIDPARAMS;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface,
-					      LPDIRECT3DVIEWPORT3 lpDirect3DViewport3,
-					      LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3,
-					      DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    IDirect3DViewportImpl *res = NULL;
-
-    TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpDirect3DViewport3, lplpDirect3DViewport3, dwFlags);
-    
-    switch (dwFlags) {
-        case D3DNEXT_NEXT: {
-	    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
-	    res = lpDirect3DViewportImpl->next;
-	} break;
-	case D3DNEXT_HEAD: {
-	    res = This->viewport_list;
-	} break;
-	case D3DNEXT_TAIL: {
-	    IDirect3DViewportImpl *cur_viewport = This->viewport_list;
-	    if (cur_viewport != NULL) {
-	        while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
-	    }
-	    res = cur_viewport;
-	} break;
-	default:
-	    *lplpDirect3DViewport3 = NULL;
-	    return DDERR_INVALIDPARAMS;
-    }
-    *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface,
-						 LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
-
-    /* Do nothing if the specified viewport is the same as the current one */
-    if (This->current_viewport == ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3))
-      return DD_OK;
-    
-    /* Should check if the viewport was added or not */
-
-    /* Release previous viewport and AddRef the new one */
-    if (This->current_viewport)
-      IDirect3DViewport3_Release(ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
-    IDirect3DViewport3_AddRef(lpDirect3DViewport3);
-    
-    /* Set this viewport as the current viewport */
-    This->current_viewport = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
-
-    /* Activate this viewport */
-    This->current_viewport->active_device = This;
-    This->current_viewport->activate(This->current_viewport);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface,
-						 LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3DViewport3);
-
-    *lplpDirect3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
-
-    /* AddRef the returned viewport */
-    IDirect3DViewport3_AddRef(*lplpDirect3DViewport3);
-    
-    TRACE(" returning interface %p\n", *lplpDirect3DViewport3);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface,
-                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                 DWORD dwVertexTypeDesc,
-                                 DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%08x,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexTypeDesc, dwFlags);
-
-    This->primitive_type = d3dptPrimitiveType;
-    This->vertex_type = dwVertexTypeDesc;
-    This->render_flags = dwFlags;
-    This->vertex_size = get_flexible_vertex_size(This->vertex_type);
-    This->nb_vertices = 0;
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface,
-                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                        DWORD d3dvtVertexType,
-                                        LPVOID lpvVertices,
-                                        DWORD dwNumVertices,
-                                        DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface,
-                                     LPVOID lpVertexType)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpVertexType);
-
-    if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
-    {
-	LPBYTE old_buffer;
-	This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
-	old_buffer = This->vertex_buffer;
-	This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
-	if (old_buffer)
-	{
-	    CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
-	    HeapFree(GetProcessHeap(), 0, old_buffer);
-	}
-    }
-
-    CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, lpVertexType, This->vertex_size);
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface,
-                                    WORD wVertexIndex)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%04x): stub!\n", This, iface, wVertexIndex);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface,
-                                  DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%08lx)\n", This, iface, dwFlags);
-
-    IDirect3DDevice3_DrawPrimitive(iface, This->primitive_type, This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface,
-                                            D3DLIGHTSTATETYPE dwLightStateType,
-                                            LPDWORD lpdwLightState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%08x,%p): stub !\n", This, iface, dwLightStateType, lpdwLightState);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
-                                            D3DLIGHTSTATETYPE dwLightStateType,
-                                            DWORD dwLightState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwLightStateType, dwLightState);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
-                                                 LPDIRECT3DTEXTURE2 lpD3DTex1,
-                                                 LPDIRECT3DTEXTURE2 lpD3DTex2)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    IDirectDrawSurfaceImpl tmp,*surf1,*surf2;
-    TRACE("(%p/%p)->(%p,%p):\n", This, iface, lpD3DTex1, lpD3DTex2);
-
-    surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirect3DTexture2,lpD3DTex1);
-    surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirect3DTexture2,lpD3DTex2);
-    tmp = *surf1;
-    *surf1 = *surf2;
-    *surf2 = tmp;
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface,
-                                        LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
-                                        LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
-                                        DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
-                                                 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
-                                                 LPVOID lpArg)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumTextureProc, lpArg);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface,
-                                 D3DPRIMITIVETYPE d3dpt,
-                                 D3DVERTEXTYPE dwVertexTypeDesc,
-                                 DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%08x,%08x,%08lx): stub!\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface,
-                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                        D3DVERTEXTYPE d3dvtVertexType,
-                                        LPVOID lpvVertices,
-                                        DWORD dwNumVertices,
-                                        DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
-                                         D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                         D3DVERTEXTYPE d3dvtVertexType,
-                                         LPVOID lpvVertices,
-                                         DWORD dwVertexCount,
-                                         DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
-                                                D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                D3DVERTEXTYPE d3dvtVertexType,
-                                                LPVOID lpvVertices,
-                                                DWORD dwVertexCount,
-                                                LPWORD dwIndices,
-                                                DWORD dwIndexCount,
-                                                DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface,
-                                      LPDIRECT3D lpDirect3D,
-                                      LPGUID lpGUID,
-                                      LPD3DDEVICEDESC lpD3DDVDesc)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDirect3D, lpGUID, lpD3DDVDesc);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
-                                               LPD3DEXECUTEBUFFERDESC lpDesc,
-                                               LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
-                                               IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface,
-                                   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-                                   LPDIRECT3DVIEWPORT lpDirect3DViewport,
-                                   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    IDirect3DExecuteBufferImpl *lpDirect3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, lpDirect3DExecuteBuffer);
-    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport);
-    
-    TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
-
-    /* Put this as the default context */
-
-    /* Execute... */
-    lpDirect3DExecuteBufferImpl->execute(lpDirect3DExecuteBufferImpl, This, lpDirect3DViewportImpl);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface,
-                                        LPDIRECT3DVIEWPORT lpDirect3DViewport,
-                                        LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
-                                        DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface,
-                                LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-                                LPDIRECT3DVIEWPORT lpDirect3DViewport,
-                                DWORD dwFlags,
-                                LPD3DRECT lpRect)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx,%p): stub!\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface,
-                                          LPDWORD lpCount,
-                                          LPD3DPICKRECORD lpD3DPickRec)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpCount, lpD3DPickRec);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface,
-                                        LPD3DMATRIXHANDLE lpD3DMatHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DMatHandle);
-
-    *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
-    TRACE(" returning matrix handle %p\n", (void *) *lpD3DMatHandle);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface,
-                                     D3DMATRIXHANDLE D3DMatHandle,
-                                     LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix);
-
-    if (TRACE_ON(ddraw)) {
-	dump_D3DMATRIX(lpD3DMatrix);
-    }
-    *((D3DMATRIX *) D3DMatHandle) = *lpD3DMatrix;   
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface,
-                                     D3DMATRIXHANDLE D3DMatHandle,
-                                     LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix);
-
-    *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface,
-                                        D3DMATRIXHANDLE D3DMatHandle)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) D3DMatHandle);
-
-    HeapFree(GetProcessHeap(), 0, (void *) D3DMatHandle);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface,
-                                           REFIID riid,
-                                           LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                           riid,
-                                           obp);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface,
-                                           REFIID riid,
-                                           LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                           riid,
-                                           obp);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface,
-                                           REFIID riid,
-                                           LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface),
-                                           riid,
-                                           obp);
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface,
-					LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
-    return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-					(LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface,
-					LPDIRECT3DVIEWPORT lpDirect3DViewport)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport);
-    return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
-					(LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface,
-					   LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
-    return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-					   (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface,
-					   LPDIRECT3DVIEWPORT lpDirect3DViewport)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport);
-    return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
-					   (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface,
-					 LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
-					 LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
-					 DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags);
-    return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-					 (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */,
-					 (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2,
-					 dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface,
-					 LPDIRECT3DVIEWPORT lpDirect3DViewport,
-					 LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
-					 DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags);
-    return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
-					 (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */,
-					 (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport,
-					 dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface,
-					LPDIRECT3D3* lplpDirect3D3)
-{
-    HRESULT ret;
-    LPDIRECT3D7 ret_ptr;
-  
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D3);
-    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-				       &ret_ptr);
-    *lplpDirect3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
-    TRACE(" returning interface %p\n", *lplpDirect3D3);
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface,
-					LPDIRECT3D2* lplpDirect3D2)
-{
-    HRESULT ret;
-    LPDIRECT3D7 ret_ptr;
-  
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D2);
-    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-				       &ret_ptr);
-    *lplpDirect3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
-    TRACE(" returning interface %p\n", *lplpDirect3D2);
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface,
-					LPDIRECT3D* lplpDirect3D)
-{
-    HRESULT ret;
-    LPDIRECT3D7 ret_ptr;
-  
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D);
-    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface),
-				       &ret_ptr);
-    *lplpDirect3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
-    TRACE(" returning interface %p\n", *lplpDirect3D);
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-					       LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
-    return IDirect3DDevice3_SetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-					       (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-					       LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lplpDirect3DViewport2);
-    return IDirect3DDevice3_GetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-					       (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface,
-                                               LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
-                                               LPVOID lpArg)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DEnumPixelProc, lpArg);
-    return IDirect3DDevice7_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                               lpD3DEnumPixelProc,
-                                               lpArg);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
-    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                         dtstTransformStateType,
-                                         lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                         dtstTransformStateType,
-                                         lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                         dtstTransformStateType,
-                                         lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface,
-                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                         LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                         dtstTransformStateType,
-                                         lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                              dtstTransformStateType,
-                                              lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
-                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                              LPD3DMATRIX lpD3DMatrix)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
-    return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                              dtstTransformStateType,
-                                              lpD3DMatrix);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           DWORD dwRenderState)
-{
-    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState);
-    return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                           dwRenderStateType,
-                                           dwRenderState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           DWORD dwRenderState)
-{
-    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState);
-    return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                           dwRenderStateType,
-                                           dwRenderState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           LPDWORD lpdwRenderState)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState);
-    return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                           dwRenderStateType,
-                                           lpdwRenderState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface,
-                                           D3DRENDERSTATETYPE dwRenderStateType,
-                                           LPDWORD lpdwRenderState)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState);
-    return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                           dwRenderStateType,
-                                           lpdwRenderState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface,
-                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                          DWORD d3dvtVertexType,
-                                          LPVOID lpvVertices,
-                                          DWORD dwVertexCount,
-                                          DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
-    return IDirect3DDevice7_DrawPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                          d3dptPrimitiveType,
-                                          d3dvtVertexType,
-                                          lpvVertices,
-                                          dwVertexCount,
-                                          dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface,
-                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                 DWORD d3dvtVertexType,
-                                                 LPVOID lpvVertices,
-                                                 DWORD dwVertexCount,
-                                                 LPWORD dwIndices,
-                                                 DWORD dwIndexCount,
-                                                 DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    return IDirect3DDevice7_DrawIndexedPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                 d3dptPrimitiveType,
-                                                 d3dvtVertexType,
-                                                 lpvVertices,
-                                                 dwVertexCount,
-                                                 dwIndices,
-                                                 dwIndexCount,
-                                                 dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
-    return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                          lpD3DClipStatus);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
-    return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                          lpD3DClipStatus);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
-    return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                          lpD3DClipStatus);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface,
-                                          LPD3DCLIPSTATUS lpD3DClipStatus)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
-    return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                          lpD3DClipStatus);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
-                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                 DWORD dwVertexType,
-                                                 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                 DWORD dwVertexCount,
-                                                 DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
-    return IDirect3DDevice7_DrawPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                 d3dptPrimitiveType,
-                                                 dwVertexType,
-                                                 lpD3DDrawPrimStrideData,
-                                                 dwVertexCount,
-                                                 dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
-                                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                        DWORD dwVertexType,
-                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                        DWORD dwVertexCount,
-                                                        LPWORD lpIndex,
-                                                        DWORD dwIndexCount,
-                                                        DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
-    return IDirect3DDevice7_DrawIndexedPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                        d3dptPrimitiveType,
-                                                        dwVertexType,
-                                                        lpD3DDrawPrimStrideData,
-                                                        dwVertexCount,
-                                                        lpIndex,
-                                                        dwIndexCount,
-                                                        dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface,
-                                                    LPD3DVECTOR lpCenters,
-                                                    LPD3DVALUE lpRadii,
-                                                    DWORD dwNumSpheres,
-                                                    DWORD dwFlags,
-                                                    LPDWORD lpdwReturnValues)
-{
-    TRACE("(%p)->(%p,%p,%08lx,%08lx,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues);
-    return IDirect3DDevice7_ComputeSphereVisibility(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                    lpCenters,
-                                                    lpRadii,
-                                                    dwNumSpheres,
-                                                    dwFlags,
-                                                    lpdwReturnValues);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface,
-                                                 DWORD dwStage,
-                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                 LPDWORD lpdwState)
-{
-    TRACE("(%p)->(%08lx,%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, lpdwState);
-    return IDirect3DDevice7_GetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                 dwStage,
-                                                 d3dTexStageStateType,
-                                                 lpdwState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface,
-                                                 DWORD dwStage,
-                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-                                                 DWORD dwState)
-{
-    TRACE("(%p)->(%08lx,%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, dwState);
-    return IDirect3DDevice7_SetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                                 dwStage,
-                                                 d3dTexStageStateType,
-                                                 dwState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface,
-                                           LPDWORD lpdwPasses)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpdwPasses);
-    return IDirect3DDevice7_ValidateDevice(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                           lpdwPasses);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface,
-                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                    LPD3DDEVICEDESC lpD3DHELDevDesc)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
-    return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                    lpD3DHWDevDesc,
-                                    lpD3DHELDevDesc);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface,
-                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
-                                    LPD3DDEVICEDESC lpD3DHELDevDesc)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
-    return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
-                                    lpD3DHWDevDesc,
-                                    lpD3DHELDevDesc);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface,
-                                              LPDIRECT3DTEXTURE lpD3DTex1,
-                                              LPDIRECT3DTEXTURE lpD3DTex2)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", iface, lpD3DTex1, lpD3DTex2);
-    return IDirect3DDevice2_SwapTextureHandles(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, iface),
-                                               COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTex1),
-                                               COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTex2));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface,
-                                     LPD3DSTATS lpD3DStats)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats);
-    return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                     lpD3DStats);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface,
-                                     LPD3DSTATS lpD3DStats)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats);
-    return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
-                                     lpD3DStats);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface,
-                                            LPDIRECTDRAWSURFACE4 lpNewRenderTarget,
-                                            DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags);
-    return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                            (LPDIRECTDRAWSURFACE7) lpNewRenderTarget /* No cast needed as DSurf4 == DSurf7 */,
-                                            dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface,
-                                            LPDIRECTDRAWSURFACE4* lplpRenderTarget)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget);
-    return IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-                                            (LPDIRECTDRAWSURFACE7*) lplpRenderTarget /* No cast needed as DSurf4 == DSurf7 */);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
-                                            LPDIRECTDRAWSURFACE lpNewRenderTarget,
-                                            DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags);
-    return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-                                            COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface3, IDirectDrawSurface7, lpNewRenderTarget),
-                                            dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
-                                            LPDIRECTDRAWSURFACE* lplpRenderTarget)
-{
-    HRESULT ret;
-    LPDIRECTDRAWSURFACE7 ret_val;
-  
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget);
-    ret = IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
-					   &ret_val);
-    *lplpRenderTarget = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, ret_val);
-    TRACE(" returning interface %p\n", *lplpRenderTarget);
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface,
-                                   LPVOID lpVertexType)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpVertexType);
-    return IDirect3DDevice3_Vertex(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                   lpVertexType);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface,
-                                  WORD wVertexIndex)
-{
-    TRACE("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", iface, wVertexIndex);
-    return IDirect3DDevice3_Index(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                  wVertexIndex);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface,
-                                DWORD dwFlags)
-{
-    TRACE("(%p)->(%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwFlags);
-    return IDirect3DDevice3_End(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface,
-                                          D3DLIGHTSTATETYPE dwLightStateType,
-                                          LPDWORD lpdwLightState)
-{
-    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, lpdwLightState);
-    return IDirect3DDevice3_GetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                          dwLightStateType,
-                                          lpdwLightState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface,
-                                          D3DLIGHTSTATETYPE dwLightStateType,
-                                          DWORD dwLightState)
-{
-    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, dwLightState);
-    return IDirect3DDevice3_SetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
-                                          dwLightStateType,
-                                          dwLightState);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface,
-                                               LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
-                                               LPVOID lpArg)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", iface, lpD3DEnumTextureProc, lpArg);
-    return IDirect3DDevice2_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, iface),
-                                               lpD3DEnumTextureProc,
-                                               lpArg);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
-				       DWORD dwStage,
-				       LPDIRECT3DTEXTURE2 lpTexture2)
-{
-    TRACE("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, lpTexture2);
-    return IDirect3DDevice7_SetTexture(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-				       dwStage,
-				       COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, lpTexture2));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface,
-					    D3DPRIMITIVETYPE d3dptPrimitiveType,
-					    LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
-					    DWORD dwStartVertex,
-					    DWORD dwNumVertices,
-					    DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%p,%08lx,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, 
-	  d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
-    return IDirect3DDevice7_DrawPrimitiveVB(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-					    d3dptPrimitiveType,
-					    COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpD3DVertexBuf),
-					    dwStartVertex,
-					    dwNumVertices,
-					    dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface,
-						   D3DPRIMITIVETYPE d3dptPrimitiveType,
-						   LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
-						   LPWORD lpwIndices,
-						   DWORD dwIndexCount,
-						   DWORD dwFlags)
-{
-    TRACE("(%p)->(%08x,%p,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface,
-	  d3dptPrimitiveType, lpD3DVertexBuf, lpwIndices, dwIndexCount, dwFlags);
-    return IDirect3DDevice7_DrawIndexedPrimitiveVB(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-						   d3dptPrimitiveType,
-						   COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpD3DVertexBuf),
-						   0,
-						   dwIndexCount,
-						   lpwIndices,
-						   dwIndexCount,
-						   dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface,
-				       DWORD dwStage,
-				       LPDIRECT3DTEXTURE2* lplpTexture2)
-{
-    HRESULT ret;
-    LPDIRECTDRAWSURFACE7 ret_val;
-
-    TRACE("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, lplpTexture2);
-    ret = IDirect3DDevice7_GetTexture(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
-				      dwStage,
-				      &ret_val);
-
-    *lplpTexture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
-
-    TRACE(" returning interface %p.\n", *lplpTexture2);
-    
-    return ret;
-}
diff --git a/dlls/ddraw/device_opengl.c b/dlls/ddraw/device_opengl.c
deleted file mode 100644
index d19996e..0000000
--- a/dlls/ddraw/device_opengl.c
+++ /dev/null
@@ -1,4450 +0,0 @@
-/*
- * Direct3D Device
- *
- * Copyright (c) 1998-2004 Lionel Ulmer
- * Copyright (c) 2002-2005 Christian Costa
- *
- * This file contains the MESA implementation of all the D3D devices that
- * Wine supports.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-#include <string.h>
-#include <math.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "objbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-#include "wine/library.h"
-
-#include "d3d_private.h"
-#include "opengl_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
-
-/* x11drv GDI escapes */
-#define X11DRV_ESCAPE 6789
-enum x11drv_escape_codes
-{
-    X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
-    X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
-    X11DRV_GET_FONT,      /* get current X font for a DC */
-};
-
-/* They are non-static as they are used by Direct3D in the creation function */
-const GUID IID_D3DDEVICE_OpenGL = {
-  0x31416d44,
-  0x86ae,
-  0x11d2,
-  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
-};
-
-const float id_mat[16] = {
-    1.0, 0.0, 0.0, 0.0,
-    0.0, 1.0, 0.0, 0.0,
-    0.0, 0.0, 1.0, 0.0,
-    0.0, 0.0, 0.0, 1.0
-};
-
-/* This is filled at DLL loading time */
-static D3DDEVICEDESC7 opengl_device_caps;
-GL_EXTENSIONS_LIST GL_extensions;
-
-static void draw_primitive_strided(IDirect3DDeviceImpl *This,
-				   D3DPRIMITIVETYPE d3dptPrimitiveType,
-				   DWORD d3dvtVertexType,
-				   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-				   DWORD dwVertexCount,
-				   LPWORD dwIndices,
-				   DWORD dwIndexCount,
-				   DWORD dwFlags) ;
-
-static DWORD draw_primitive_handle_textures(IDirect3DDeviceImpl *This);
-
-/* retrieve the X display to use on a given DC */
-inline static Display *get_display( HDC hdc )
-{
-    Display *display;
-    enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
-
-    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
-                    sizeof(display), (LPSTR)&display )) display = NULL;
-
-    return display;
-}
-
-#define UNLOCK_TEX_SIZE 256
-
-#define DEPTH_RANGE_BIT (0x00000001 << 0)
-#define VIEWPORT_BIT    (0x00000001 << 1)
-
-static DWORD d3ddevice_set_state_for_flush(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, BOOLEAN use_alpha, BOOLEAN *initial) {
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-    DWORD opt_bitmap = 0x00000000;
-    
-    if ((gl_d3d_dev->current_bound_texture[1] != NULL) &&
-	((d3d_dev->state_block.texture_stage_state[1][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE))) {
-	if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE1_WINE) {
-	    GL_extensions.glActiveTexture(GL_TEXTURE1_WINE);
-	    gl_d3d_dev->current_active_tex_unit = GL_TEXTURE1_WINE;
-	}
-	/* Disable multi-texturing for level 1 to disable all others */
-	glDisable(GL_TEXTURE_2D);
-    }
-    if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE0_WINE) {
-	GL_extensions.glActiveTexture(GL_TEXTURE0_WINE);
-	gl_d3d_dev->current_active_tex_unit = GL_TEXTURE0_WINE;
-    }
-    if ((gl_d3d_dev->current_bound_texture[0] == NULL) ||
-	(d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE))
-	glEnable(GL_TEXTURE_2D);
-    if (gl_d3d_dev->unlock_tex == 0) {
-        glGenTextures(1, &gl_d3d_dev->unlock_tex);
-	glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex);
-	*initial = TRUE;
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-    } else {
-        glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex);
-	*initial = FALSE;
-    }
-    if (d3d_dev->tex_mat_is_identity[0] == FALSE) {
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-    }
-    
-    if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) {
-	gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO;
-	d3ddevice_set_ortho(d3d_dev);
-    }
-    
-    if (gl_d3d_dev->depth_test != FALSE) glDisable(GL_DEPTH_TEST);
-    glEnable(GL_SCISSOR_TEST);
-    if ((d3d_dev->active_viewport.dvMinZ != 0.0) ||
-	(d3d_dev->active_viewport.dvMaxZ != 1.0)) {
-	glDepthRange(0.0, 1.0);
-	opt_bitmap |= DEPTH_RANGE_BIT;
-    }
-    if ((d3d_dev->active_viewport.dwX != 0) ||
-	(d3d_dev->active_viewport.dwY != 0) ||
-	(d3d_dev->active_viewport.dwWidth != d3d_dev->surface->surface_desc.dwWidth) ||
-	(d3d_dev->active_viewport.dwHeight != d3d_dev->surface->surface_desc.dwHeight)) {
-	glViewport(0, 0, d3d_dev->surface->surface_desc.dwWidth, d3d_dev->surface->surface_desc.dwHeight);
-	opt_bitmap |= VIEWPORT_BIT;
-    }
-    glScissor(pRect->left, d3d_dev->surface->surface_desc.dwHeight - pRect->bottom,
-	      pRect->right - pRect->left, pRect->bottom - pRect->top);
-    if (gl_d3d_dev->lighting != FALSE) glDisable(GL_LIGHTING);
-    if (gl_d3d_dev->cull_face != FALSE) glDisable(GL_CULL_FACE);
-    if (use_alpha) {
-	if (gl_d3d_dev->alpha_test == FALSE) glEnable(GL_ALPHA_TEST);
-	if ((gl_d3d_dev->current_alpha_test_func != GL_NOTEQUAL) || (gl_d3d_dev->current_alpha_test_ref != 0.0))
-	    glAlphaFunc(GL_NOTEQUAL, 0.0);
-    } else {
-	if (gl_d3d_dev->alpha_test != FALSE) glDisable(GL_ALPHA_TEST);
-    }
-    if (gl_d3d_dev->stencil_test != FALSE) glDisable(GL_STENCIL_TEST);
-    if (gl_d3d_dev->blending != FALSE) glDisable(GL_BLEND);
-    if (gl_d3d_dev->fogging != FALSE) glDisable(GL_FOG);
-    if (gl_d3d_dev->current_tex_env != GL_REPLACE)
-	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    
-    return opt_bitmap;
-}
-
-static void d3ddevice_restore_state_after_flush(IDirect3DDeviceImpl *d3d_dev, DWORD opt_bitmap, BOOLEAN use_alpha) {
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-
-    /* And restore all the various states modified by this code */
-    if (gl_d3d_dev->depth_test != 0) glEnable(GL_DEPTH_TEST);
-    if (gl_d3d_dev->lighting != 0) glEnable(GL_LIGHTING);
-    if ((gl_d3d_dev->alpha_test != 0) && (use_alpha == 0))
-	glEnable(GL_ALPHA_TEST);
-    else if ((gl_d3d_dev->alpha_test == 0) && (use_alpha != 0))
-	glDisable(GL_ALPHA_TEST);
-    if (use_alpha) {
-	if ((gl_d3d_dev->current_alpha_test_func != GL_NOTEQUAL) || (gl_d3d_dev->current_alpha_test_ref != 0.0))
-	    glAlphaFunc(gl_d3d_dev->current_alpha_test_func, gl_d3d_dev->current_alpha_test_ref);
-    }
-    if (gl_d3d_dev->stencil_test != 0) glEnable(GL_STENCIL_TEST);
-    if (gl_d3d_dev->cull_face != 0) glEnable(GL_CULL_FACE);
-    if (gl_d3d_dev->blending != 0) glEnable(GL_BLEND);
-    if (gl_d3d_dev->fogging != 0) glEnable(GL_FOG);
-    glDisable(GL_SCISSOR_TEST);
-    if (opt_bitmap & DEPTH_RANGE_BIT) {
-	glDepthRange(d3d_dev->active_viewport.dvMinZ, d3d_dev->active_viewport.dvMaxZ);
-    }
-    if (opt_bitmap & VIEWPORT_BIT) {
-	glViewport(d3d_dev->active_viewport.dwX,
-		   d3d_dev->surface->surface_desc.dwHeight - (d3d_dev->active_viewport.dwHeight + d3d_dev->active_viewport.dwY),
-		   d3d_dev->active_viewport.dwWidth, d3d_dev->active_viewport.dwHeight);
-    }
-    if (d3d_dev->tex_mat_is_identity[0] == FALSE) {
-	d3d_dev->matrices_updated(d3d_dev, TEXMAT0_CHANGED);
-    }
-    
-    if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE0_WINE) {
-	GL_extensions.glActiveTexture(GL_TEXTURE0_WINE);
-	gl_d3d_dev->current_active_tex_unit = GL_TEXTURE0_WINE;
-    }
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, gl_d3d_dev->current_tex_env);
-    /* Note that here we could directly re-bind the previous texture... But it would in some case be a spurious
-       bind if ever the game changes the texture just after.
-
-       So choose 0x00000001 to postpone the binding to the next time we draw something on screen. */
-    gl_d3d_dev->current_bound_texture[0] = (IDirectDrawSurfaceImpl *) 0x00000001;
-    if (d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE) glDisable(GL_TEXTURE_2D);
-
-    /* And re-enabled if needed texture level 1 */
-    if ((gl_d3d_dev->current_bound_texture[1] != NULL) &&
-	(d3d_dev->state_block.texture_stage_state[1][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) {
-	if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE1_WINE) {
-	    GL_extensions.glActiveTexture(GL_TEXTURE1_WINE);
-	    gl_d3d_dev->current_active_tex_unit = GL_TEXTURE1_WINE;
-	}
-	glEnable(GL_TEXTURE_2D);
-    }
-}
-
-/* retrieve the X drawable to use on a given DC */
-inline static Drawable get_drawable( HDC hdc )
-{
-    Drawable drawable;
-    enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
-
-    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
-                    sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
-
-    return drawable;
-}
-
-static BOOL opengl_flip( LPVOID dev, LPVOID drawable)
-{
-    IDirect3DDeviceImpl *d3d_dev = (IDirect3DDeviceImpl *) dev;
-    IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) dev;
-
-    TRACE("(%p, %ld)\n", gl_d3d_dev->display,(Drawable)drawable);
-    ENTER_GL();
-    if (gl_d3d_dev->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
-        d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_BACK]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK]);
-    }
-    gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
-    gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL;
-    glXSwapBuffers(gl_d3d_dev->display, (Drawable)drawable);
-    LEAVE_GL();
-    
-    return TRUE;
-}
-
-
-/*******************************************************************************
- *				OpenGL static functions
- */
-static void set_context(IDirect3DDeviceImpl* This)
-{
-    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
-   
-    TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
-    ENTER_GL();
-    if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
-	ERR("Error in setting current context (context %p drawable %ld)!\n",
-	    glThis->gl_context, glThis->drawable);
-    }
-    LEAVE_GL();
-}
-
-static void fill_opengl_caps(D3DDEVICEDESC *d1)
-{
-    d1->dwSize  = sizeof(*d1);
-    d1->dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS | D3DDD_BCLIPPING | D3DDD_LIGHTINGCAPS |
-	D3DDD_LINECAPS | D3DDD_TRICAPS | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH |
-	D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT;
-    d1->dcmColorModel = D3DCOLOR_RGB;
-    d1->dwDevCaps = opengl_device_caps.dwDevCaps;
-    d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
-    d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
-    d1->bClipping = TRUE;
-    d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
-    d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
-    d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
-    d1->dlcLightingCaps.dwNumLights = opengl_device_caps.dwMaxActiveLights;
-    d1->dpcLineCaps = opengl_device_caps.dpcLineCaps;
-    d1->dpcTriCaps = opengl_device_caps.dpcTriCaps;
-    d1->dwDeviceRenderBitDepth  = opengl_device_caps.dwDeviceRenderBitDepth;
-    d1->dwDeviceZBufferBitDepth = opengl_device_caps.dwDeviceZBufferBitDepth;
-    d1->dwMaxBufferSize = 0;
-    d1->dwMaxVertexCount = 65536;
-    d1->dwMinTextureWidth  = opengl_device_caps.dwMinTextureWidth;
-    d1->dwMinTextureHeight = opengl_device_caps.dwMinTextureHeight;
-    d1->dwMaxTextureWidth  = opengl_device_caps.dwMaxTextureWidth;
-    d1->dwMaxTextureHeight = opengl_device_caps.dwMaxTextureHeight;
-    d1->dwMinStippleWidth  = 1;
-    d1->dwMinStippleHeight = 1;
-    d1->dwMaxStippleWidth  = 32;
-    d1->dwMaxStippleHeight = 32;
-    d1->dwMaxTextureRepeat = opengl_device_caps.dwMaxTextureRepeat;
-    d1->dwMaxTextureAspectRatio = opengl_device_caps.dwMaxTextureAspectRatio;
-    d1->dwMaxAnisotropy = opengl_device_caps.dwMaxAnisotropy;
-    d1->dvGuardBandLeft = opengl_device_caps.dvGuardBandLeft;
-    d1->dvGuardBandRight = opengl_device_caps.dvGuardBandRight;
-    d1->dvGuardBandTop = opengl_device_caps.dvGuardBandTop;
-    d1->dvGuardBandBottom = opengl_device_caps.dvGuardBandBottom;
-    d1->dvExtentsAdjust = opengl_device_caps.dvExtentsAdjust;
-    d1->dwStencilCaps = opengl_device_caps.dwStencilCaps;
-    d1->dwFVFCaps = opengl_device_caps.dwFVFCaps;
-    d1->dwTextureOpCaps = opengl_device_caps.dwTextureOpCaps;
-    d1->wMaxTextureBlendStages = opengl_device_caps.wMaxTextureBlendStages;
-    d1->wMaxSimultaneousTextures = opengl_device_caps.wMaxSimultaneousTextures;
-}
-
-static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
-{
-    *d = opengl_device_caps;
-}
-
-HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version)
-{
-    D3DDEVICEDESC dref, d1, d2;
-    HRESULT ret_value;
-
-    /* Some games (Motoracer 2 demo) have the bad idea to modify the device name string.
-       Let's put the string in a sufficiently sized array in writable memory. */
-    char device_name[50];
-    strcpy(device_name,"direct3d");
-
-    fill_opengl_caps(&dref);
-
-    if (version > 1) {
-        /* It seems that enumerating the reference IID on Direct3D 1 games (AvP / Motoracer2) breaks them */
-	char interface_name[] = "WINE Reference Direct3DX using OpenGL";
-        TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
-	d1 = dref;
-	d2 = dref;
-	ret_value = cb((LPIID) &IID_IDirect3DRefDevice, interface_name, device_name, &d1, &d2, context);
-	if (ret_value != D3DENUMRET_OK)
-	    return ret_value;
-    }
-
-    {
-	char interface_name[] = "WINE Direct3DX using OpenGL";
-	TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
-	d1 = dref;
-	d2 = dref;
-	ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, interface_name, device_name, &d1, &d2, context);
-	if (ret_value != D3DENUMRET_OK)
-	    return ret_value;
-    }
-
-    return D3DENUMRET_OK;
-}
-
-HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
-{
-    D3DDEVICEDESC7 ddesc;
-    char interface_name[] = "WINE Direct3D7 using OpenGL";
-    char device_name[] = "Wine D3D7 device";
-
-    fill_opengl_caps_7(&ddesc);
-    
-    TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
-    
-    return cb(interface_name, device_name, &ddesc, context);
-}
-
-static ULONG WINAPI
-GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    ULONG ref = InterlockedDecrement(&This->ref);
-    
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
-
-    if (!ref) {
-        int i;
-	IDirectDrawSurfaceImpl *surface = This->surface, *surf;
-	
-	/* Release texture associated with the device */ 
-	for (i = 0; i < MAX_TEXTURES; i++) {
-	    if (This->current_texture[i] != NULL)
-	        IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7));
-	    HeapFree(GetProcessHeap(), 0, This->tex_mat[i]);
-	}
-
-	/* Look for the front buffer and override its surface's Flip method (if in double buffering) */
-	for (surf = surface; surf != NULL; surf = surf->surface_owner) {
-	    if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
-	        surf->aux_ctx  = NULL;
-		surf->aux_data = NULL;
-		surf->aux_flip = NULL;
-		break;
-	    }
-	}
-	for (surf = surface; surf != NULL; surf = surf->surface_owner) {
-	    IDirectDrawSurfaceImpl *surf2;
-	    for (surf2 = surf; surf2->prev_attached != NULL; surf2 = surf2->prev_attached) ;
-	    for (; surf2 != NULL; surf2 = surf2->next_attached) {
-	        if (((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
-		    ((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
-		    /* Override the Lock / Unlock function for all these surfaces */
-		    surf2->lock_update = surf2->lock_update_prev;
-		    surf2->unlock_update = surf2->unlock_update_prev;
-		    /* And install also the blt / bltfast overrides */
-		    surf2->aux_blt = NULL;
-		    surf2->aux_bltfast = NULL;
-		}
-		surf2->d3ddevice = NULL;
-	    }
-	}
-	
-	/* And warn the D3D object that this device is no longer active... */
-	This->d3d->d3d_removed_device(This->d3d, This);
-
-        /* Free light arrays */
-        HeapFree(GetProcessHeap(), 0, This->light_parameters);
-        HeapFree(GetProcessHeap(), 0, This->active_lights);
-
-	HeapFree(GetProcessHeap(), 0, This->world_mat);
-	HeapFree(GetProcessHeap(), 0, This->view_mat);
-	HeapFree(GetProcessHeap(), 0, This->proj_mat);
-
-	HeapFree(GetProcessHeap(), 0, glThis->surface_ptr);
-
-	DeleteCriticalSection(&(This->crit));
-	
-	ENTER_GL();
-	if (glThis->unlock_tex)
-	    glDeleteTextures(1, &(glThis->unlock_tex));
-	glXDestroyContext(glThis->display, glThis->gl_context);
-	LEAVE_GL();
-	HeapFree(GetProcessHeap(), 0, This->clipping_planes);
-	HeapFree(GetProcessHeap(), 0, This->vertex_buffer);
-
-	HeapFree(GetProcessHeap(), 0, This);
-	return 0;
-    }
-    return ref;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
-				       LPD3DDEVICEDESC lpD3DHWDevDesc,
-				       LPD3DDEVICEDESC lpD3DHELDevDesc)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    D3DDEVICEDESC desc;
-    DWORD dwSize;
-
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
-
-    fill_opengl_caps(&desc);
-    dwSize = lpD3DHWDevDesc->dwSize;
-    memset(lpD3DHWDevDesc, 0, dwSize);
-    memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
-
-    dwSize = lpD3DHELDevDesc->dwSize;
-    memset(lpD3DHELDevDesc, 0, dwSize);
-    memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
-
-    TRACE(" returning caps : (no dump function yet)\n");
-
-    return DD_OK;
-}
-
-static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
-					  LPD3DENUMPIXELFORMATSCALLBACK cb_2,
-					  LPVOID context, int version)
-{
-    DDSURFACEDESC sdesc;
-    LPDDPIXELFORMAT pformat;
-
-    /* Do the texture enumeration */
-    sdesc.dwSize = sizeof(DDSURFACEDESC);
-    sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
-    sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
-    pformat = &(sdesc.ddpfPixelFormat);
-    pformat->dwSize = sizeof(DDPIXELFORMAT);
-    pformat->dwFourCC = 0;
-
-    TRACE("Enumerating GL_RGBA unpacked (32)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 32;
-    pformat->u2.dwRBitMask =        0x00FF0000;
-    pformat->u3.dwGBitMask =        0x0000FF00;
-    pformat->u4.dwBBitMask =        0x000000FF;
-    pformat->u5.dwRGBAlphaBitMask = 0xFF000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating GL_RGB unpacked (32)\n");
-    pformat->dwFlags = DDPF_RGB;
-    pformat->u1.dwRGBBitCount = 32;
-    pformat->u2.dwRBitMask =        0x00FF0000;
-    pformat->u3.dwGBitMask =        0x0000FF00;
-    pformat->u4.dwBBitMask =        0x000000FF;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-    
-    TRACE("Enumerating GL_RGB unpacked (24)\n");
-    pformat->dwFlags = DDPF_RGB;
-    pformat->u1.dwRGBBitCount = 24;
-    pformat->u2.dwRBitMask = 0x00FF0000;
-    pformat->u3.dwGBitMask = 0x0000FF00;
-    pformat->u4.dwBBitMask = 0x000000FF;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    /* Note : even if this is an 'emulated' texture format, it needs to be first
-              as some dumb applications seem to rely on that. */
-    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask =        0x00007C00;
-    pformat->u3.dwGBitMask =        0x000003E0;
-    pformat->u4.dwBBitMask =        0x0000001F;
-    pformat->u5.dwRGBAlphaBitMask = 0x00008000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask =        0x00000F00;
-    pformat->u3.dwGBitMask =        0x000000F0;
-    pformat->u4.dwBBitMask =        0x0000000F;
-    pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
-    pformat->dwFlags = DDPF_RGB;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask = 0x0000F800;
-    pformat->u3.dwGBitMask = 0x000007E0;
-    pformat->u4.dwBBitMask = 0x0000001F;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_5_5 (16)\n");
-    pformat->dwFlags = DDPF_RGB;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask = 0x00007C00;
-    pformat->u3.dwGBitMask = 0x000003E0;
-    pformat->u4.dwBBitMask = 0x0000001F;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-    
-#if 0
-    /* This is a compromise : some games choose the first 16 bit texture format with alpha they
-       find enumerated, others the last one. And both want to have the ARGB one.
-       
-       So basically, forget our OpenGL roots and do not even enumerate our RGBA ones.
-    */
-    /* See argument about the RGBA format for 'packed' texture formats */
-    TRACE("Enumerating GL_RGBA unpacked (32)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 32;
-    pformat->u2.dwRBitMask =        0xFF000000;
-    pformat->u3.dwGBitMask =        0x00FF0000;
-    pformat->u4.dwBBitMask =        0x0000FF00;
-    pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-    
-    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask =        0x0000F000;
-    pformat->u3.dwGBitMask =        0x00000F00;
-    pformat->u4.dwBBitMask =        0x000000F0;
-    pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
-    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-    pformat->u1.dwRGBBitCount = 16;
-    pformat->u2.dwRBitMask =        0x0000F800;
-    pformat->u3.dwGBitMask =        0x000007C0;
-    pformat->u4.dwBBitMask =        0x0000003E;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000001;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-#endif
-
-    TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
-    pformat->dwFlags = DDPF_RGB;
-    pformat->u1.dwRGBBitCount = 8;
-    pformat->u2.dwRBitMask =        0x000000E0;
-    pformat->u3.dwGBitMask =        0x0000001C;
-    pformat->u4.dwBBitMask =        0x00000003;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    TRACE("Enumerating Paletted (8)\n");
-    pformat->dwFlags = DDPF_PALETTEINDEXED8;
-    pformat->u1.dwRGBBitCount = 8;
-    pformat->u2.dwRBitMask =        0x00000000;
-    pformat->u3.dwGBitMask =        0x00000000;
-    pformat->u4.dwBBitMask =        0x00000000;
-    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-    /* DXT textures only exist for devices created from IDirect3D3 and above */
-    if ((version >= 3) && GL_extensions.s3tc_compressed_texture) {
-	TRACE("Enumerating DXT1\n");
-	pformat->dwFlags = DDPF_FOURCC;
-        pformat->dwFourCC = MAKE_FOURCC('D','X','T','1');
-	if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-	if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-	TRACE("Enumerating DXT3\n");
-	pformat->dwFlags = DDPF_FOURCC;
-        pformat->dwFourCC = MAKE_FOURCC('D','X','T','3');
-	if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-	if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-
-	TRACE("Enumerating DXT5\n");
-	pformat->dwFlags = DDPF_FOURCC;
-        pformat->dwFourCC = MAKE_FOURCC('D','X','T','5');
-	if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
-	if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
-    }
-
-    TRACE("End of enumeration\n");
-    return DD_OK;
-}
-
-
-HRESULT
-d3ddevice_find(IDirectDrawImpl *d3d,
-	       LPD3DFINDDEVICESEARCH lpD3DDFS,
-	       LPD3DFINDDEVICERESULT lplpD3DDevice)
-{
-    D3DDEVICEDESC desc;
-  
-    if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
-	(lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
-        TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
-	return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
-    }
-    if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
-        TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
-	if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
-	    (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
-	    (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
-	    TRACE(" no match for this GUID.\n");
-	    return DDERR_INVALIDPARAMS;
-	}
-    }
-
-    /* Now return our own GUID */
-    lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
-    fill_opengl_caps(&desc);
-    lplpD3DDevice->ddHwDesc = desc;
-    lplpD3DDevice->ddSwDesc = desc;
-
-    TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
-    
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
-					       LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
-					       LPVOID lpArg)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
-    return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg, This->version);
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
-					       LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
-					       LPVOID lpArg)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
-    return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg, This->version);
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
-					      D3DRENDERSTATETYPE dwRenderStateType,
-					      DWORD dwRenderState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
-
-    /* Call the render state functions */
-    store_render_state(This, dwRenderStateType, dwRenderState, &This->state_block);
-    set_render_state(This, dwRenderStateType, &This->state_block);
-
-    return DD_OK;
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
-					      D3DRENDERSTATETYPE dwRenderStateType,
-					      LPDWORD lpdwRenderState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
-
-    /* Call the render state functions */
-    get_render_state(This, dwRenderStateType, lpdwRenderState, &This->state_block);
-
-    TRACE(" - asked for rendering state : %s, returning value %08lx.\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
-
-    return DD_OK;
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface,
-					  D3DLIGHTSTATETYPE dwLightStateType,
-					  LPDWORD lpdwLightState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwLightStateType, lpdwLightState);
-
-    if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX)) {
-	TRACE("Unexpected Light State Type\n");
-	return DDERR_INVALIDPARAMS;
-    }
-	
-    if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
-	*lpdwLightState = This->material;
-    } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) {
-	*lpdwLightState = D3DCOLOR_RGB;
-    } else {
-        D3DRENDERSTATETYPE rs;
-	switch (dwLightStateType) {
-	    case D3DLIGHTSTATE_AMBIENT:       /* 2 */
-		rs = D3DRENDERSTATE_AMBIENT;
-		break;		
-	    case D3DLIGHTSTATE_FOGMODE:       /* 4 */
-		rs = D3DRENDERSTATE_FOGVERTEXMODE;
-		break;
-	    case D3DLIGHTSTATE_FOGSTART:      /* 5 */
-		rs = D3DRENDERSTATE_FOGSTART;
-		break;
-	    case D3DLIGHTSTATE_FOGEND:        /* 6 */
-		rs = D3DRENDERSTATE_FOGEND;
-		break;
-	    case D3DLIGHTSTATE_FOGDENSITY:    /* 7 */
-		rs = D3DRENDERSTATE_FOGDENSITY;
-		break;
-	    case D3DLIGHTSTATE_COLORVERTEX:   /* 8 */
-		rs = D3DRENDERSTATE_COLORVERTEX;
-		break;
-	    default:
-		ERR("Unknown D3DLIGHTSTATETYPE %d.\n", dwLightStateType);
-		return DDERR_INVALIDPARAMS;
-	}
-
-	IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
-	                   		rs,lpdwLightState);
-    }
-
-    return DD_OK;
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
-					  D3DLIGHTSTATETYPE dwLightStateType,
-					  DWORD dwLightState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    
-    TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
-
-    if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX)) {
-	TRACE("Unexpected Light State Type\n");
-	return DDERR_INVALIDPARAMS;
-    }
-	
-    if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
-	IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
-
-	if (mat != NULL) {
-	    TRACE(" activating material %p.\n", mat);
-	    mat->activate(mat);
-	} else {
-	    FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
-	}
-	This->material = dwLightState;
-    } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) {
-	switch (dwLightState) {
-	    case D3DCOLOR_MONO:
-	       ERR("DDCOLOR_MONO should not happen!\n");
-	       break;
-	    case D3DCOLOR_RGB:
-	       /* We are already in this mode */
-	       TRACE("Setting color model to RGB (no-op).\n");
-	       break;
-	    default:
-	       ERR("Unknown color model!\n");
-	       return DDERR_INVALIDPARAMS;
-	}
-    } else {
-        D3DRENDERSTATETYPE rs;
-	switch (dwLightStateType) {
-	    case D3DLIGHTSTATE_AMBIENT:       /* 2 */
-		rs = D3DRENDERSTATE_AMBIENT;
-		break;		
-	    case D3DLIGHTSTATE_FOGMODE:       /* 4 */
-		rs = D3DRENDERSTATE_FOGVERTEXMODE;
-		break;
-	    case D3DLIGHTSTATE_FOGSTART:      /* 5 */
-		rs = D3DRENDERSTATE_FOGSTART;
-		break;
-	    case D3DLIGHTSTATE_FOGEND:        /* 6 */
-		rs = D3DRENDERSTATE_FOGEND;
-		break;
-	    case D3DLIGHTSTATE_FOGDENSITY:    /* 7 */
-		rs = D3DRENDERSTATE_FOGDENSITY;
-		break;
-	    case D3DLIGHTSTATE_COLORVERTEX:   /* 8 */
-		rs = D3DRENDERSTATE_COLORVERTEX;
-		break;
-	    default:
-		ERR("Unknown D3DLIGHTSTATETYPE %d.\n", dwLightStateType);
-		return DDERR_INVALIDPARAMS;
-	}
-
-	IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
-	                   		rs,dwLightState);
-    }
-
-    return DD_OK;
-}
-
-static GLenum convert_D3D_ptype_to_GL(D3DPRIMITIVETYPE d3dpt)
-{
-    switch (d3dpt) {
-        case D3DPT_POINTLIST:
-            TRACE(" primitive type is POINTS\n");
-	    return GL_POINTS;
-
-	case D3DPT_LINELIST:
-	    TRACE(" primitive type is LINES\n");
-	    return GL_LINES;
-		
-	case D3DPT_LINESTRIP:
-	    TRACE(" primitive type is LINE_STRIP\n");
-	    return GL_LINE_STRIP;
-	    
-	case D3DPT_TRIANGLELIST:
-	    TRACE(" primitive type is TRIANGLES\n");
-	    return GL_TRIANGLES;
-	    
-	case D3DPT_TRIANGLESTRIP:
-	    TRACE(" primitive type is TRIANGLE_STRIP\n");
-	    return GL_TRIANGLE_STRIP;
-	    
-	case D3DPT_TRIANGLEFAN:
-	    TRACE(" primitive type is TRIANGLE_FAN\n");
-	    return GL_TRIANGLE_FAN;
-	    
-	default:
-	    FIXME("Unhandled primitive %08x\n", d3dpt);
-	    return GL_POINTS;
-    }
-}
-
-/* This function calculate the Z coordinate from Zproj */ 
-static float ZfromZproj(IDirect3DDeviceImpl *This, D3DVALUE Zproj)
-{
-    float a,b,c,d;
-    /* Assume that X = Y = 0 and W = 1 */
-    a = This->proj_mat->_33;
-    b = This->proj_mat->_34;
-    c = This->proj_mat->_43;
-    d = This->proj_mat->_44;
-    /* We have in homogenous coordinates Z' = a * Z + c and W' = b * Z + d
-     * So in non homogenous coordinates we have Zproj = (a * Z + c) / (b * Z + d)
-     * And finally Z = (d * Zproj - c) / (a - b * Zproj)
-     */
-    return (d*Zproj - c) / (a - b*Zproj);
-}
-
-static void build_fog_table(BYTE *fog_table, DWORD fog_color) {
-    int i;
-    
-    TRACE(" rebuilding fog table (%06lx)...\n", fog_color & 0x00FFFFFF);
-    
-    for (i = 0; i < 3; i++) {
-        BYTE fog_color_component = (fog_color >> (8 * i)) & 0xFF;
-	DWORD elt;
-	for (elt = 0; elt < 0x10000; elt++) {
-	    /* We apply the fog transformation and cache the result */
-	    DWORD fog_intensity = elt & 0xFF;
-	    DWORD vertex_color = (elt >> 8) & 0xFF;
-	    fog_table[(i * 0x10000) + elt] = ((fog_intensity * vertex_color) + ((0xFF - fog_intensity) * fog_color_component)) / 0xFF;
-	}
-    }
-}
-
-static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
-					   BOOLEAN vertex_transformed,
-					   BOOLEAN vertex_lit) {
-    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
-  
-    /* Puts GL in the correct lighting / transformation mode */
-    if ((vertex_transformed == FALSE) && 
-	(glThis->transform_state != GL_TRANSFORM_NORMAL)) {
-        /* Need to put the correct transformation again if we go from Transformed
-	   vertices to non-transformed ones.
-	*/
-        This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
-			   This->world_mat, This->view_mat, This->proj_mat);
-	glThis->transform_state = GL_TRANSFORM_NORMAL;
-
-    } else if (vertex_transformed &&
-	       (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
-        /* Set our orthographic projection */
-	if (glThis->transform_state != GL_TRANSFORM_ORTHO) {
-	    glThis->transform_state = GL_TRANSFORM_ORTHO;
-	    d3ddevice_set_ortho(This);
-	}
-    }
-
-    /* TODO: optimize this to not always reset all the fog stuff on all DrawPrimitive call
-             if no fogging state change occurred */
-    if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1]) {
-        if (vertex_transformed) {
-	    if (glThis->fogging != 0) {
-		glDisable(GL_FOG);
-		glThis->fogging = 0;
-	    }
-	    /* Now check if our fog_table still corresponds to the current vertex color.
-	       Element '0x..00' is always the fog color as it corresponds to maximum fog intensity */
-	    if ((glThis->fog_table[0 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >>  0) & 0xFF)) ||
-		(glThis->fog_table[1 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >>  8) & 0xFF)) ||
-		(glThis->fog_table[2 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 16) & 0xFF))) {
-	        /* We need to rebuild our fog table.... */
-		build_fog_table(glThis->fog_table, This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]);
-	    }
-	} else {
-	    if (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1] != D3DFOG_NONE) {
-	        switch (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1]) {
-                    case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); break; 
-		    case D3DFOG_EXP:    glFogi(GL_FOG_MODE, GL_EXP); break; 
-		    case D3DFOG_EXP2:   glFogi(GL_FOG_MODE, GL_EXP2); break;
-		}
-		if (vertex_lit == FALSE) {
-		    glFogf(GL_FOG_START, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]);
-		    glFogf(GL_FOG_END, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]);
-		} else {
-		    /* Special case of 'pixel fog' */
-		    glFogf(GL_FOG_START, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]));
-		    glFogf(GL_FOG_END, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]));
-		}
-		if (glThis->fogging == 0) {
-		    glEnable(GL_FOG);
-		    glThis->fogging = 1;
-		}
-	    } else {
-		if (glThis->fogging != 0) {
-		    glDisable(GL_FOG);
-		    glThis->fogging = 0;
-		}
-	    }
-        }
-    } else {
-	if (glThis->fogging != 0) {
-	    glDisable(GL_FOG);
-	    glThis->fogging = 0;
-	}
-    }
-    
-    /* Handle the 'no-normal' case */
-    if ((vertex_lit == FALSE) && This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1]) {
-	if (glThis->lighting == 0) {
-	    glEnable(GL_LIGHTING);
-	    glThis->lighting = 1;
-	}
-    } else {
-	if (glThis->lighting != 0) {
-	    glDisable(GL_LIGHTING);
-	    glThis->lighting = 0;
-	}
-    }
-
-    /* Handle the code for pre-vertex material properties */
-    if (vertex_transformed == FALSE) {
-        if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] &&
-	    This->state_block.render_state[D3DRENDERSTATE_COLORVERTEX - 1]) {
-	    if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
-		(This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
-		(This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
-		(This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != D3DMCS_MATERIAL)) {
-	        glEnable(GL_COLOR_MATERIAL);
-	    }
-	}
-    }
-}
-
-
-inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
-				  D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
-{
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-
-    switch (d3dvt) {
-        case D3DVT_VERTEX: {
-	    strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
-	    strided.position.dwStride = sizeof(D3DVERTEX);
-	    strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
-	    strided.normal.dwStride = sizeof(D3DVERTEX);
-	    strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
-	    strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
-	    draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
-	} break;
-
-        case D3DVT_LVERTEX: {
-	    strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
-	    strided.position.dwStride = sizeof(D3DLVERTEX);
-	    strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
-	    strided.diffuse.dwStride = sizeof(D3DLVERTEX);
-	    strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
-	    strided.specular.dwStride = sizeof(D3DLVERTEX);
-	    strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
-	    strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
-	    draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
-	} break;
-
-        case D3DVT_TLVERTEX: {
-	    strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
-	    strided.position.dwStride = sizeof(D3DTLVERTEX);
-	    strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
-	    strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
-	    strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
-	    strided.specular.dwStride = sizeof(D3DTLVERTEX);
-	    strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
-	    strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
-	    draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
-	} break;
-
-        default:
-	    FIXME("Unhandled vertex type %08x\n", d3dvt);
-	    break;
-    }
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
-				       D3DPRIMITIVETYPE d3dptPrimitiveType,
-				       D3DVERTEXTYPE d3dvtVertexType,
-				       LPVOID lpvVertices,
-				       DWORD dwVertexCount,
-				       DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-
-    TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
-		   
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
-					      D3DPRIMITIVETYPE d3dptPrimitiveType,
-					      D3DVERTEXTYPE d3dvtVertexType,
-					      LPVOID lpvVertices,
-					      DWORD dwVertexCount,
-					      LPWORD dwIndices,
-					      DWORD dwIndexCount,
-					      DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
-    TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
-					     LPD3DEXECUTEBUFFERDESC lpDesc,
-					     LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
-					     IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
-    IDirect3DExecuteBufferImpl *ret;
-    HRESULT ret_value;
-    
-    TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
-
-    ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
-    *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
-
-    TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
-    
-    return ret_value;
-}
-
-static void flush_zbuffer_to_GL(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, IDirectDrawSurfaceImpl *surf) {
-    static BOOLEAN first = TRUE;
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-    unsigned int row;
-    GLenum type;
-    
-    if (first) {
-	MESSAGE("Warning : application does direct locking of ZBuffer - expect slowdowns on many GL implementations :-)\n");
-	first = FALSE;
-    }
-    
-    TRACE("flushing ZBuffer back to GL\n");
-    
-    if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) {
-	gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO;
-	d3ddevice_set_ortho(d3d_dev);
-    }
-    
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-
-    if (gl_d3d_dev->depth_test == 0) glEnable(GL_DEPTH_TEST);
-    if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS) glDepthFunc(GL_ALWAYS);
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
-
-    /* This loop here is to prevent using PixelZoom that may be unoptimized for the 1.0 / -1.0 case
-       in some drivers...
-    */
-    switch (surf->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth) {
-        case 16: type = GL_UNSIGNED_SHORT; break;
-	case 32: type = GL_UNSIGNED_INT; break;
-	default: FIXME("Unhandled ZBuffer format !\n"); goto restore_state;
-    }
-	
-    for (row = 0; row < surf->surface_desc.dwHeight; row++) {
-	/* glRasterPos3d(0.0, row + 1.0, 0.5); */
-	glRasterPos2i(0, row + 1);
-	glDrawPixels(surf->surface_desc.dwWidth, 1, GL_DEPTH_COMPONENT, type,
-		     ((unsigned char *) surf->surface_desc.lpSurface) + (row * surf->surface_desc.u1.lPitch));
-    }
-
-  restore_state:
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS)
-	glDepthFunc(convert_D3D_compare_to_GL(d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1]));
-    if (gl_d3d_dev->depth_test == 0) glDisable(GL_DEPTH_TEST);
-}
-
-/* These are the various handler used in the generic path */
-inline static void handle_xyz(D3DVALUE *coords) {
-    glVertex3fv(coords);
-}
-inline static void handle_xyzrhw(D3DVALUE *coords) {
-    if ((coords[3] < 1e-8) && (coords[3] > -1e-8))
-        glVertex3fv(coords);
-    else {
-        GLfloat w = 1.0 / coords[3];
-	
-        glVertex4f(coords[0] * w,
-		   coords[1] * w,
-		   coords[2] * w,
-		   w);
-    }
-}
-inline static void handle_normal(D3DVALUE *coords) {
-    glNormal3fv(coords);
-}
-
-inline static void handle_diffuse_base(STATEBLOCK *sb, DWORD *color) {
-    if (sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] ||
-	sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1]) {
-        glColor4ub((*color >> 16) & 0xFF,
-		   (*color >>  8) & 0xFF,
-		   (*color >>  0) & 0xFF,
-		   (*color >> 24) & 0xFF);
-    } else {
-        glColor3ub((*color >> 16) & 0xFF,
-		   (*color >>  8) & 0xFF,
-		   (*color >>  0) & 0xFF);    
-    }
-}
-
-inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) {
-    glColor4ub((*color >> 16) & 0xFF,
-	       (*color >>  8) & 0xFF,
-	       (*color >>  0) & 0xFF,
-	       (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
-}
-
-inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
-    if ((lighted == FALSE) &&
-	sb->render_state[D3DRENDERSTATE_LIGHTING - 1] &&
-	sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1]) {
-        if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	    handle_diffuse_base(sb, color);
-	}
-	if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
-	    handle_diffuse_base(sb, color);
-	}
-	if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) &&
-	    sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
-	    handle_diffuse_base(sb, color);
-	}
-	if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
-	    handle_diffuse_base(sb, color);
-	}
-    } else {
-        handle_diffuse_base(sb, color);
-    }    
-}
-
-inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
-    if ((lighted == FALSE) &&
-	sb->render_state[D3DRENDERSTATE_LIGHTING - 1] &&
-	sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1]) {
-        if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	    handle_specular_base(sb, color);
-	}
-	if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
-	    handle_specular_base(sb, color);
-	}
-	if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) &&
-	    sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
-	    handle_specular_base(sb, color);
-	}
-	if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
-	    glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
-	    handle_specular_base(sb, color);
-	}
-    }
-    /* No else here as we do not know how to handle 'specular' on its own in any case.. */
-}
-
-inline static void handle_diffuse_and_specular(STATEBLOCK *sb, BYTE *fog_table, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) {
-    if (lighted) {
-        DWORD color = *color_d;
-        if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1]) {
-	    /* Special case where the specular value is used to do fogging */
-	    BYTE fog_intensity = *color_s >> 24; /* The alpha value of the specular component is the fog 'intensity' for this vertex */
-	    color &= 0xFF000000; /* Only keep the alpha component */
-	    color |= fog_table[((*color_d >>  0) & 0xFF) << 8 | fog_intensity] <<  0;
-	    color |= fog_table[((*color_d >>  8) & 0xFF) << 8 | fog_intensity] <<  8;
-	    color |= fog_table[((*color_d >> 16) & 0xFF) << 8 | fog_intensity] << 16;
-	}
-	if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) {
-	    /* Standard specular value in transformed mode. TODO */
-	}
-	handle_diffuse_base(sb, &color);
-    } else {
-        if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1]) {
-	    handle_diffuse(sb, color_d, FALSE);
-	    handle_specular(sb, color_s, FALSE);
-	} else {
-	    /* In that case, only put the diffuse color... */
-	    handle_diffuse_base(sb, color_d);
-	}
-    }
-}
-
-static void handle_texture(DWORD size, const D3DVALUE *coords) {
-    switch (size) {
-        case 1: glTexCoord1fv(coords); break;
-	case 2: glTexCoord2fv(coords); break;
-	case 3: glTexCoord3fv(coords); break;
-	case 4: glTexCoord4fv(coords); break;
-    }
-}
-
-inline static void handle_textures(DWORD size, const D3DVALUE *coords, int tex_stage) {
-    if (GL_extensions.max_texture_units > 0) {
-	GL_extensions.glMultiTexCoord[size - 1](GL_TEXTURE0_WINE + tex_stage, coords);
-    } else {
-	if (tex_stage == 0) handle_texture(size, coords);
-    }
-}
-
-static void draw_primitive_strided(IDirect3DDeviceImpl *This,
-				   D3DPRIMITIVETYPE d3dptPrimitiveType,
-				   DWORD d3dvtVertexType,
-				   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-				   DWORD dwVertexCount,
-				   LPWORD dwIndices,
-				   DWORD dwIndexCount,
-				   DWORD dwFlags)
-{
-    BOOLEAN vertex_lighted = FALSE;
-    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
-    int num_active_stages = 0;
-    int num_tex_index = GET_TEXCOUNT_FROM_FVF(d3dvtVertexType);
-    BOOL reenable_depth_test = FALSE;
-    
-    /* I put the trace before the various locks... So as to better understand where locks occur :-) */
-    if (TRACE_ON(ddraw)) {
-        TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
-    }
-
-    /* This is to prevent 'thread contention' between a thread locking the device and another
-       doing 3D display on it... */
-    EnterCriticalSection(&(This->crit));   
-    
-    ENTER_GL();
-    if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
-        This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]);
-    }
-    glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
-
-    if (This->current_zbuffer == NULL) {
-	/* Search for an attached ZBuffer */
-	static const DDSCAPS2 zbuf_caps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
-	LPDIRECTDRAWSURFACE7 zbuf;
-	HRESULT hr;
-	
-	hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->surface, IDirectDrawSurface7),
-						    (DDSCAPS2 *) &zbuf_caps, &zbuf);
-	if (SUCCEEDED(hr)) {
-	    This->current_zbuffer = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, zbuf);
-	    IDirectDrawSurface7_Release(zbuf);
-	} else if (glThis->depth_test) {
-	    glDisable(GL_DEPTH_TEST);
-	    reenable_depth_test = TRUE;
-	}
-    }
-    if (This->current_zbuffer != NULL) {
-	if (This->current_zbuffer->get_dirty_status(This->current_zbuffer, NULL)) {
-	    flush_zbuffer_to_GL(This, NULL, This->current_zbuffer);
-	}
-    }
-    
-    if ( ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) ||
-         ((d3dvtVertexType & D3DFVF_NORMAL) == 0) )
-        vertex_lighted = TRUE;
-    
-    /* Compute the number of active texture stages and set the various texture parameters */
-    num_active_stages = draw_primitive_handle_textures(This);
-
-    /* And restore to handle '0' in the case we use glTexCoord calls */
-    if (glThis->current_active_tex_unit != GL_TEXTURE0_WINE) {
-	GL_extensions.glActiveTexture(GL_TEXTURE0_WINE);
-	glThis->current_active_tex_unit = GL_TEXTURE0_WINE;
-    }
-
-    draw_primitive_handle_GL_state(This,
-				   (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
-				   vertex_lighted);
-
-    /* First, see if we can use the OpenGL vertex arrays... This is very limited
-       for now to some 'special' cases where we can do a direct mapping between D3D
-       types and GL types.
-
-       Note: in the future all calls will go through vertex arrays but the arrays
-             will be generated by this function.
-
-       Note2: colours cannot be mapped directly because they are stored as BGRA in memory
-              (ie not as an array of R, G, B, A as OpenGL does it but as a LWORD 0xAARRGGBB
-	      which, as we are little indian, gives a B, G, R, A storage in memory.
-    */
-    if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) && /* Standard XYZ vertices */
-	((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == 0)) {
-	int tex_stage;
-	TRACE(" using GL vertex arrays for performance !\n");
-	/* First, the vertices (we are sure we have some :-) */
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glVertexPointer(3, GL_FLOAT, lpD3DDrawPrimStrideData->position.dwStride, lpD3DDrawPrimStrideData->position.lpvData);
-	/* Then the normals */
-	if (d3dvtVertexType & D3DFVF_NORMAL) {
-	    glEnableClientState(GL_NORMAL_ARRAY);
-	    glNormalPointer(GL_FLOAT, lpD3DDrawPrimStrideData->normal.dwStride, lpD3DDrawPrimStrideData->normal.lpvData);
-	}
-	/* Then the diffuse colour */
-	if (d3dvtVertexType & D3DFVF_DIFFUSE) {
-	    glEnableClientState(GL_COLOR_ARRAY);
-	    glColorPointer(3, GL_UNSIGNED_BYTE, lpD3DDrawPrimStrideData->normal.dwStride,
-			   ((char *) lpD3DDrawPrimStrideData->diffuse.lpvData));
-	}
-	/* Then the various textures */
-	for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) {
-	    int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0x0000FFFF;
-	    if (tex_index >= num_tex_index) {
-		WARN("Default texture coordinate not handled in the vertex array path !!!\n");
-		tex_index = num_tex_index - 1;
-	    }
-	    if (GL_extensions.glClientActiveTexture) {
-		GL_extensions.glClientActiveTexture(GL_TEXTURE0_WINE + tex_stage);
-	    }
-	    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	    glTexCoordPointer(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), GL_FLOAT, lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride,
-			      lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData);
-	}
-	if (dwIndices != NULL) {
-	    glDrawElements(convert_D3D_ptype_to_GL(d3dptPrimitiveType), dwIndexCount, GL_UNSIGNED_SHORT, dwIndices);
-	} else {
-	    glDrawArrays(convert_D3D_ptype_to_GL(d3dptPrimitiveType), 0, dwIndexCount);
-	}
-	glDisableClientState(GL_VERTEX_ARRAY);
-	if (d3dvtVertexType & D3DFVF_NORMAL) {
-	    glDisableClientState(GL_NORMAL_ARRAY);
-	}
-	if (d3dvtVertexType & D3DFVF_DIFFUSE) {
-	    glDisableClientState(GL_COLOR_ARRAY);
-	}
-	for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) {
-	    if (GL_extensions.glClientActiveTexture) {
-		GL_extensions.glClientActiveTexture(GL_TEXTURE0_WINE + tex_stage);
-	    }
-	    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	}
-    } else {
-	glBegin(convert_D3D_ptype_to_GL(d3dptPrimitiveType));
-	
-	/* Some fast paths first before the generic case.... */
-	if ((d3dvtVertexType == D3DFVF_VERTEX) && (num_active_stages <= 1)) {
-	    unsigned int index;
-	    
-	    for (index = 0; index < dwIndexCount; index++) {
-		int i = (dwIndices == NULL) ? index : dwIndices[index];
-		D3DVALUE *normal = 
-		    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
-		D3DVALUE *tex_coord =
-		    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
-		D3DVALUE *position =
-		    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-		
-		handle_normal(normal);
-		handle_texture(2, tex_coord);
-		handle_xyz(position);
-		
-		TRACE_(ddraw_geom)(" %f %f %f / %f %f %f (%f %f)\n",
-				   position[0], position[1], position[2],
-				   normal[0], normal[1], normal[2],
-				   tex_coord[0], tex_coord[1]);
-	    }
-	} else if ((d3dvtVertexType == D3DFVF_TLVERTEX) && (num_active_stages <= 1)) {
-	    unsigned int index;
-	    
-	    for (index = 0; index < dwIndexCount; index++) {
-		int i = (dwIndices == NULL) ? index : dwIndices[index];
-		DWORD *color_d = 
-		    (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
-		DWORD *color_s = 
-		    (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-		D3DVALUE *tex_coord =
-		    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
-		D3DVALUE *position =
-		    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-		
-		handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, TRUE);
-		handle_texture(2, tex_coord);
-		handle_xyzrhw(position);
-		
-		TRACE_(ddraw_geom)(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
-				   position[0], position[1], position[2], position[3], 
-				   (*color_d >> 16) & 0xFF,
-				   (*color_d >>  8) & 0xFF,
-				   (*color_d >>  0) & 0xFF,
-				   (*color_d >> 24) & 0xFF,
-				   (*color_s >> 16) & 0xFF,
-				   (*color_s >>  8) & 0xFF,
-				   (*color_s >>  0) & 0xFF,
-				   (*color_s >> 24) & 0xFF,
-				   tex_coord[0], tex_coord[1]);
-	    } 
-	} else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
-		   ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
-	    /* This is the 'slow path' but that should support all possible vertex formats out there...
-	       Note that people should write a fast path for all vertex formats out there...
-	       */  
-	    unsigned int index;
-	    /* static const D3DVALUE no_index[] = { 0.0, 0.0, 0.0, 0.0 }; */
-	    
-	    for (index = 0; index < dwIndexCount; index++) {
-		int i = (dwIndices == NULL) ? index : dwIndices[index];
-		int tex_stage;
-		
-		if (d3dvtVertexType & D3DFVF_NORMAL) { 
-		    D3DVALUE *normal = 
-			(D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);	    
-		    handle_normal(normal);
-		}
-		if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
-		    DWORD *color_d = 
-			(DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
-		    DWORD *color_s = 
-			(DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-		    handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, vertex_lighted);
-		} else {
-		    if (d3dvtVertexType & D3DFVF_SPECULAR) { 
-			DWORD *color_s = 
-			    (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-			handle_specular(&(This->state_block), color_s, vertex_lighted);
-		    } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
-			DWORD *color_d = 
-			    (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
-			handle_diffuse(&(This->state_block), color_d, vertex_lighted);
-		    }
-		}
-		
-		for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) {
-		    int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0x0000FFFF;
-		    D3DVALUE *tex_coord;
-		    
-		    if (tex_index >= num_tex_index) {
-			/* This will have to be checked on Windows. RealMYST uses this feature and I would find it more
-			 * logical to re-use the index of the previous stage than a default index of '0'.
-			 */
-			
-			/* handle_textures((const D3DVALUE *) no_index, tex_stage); */
-			tex_index = num_tex_index - 1;
-		    }
-		    tex_coord = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + 
-					      i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
-		    handle_textures(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), tex_coord, tex_stage);
-		}
-		
-		if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-		    D3DVALUE *position =
-			(D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-		    handle_xyz(position);
-		} else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
-		    D3DVALUE *position =
-			(D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-		    handle_xyzrhw(position);
-		}
-		
-		if (TRACE_ON(ddraw_geom)) {
-		    unsigned int tex_index;
-		    
-		    if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-			D3DVALUE *position =
-			    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-			TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
-		    } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
-			D3DVALUE *position =
-			    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
-			TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
-		    }
-		    if (d3dvtVertexType & D3DFVF_NORMAL) { 
-			D3DVALUE *normal = 
-			    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);	    
-			TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
-		    }
-		    if (d3dvtVertexType & D3DFVF_DIFFUSE) {
-			DWORD *color_d = 
-			    (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
-			TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
-					   (*color_d >> 16) & 0xFF,
-					   (*color_d >>  8) & 0xFF,
-					   (*color_d >>  0) & 0xFF,
-					   (*color_d >> 24) & 0xFF);
-		    }
-		    if (d3dvtVertexType & D3DFVF_SPECULAR) { 
-			DWORD *color_s = 
-			    (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-			TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
-					   (*color_s >> 16) & 0xFF,
-					   (*color_s >>  8) & 0xFF,
-					   (*color_s >>  0) & 0xFF,
-					   (*color_s >> 24) & 0xFF);
-		    }
-		    for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) {
-			D3DVALUE *tex_coord =
-			    (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + 
-					  i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
-			switch (GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)) {
-			    case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break;
-			    case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break;
-			    case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break;
-			    case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break;
-			    default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)); break;
-			}
-		    }
-		    TRACE_(ddraw_geom)("\n");
-		}
-	    }
-	} else {
-	    ERR(" matrix weighting not handled yet....\n");
-	}
-	
-	glEnd();
-    }
-
-    /* Whatever the case, disable the color material stuff */
-    glDisable(GL_COLOR_MATERIAL);
-
-    if (reenable_depth_test)
-	glEnable(GL_DEPTH_TEST);
-
-    LEAVE_GL();
-    TRACE("End\n");    
-
-    LeaveCriticalSection(&(This->crit));
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
-					  D3DPRIMITIVETYPE d3dptPrimitiveType,
-					  DWORD d3dvtVertexType,
-					  LPVOID lpvVertices,
-					  DWORD dwVertexCount,
-					  DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-
-    TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided, 0);
-    draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, NULL, dwVertexCount, dwFlags);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
-						 D3DPRIMITIVETYPE d3dptPrimitiveType,
-						 DWORD d3dvtVertexType,
-						 LPVOID lpvVertices,
-						 DWORD dwVertexCount,
-						 LPWORD dwIndices,
-						 DWORD dwIndexCount,
-						 DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-
-    TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided, 0);
-    draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                   DWORD dwVertexType,
-                                                   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                   DWORD dwVertexCount,
-                                                   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-
-    TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-    draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, NULL, dwVertexCount, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
-                                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
-                                                          DWORD dwVertexType,
-                                                          LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-                                                          DWORD dwVertexCount,
-                                                          LPWORD lpIndex,
-                                                          DWORD dwIndexCount,
-                                                          DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-
-    TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-					    D3DPRIMITIVETYPE d3dptPrimitiveType,
-					    LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-					    DWORD dwStartVertex,
-					    DWORD dwNumVertices,
-					    DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-
-    TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    if (vb_impl->processed) {
-        IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
-	IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-
-	glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
-	This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
-			   &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
-
-	convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided, dwStartVertex);
-	draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwNumVertices, NULL, dwNumVertices, dwFlags);
-
-    } else {
-        convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided, dwStartVertex);
-	draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwNumVertices, NULL, dwNumVertices, dwFlags);
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
-						   D3DPRIMITIVETYPE d3dptPrimitiveType,
-						   LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
-						   DWORD dwStartVertex,
-						   DWORD dwNumVertices,
-						   LPWORD lpwIndices,
-						   DWORD dwIndexCount,
-						   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-    
-    TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
-    }
-
-    if (vb_impl->processed) {
-        IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
-	IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-
-	glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
-	This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
-			   &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
-
-	convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided, dwStartVertex);
-	draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
-
-    } else {
-        convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided, dwStartVertex);
-	draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
-    }
-
-    return DD_OK;
-}
-
-/* We need a static function for that to handle the 'special' case of 'SELECT_ARG2' */
-static BOOLEAN
-handle_color_alpha_args(IDirect3DDeviceImpl *This, DWORD dwStage, D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, DWORD dwState, D3DTEXTUREOP tex_op)
-{
-    BOOLEAN is_complement = FALSE;
-    BOOLEAN is_alpha_replicate = FALSE;
-    BOOLEAN handled = TRUE;
-    GLenum src;
-    BOOLEAN is_color = ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2));
-    int num;
-    
-    if (is_color) {
-        if (d3dTexStageStateType == D3DTSS_COLORARG1) num = 0;
-	else if (d3dTexStageStateType == D3DTSS_COLORARG2) num = 1;
-	else {
-	    handled = FALSE;
-	    num = 0;
-	}
-	if (tex_op == D3DTOP_SELECTARG2) {
-	    num = 1 - num;
-	}
-    } else {
-        if (d3dTexStageStateType == D3DTSS_ALPHAARG1) num = 0;
-	else if (d3dTexStageStateType == D3DTSS_ALPHAARG2) num = 1;
-	else {
-	    handled = FALSE;
-	    num = 0;
-	}
-	if (tex_op == D3DTOP_SELECTARG2) {
-	    num = 1 - num;
-	}
-    }
-    
-    if (dwState & D3DTA_COMPLEMENT) {
-        is_complement = TRUE;
-    }
-    if (dwState & D3DTA_ALPHAREPLICATE) {
-	is_alpha_replicate = TRUE;
-    }
-    dwState &= D3DTA_SELECTMASK;
-    if ((dwStage == 0) && (dwState == D3DTA_CURRENT)) {
-        dwState = D3DTA_DIFFUSE;
-    }
-
-    switch (dwState) {
-        case D3DTA_CURRENT: src = GL_PREVIOUS_EXT; break;
-	case D3DTA_DIFFUSE: src = GL_PRIMARY_COLOR_EXT; break;
-	case D3DTA_TEXTURE: src = GL_TEXTURE; break;
-	case D3DTA_TFACTOR: {
-	    /* Get the constant value from the current rendering state */
-	    GLfloat color[4];
-	    DWORD col = This->state_block.render_state[D3DRENDERSTATE_TEXTUREFACTOR - 1];
-	    
-	    color[0] = ((col >> 16) & 0xFF) / 255.0f;
-	    color[1] = ((col >>  8) & 0xFF) / 255.0f;
-	    color[2] = ((col >>  0) & 0xFF) / 255.0f;
-	    color[3] = ((col >> 24) & 0xFF) / 255.0f;
-	    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
-	    
-	    src = GL_CONSTANT_EXT;
-	} break;
-	default: src = GL_TEXTURE; handled = FALSE; break;
-    }
-
-    if (is_color) {
-        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT + num, src);
-	if (is_alpha_replicate) {
-	    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
-	} else {
-	    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + num, is_complement ? GL_ONE_MINUS_SRC_COLOR : GL_SRC_COLOR);
-	}
-    } else {
-        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT + num, src);
-	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
-    }
-
-    return handled;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
-						 DWORD dwStage,
-						 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
-						 DWORD dwState)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    const char *type;
-    DWORD prev_state;
-    GLenum unit;
-    
-    TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
-
-    if (((GL_extensions.max_texture_units == 0) && (dwStage > 0)) ||
-	((GL_extensions.max_texture_units != 0) && (dwStage >= GL_extensions.max_texture_units))) {
-	return DD_OK;
-    }
-
-    unit = GL_TEXTURE0_WINE + dwStage;
-    if (unit != glThis->current_active_tex_unit) {
-	GL_extensions.glActiveTexture(unit);
-	glThis->current_active_tex_unit = unit;
-    }
-    
-    switch (d3dTexStageStateType) {
-#define GEN_CASE(a) case a: type = #a; break
-        GEN_CASE(D3DTSS_COLOROP);
-	GEN_CASE(D3DTSS_COLORARG1);
-	GEN_CASE(D3DTSS_COLORARG2);
-	GEN_CASE(D3DTSS_ALPHAOP);
-	GEN_CASE(D3DTSS_ALPHAARG1);
-	GEN_CASE(D3DTSS_ALPHAARG2);
-	GEN_CASE(D3DTSS_BUMPENVMAT00);
-	GEN_CASE(D3DTSS_BUMPENVMAT01);
-	GEN_CASE(D3DTSS_BUMPENVMAT10);
-	GEN_CASE(D3DTSS_BUMPENVMAT11);
-	GEN_CASE(D3DTSS_TEXCOORDINDEX);
-	GEN_CASE(D3DTSS_ADDRESS);
-	GEN_CASE(D3DTSS_ADDRESSU);
-	GEN_CASE(D3DTSS_ADDRESSV);
-	GEN_CASE(D3DTSS_BORDERCOLOR);
-	GEN_CASE(D3DTSS_MAGFILTER);
-	GEN_CASE(D3DTSS_MINFILTER);
-	GEN_CASE(D3DTSS_MIPFILTER);
-	GEN_CASE(D3DTSS_MIPMAPLODBIAS);
-	GEN_CASE(D3DTSS_MAXMIPLEVEL);
-	GEN_CASE(D3DTSS_MAXANISOTROPY);
-	GEN_CASE(D3DTSS_BUMPENVLSCALE);
-	GEN_CASE(D3DTSS_BUMPENVLOFFSET);
-	GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
-#undef GEN_CASE
-        default: type = "UNKNOWN";
-    }
-
-    /* Store the values in the state array */
-    prev_state = This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1];
-    This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
-    /* Some special cases when one state modifies more than one... */
-    if (d3dTexStageStateType == D3DTSS_ADDRESS) {
-        This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
-	This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
-    }
-
-    ENTER_GL();
-    
-    switch (d3dTexStageStateType) {
-        case D3DTSS_MINFILTER:
-        case D3DTSS_MIPFILTER:
-	    if (TRACE_ON(ddraw)) {
-	        if (d3dTexStageStateType == D3DTSS_MINFILTER) {
-		    switch ((D3DTEXTUREMINFILTER) dwState) {
-	                case D3DTFN_POINT:  TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_POINT\n"); break;
-			case D3DTFN_LINEAR: TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_LINEAR\n"); break;
-			default: FIXME(" Unhandled stage type : D3DTSS_MINFILTER => %08lx\n", dwState); break;
-		    }
-		} else {
-		    switch ((D3DTEXTUREMIPFILTER) dwState) {
-	                case D3DTFP_NONE:   TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_NONE\n"); break;
-			case D3DTFP_POINT:  TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_POINT\n"); break;
-			case D3DTFP_LINEAR: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_LINEAR\n"); break;
-			default: FIXME(" Unhandled stage type : D3DTSS_MIPFILTER => %08lx\n", dwState); break;
-		    }
-		}
-	    }
-	    break;
-	    
-        case D3DTSS_MAGFILTER:
-	    if (TRACE_ON(ddraw)) {
-	        switch ((D3DTEXTUREMAGFILTER) dwState) {
-	            case D3DTFG_POINT:  TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFG_POINT\n"); break;
-		    case D3DTFG_LINEAR: TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFG_LINEAR\n"); break;
-		    default: FIXME(" Unhandled stage type : D3DTSS_MAGFILTER => %08lx\n", dwState); break;
-		}
-	    }
-            break;
-
-        case D3DTSS_ADDRESS:
-        case D3DTSS_ADDRESSU:
-        case D3DTSS_ADDRESSV: {
-	    switch ((D3DTEXTUREADDRESS) dwState) {
-	        case D3DTADDRESS_WRAP:   TRACE(" Stage type is : %s => D3DTADDRESS_WRAP\n", type); break;
-	        case D3DTADDRESS_CLAMP:  TRACE(" Stage type is : %s => D3DTADDRESS_CLAMP\n", type); break;
-	        case D3DTADDRESS_BORDER: TRACE(" Stage type is : %s => D3DTADDRESS_BORDER\n", type); break;
-		case D3DTADDRESS_MIRROR:
-		    if (GL_extensions.mirrored_repeat) {
-			TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type);
-		    } else {
-			FIXME(" Stage type is : %s => D3DTADDRESS_MIRROR - not supported by GL !\n", type);
-		    }
-		    break;
-	        default: FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); break;
-	    }
-        } break;
-
-	case D3DTSS_ALPHAOP:
-	case D3DTSS_COLOROP: {
-            int scale = 1;
-            GLenum parm = (d3dTexStageStateType == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
-	    const char *value;
-	    int handled = 1;
-	    
-	    switch (dwState) {
-#define GEN_CASE(a) case a: value = #a; break
-	        GEN_CASE(D3DTOP_DISABLE);
-		GEN_CASE(D3DTOP_SELECTARG1);
-		GEN_CASE(D3DTOP_SELECTARG2);
-		GEN_CASE(D3DTOP_MODULATE);
-		GEN_CASE(D3DTOP_MODULATE2X);
-		GEN_CASE(D3DTOP_MODULATE4X);
-		GEN_CASE(D3DTOP_ADD);
-		GEN_CASE(D3DTOP_ADDSIGNED);
-		GEN_CASE(D3DTOP_ADDSIGNED2X);
-		GEN_CASE(D3DTOP_SUBTRACT);
-		GEN_CASE(D3DTOP_ADDSMOOTH);
-		GEN_CASE(D3DTOP_BLENDDIFFUSEALPHA);
-		GEN_CASE(D3DTOP_BLENDTEXTUREALPHA);
-		GEN_CASE(D3DTOP_BLENDFACTORALPHA);
-		GEN_CASE(D3DTOP_BLENDTEXTUREALPHAPM);
-		GEN_CASE(D3DTOP_BLENDCURRENTALPHA);
-		GEN_CASE(D3DTOP_PREMODULATE);
-		GEN_CASE(D3DTOP_MODULATEALPHA_ADDCOLOR);
-		GEN_CASE(D3DTOP_MODULATECOLOR_ADDALPHA);
-		GEN_CASE(D3DTOP_MODULATEINVALPHA_ADDCOLOR);
-		GEN_CASE(D3DTOP_MODULATEINVCOLOR_ADDALPHA);
-		GEN_CASE(D3DTOP_BUMPENVMAP);
-		GEN_CASE(D3DTOP_BUMPENVMAPLUMINANCE);
-		GEN_CASE(D3DTOP_DOTPRODUCT3);
-		GEN_CASE(D3DTOP_FORCE_DWORD);
-#undef GEN_CASE
-	        default: value = "UNKNOWN";
-	    }
-
-            if ((d3dTexStageStateType == D3DTSS_COLOROP) && (dwState == D3DTOP_DISABLE)) {
-                glDisable(GL_TEXTURE_2D);
-		TRACE(" disabling 2D texturing.\n");
-            } else {
-	        /* Re-enable texturing only if COLOROP was not already disabled... */
-	        if ((glThis->current_bound_texture[dwStage] != NULL) &&
-		    (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) {
-		    glEnable(GL_TEXTURE_2D);
-		    TRACE(" enabling 2D texturing.\n");
-		}
-		
-                /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
-                if ((dwState != D3DTOP_DISABLE) &&
-		    (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) {
-		    if (glThis->current_tex_env != GL_COMBINE_EXT) {
-			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
-			glThis->current_tex_env = GL_COMBINE_EXT;
-		    }
-                }
-
-                /* Now set up the operand correctly */
-                switch (dwState) {
-                    case D3DTOP_DISABLE:
-		        /* Contrary to the docs, alpha can be disabled when colorop is enabled
-			   and it works, so ignore this op */
-		        TRACE(" Note : disable ALPHAOP but COLOROP enabled!\n");
-			break;
-
-		    case D3DTOP_SELECTARG1:
-		    case D3DTOP_SELECTARG2:
-			glTexEnvi(GL_TEXTURE_ENV, parm, GL_REPLACE);
-			break;
-			
-		    case D3DTOP_MODULATE4X:
-			scale = scale * 2;  /* Drop through */
-		    case D3DTOP_MODULATE2X:
-			scale = scale * 2;  /* Drop through */
-		    case D3DTOP_MODULATE:
-			glTexEnvi(GL_TEXTURE_ENV, parm, GL_MODULATE);
-			break;
-
-		    case D3DTOP_ADD:
-			glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD);
-			break;
-
-		    case D3DTOP_ADDSIGNED2X:
-			scale = scale * 2;  /* Drop through */
-		    case D3DTOP_ADDSIGNED:
-			glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD_SIGNED_EXT);
-			break;
-
-			/* For the four blending modes, use the Arg2 parameter */
-		    case D3DTOP_BLENDDIFFUSEALPHA:
-		    case D3DTOP_BLENDTEXTUREALPHA:
-		    case D3DTOP_BLENDFACTORALPHA:
-		    case D3DTOP_BLENDCURRENTALPHA: {
-		        GLenum src = GL_PRIMARY_COLOR_EXT; /* Just to prevent a compiler warning.. */
-
-			switch (dwState) {
-			    case D3DTOP_BLENDDIFFUSEALPHA: src = GL_PRIMARY_COLOR_EXT;
-			    case D3DTOP_BLENDTEXTUREALPHA: src = GL_TEXTURE;
-			    case D3DTOP_BLENDFACTORALPHA:  src = GL_CONSTANT_EXT;
-			    case D3DTOP_BLENDCURRENTALPHA: src = GL_PREVIOUS_EXT;
-			}
-			
-			glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_EXT);
-			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, src);
-			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
-			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, src);
-			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
-		    } break;
-			
-		    default:
-			handled = FALSE;
-			break;
-                }
-            }
-
-	    if (((prev_state == D3DTOP_SELECTARG2) && (dwState != D3DTOP_SELECTARG2)) ||
-		((dwState == D3DTOP_SELECTARG2) && (prev_state != D3DTOP_SELECTARG2))) {
-	        /* Switch the arguments if needed... */
-	        if (d3dTexStageStateType == D3DTSS_COLOROP) {
-		    handle_color_alpha_args(This, dwStage, D3DTSS_COLORARG1,
-					    This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG1 - 1],
-					    dwState);
-		    handle_color_alpha_args(This, dwStage, D3DTSS_COLORARG2,
-					    This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG2 - 1],
-					    dwState);
-		} else {
-		    handle_color_alpha_args(This, dwStage, D3DTSS_ALPHAARG1,
-					    This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG1 - 1],
-					    dwState);
-		    handle_color_alpha_args(This, dwStage, D3DTSS_ALPHAARG2,
-					    This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG2 - 1],
-					    dwState);
-		}
-	    }
-	    
-	    if (handled) {
-	        if (d3dTexStageStateType == D3DTSS_ALPHAOP) {
-		    glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale);
-		} else {
-		    glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, scale);
-		}			
-		TRACE(" Stage type is : %s => %s\n", type, value);
-	    } else {
-	        FIXME(" Unhandled stage type is : %s => %s\n", type, value);
-	    }
-        } break;
-
-	case D3DTSS_COLORARG1:
-	case D3DTSS_COLORARG2:
-	case D3DTSS_ALPHAARG1:
-	case D3DTSS_ALPHAARG2: {
-	    const char *value, *value_comp = "", *value_alpha = "";
-	    BOOLEAN handled;
-	    D3DTEXTUREOP tex_op;
-	    
-	    switch (dwState & D3DTA_SELECTMASK) {
-#define GEN_CASE(a) case a: value = #a; break
-	        GEN_CASE(D3DTA_DIFFUSE);
-		GEN_CASE(D3DTA_CURRENT);
-		GEN_CASE(D3DTA_TEXTURE);
-		GEN_CASE(D3DTA_TFACTOR);
-	        GEN_CASE(D3DTA_SPECULAR);
-#undef GEN_CASE
-	        default: value = "UNKNOWN";
-	    }
-	    if (dwState & D3DTA_COMPLEMENT) {
-	        value_comp = " | D3DTA_COMPLEMENT";
-	    }
-	    if (dwState & D3DTA_ALPHAREPLICATE) {
-	        value_alpha = " | D3DTA_ALPHAREPLICATE";
-	    }
-
-	    if ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2)) {
-	        tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1];
-	    } else {
-	        tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAOP - 1];
-	    }
-	    
-	    handled = handle_color_alpha_args(This, dwStage, d3dTexStageStateType, dwState, tex_op);
-	    
-	    if (handled) {
-	        TRACE(" Stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha);
-	    } else {
-	        FIXME(" Unhandled stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha);
-	    }
-	} break;
-
-	case D3DTSS_MIPMAPLODBIAS: {
-	    D3DVALUE value = *((D3DVALUE *) &dwState);
-	    BOOLEAN handled = TRUE;
-	    
-	    if ((value != 0.0) && (GL_extensions.mipmap_lodbias == FALSE))
-	        handled = FALSE;
-
-	    if (handled) {
-	        TRACE(" Stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value);
-		glTexEnvf(GL_TEXTURE_FILTER_CONTROL_WINE, GL_TEXTURE_LOD_BIAS_WINE, value);
-	    } else {
-	        FIXME(" Unhandled stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value);
-	    }
-	} break;
-
-	case D3DTSS_MAXMIPLEVEL: 
-	    TRACE(" Stage type : D3DTSS_MAXMIPLEVEL => %ld\n", dwState);
-	    break;
-
-	case D3DTSS_BORDERCOLOR:
-	    TRACE(" Stage type : D3DTSS_BORDERCOLOR => %02lx %02lx %02lx %02lx (RGBA)\n",
-		  ((dwState >> 16) & 0xFF),
-		  ((dwState >>  8) & 0xFF),
-		  ((dwState >>  0) & 0xFF),
-		  ((dwState >> 24) & 0xFF));
-	    break;
-	    
-	case D3DTSS_TEXCOORDINDEX: {
-	    BOOLEAN handled = TRUE;
-	    const char *value;
-	    
-	    switch (dwState & 0xFFFF0000) {
-#define GEN_CASE(a) case a: value = #a; break
-	        GEN_CASE(D3DTSS_TCI_PASSTHRU);
-		GEN_CASE(D3DTSS_TCI_CAMERASPACENORMAL);
-		GEN_CASE(D3DTSS_TCI_CAMERASPACEPOSITION);
-		GEN_CASE(D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
-#undef GEN_CASE
-		default: value = "UNKNOWN";
-	    }
-	    if ((dwState & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU)
-	        handled = FALSE;
-
-	    if (handled) {
-	        TRACE(" Stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value);
-	    } else {
-	        FIXME(" Unhandled stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value);
-	    }
-	} break;
-	    
-	case D3DTSS_TEXTURETRANSFORMFLAGS: {
-	    const char *projected = "", *value;
-	    BOOLEAN handled = TRUE;
-	    switch (dwState & 0xFF) {
-#define GEN_CASE(a) case a: value = #a; break
-	        GEN_CASE(D3DTTFF_DISABLE);
-		GEN_CASE(D3DTTFF_COUNT1);
-		GEN_CASE(D3DTTFF_COUNT2);
-		GEN_CASE(D3DTTFF_COUNT3);
-		GEN_CASE(D3DTTFF_COUNT4);
-#undef GEN_CASE
-		default: value = "UNKNOWN";
-	    }
-	    if (dwState & D3DTTFF_PROJECTED) {
-	        projected = " | D3DTTFF_PROJECTED";
-		handled = FALSE;
-	    }
-
-	    if ((dwState & 0xFF) != D3DTTFF_DISABLE) {
-	        This->matrices_updated(This, TEXMAT0_CHANGED << dwStage);
-	    }
-
-	    if (handled) {
-	        TRACE(" Stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected);
-	    } else {
-	        FIXME(" Unhandled stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected);
-	    }
-	} break;
-	    
-	default:
-	    FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState);
-	    break;
-    }
-
-    LEAVE_GL();
-    
-    return DD_OK;
-}
-
-static DWORD
-draw_primitive_handle_textures(IDirect3DDeviceImpl *This)
-{
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    DWORD stage;
-    BOOLEAN enable_colorkey = FALSE;
-    
-    for (stage = 0; stage < MAX_TEXTURES; stage++) {
-	IDirectDrawSurfaceImpl *surf_ptr = This->current_texture[stage];
-	GLenum unit;
-
-	/* If this stage is disabled, no need to go further... */
-	if (This->state_block.texture_stage_state[stage][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE)
-	    break;
-	
-	/* First check if we need to bind any other texture for this stage */
-	if (This->current_texture[stage] != glThis->current_bound_texture[stage]) {
-	    if (This->current_texture[stage] == NULL) {
-		TRACE(" disabling 2D texturing for stage %ld.\n", stage);
-		
-		unit = GL_TEXTURE0_WINE + stage;
-		if (unit != glThis->current_active_tex_unit) {
-		    GL_extensions.glActiveTexture(unit);
-		    glThis->current_active_tex_unit = unit;
-		}
-		glBindTexture(GL_TEXTURE_2D, 0);
-		glDisable(GL_TEXTURE_2D);
-	    } else {
-		GLenum tex_name = gltex_get_tex_name(surf_ptr);
-		
-		unit = GL_TEXTURE0_WINE + stage;
-		if (unit != glThis->current_active_tex_unit) {
-		    GL_extensions.glActiveTexture(unit);
-		    glThis->current_active_tex_unit = unit;
-		}
-
-		if (glThis->current_bound_texture[stage] == NULL) {
-		    if (This->state_block.texture_stage_state[stage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE) {
-			TRACE(" enabling 2D texturing and");
-			glEnable(GL_TEXTURE_2D);
-		    }
-		}
-		TRACE(" activating OpenGL texture id %d for stage %ld.\n", tex_name, stage);
-		glBindTexture(GL_TEXTURE_2D, tex_name);
-	    }
-
-	    glThis->current_bound_texture[stage] = This->current_texture[stage];
-	} else {
-	    if (glThis->current_bound_texture[stage] == NULL) {
-		TRACE(" displaying without texturing activated for stage %ld.\n", stage);
-	    } else {
-		TRACE(" using already bound texture id %d for stage %ld.\n",
-		      ((IDirect3DTextureGLImpl *) (glThis->current_bound_texture[stage])->tex_private)->tex_name, stage);
-	    }
-	}
-
-	/* If no texure valid for this stage, go out of the loop */
-	if (This->current_texture[stage] == NULL) break;
-
-	/* Then check if we need to flush this texture to GL or not (ie did it change) ?.
-	   This will also update the various texture parameters if needed.
-	*/
-	gltex_upload_texture(surf_ptr, This, stage);
-
-	/* And finally check for color-keying (only on first stage) */
-	if (This->current_texture[stage]->surface_desc.dwFlags & DDSD_CKSRCBLT) {
-	    if (stage == 0) {
-		enable_colorkey = TRUE;
-	    } else {
-		static BOOL warn = FALSE;
-		if (warn == FALSE) {
-		    warn = TRUE;
-		    WARN(" Surface has color keying on stage different from 0 (%ld) !", stage);
-		}
-	    }
-	} else {
-	    if (stage == 0) {
-		enable_colorkey = FALSE;
-	    }
-	}
-    }
-
-    /* Apparently, whatever the state of BLEND, color keying is always activated for 'old' D3D versions */
-    if (((This->state_block.render_state[D3DRENDERSTATE_COLORKEYENABLE - 1]) ||
-	 (glThis->parent.version == 1)) &&
-	(enable_colorkey)) {
-	TRACE(" colorkey activated.\n");
-	
-	if (glThis->alpha_test == FALSE) {
-	    glEnable(GL_ALPHA_TEST);
-	    glThis->alpha_test = TRUE;
-	}
-	if ((glThis->current_alpha_test_func != GL_NOTEQUAL) || (glThis->current_alpha_test_ref != 0.0)) {
-	    if (This->state_block.render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1]) {
-		static BOOL warn = FALSE;
-		if (warn == FALSE) {
-		    warn = TRUE;
-		    WARN(" Overriding application-given alpha test values - some graphical glitches may appear !\n");
-		}
-	    }
-	    glThis->current_alpha_test_func = GL_NOTEQUAL;
-	    glThis->current_alpha_test_ref = 0.0;
-	    glAlphaFunc(GL_NOTEQUAL, 0.0);
-	}
-	/* Some sanity checks should be added here if a game mixes alphatest + color keying...
-	   Only one has been found for now, and the ALPHAFUNC is 'Always' so it works :-) */
-    } else {
-	if (This->state_block.render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == FALSE) {
-	    glDisable(GL_ALPHA_TEST);
-	    glThis->alpha_test = FALSE;
-	}
-	/* Maybe we should restore here the application-given alpha test states ? */
-    }
-    
-    return stage;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
-				       DWORD dwStage,
-				       LPDIRECTDRAWSURFACE7 lpTexture2)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
-
-    if (((GL_extensions.max_texture_units == 0) && (dwStage > 0)) ||
-	((GL_extensions.max_texture_units != 0) && (dwStage >= GL_extensions.max_texture_units))) {
-	if (lpTexture2 != NULL) {
-	    WARN(" setting a texture to a non-supported texture stage !\n");
-	}
-	return DD_OK;
-    }
-
-    if (This->current_texture[dwStage] != NULL) {
-	IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
-    }
-    
-    if (lpTexture2 == NULL) {
-	This->current_texture[dwStage] = NULL;
-    } else {
-        IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
-	IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
-	This->current_texture[dwStage] = tex_impl;
-    }
-    
-    return DD_OK;
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
-				 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
-
-    fill_opengl_caps_7(lpD3DHELDevDesc);
-
-    TRACE(" returning caps : no dump function yet.\n");
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
-				     LPD3DMATERIAL7 lpMat)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
-    
-    if (TRACE_ON(ddraw)) {
-        TRACE(" material is :\n");
-	dump_D3DMATERIAL7(lpMat);
-    }
-    
-    This->current_material = *lpMat;
-
-    ENTER_GL();
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_DIFFUSE,
-		 (float *) &(This->current_material.u.diffuse));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_AMBIENT,
-		 (float *) &(This->current_material.u1.ambient));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_SPECULAR,
-		 (float *) &(This->current_material.u2.specular));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_EMISSION,
-		 (float *) &(This->current_material.u3.emissive));
-    glMaterialf(GL_FRONT_AND_BACK,
-		GL_SHININESS,
-		This->current_material.u4.power); /* Not sure about this... */
-    LEAVE_GL();
-
-    return DD_OK;
-}
-
-static LPD3DLIGHT7 get_light(IDirect3DDeviceImpl *This, DWORD dwLightIndex)
-{
-    if (dwLightIndex >= This->num_set_lights)
-    {
-        /* Extend, or allocate the light parameters array. */
-        DWORD newlightnum = dwLightIndex + 1;
-        LPD3DLIGHT7 newarrayptr = NULL;
-
-        if (This->light_parameters)
-            newarrayptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                This->light_parameters, newlightnum * sizeof(D3DLIGHT7));
-        else
-            newarrayptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                newlightnum * sizeof(D3DLIGHT7));
-
-        if (!newarrayptr)
-            return NULL;
-
-        This->light_parameters = newarrayptr;
-        This->num_set_lights = newlightnum;
-    }
-
-    return &This->light_parameters[dwLightIndex];
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
-				  DWORD dwLightIndex,
-				  LPD3DLIGHT7 lpLight)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    LPD3DLIGHT7 lpdestlight = get_light( This, dwLightIndex );
-
-    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
-    
-    if (TRACE_ON(ddraw)) {
-        TRACE(" setting light :\n");
-	dump_D3DLIGHT7(lpLight);
-    }
-    
-    /* DirectX7 documentation states that this function can return
-       DDERR_OUTOFMEMORY, so we do just that in case of an allocation
-       error (which is the only reason why get_light() can fail). */
-    if( !lpdestlight )
-        return DDERR_OUTOFMEMORY;
-
-    *lpdestlight = *lpLight;
-
-    /* Some checks to print out nice warnings :-) */
-    switch (lpLight->dltType) {
-        case D3DLIGHT_DIRECTIONAL:
-        case D3DLIGHT_POINT:
-            /* These are handled properly... */
-            break;
-	    
-        case D3DLIGHT_SPOT:
-            if ((lpLight->dvTheta != 0.0) ||
-		(lpLight->dvTheta != lpLight->dvPhi)) {
-	        ERR("dvTheta not fully supported yet !\n");
-	    }
-	    break;
-
-	default:
-	    ERR("Light type not handled yet : %08x !\n", lpLight->dltType);
-    }
-    
-    /* This will force the Light setting on next drawing of primitives */
-    glThis->transform_state = GL_TRANSFORM_NONE;
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
-				     DWORD dwLightIndex,
-				     BOOL bEnable)
-{
-    int lightslot = -1, i;
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    LPD3DLIGHT7 lpdestlight = get_light(This, dwLightIndex);
-
-    TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
-
-    /* The DirectX doc isn't as explicit as for SetLight as whether we can
-       return this from this function, but it doesn't state otherwise. */
-    if (!lpdestlight)
-        return DDERR_OUTOFMEMORY;
-
-    /* If this light hasn't been set, initialise it with default values. */
-    if (lpdestlight->dltType == 0)
-    {
-        TRACE("setting default light parameters\n");
-
-        /* We always use HEAP_ZERO_MEMORY when allocating the light_parameters
-           array, so we only have to setup anything that shoud not be zero. */
-        lpdestlight->dltType = D3DLIGHT_DIRECTIONAL;
-        lpdestlight->dcvDiffuse.u1.r = 1.f;
-        lpdestlight->dcvDiffuse.u2.g = 1.f;
-        lpdestlight->dcvDiffuse.u3.b = 1.f;
-        lpdestlight->dvDirection.u3.z = 1.f;
-    }
-
-    /* Look for this light in the active lights array. */
-    for (i = 0; i < This->max_active_lights; i++)
-        if (This->active_lights[i] == dwLightIndex)
-        {
-            lightslot = i;
-            break;
-        }
-
-    /* If we didn't find it, let's find the first available slot, if any. */
-    if (lightslot == -1)
-        for (i = 0; i < This->max_active_lights; i++)
-            if (This->active_lights[i] == ~0)
-            {
-                lightslot = i;
-                break;
-            }
-
-    ENTER_GL();
-    if (bEnable) {
-        if (lightslot == -1)
-        {
-            /* This means that the app is trying to enable more lights than
-               the maximum possible indicated in the caps.
-
-               Windows actually let you do this, and disable one of the
-               previously enabled lights to let you enable this one.
-
-               It's not documented and I'm not sure how windows pick which light
-               to disable to make room for this one. */
-            FIXME("Enabling more light than the maximum is not supported yet.");
-            return D3D_OK;
-        }
-
-        glEnable(GL_LIGHT0 + lightslot);
-
-
-        if (This->active_lights[lightslot] == ~0)
-        {
-	    /* This light gets active... Need to update its parameters to GL before the next drawing */
-	    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-
-            This->active_lights[lightslot] = dwLightIndex;
-	    glThis->transform_state = GL_TRANSFORM_NONE;
-	}
-    } else {
-        glDisable(GL_LIGHT0 + lightslot);
-        This->active_lights[lightslot] = ~0;
-    }
-
-    LEAVE_GL();
-    return DD_OK;
-}
-
-HRESULT  WINAPI  
-GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, D3DVALUE* pPlaneEquation) 
-{
-    IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
-    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
-
-    TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
-
-    if (dwIndex >= This->max_clipping_planes) {
-	return DDERR_INVALIDPARAMS;
-    }
-
-    TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
-
-    memcpy(This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
-    
-    /* This is to force the reset of the transformation matrices on the next drawing.
-     * This is needed to use the correct matrices for the various clipping planes.
-     */
-    glThis->transform_state = GL_TRANSFORM_NONE;
-    
-    return D3D_OK;
-}
-
-static HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface,
-				     LPD3DVIEWPORT7 lpData)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" viewport is :\n");
-	TRACE("    - dwX = %ld   dwY = %ld\n",
-	      lpData->dwX, lpData->dwY);
-	TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
-	      lpData->dwWidth, lpData->dwHeight);
-	TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
-	      lpData->dvMinZ, lpData->dvMaxZ);
-    }
-    ENTER_GL();
-    
-    /* Set the viewport */
-    if ((lpData->dvMinZ != This->active_viewport.dvMinZ) ||
-	(lpData->dvMaxZ != This->active_viewport.dvMaxZ)) {
-	glDepthRange(lpData->dvMinZ, lpData->dvMaxZ);
-    }
-    if ((lpData->dwX != This->active_viewport.dwX) ||
-	(lpData->dwY != This->active_viewport.dwY) ||
-	(lpData->dwWidth != This->active_viewport.dwWidth) ||
-	(lpData->dwHeight != This->active_viewport.dwHeight)) {
-	glViewport(lpData->dwX,
-		   This->surface->surface_desc.dwHeight - (lpData->dwHeight + lpData->dwY),
-		   lpData->dwWidth, lpData->dwHeight);
-    }
-
-    LEAVE_GL();
-
-    This->active_viewport = *lpData;
-    
-    return DD_OK;
-}
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice7.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DDevice7Vtbl VTABLE_IDirect3DDevice7 =
-{
-    XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
-    XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
-    XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
-    XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
-    XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
-    XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
-    XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
-    XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
-    XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
-    XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
-    XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
-    XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
-    XCAST(SetViewport) GL_IDirect3DDeviceImpl_7_SetViewport,
-    XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
-    XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
-    XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
-    XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
-    XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
-    XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
-    XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
-    XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
-    XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
-    XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
-    XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
-    XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
-    XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
-    XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
-    XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
-    XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
-    XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
-    XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
-    XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
-    XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
-    XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
-    XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
-    XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
-    XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
-    XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
-    XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
-    XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
-    XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
-    XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
-    XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
-    XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
-    XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
-    XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
-    XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
-    XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice3.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DDevice3Vtbl VTABLE_IDirect3DDevice3 =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
-    XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
-    XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
-    XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
-    XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
-    XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
-    XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
-    XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
-    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
-    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
-    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
-    XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
-    XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
-    XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
-    XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
-    XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
-    XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
-    XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
-    XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
-    XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
-    XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
-    XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
-    XCAST(GetLightState) GL_IDirect3DDeviceImpl_3_2T_GetLightState,
-    XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
-    XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
-    XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
-    XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
-    XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
-    XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
-    XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
-    XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
-    XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
-    XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
-    XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
-    XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
-    XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
-    XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
-    XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
-    XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
-    XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
-    XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice2.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DDevice2Vtbl VTABLE_IDirect3DDevice2 =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
-    XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
-    XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
-    XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
-    XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
-    XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
-    XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
-    XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
-    XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
-    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
-    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
-    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
-    XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
-    XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
-    XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
-    XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
-    XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
-    XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
-    XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
-    XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
-    XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
-    XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
-    XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
-    XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
-    XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
-    XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
-    XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
-    XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
-    XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
-    XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
-    XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
-    XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DDeviceVtbl VTABLE_IDirect3DDevice =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
-    XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
-    XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
-    XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
-    XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
-    XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
-    XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
-    XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
-    XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
-    XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
-    XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
-    XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
-    XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
-    XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
-    XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
-    XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
-    XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
-    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
-    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
-    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
-			       WINE_GL_BUFFER_TYPE buffer_type,
-			       DWORD dwCount,
-			       LPD3DRECT lpRects,
-			       DWORD dwFlags,
-			       DWORD dwColor,
-			       D3DVALUE dvZ,
-			       DWORD dwStencil)
-{
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    GLbitfield bitfield = 0;
-    D3DRECT rect;
-    unsigned int i;
-    
-    TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
-    if (TRACE_ON(ddraw)) {
-	if (dwCount > 0) {
-	    unsigned int i;
-	    TRACE(" rectangles :\n");
-	    for (i = 0; i < dwCount; i++) {
-	        TRACE("  - %ld x %ld     %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
-	    }
-	}
-    }
-
-    if (dwCount == 0) {
-        dwCount = 1;
-	rect.u1.x1 = 0;
-	rect.u2.y1 = 0;
-	rect.u3.x2 = This->surface->surface_desc.dwWidth;
-	rect.u4.y2 = This->surface->surface_desc.dwHeight;
-	lpRects = &rect;
-    }
-    
-    /* Clears the screen */
-    ENTER_GL();
-
-    if (dwFlags & D3DCLEAR_TARGET) {
-	if (glThis->state[buffer_type] == SURFACE_MEMORY_DIRTY) {
-	    /* TODO: optimize here the case where Clear changes all the screen... */
-	    This->flush_to_framebuffer(This, &(glThis->lock_rect[buffer_type]), glThis->lock_surf[buffer_type]);
-	}
-	glThis->state[buffer_type] = SURFACE_GL;
-    }
-
-    if (dwFlags & D3DCLEAR_ZBUFFER) {
-	bitfield |= GL_DEPTH_BUFFER_BIT;
-	if (glThis->depth_mask == FALSE) {
-	    glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
-	}
-	if (dvZ != glThis->prev_clear_Z) {
-	    glClearDepth(dvZ);
-	    glThis->prev_clear_Z = dvZ;
-	}
-	TRACE(" depth value : %f\n", dvZ);
-    }
-    if (dwFlags & D3DCLEAR_STENCIL) {
-        bitfield |= GL_STENCIL_BUFFER_BIT;
-	if (dwStencil != glThis->prev_clear_stencil) {
-	    glClearStencil(dwStencil);
-	    glThis->prev_clear_stencil = dwStencil;
-	}
-	TRACE(" stencil value : %ld\n", dwStencil);
-    }    
-    if (dwFlags & D3DCLEAR_TARGET) {
-        bitfield |= GL_COLOR_BUFFER_BIT;
-	if (dwColor != glThis->prev_clear_color) {
-	    glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
-			 ((dwColor >>  8) & 0xFF) / 255.0,
-			 ((dwColor >>  0) & 0xFF) / 255.0,
-			 ((dwColor >> 24) & 0xFF) / 255.0);
-	    glThis->prev_clear_color = dwColor;
-	}
-	TRACE(" color value (ARGB) : %08lx\n", dwColor);
-    }
-
-    glEnable(GL_SCISSOR_TEST); 
-    for (i = 0; i < dwCount; i++) {
-        glScissor(lpRects[i].u1.x1, This->surface->surface_desc.dwHeight - lpRects[i].u4.y2,
-		  lpRects[i].u3.x2 - lpRects[i].u1.x1, lpRects[i].u4.y2 - lpRects[i].u2.y1);
-        glClear(bitfield);
-    }
-    glDisable(GL_SCISSOR_TEST); 
-    
-    if (dwFlags & D3DCLEAR_ZBUFFER) {
-	if (glThis->depth_mask == FALSE) glDepthMask(GL_FALSE);
-    }
-    
-    LEAVE_GL();
-    
-    return DD_OK;
-}
-
-static HRESULT d3ddevice_clear_back(IDirect3DDeviceImpl *This,
-				    DWORD dwCount,
-				    LPD3DRECT lpRects,
-				    DWORD dwFlags,
-				    DWORD dwColor,
-				    D3DVALUE dvZ,
-				    DWORD dwStencil)
-{
-    return d3ddevice_clear(This, WINE_GL_BUFFER_BACK, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
-}
-
-static HRESULT
-setup_rect_and_surface_for_blt(IDirectDrawSurfaceImpl *This,
-			       WINE_GL_BUFFER_TYPE *buffer_type_p, D3DRECT *rect)
-{
-    IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice;
-    WINE_GL_BUFFER_TYPE buffer_type;
-    
-    /* First check if we BLT to the backbuffer... */
-    if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) != 0) {
-	buffer_type = WINE_GL_BUFFER_BACK;
-    } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
-	buffer_type = WINE_GL_BUFFER_FRONT;
-    } else {
-	ERR("Only BLT override to front or back-buffer is supported for now !\n");
-	return DDERR_INVALIDPARAMS;
-    }
-            
-    if ((gl_d3d_dev->state[buffer_type] == SURFACE_MEMORY_DIRTY) &&
-	(rect->u1.x1 >= gl_d3d_dev->lock_rect[buffer_type].left) &&
-	(rect->u2.y1 >= gl_d3d_dev->lock_rect[buffer_type].top) &&
-	(rect->u3.x2 <= gl_d3d_dev->lock_rect[buffer_type].right) &&
-	(rect->u4.y2 <= gl_d3d_dev->lock_rect[buffer_type].bottom)) {
-	/* If the memory zone is already dirty, use the standard 'in memory' blit operations and not
-	 * GL to do it.
-	 */
-	return DDERR_INVALIDPARAMS;
-    }
-    *buffer_type_p = buffer_type;
-    
-    return DD_OK;
-}
-
-HRESULT
-d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
-	      LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
-	      DWORD dwFlags, LPDDBLTFX lpbltfx)
-{
-    WINE_GL_BUFFER_TYPE buffer_type;
-    D3DRECT rect;
-
-    if (rdst) {
-	rect.u1.x1 = rdst->left;
-	rect.u2.y1 = rdst->top;
-	rect.u3.x2 = rdst->right;
-	rect.u4.y2 = rdst->bottom;
-    } else {
-	rect.u1.x1 = 0;
-	rect.u2.y1 = 0;
-	rect.u3.x2 = This->surface_desc.dwWidth;
-	rect.u4.y2 = This->surface_desc.dwHeight;
-    }
-    
-    if (setup_rect_and_surface_for_blt(This, &buffer_type, &rect) != DD_OK) return DDERR_INVALIDPARAMS;
-
-    if (dwFlags & DDBLT_COLORFILL) {
-        /* This is easy to handle for the D3D Device... */
-        DWORD color;
-        GLint prev_draw;
-        
-        /* The color as given in the Blt function is in the format of the frame-buffer...
-         * 'clear' expect it in ARGB format => we need to do some conversion :-)
-         */
-        if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-            if (This->palette) {
-                color = ((0xFF000000) |
-                         (This->palette->palents[lpbltfx->u5.dwFillColor].peRed << 16) |
-                         (This->palette->palents[lpbltfx->u5.dwFillColor].peGreen << 8) |
-                         (This->palette->palents[lpbltfx->u5.dwFillColor].peBlue));
-            } else {
-                color = 0xFF000000;
-            }
-        } else if ((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) &&
-                   (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) == 0) ||
-                    (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000))) {
-            if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) &&
-                (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
-                (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
-                (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F)) {
-                if (lpbltfx->u5.dwFillColor == 0xFFFF) {
-                    color = 0xFFFFFFFF;
-                } else {
-                    color = ((0xFF000000) |
-                             ((lpbltfx->u5.dwFillColor & 0xF800) << 8) |
-                             ((lpbltfx->u5.dwFillColor & 0x07E0) << 5) |
-                             ((lpbltfx->u5.dwFillColor & 0x001F) << 3));
-                }
-            } else if (((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) ||
-                        (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 24)) &&
-                       (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
-                       (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
-                       (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF)) {
-                color = 0xFF000000 | lpbltfx->u5.dwFillColor;
-            } else {
-                ERR("Wrong surface type for BLT override (unknown RGB format) !\n");
-                return DDERR_INVALIDPARAMS;
-            }
-        } else {
-            ERR("Wrong surface type for BLT override !\n");
-            return DDERR_INVALIDPARAMS;
-        }
-        
-        TRACE(" executing D3D Device override.\n");
-	
-        ENTER_GL();
-
-        glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
-        if (buffer_type == WINE_GL_BUFFER_FRONT)
-            glDrawBuffer(GL_FRONT);
-        else
-            glDrawBuffer(GL_BACK);
-        
-        d3ddevice_clear(This->d3ddevice, buffer_type, 1, &rect, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
-	
-        if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) ||
-            ((buffer_type == WINE_GL_BUFFER_BACK)  && (prev_draw == GL_FRONT)))
-            glDrawBuffer(prev_draw);
-	
-        LEAVE_GL();
-        
-        return DD_OK;
-    } else if ((dwFlags & (~(DDBLT_KEYSRC|DDBLT_WAIT|DDBLT_ASYNC))) == 0) {
-	/* Normal blit without any special case... */
-	if (src != NULL) {
-	    /* And which has a SRC surface */
-	    IDirectDrawSurfaceImpl *src_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
-	    
-	    if ((src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
-		(src_impl->d3ddevice == This->d3ddevice) &&
-		((dwFlags & DDBLT_KEYSRC) == 0)) {
-		/* Both are 3D devices and using the same GL device and the Blt is without color-keying */
-		D3DRECT src_rect;
-		int width, height;
-		GLint prev_draw;
-		WINE_GL_BUFFER_TYPE src_buffer_type;
-		IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice;
-		BOOLEAN initial;
-		DWORD opt_bitmap;
-		int x, y;
-	
-		if (rsrc) {
-		    src_rect.u1.x1 = rsrc->left;
-		    src_rect.u2.y1 = rsrc->top;
-		    src_rect.u3.x2 = rsrc->right;
-		    src_rect.u4.y2 = rsrc->bottom;
-		} else {
-		    src_rect.u1.x1 = 0;
-		    src_rect.u2.y1 = 0;
-		    src_rect.u3.x2 = src_impl->surface_desc.dwWidth;
-		    src_rect.u4.y2 = src_impl->surface_desc.dwHeight;
-		}
-
-		width = src_rect.u3.x2 - src_rect.u1.x1;
-		height = src_rect.u4.y2 - src_rect.u2.y1;
-
-		if ((width != (rect.u3.x2 - rect.u1.x1)) ||
-		    (height != (rect.u4.y2 - rect.u2.y1))) {
-		    FIXME(" buffer to buffer copy not supported with stretching yet !\n");
-		    return DDERR_INVALIDPARAMS;
-		}
-
-		/* First check if we BLT from the backbuffer... */
-		if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) != 0) {
-		    src_buffer_type = WINE_GL_BUFFER_BACK;
-		} else if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
-		    src_buffer_type = WINE_GL_BUFFER_FRONT;
-		} else {
-		    ERR("Unexpected case in direct buffer to buffer copy !\n");
-		    return DDERR_INVALIDPARAMS;
-		}
-		
-		TRACE(" using direct buffer to buffer copy.\n");
-
-		ENTER_GL();
-
-		opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, (LPCRECT) &rect, FALSE, &initial);
-		
-		if (upload_surface_to_tex_memory_init(This, 0, &gl_d3d_dev->current_internal_format,
-						      initial, FALSE, UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) {
-		    ERR(" unsupported pixel format at direct buffer to buffer copy.\n");
-		    LEAVE_GL();
-		    return DDERR_INVALIDPARAMS;
-		}
-		
-		glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
-		if (buffer_type == WINE_GL_BUFFER_FRONT)
-		    glDrawBuffer(GL_FRONT);
-		else
-		    glDrawBuffer(GL_BACK);
-
-		if (src_buffer_type == WINE_GL_BUFFER_FRONT)
-		    glReadBuffer(GL_FRONT);
-		else
-		    glReadBuffer(GL_BACK);
-
-		/* Now the serious stuff happens. Basically, we copy from the source buffer to the texture memory.
-		   And directly re-draws this on the destination buffer. */
-		for (y = 0; y < height; y += UNLOCK_TEX_SIZE) {
-		    int get_height;
-		    
-		    if ((src_rect.u2.y1 + y + UNLOCK_TEX_SIZE) > src_impl->surface_desc.dwHeight)
-			get_height = src_impl->surface_desc.dwHeight - (src_rect.u2.y1 + y);
-		    else
-			get_height = UNLOCK_TEX_SIZE;
-		    
-		    for (x = 0; x < width; x += UNLOCK_TEX_SIZE) {
-			int get_width;
-			
-			if ((src_rect.u1.x1 + x + UNLOCK_TEX_SIZE) > src_impl->surface_desc.dwWidth)
-			    get_width = src_impl->surface_desc.dwWidth - (src_rect.u1.x1 + x);
-			else
-			    get_width = UNLOCK_TEX_SIZE;
-			
-			glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
-					    0, UNLOCK_TEX_SIZE - get_height,
-					    src_rect.u1.x1 + x, src_impl->surface_desc.dwHeight - (src_rect.u2.y1 + y + get_height),
-					    get_width, get_height);
-			
-			glBegin(GL_QUADS);
-			glTexCoord2f(0.0, 0.0);
-			glVertex3d(rect.u1.x1 + x,
-				   rect.u2.y1 + y + UNLOCK_TEX_SIZE,
-				   0.5);
-			glTexCoord2f(1.0, 0.0);
-			glVertex3d(rect.u1.x1 + x + UNLOCK_TEX_SIZE,
-				   rect.u2.y1 + y + UNLOCK_TEX_SIZE,
-				   0.5);
-			glTexCoord2f(1.0, 1.0);
-			glVertex3d(rect.u1.x1 + x + UNLOCK_TEX_SIZE,
-				   rect.u2.y1 + y,
-				   0.5);
-			glTexCoord2f(0.0, 1.0);
-			glVertex3d(rect.u1.x1 + x,
-				   rect.u2.y1 + y,
-				   0.5);
-			glEnd();
-		    }
-		}
-		
-		upload_surface_to_tex_memory_release();
-		d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, FALSE);
-		
-		if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) ||
-		    ((buffer_type == WINE_GL_BUFFER_BACK)  && (prev_draw == GL_FRONT)))
-		    glDrawBuffer(prev_draw);
-		
-		LEAVE_GL();
-
-		return DD_OK;
-	    } else {
-		/* This is the normal 'with source' Blit. Use the texture engine to do the Blt for us
-		   (this prevents calling glReadPixels) */
-		D3DRECT src_rect;
-		int width, height;
-		GLint prev_draw;
-		IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice;
-		BOOLEAN initial;
-		DWORD opt_bitmap;
-		int x, y;
-		double x_stretch, y_stretch;
-		
-		if (rsrc) {
-		    src_rect.u1.x1 = rsrc->left;
-		    src_rect.u2.y1 = rsrc->top;
-		    src_rect.u3.x2 = rsrc->right;
-		    src_rect.u4.y2 = rsrc->bottom;
-		} else {
-		    src_rect.u1.x1 = 0;
-		    src_rect.u2.y1 = 0;
-		    src_rect.u3.x2 = src_impl->surface_desc.dwWidth;
-		    src_rect.u4.y2 = src_impl->surface_desc.dwHeight;
-		}
-
-		width = src_rect.u3.x2 - src_rect.u1.x1;
-		height = src_rect.u4.y2 - src_rect.u2.y1;
-
-		x_stretch = (double) (rect.u3.x2 - rect.u1.x1) / (double) width;
-		y_stretch = (double) (rect.u4.y2 - rect.u2.y1) / (double) height;
-
-		TRACE(" using memory to buffer Blt override.\n");
-
-		ENTER_GL();
-
-		opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, (LPCRECT) &rect, ((dwFlags & DDBLT_KEYSRC) != 0), &initial);
-		
-		if (upload_surface_to_tex_memory_init(src_impl, 0, &gl_d3d_dev->current_internal_format,
-						      initial, ((dwFlags & DDBLT_KEYSRC) != 0), UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) {
-		    ERR(" unsupported pixel format at memory to buffer Blt override.\n");
-		    LEAVE_GL();
-		    return DDERR_INVALIDPARAMS;
-		}
-		
-		glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
-		if (buffer_type == WINE_GL_BUFFER_FRONT)
-		    glDrawBuffer(GL_FRONT);
-		else
-		    glDrawBuffer(GL_BACK);
-
-		/* Now the serious stuff happens. This is basically the same code as for the memory
-		   flush to frame buffer ... with stretching and different rectangles added :-) */
-		for (y = 0; y < height; y += UNLOCK_TEX_SIZE) {
-		    RECT flush_rect;
-
-		    flush_rect.top    = src_rect.u2.y1 + y;
-		    flush_rect.bottom = ((src_rect.u2.y1 + y + UNLOCK_TEX_SIZE > src_rect.u4.y2) ?
-					 src_rect.u4.y2 :
-					 (src_rect.u2.y1 + y + UNLOCK_TEX_SIZE));
-		    
-		    for (x = 0; x < width; x += UNLOCK_TEX_SIZE) {
-			flush_rect.left  = src_rect.u1.x1 + x;
-			flush_rect.right = ((src_rect.u1.x1 + x + UNLOCK_TEX_SIZE > src_rect.u3.x2) ?
-					    src_rect.u3.x2 :
-					    (src_rect.u1.x1 + x + UNLOCK_TEX_SIZE));
-			
-			upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr));
-			
-			glBegin(GL_QUADS);
-			glTexCoord2f(0.0, 0.0);
-			glVertex3d(rect.u1.x1 + (x * x_stretch),
-				   rect.u2.y1 + (y * y_stretch),
-				   0.5);
-			glTexCoord2f(1.0, 0.0);
-			glVertex3d(rect.u1.x1 + ((x + UNLOCK_TEX_SIZE) * x_stretch),
-				   rect.u2.y1 + (y * y_stretch),
-				   0.5);
-			glTexCoord2f(1.0, 1.0);
-			glVertex3d(rect.u1.x1 + ((x + UNLOCK_TEX_SIZE) * x_stretch),
-				   rect.u2.y1 + ((y + UNLOCK_TEX_SIZE) * y_stretch),
-				   0.5);
-			glTexCoord2f(0.0, 1.0);
-			glVertex3d(rect.u1.x1 + (x * x_stretch),
-				   rect.u2.y1 + ((y + UNLOCK_TEX_SIZE) * y_stretch),
-				   0.5);
-			glEnd();
-		    }
-		}
-		
-		upload_surface_to_tex_memory_release();
-		d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, ((dwFlags & DDBLT_KEYSRC) != 0));
-		
-		if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) ||
-		    ((buffer_type == WINE_GL_BUFFER_BACK)  && (prev_draw == GL_FRONT)))
-		    glDrawBuffer(prev_draw);
-		
-		LEAVE_GL();
-
-		return DD_OK;		
-	    }
-	}
-    }
-    return DDERR_INVALIDPARAMS;
-}
-
-HRESULT
-d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
-		  DWORD dsty, LPDIRECTDRAWSURFACE7 src,
-		  LPRECT rsrc, DWORD trans)
-{
-    RECT rsrc2;
-    RECT rdst;
-    IDirectDrawSurfaceImpl *src_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
-    IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice;
-    WINE_GL_BUFFER_TYPE buffer_type;
-    GLint prev_draw;
-    DWORD opt_bitmap;
-    BOOLEAN initial;
-    int width, height, x, y;
-    
-    /* Cannot support DSTCOLORKEY blitting... */
-    if ((trans & DDBLTFAST_DESTCOLORKEY) != 0) return DDERR_INVALIDPARAMS;
-
-    if (rsrc == NULL) {
-	WARN("rsrc is NULL - getting the whole surface !!\n");
-	rsrc = &rsrc2;
-	rsrc->left = rsrc->top = 0;
-	rsrc->right = src_impl->surface_desc.dwWidth;
-	rsrc->bottom = src_impl->surface_desc.dwHeight;
-    } else {
-	rsrc2 = *rsrc;
-	rsrc = &rsrc2;
-    }
-
-    rdst.left = dstx;
-    rdst.top = dsty;
-    rdst.right = dstx + (rsrc->right - rsrc->left);
-    if (rdst.right > This->surface_desc.dwWidth) {
-	rsrc->right -= (This->surface_desc.dwWidth - rdst.right);
-	rdst.right = This->surface_desc.dwWidth;
-    }
-    rdst.bottom = dsty + (rsrc->bottom - rsrc->top);
-    if (rdst.bottom > This->surface_desc.dwHeight) {
-	rsrc->bottom -= (This->surface_desc.dwHeight - rdst.bottom);
-	rdst.bottom = This->surface_desc.dwHeight;
-    }
-
-    width = rsrc->right - rsrc->left;
-    height = rsrc->bottom - rsrc->top;
-    
-    if (setup_rect_and_surface_for_blt(This, &buffer_type, (D3DRECT *) &rdst) != DD_OK) return DDERR_INVALIDPARAMS;
-
-    TRACE(" using BltFast memory to frame buffer override.\n");
-    
-    ENTER_GL();
-    
-    opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, &rdst, (trans & DDBLTFAST_SRCCOLORKEY) != 0, &initial);
-    
-    if (upload_surface_to_tex_memory_init(src_impl, 0, &gl_d3d_dev->current_internal_format,
-					  initial, (trans & DDBLTFAST_SRCCOLORKEY) != 0,
-					  UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) {
-	ERR(" unsupported pixel format at memory to buffer Blt override.\n");
-	LEAVE_GL();
-	return DDERR_INVALIDPARAMS;
-    }
-    
-    glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
-    if (buffer_type == WINE_GL_BUFFER_FRONT)
-	glDrawBuffer(GL_FRONT);
-    else
-	glDrawBuffer(GL_BACK);
-    
-    /* Now the serious stuff happens. This is basically the same code that for the memory
-       flush to frame buffer but with different rectangles for source and destination :-) */
-    for (y = 0; y < height; y += UNLOCK_TEX_SIZE) {
-	RECT flush_rect;
-	
-	flush_rect.top    = rsrc->top + y;
-	flush_rect.bottom = ((rsrc->top + y + UNLOCK_TEX_SIZE > rsrc->bottom) ?
-			     rsrc->bottom :
-			     (rsrc->top + y + UNLOCK_TEX_SIZE));
-	
-	for (x = 0; x < width; x += UNLOCK_TEX_SIZE) {
-	    flush_rect.left  = rsrc->left + x;
-	    flush_rect.right = ((rsrc->left + x + UNLOCK_TEX_SIZE > rsrc->right) ?
-				rsrc->right :
-				(rsrc->left + x + UNLOCK_TEX_SIZE));
-	    
-	    upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr));
-	    
-	    glBegin(GL_QUADS);
-	    glTexCoord2f(0.0, 0.0);
-	    glVertex3d(rdst.left + x,
-		       rdst.top + y,
-		       0.5);
-	    glTexCoord2f(1.0, 0.0);
-	    glVertex3d(rdst.left + (x + UNLOCK_TEX_SIZE),
-		       rdst.top + y,
-		       0.5);
-	    glTexCoord2f(1.0, 1.0);
-	    glVertex3d(rdst.left + (x + UNLOCK_TEX_SIZE),
-		       rdst.top + (y + UNLOCK_TEX_SIZE),
-		       0.5);
-	    glTexCoord2f(0.0, 1.0);
-	    glVertex3d(rdst.left + x,
-		       rdst.top + (y + UNLOCK_TEX_SIZE),
-		       0.5);
-	    glEnd();
-	}
-    }
-    
-    upload_surface_to_tex_memory_release();
-    d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, (trans & DDBLTFAST_SRCCOLORKEY) != 0);
-    
-    if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) ||
-	((buffer_type == WINE_GL_BUFFER_BACK)  && (prev_draw == GL_FRONT)))
-	glDrawBuffer(prev_draw);
-    
-    LEAVE_GL();
-    
-    return DD_OK;
-}
-
-void
-d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
-{
-    GLfloat height, width;
-    GLfloat trans_mat[16];
-
-    TRACE("(%p)\n", This);
-    
-    width = This->surface->surface_desc.dwWidth;
-    height = This->surface->surface_desc.dwHeight;
-    
-    /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
-     * to OpenGL screen coordinates (ie the upper left corner is not the same).
-     */
-    trans_mat[ 0] = 2.0 / width;  trans_mat[ 4] = 0.0;           trans_mat[ 8] = 0.0;    trans_mat[12] = -1.0;
-    trans_mat[ 1] = 0.0;          trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0;    trans_mat[13] =  1.0;
-#if 0
-    /* It has been checked that in Messiah, which mixes XYZ and XYZRHZ vertex format in the same scene,
-     * that the Z coordinate needs to be given to GL unchanged.
-     */
-    trans_mat[ 2] = 0.0;          trans_mat[ 6] = 0.0;           trans_mat[10] = 2.0;    trans_mat[14] = -1.0;
-#endif
-    trans_mat[ 2] = 0.0;          trans_mat[ 6] = 0.0;           trans_mat[10] = 1.0;    trans_mat[14] =  0.0;
-    trans_mat[ 3] = 0.0;          trans_mat[ 7] = 0.0;           trans_mat[11] = 0.0;    trans_mat[15] =  1.0;
-    
-    ENTER_GL();
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    /* See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
-       Correctness Tips section).
-       
-       Basically, from what I understood, if the game does not filter the font texture,
-       as the 'real' pixel will lie at the middle of the two texels, OpenGL may choose the wrong
-       one and we will have strange artifacts (as the rounding and stuff may give different results
-       for different pixels, ie sometimes take the left pixel, sometimes the right).
-    */
-    glTranslatef(0.375, 0.375, 0);
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf(trans_mat);
-    LEAVE_GL();
-}
-
-void
-d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
-		       D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
-{
-    TRACE("(%p,%08lx,%p,%p,%p)\n", This, matrices, world_mat, view_mat, proj_mat);
-    
-    ENTER_GL();
-    if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
-        glMatrixMode(GL_MODELVIEW);
-	glLoadMatrixf((float *) view_mat);
-
-	/* Now also re-loads all the Lights and Clipping Planes using the new matrices */
-	if (This->state_block.render_state[D3DRENDERSTATE_CLIPPING - 1] != FALSE) {
-	    GLint i;
-	    DWORD runner;
-	    for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner <<= 1) {
-	        if (runner & This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) {
-		    GLdouble plane[4];
-
-		    plane[0] = This->clipping_planes[i].plane[0];
-		    plane[1] = This->clipping_planes[i].plane[1];
-		    plane[2] = This->clipping_planes[i].plane[2];
-		    plane[3] = This->clipping_planes[i].plane[3];
-		    
-		    glClipPlane( GL_CLIP_PLANE0 + i, (const GLdouble*) (&plane) );
-		}
-	    }
-	}
-	if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] != FALSE) {
-	    GLint i;
-
-            for (i = 0; i < This->max_active_lights; i++ )
-            {
-                DWORD dwLightIndex = This->active_lights[i];
-                if (dwLightIndex != ~0)
-                {
-                    LPD3DLIGHT7 pLight = &This->light_parameters[dwLightIndex];
-                    switch (pLight->dltType)
-                    {
-		        case D3DLIGHT_DIRECTIONAL: {
-			    float direction[4];
-			    float cut_off = 180.0;
-			    
-			    glLightfv(GL_LIGHT0 + i, GL_AMBIENT,  (float *) &pLight->dcvAmbient);
-			    glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  (float *) &pLight->dcvDiffuse);
-			    glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular);
-			    glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off);
-			    
-			    direction[0] = pLight->dvDirection.u1.x;
-			    direction[1] = pLight->dvDirection.u2.y;
-			    direction[2] = pLight->dvDirection.u3.z;
-			    direction[3] = 0.0;
-			    glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) direction);
-			} break;
-
-			case D3DLIGHT_POINT: {
-			    float position[4];
-			    float cut_off = 180.0;
-			    
-			    glLightfv(GL_LIGHT0 + i, GL_AMBIENT,  (float *) &pLight->dcvAmbient);
-			    glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  (float *) &pLight->dcvDiffuse);
-			    glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular);
-			    position[0] = pLight->dvPosition.u1.x;
-			    position[1] = pLight->dvPosition.u2.y;
-			    position[2] = pLight->dvPosition.u3.z;
-			    position[3] = 1.0;
-			    glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) position);
-			    glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &pLight->dvAttenuation0);
-			    glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &pLight->dvAttenuation1);
-			    glLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &pLight->dvAttenuation2);
-			    glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off);
-			} break;
-
-			case D3DLIGHT_SPOT: {
-			    float direction[4];
-			    float position[4];
-			    float cut_off = 90.0 * (This->light_parameters[i].dvPhi / M_PI);
-			    
-			    glLightfv(GL_LIGHT0 + i, GL_AMBIENT,  (float *) &pLight->dcvAmbient);
-			    glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  (float *) &pLight->dcvDiffuse);
-			    glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular);
-			    
-			    direction[0] = pLight->dvDirection.u1.x;
-			    direction[1] = pLight->dvDirection.u2.y;
-			    direction[2] = pLight->dvDirection.u3.z;
-			    direction[3] = 0.0;
-			    glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, (float *) direction);
-			    position[0] = pLight->dvPosition.u1.x;
-			    position[1] = pLight->dvPosition.u2.y;
-			    position[2] = pLight->dvPosition.u3.z;
-			    position[3] = 1.0;
-			    glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) position);
-			    glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &pLight->dvAttenuation0);
-			    glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &pLight->dvAttenuation1);
-			    glLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &pLight->dvAttenuation2);
-			    glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off);
-			    glLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &pLight->dvFalloff);
-			} break;
-
-			default:
-			    /* No warning here as it's already done at light setting */
-			    break;
-		    }
-		}
-	    }
-        }
-	
-	glMultMatrixf((float *) world_mat);
-    }
-    if ((matrices & PROJMAT_CHANGED) != 0) {
-	glMatrixMode(GL_PROJECTION);
-	glLoadMatrixf((float *) proj_mat);
-    }
-    LEAVE_GL();
-}
-
-void
-d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
-{
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    DWORD tex_mat, tex_stage;
-
-    TRACE("(%p,%08lx)\n", This, matrices);
-    
-    if (matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED)) {
-        if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
-	    /* This will force an update of the transform state at the next drawing. */
-	    glThis->transform_state = GL_TRANSFORM_NONE;
-	}
-    }
-    if (matrices & (TEXMAT0_CHANGED|TEXMAT1_CHANGED|TEXMAT2_CHANGED|TEXMAT3_CHANGED|
-		    TEXMAT4_CHANGED|TEXMAT5_CHANGED|TEXMAT6_CHANGED|TEXMAT7_CHANGED))
-    {
-        ENTER_GL();
-	for (tex_mat = TEXMAT0_CHANGED, tex_stage = 0; tex_mat <= TEXMAT7_CHANGED; tex_mat <<= 1, tex_stage++) {
-	    GLenum unit = GL_TEXTURE0_WINE + tex_stage;
-	    if (matrices & tex_mat) {
-	        if (This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXTURETRANSFORMFLAGS - 1] != D3DTTFF_DISABLE) {
-		    int is_identity = (memcmp(This->tex_mat[tex_stage], id_mat, 16 * sizeof(D3DVALUE)) != 0);
-
-		    if (This->tex_mat_is_identity[tex_stage] != is_identity) {
-			if (glThis->current_active_tex_unit != unit) {
-			    GL_extensions.glActiveTexture(unit);
-			    glThis->current_active_tex_unit = unit;
-			}
-			glMatrixMode(GL_TEXTURE);
-			glLoadMatrixf((float *) This->tex_mat[tex_stage]);
-		    }
-		    This->tex_mat_is_identity[tex_stage] = is_identity;
-		} else {
-		    if (This->tex_mat_is_identity[tex_stage] == FALSE) {
-			if (glThis->current_active_tex_unit != unit) {
-			    GL_extensions.glActiveTexture(unit);
-			    glThis->current_active_tex_unit = unit;
-			}
-			glMatrixMode(GL_TEXTURE);
-			glLoadIdentity();
-			This->tex_mat_is_identity[tex_stage] = TRUE;
-		    }
-		}
-	    }
-	}
-	LEAVE_GL();
-    }
-}
-
-/* TODO for both these functions :
-    - change / restore OpenGL parameters for pictures transfers in case they are ever modified
-      by other OpenGL code in D3D
-    - handle the case where no 'Begin / EndScene' was done between two locks
-    - handle the rectangles in the unlock too
-    - handle pitch correctly...
-*/
-static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
-{
-    IDirect3DDeviceImpl *d3d_dev = This->d3ddevice;
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-    WINE_GL_BUFFER_TYPE buffer_type;
-    RECT loc_rect;
-    
-    if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
-        buffer_type = WINE_GL_BUFFER_FRONT;
-	if ((gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] != SURFACE_GL) &&
-	    (gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] != This)) {
-	    ERR("Change of front buffer.. Expect graphic corruptions !\n");
-	}
-	gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] = This;
-    } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
-        buffer_type = WINE_GL_BUFFER_BACK;
-	if ((gl_d3d_dev->state[WINE_GL_BUFFER_BACK] != SURFACE_GL) &&
-	    (gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] != This)) {
-	    ERR("Change of back buffer.. Expect graphic corruptions !\n");
-	}
-	gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] = This;
-    } else {
-        ERR("Wrong surface type for locking !\n");
-	return;
-    }
-
-    if (pRect == NULL) {
-	loc_rect.top = 0;
-	loc_rect.left = 0;
-	loc_rect.bottom = This->surface_desc.dwHeight;
-	loc_rect.right = This->surface_desc.dwWidth;
-	pRect = &loc_rect;
-    }
-    
-    /* Try to acquire the device critical section */
-    EnterCriticalSection(&(d3d_dev->crit));
-    
-    if (gl_d3d_dev->lock_rect_valid[buffer_type]) {
-	ERR("Two consecutive locks on %s buffer... Expect problems !\n",
-	    (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"));
-    }
-    gl_d3d_dev->lock_rect_valid[buffer_type] = TRUE;
-    
-    if (gl_d3d_dev->state[buffer_type] != SURFACE_GL) {
-	/* Check if the new rectangle is in the previous one or not.
-	   If it is not, flush first the previous locks on screen.
-	*/
-	if ((pRect->top    < gl_d3d_dev->lock_rect[buffer_type].top) ||
-	    (pRect->left   < gl_d3d_dev->lock_rect[buffer_type].left) ||
-	    (pRect->right  > gl_d3d_dev->lock_rect[buffer_type].right) ||
-	    (pRect->bottom > gl_d3d_dev->lock_rect[buffer_type].bottom)) {
-	    if (gl_d3d_dev->state[buffer_type] == SURFACE_MEMORY_DIRTY) {
-		TRACE(" flushing back to %s buffer as new rect : (%ldx%ld) - (%ldx%ld) not included in old rect : (%ldx%ld) - (%ldx%ld)\n",
-		      (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"),
-		      pRect->left, pRect->top, pRect->right, pRect->bottom,
-		      gl_d3d_dev->lock_rect[buffer_type].left, gl_d3d_dev->lock_rect[buffer_type].top,
-		      gl_d3d_dev->lock_rect[buffer_type].right, gl_d3d_dev->lock_rect[buffer_type].bottom);
-		d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[buffer_type]), gl_d3d_dev->lock_surf[buffer_type]);
-	    }
-	    gl_d3d_dev->state[buffer_type] = SURFACE_GL;
-	    gl_d3d_dev->lock_rect[buffer_type] = *pRect;
-	}
-	/* In the other case, do not upgrade the locking rectangle as it's no need... */
-    } else {
-	gl_d3d_dev->lock_rect[buffer_type] = *pRect;
-    }
-    
-    if (gl_d3d_dev->state[buffer_type] == SURFACE_GL) {
-        /* If the surface is already in memory, no need to do anything here... */
-        GLenum buffer_format;
-	GLenum buffer_color;
-	int y;
-	char *dst;
-
-	TRACE(" copying %s buffer to main memory with rectangle (%ldx%ld) - (%ldx%ld).\n", (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"),
-	      pRect->left, pRect->top, pRect->right, pRect->bottom);
-	
-	/* Note that here we cannot do 'optmizations' about the WriteOnly flag... Indeed, a game
-	   may only write to the device... But when we will blit it back to the screen, we need
-	   also to blit correctly the parts the application did not overwrite... */
-
-	if (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) != 0) &&
-	    (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) == 0) ||
-	     (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000))) {
-	    if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) &&
-		(This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
-		(This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
-		(This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F)) {
-		buffer_format = GL_UNSIGNED_SHORT_5_6_5;
-		buffer_color = GL_RGB;
-	    } else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 24) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xFF0000) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x00FF00) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x0000FF)) {
-		buffer_format = GL_UNSIGNED_BYTE;
-		buffer_color = GL_RGB;
-	    } else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
-		       (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF)) {
-		buffer_format = GL_UNSIGNED_INT_8_8_8_8_REV;
-		buffer_color = GL_BGRA;
-	    } else {
-		ERR(" unsupported pixel format at device locking.\n");
-		return;
-	    }
-	} else {
-	    ERR(" unsupported pixel format at device locking - alpha on frame buffer.\n");
-	    return;
-	}
-
-	ENTER_GL();
-	
-	if (buffer_type == WINE_GL_BUFFER_FRONT)
-	    /* Application wants to lock the front buffer */
-	    glReadBuffer(GL_FRONT);
-	else 
-	    /* Application wants to lock the back buffer */
-	    glReadBuffer(GL_BACK);
-
-	dst = ((char *)This->surface_desc.lpSurface) +
-	  (pRect->top * This->surface_desc.u1.lPitch) + (pRect->left * GET_BPP(This->surface_desc));
-
-	if (This->surface_desc.u1.lPitch != (GET_BPP(This->surface_desc) * This->surface_desc.dwWidth)) {
-	    /* Slow-path in case of 'odd' surfaces. This could be fixed using some GL options, but I
-	     * could not be bothered considering the rare cases where it may be useful :-)
-	     */
-	    for (y = (This->surface_desc.dwHeight - pRect->top - 1);
-		 y >= ((int) This->surface_desc.dwHeight - (int) pRect->bottom);
-		 y--) {
-		glReadPixels(pRect->left, y,
-			     pRect->right - pRect->left, 1,
-			     buffer_color, buffer_format, dst);
-		dst += This->surface_desc.u1.lPitch;
-	    }
-	} else {
-	    /* Faster path for surface copy. Note that I can use static variables here as I am
-	     * protected by the OpenGL critical section so this function won't be called by
-	     * two threads at the same time.
-	     */
-	    static char *buffer = NULL;
-	    static int buffer_width = 0;
-	    char *dst2 = dst + ((pRect->bottom - pRect->top) - 1) * This->surface_desc.u1.lPitch;
-	    int current_width = (pRect->right - pRect->left) * GET_BPP(This->surface_desc);
-	    
-	    glReadPixels(pRect->left, ((int) This->surface_desc.dwHeight - (int) pRect->bottom),
-			 pRect->right - pRect->left, pRect->bottom - pRect->top,
-			 buffer_color, buffer_format, dst);
-
-	    if (current_width > buffer_width) {
-                HeapFree(GetProcessHeap(), 0, buffer);
-		buffer_width = current_width;
-		buffer = HeapAlloc(GetProcessHeap(), 0, buffer_width);
-	    }
-	    for (y = 0; y < ((pRect->bottom - pRect->top) / 2); y++) {
-		memcpy(buffer, dst, current_width);
-		memcpy(dst, dst2, current_width);
-		memcpy(dst2, buffer, current_width);
-		dst  += This->surface_desc.u1.lPitch;
-		dst2 -= This->surface_desc.u1.lPitch;
-	    }
-	}
-
-	gl_d3d_dev->state[buffer_type] = SURFACE_MEMORY;
-	
-#if 0
-	/* I keep this code here as it's very useful to debug :-) */
-	{
-	    static int flush_count = 0;
-	    char buf[128];
-	    FILE *f;
-	    
-	    if ((++flush_count % 50) == 0) {
-	        sprintf(buf, "lock_%06d.pnm", flush_count);
-		f = fopen(buf, "wb");
-		DDRAW_dump_surface_to_disk(This, f);
-	    }
-	}
-#endif
-	
-	LEAVE_GL();
-    }
-}
-
-static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, IDirectDrawSurfaceImpl *surf) {
-    RECT loc_rect;
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-    int x, y;
-    BOOLEAN initial;
-    DWORD opt_bitmap;
-    
-    /* Note : no need here to lock the 'device critical section' as we are already protected by
-       the GL critical section. */
-
-    if (pRect == NULL) {
-	loc_rect.top = 0;
-	loc_rect.left = 0;
-	loc_rect.bottom = d3d_dev->surface->surface_desc.dwHeight;
-	loc_rect.right = d3d_dev->surface->surface_desc.dwWidth;
-	pRect = &loc_rect;
-    }
-    
-    TRACE(" flushing memory back to screen memory (%ld,%ld) x (%ld,%ld).\n", pRect->top, pRect->left, pRect->right, pRect->bottom);
-
-    opt_bitmap = d3ddevice_set_state_for_flush(d3d_dev, pRect, FALSE, &initial);
-    
-    if (upload_surface_to_tex_memory_init(surf, 0, &gl_d3d_dev->current_internal_format,
-					  initial, FALSE, UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) {
-        ERR(" unsupported pixel format at frame buffer flush.\n");
-	return;
-    }
-	
-    for (y = pRect->top; y < pRect->bottom; y += UNLOCK_TEX_SIZE) {
-	RECT flush_rect;
-	
-	flush_rect.top = y;
-	flush_rect.bottom = (y + UNLOCK_TEX_SIZE > pRect->bottom) ? pRect->bottom : (y + UNLOCK_TEX_SIZE);
-
-	for (x = pRect->left; x < pRect->right; x += UNLOCK_TEX_SIZE) {
-	    /* First, upload the texture... */
-	    flush_rect.left = x;
-	    flush_rect.right = (x + UNLOCK_TEX_SIZE > pRect->right)  ? pRect->right  : (x + UNLOCK_TEX_SIZE);
-
-	    upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr));
-
-	    glBegin(GL_QUADS);
-	    glTexCoord2f(0.0, 0.0);
-	    glVertex3d(x, y, 0.5);
-	    glTexCoord2f(1.0, 0.0);
-	    glVertex3d(x + UNLOCK_TEX_SIZE, y, 0.5);
-	    glTexCoord2f(1.0, 1.0);
-	    glVertex3d(x + UNLOCK_TEX_SIZE, y + UNLOCK_TEX_SIZE, 0.5);
-	    glTexCoord2f(0.0, 1.0);
-	    glVertex3d(x, y + UNLOCK_TEX_SIZE, 0.5);
-	    glEnd();
-	}
-    }
-    
-    upload_surface_to_tex_memory_release();
-    d3ddevice_restore_state_after_flush(d3d_dev, opt_bitmap, FALSE);
-    
-#if 0
-    /* I keep this code here as it's very useful to debug :-) */
-    {
-        static int flush_count = 0;
-	char buf[128];
-	FILE *f;
-
-	if ((++flush_count % 50) == 0) {
-	    sprintf(buf, "flush_%06d.pnm", flush_count);
-	    f = fopen(buf, "wb");
-	    DDRAW_dump_surface_to_disk(surf, f);
-	}
-    }
-#endif
-}
-
-static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
-{
-    WINE_GL_BUFFER_TYPE buffer_type;
-    IDirect3DDeviceImpl *d3d_dev = This->d3ddevice;
-    IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-  
-    if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
-        buffer_type = WINE_GL_BUFFER_FRONT;
-    } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
-	buffer_type = WINE_GL_BUFFER_BACK;
-    } else {
-        ERR("Wrong surface type for locking !\n");
-	return;
-    }
-
-    if (gl_d3d_dev->lock_rect_valid[buffer_type] == FALSE) {
-	ERR("Unlock without prior lock on %s buffer... Expect problems !\n",
-	    (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"));
-    }
-    gl_d3d_dev->lock_rect_valid[buffer_type] = FALSE;
-    
-    /* First, check if we need to do anything. For the backbuffer, flushing is done at the next 3D activity. */
-    if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
-        if (buffer_type == WINE_GL_BUFFER_FRONT) {
-	    GLint prev_draw;
-
-	    TRACE(" flushing front buffer immediately on screen.\n");
-	    
-	    ENTER_GL();
-	    glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
-	    glDrawBuffer(GL_FRONT);
-	    /* Note: we do not use the application provided lock rectangle but our own stored at
-	             lock time. This is because in old D3D versions, the 'lock' parameter did not
-		     exist.
-	    */
-	    d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_FRONT]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT]);
-	    glDrawBuffer(prev_draw);
-	    LEAVE_GL();
-	} else {
-	    gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_MEMORY_DIRTY;
-	}
-    }
-
-    /* And 'frees' the device critical section */
-    LeaveCriticalSection(&(d3d_dev->crit));
-}
-
-static void
-apply_texture_state(IDirect3DDeviceImpl *This)
-{
-    int stage, state;
-    
-    /* Initialize texture stages states */
-    for (stage = 0; stage < MAX_TEXTURES; stage++) {
-       for (state = 0; state < HIGHEST_TEXTURE_STAGE_STATE; state += 1) {
-	   if (This->state_block.set_flags.texture_stage_state[stage][state]) {
-	       IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
-						     stage, state + 1, This->state_block.texture_stage_state[stage][state]);
-	   }
-       }
-    }
-}     
-
-HRESULT
-d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version)
-{
-    IDirect3DDeviceImpl *object;
-    IDirect3DDeviceGLImpl *gl_object;
-    IDirectDrawSurfaceImpl *surf;
-    HDC device_context;
-    XVisualInfo *vis;
-    int num;
-    int tex_num;
-    XVisualInfo template;
-    GLenum buffer = GL_FRONT;
-    int light;
-    
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
-
-    gl_object = (IDirect3DDeviceGLImpl *) object;
-    
-    object->ref = 1;
-    object->d3d = d3d;
-    object->surface = surface;
-    object->set_context = set_context;
-    object->clear = d3ddevice_clear_back;
-    object->set_matrices = d3ddevice_set_matrices;
-    object->matrices_updated = d3ddevice_matrices_updated;
-    object->flush_to_framebuffer = d3ddevice_flush_to_frame_buffer;
-    object->version = version;
-    
-    TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
-
-    InitializeCriticalSection(&(object->crit));
-
-    TRACE(" device critical section : %p\n", &(object->crit));
-
-    device_context = GetDC(surface->ddraw_owner->window);
-    gl_object->display = get_display(device_context);
-    gl_object->drawable = get_drawable(device_context);
-    ReleaseDC(surface->ddraw_owner->window,device_context);
-
-    ENTER_GL();
-    template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
-    vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
-    if (vis == NULL) {
-        HeapFree(GetProcessHeap(), 0, object);
-        ERR("No visual found !\n");
-	LEAVE_GL();
-	return DDERR_INVALIDPARAMS;
-    } else {
-        TRACE(" visual found\n");
-    }
-
-    gl_object->gl_context = glXCreateContext(gl_object->display, vis,
-					     NULL, GL_TRUE);
-
-    if (gl_object->gl_context == NULL) {
-        HeapFree(GetProcessHeap(), 0, object);
-        ERR("Error in context creation !\n");
-	LEAVE_GL();
-	return DDERR_INVALIDPARAMS;
-    } else {
-        TRACE(" context created (%p)\n", gl_object->gl_context);
-    }
-    
-    /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
-    for (surf = surface; surf != NULL; surf = surf->surface_owner) {
-        if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
-            surf->aux_ctx  = (LPVOID) object;
-            surf->aux_data = (LPVOID) gl_object->drawable;
-            surf->aux_flip = opengl_flip;
-	    buffer =  GL_BACK;
-            break;
-        }
-    }
-    /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
-    if (surf == NULL) {
-        TRACE(" no double buffering : drawing on the front buffer\n");
-        buffer = GL_FRONT;
-    }
-    
-    for (surf = surface; surf != NULL; surf = surf->surface_owner) {
-        IDirectDrawSurfaceImpl *surf2;
-	for (surf2 = surf; surf2->prev_attached != NULL; surf2 = surf2->prev_attached) ;
-	for (; surf2 != NULL; surf2 = surf2->next_attached) {
-	    TRACE(" checking surface %p :", surf2);
-	    if (((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
-		((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
-	        /* Override the Lock / Unlock function for all these surfaces */
-	        surf2->lock_update_prev = surf2->lock_update;
-	        surf2->lock_update = d3ddevice_lock_update;
-		surf2->unlock_update_prev = surf2->unlock_update;
-		surf2->unlock_update = d3ddevice_unlock_update;
-		/* And install also the blt / bltfast overrides */
-		surf2->aux_blt = d3ddevice_blt;
-		surf2->aux_bltfast = d3ddevice_bltfast;
-		
-		TRACE(" overriding direct surface access.\n");
-	    } else {
-	        TRACE(" no override.\n");
-	    }
-	    surf2->d3ddevice = object;
-	}
-    }
-
-    /* Set the various light parameters */
-    object->num_set_lights = 0;
-    object->max_active_lights = opengl_device_caps.dwMaxActiveLights;
-    object->light_parameters = NULL;
-    object->active_lights = HeapAlloc(GetProcessHeap(), 0,
-        object->max_active_lights * sizeof(object->active_lights[0]));
-    /* Fill the active light array with ~0, which is used to indicate an
-       invalid light index. We don't use 0, because it's a valid light index. */
-    for (light=0; light < object->max_active_lights; light++)
-        object->active_lights[light] = ~0;
-
-    
-    /* Allocate memory for the matrices */
-    object->world_mat = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-    object->view_mat  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-    object->proj_mat  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-    memcpy(object->world_mat, id_mat, 16 * sizeof(float));
-    memcpy(object->view_mat , id_mat, 16 * sizeof(float));
-    memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
-    for (tex_num = 0; tex_num < MAX_TEXTURES; tex_num++) {
-        object->tex_mat[tex_num] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-	memcpy(object->tex_mat[tex_num], id_mat, 16 * sizeof(float));
-	object->tex_mat_is_identity[tex_num] = TRUE;
-    }
-    
-    /* Initialisation */
-    TRACE(" setting current context\n");
-    object->set_context(object);
-    TRACE(" current context set\n");
-
-    /* allocate the clipping planes */
-    object->max_clipping_planes = opengl_device_caps.wMaxUserClipPlanes;
-    object->clipping_planes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
-
-    glHint(GL_FOG_HINT,GL_NICEST);
-
-    /* Initialize the various GL contexts to be in sync with what we store locally */
-    glClearDepth(0.0);
-    glClearStencil(0);
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glDepthMask(GL_TRUE);
-    gl_object->depth_mask = TRUE;
-    glEnable(GL_DEPTH_TEST);
-    gl_object->depth_test = TRUE;
-    glDisable(GL_ALPHA_TEST);
-    glDisable(GL_STENCIL_TEST);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_LIGHTING);
-    glDisable(GL_BLEND);
-    glDisable(GL_FOG);
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    gl_object->current_tex_env = GL_REPLACE;
-    gl_object->current_active_tex_unit = GL_TEXTURE0_WINE;
-    if (GL_extensions.glActiveTexture != NULL) {
-	GL_extensions.glActiveTexture(GL_TEXTURE0_WINE);
-    }
-    gl_object->current_alpha_test_ref = 0.0;
-    gl_object->current_alpha_test_func = GL_ALWAYS;
-    glAlphaFunc(GL_ALWAYS, 0.0);
-    
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-    glDrawBuffer(buffer);
-    glReadBuffer(buffer);
-    /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
-    LEAVE_GL();
-
-    gl_object->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
-    gl_object->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL;
-    
-    /* fill_device_capabilities(d3d->ddraw); */    
-    
-    ICOM_INIT_INTERFACE(object, IDirect3DDevice,  VTABLE_IDirect3DDevice);
-    ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
-    ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
-    ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
-
-    *obj = object;
-
-    TRACE(" creating implementation at %p.\n", *obj);
-
-    /* And finally warn D3D that this device is now present */
-    object->d3d->d3d_added_device(object->d3d, object);
-
-    InitDefaultStateBlock(&object->state_block, object->version);
-    /* Apply default render state and texture stage state values */
-    apply_render_state(object, &object->state_block);
-    apply_texture_state(object);
-
-    /* And fill the fog table with the default fog value */
-    build_fog_table(gl_object->fog_table, object->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]);
-    
-    return DD_OK;
-}
-
-static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
-{
-    pc->dwSize = sizeof(*pc);
-    pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
-      D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKPLANES | D3DPMISCCAPS_MASKZ;
-    pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
-      D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL |
-	  D3DPRASTERCAPS_ZFOG;
-    if (GL_extensions.mipmap_lodbias) {
-	pc->dwRasterCaps |= D3DPRASTERCAPS_MIPMAPLODBIAS;
-    }
-    pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
-      D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
-    pc->dwSrcBlendCaps  = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
-      D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
-	D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
-    pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
-      D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
-	D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
-    pc->dwAlphaCmpCaps  = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
-      D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
-    pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
-      D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
-    pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
-      D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
-    pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
-      D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST | D3DPTFILTERCAPS_MAGFLINEAR |
-	  D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MIPFLINEAR |
-	      D3DPTFILTERCAPS_MIPFPOINT;
-    pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
-      D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
-    pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
-    if (GL_extensions.mirrored_repeat) {
-	pc->dwTextureAddressCaps |= D3DPTADDRESSCAPS_MIRROR;
-    }
-    pc->dwStippleWidth = 32;
-    pc->dwStippleHeight = 32;
-}
-
-static void fill_caps(void)
-{
-    GLint max_clip_planes;
-    GLint depth_bits;
-    
-    /* Fill first all the fields with default values which will be overriden later on with
-       correct ones from the GL code
-    */
-    opengl_device_caps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
-      D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
-      D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
-      /* D3D 7 capabilities */
-      D3DDEVCAPS_DRAWPRIMITIVES2 /*| D3DDEVCAPS_HWTRANSFORMANDLIGHT*/ | D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_DRAWPRIMITIVES2EX;
-    fill_opengl_primcaps(&(opengl_device_caps.dpcLineCaps));
-    fill_opengl_primcaps(&(opengl_device_caps.dpcTriCaps));
-    opengl_device_caps.dwDeviceRenderBitDepth  = DDBD_16|DDBD_24|DDBD_32;
-    opengl_device_caps.dwMinTextureWidth  = 1;
-    opengl_device_caps.dwMinTextureHeight = 1;
-    opengl_device_caps.dwMaxTextureWidth  = 1024;
-    opengl_device_caps.dwMaxTextureHeight = 1024;
-    opengl_device_caps.dwMaxTextureRepeat = 16;
-    opengl_device_caps.dwMaxTextureAspectRatio = 1024;
-    opengl_device_caps.dwMaxAnisotropy = 0;
-    opengl_device_caps.dvGuardBandLeft = 0.0;
-    opengl_device_caps.dvGuardBandRight = 0.0;
-    opengl_device_caps.dvGuardBandTop = 0.0;
-    opengl_device_caps.dvGuardBandBottom = 0.0;
-    opengl_device_caps.dvExtentsAdjust = 0.0;
-    opengl_device_caps.dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
-      D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
-    opengl_device_caps.dwTextureOpCaps = D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | D3DTEXOPCAPS_MODULATE4X |
-	D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_ADDSIGNED2X | D3DTEXOPCAPS_ADDSIGNED |
-	    D3DTEXOPCAPS_BLENDDIFFUSEALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHA | D3DTEXOPCAPS_BLENDFACTORALPHA | D3DTEXOPCAPS_BLENDCURRENTALPHA;
-    if (GL_extensions.max_texture_units != 0) {
-	opengl_device_caps.wMaxTextureBlendStages = GL_extensions.max_texture_units;
-	opengl_device_caps.wMaxSimultaneousTextures = GL_extensions.max_texture_units;
-	opengl_device_caps.dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | GL_extensions.max_texture_units;
-    } else {
-	opengl_device_caps.wMaxTextureBlendStages = 1;
-	opengl_device_caps.wMaxSimultaneousTextures = 1;
-	opengl_device_caps.dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
-    }
-    opengl_device_caps.dwMaxActiveLights = 16;
-    opengl_device_caps.dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
-    opengl_device_caps.deviceGUID = IID_IDirect3DTnLHalDevice;
-    opengl_device_caps.wMaxUserClipPlanes = 1;
-    opengl_device_caps.wMaxVertexBlendMatrices = 0;
-    opengl_device_caps.dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG |
-	D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
-    opengl_device_caps.dwReserved1 = 0;
-    opengl_device_caps.dwReserved2 = 0;
-    opengl_device_caps.dwReserved3 = 0;
-    opengl_device_caps.dwReserved4 = 0;
-
-    /* And now some GL overrides :-) */
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *) &opengl_device_caps.dwMaxTextureWidth);
-    opengl_device_caps.dwMaxTextureHeight = opengl_device_caps.dwMaxTextureWidth;
-    opengl_device_caps.dwMaxTextureAspectRatio = opengl_device_caps.dwMaxTextureWidth;
-    TRACE(": max texture size = %ld\n", opengl_device_caps.dwMaxTextureWidth);
-    
-    glGetIntegerv(GL_MAX_LIGHTS, (GLint *) &opengl_device_caps.dwMaxActiveLights);
-    TRACE(": max active lights = %ld\n", opengl_device_caps.dwMaxActiveLights);
-
-    glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
-    opengl_device_caps.wMaxUserClipPlanes = max_clip_planes;
-    TRACE(": max clipping planes = %d\n", opengl_device_caps.wMaxUserClipPlanes);
-
-    glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
-    TRACE(": Z bits = %d\n", depth_bits);
-    switch (depth_bits) {
-        case 16: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16; break;
-        case 24: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24; break;
-        case 32:
-        default: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32; break;
-    }
-}
-
-BOOL
-d3ddevice_init_at_startup(void *gl_handle)
-{
-    XVisualInfo template;
-    XVisualInfo *vis;
-    HDC device_context;
-    Display *display;
-    Visual *visual;
-    Drawable drawable = (Drawable) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
-    XWindowAttributes win_attr;
-    GLXContext gl_context;
-    int num;
-    const char *glExtensions;
-    const char *glVersion;
-    const char *glXExtensions = NULL;
-    const void *(*pglXGetProcAddressARB)(const GLubyte *) = NULL;
-    int major, minor, patch, num_parsed;
-    
-    TRACE("Initializing GL...\n");
-
-    if (!drawable)
-    {
-        WARN("x11drv not loaded - D3D support disabled!\n");
-        return FALSE;
-    }
-    
-    /* Get a default rendering context to have the 'caps' function query some info from GL */    
-    device_context = GetDC(0);
-    display = get_display(device_context);
-    ReleaseDC(0, device_context);
-
-    ENTER_GL();
-    if (XGetWindowAttributes(display, drawable, &win_attr)) {
-	visual = win_attr.visual;
-    } else {
-	visual = DefaultVisual(display, DefaultScreen(display));
-    }
-    template.visualid = XVisualIDFromVisual(visual);
-    vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
-    if (vis == NULL) {
-	LEAVE_GL();
-	WARN("Error creating visual info for capabilities initialization - D3D support disabled !\n");
-	return FALSE;
-    }
-    gl_context = glXCreateContext(display, vis, NULL, GL_TRUE);
-    XFree(vis);
-
-    if (gl_context == NULL) {
-	LEAVE_GL();
-	WARN("Error creating default context for capabilities initialization - D3D support disabled !\n");
-	return FALSE;
-    }
-    if (glXMakeCurrent(display, drawable, gl_context) == False) {
-	glXDestroyContext(display, gl_context);
-	LEAVE_GL();
-	WARN("Error setting default context as current for capabilities initialization - D3D support disabled !\n");
-	return FALSE;	
-    }
-    
-    /* Then, query all extensions */
-    glXExtensions = glXQueryExtensionsString(display, DefaultScreen(display)); /* Note: not used right now but will for PBuffers */
-    glExtensions = (const char *) glGetString(GL_EXTENSIONS);
-    glVersion = (const char *) glGetString(GL_VERSION);
-    if (gl_handle != NULL) {
-	pglXGetProcAddressARB = wine_dlsym(gl_handle, "glXGetProcAddressARB", NULL, 0);
-    }
-    
-    /* Parse the GL version string */
-    num_parsed = sscanf(glVersion, "%d.%d.%d", &major, &minor, &patch);
-    if (num_parsed == 1) {
-	minor = 0;
-	patch = 0;
-    } else if (num_parsed == 2) {
-	patch = 0;
-    }
-    TRACE("GL version %d.%d.%d\n", major, minor, patch);
-
-    /* And starts to fill the extension context properly */
-    memset(&GL_extensions, 0, sizeof(GL_extensions));
-    TRACE("GL supports following extensions used by Wine :\n");
-    
-    /* Mirrored Repeat extension :
-        - GL_ARB_texture_mirrored_repeat
-	- GL_IBM_texture_mirrored_repeat
-	- GL >= 1.4
-    */
-    if ((strstr(glExtensions, "GL_ARB_texture_mirrored_repeat")) ||
-	(strstr(glExtensions, "GL_IBM_texture_mirrored_repeat")) ||
-	(major > 1) ||
-	((major == 1) && (minor >= 4))) {
-	TRACE(" - mirrored repeat\n");
-	GL_extensions.mirrored_repeat = TRUE;
-    }
-
-    /* Texture LOD Bias :
-        - GL_EXT_texture_lod_bias
-    */
-    if (strstr(glExtensions, "GL_EXT_texture_lod_bias")) {
-	TRACE(" - texture lod bias\n");
-	GL_extensions.mipmap_lodbias = TRUE;
-    }
-
-    /* For all subsequent extensions, we need glXGetProcAddress */
-    if (pglXGetProcAddressARB != NULL) {
-	/* Multi-texturing :
-	    - GL_ARB_multitexture
-	    - GL >= 1.2.1
-	*/
-	if ((strstr(glExtensions, "GL_ARB_multitexture")) ||
-	    (major > 1) ||
-	    ((major == 1) && (minor > 2)) ||
-	    ((major == 1) && (minor == 2) && (patch >= 1))) {
-	    glGetIntegerv(GL_MAX_TEXTURE_UNITS_WINE, &(GL_extensions.max_texture_units));
-	    TRACE(" - multi-texturing (%d stages)\n", GL_extensions.max_texture_units);
-	    /* We query the ARB version to be the most portable we can... */
-	    GL_extensions.glActiveTexture = pglXGetProcAddressARB( (const GLubyte *) "glActiveTextureARB");
-	    GL_extensions.glMultiTexCoord[0] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord1fvARB");
-	    GL_extensions.glMultiTexCoord[1] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord2fvARB");
-	    GL_extensions.glMultiTexCoord[2] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord3fvARB");
-	    GL_extensions.glMultiTexCoord[3] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord4fvARB");
-	    GL_extensions.glClientActiveTexture = pglXGetProcAddressARB( (const GLubyte *) "glClientActiveTextureARB");
-	} else {
-	    GL_extensions.max_texture_units = 0;
-	}
-
-	if (strstr(glExtensions, "GL_EXT_texture_compression_s3tc")) {
-	    TRACE(" - S3TC compression supported\n");
-	    GL_extensions.s3tc_compressed_texture = TRUE;
-	    GL_extensions.glCompressedTexImage2D = pglXGetProcAddressARB( (const GLubyte *) "glCompressedTexImage2DARB");
-	    GL_extensions.glCompressedTexSubImage2D = pglXGetProcAddressARB( (const GLubyte *) "glCompressedTexSubImage2DARB");
-	}
-    }
-    
-    /* Fill the D3D capabilities according to what GL tells us... */
-    fill_caps();
-
-    /* And frees this now-useless context */
-    glXMakeCurrent(display, None, NULL);
-    glXDestroyContext(display, gl_context);
-    LEAVE_GL();
-    
-    return TRUE;
-}
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
new file mode 100644
index 0000000..4691ebf
--- /dev/null
+++ b/dlls/ddraw/direct3d.c
@@ -0,0 +1,1394 @@
+/*
+ * Copyright (c) 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
+
+/*****************************************************************************
+ * IUnknown Methods. Common for Version 1, 2, 3 and 7
+ *
+ * These are thunks which relay to IDirectDraw. See ddraw.c for
+ * details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_7_QueryInterface(IDirect3D7 *iface,
+                                    REFIID refiid,
+                                    void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj);
+
+    return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7),
+                                       refiid,
+                                       obj);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_3_QueryInterface(IDirect3D3 *iface,
+                                    REFIID refiid,
+                                    void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj);
+
+    return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7),
+                                       refiid,
+                                       obj);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_QueryInterface(IDirect3D2 *iface,
+                                    REFIID refiid,
+                                    void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj);
+
+    return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7),
+                                       refiid,
+                                       obj);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_QueryInterface(IDirect3D *iface,
+                                    REFIID refiid,
+                                    void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj);
+
+    return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7),
+                                       refiid,
+                                       obj);
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_7_AddRef(IDirect3D7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7\n", This);
+
+    return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_3_AddRef(IDirect3D3 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7\n", This);
+
+    return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_2_AddRef(IDirect3D2 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7\n", This);
+
+    return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_1_AddRef(IDirect3D *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7\n", This);
+
+    return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_7_Release(IDirect3D7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7", This);
+
+    return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_3_Release(IDirect3D3 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7", This);
+
+    return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_2_Release(IDirect3D2 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7", This);
+
+    return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DImpl_1_Release(IDirect3D *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p) : Thunking to IDirectDraw7", This);
+
+    return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
+}
+
+/*****************************************************************************
+ * IDirect3D Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3D::Initialize
+ *
+ * Initializes the IDirect3D interface. This is a no-op implementation,
+ * as all initialization is done at create time.
+ *
+ * Version 1
+ *
+ * Params:
+ *  refiid: ?
+ *
+ * Returns:
+ *  D3D_OK, because it's a no-op
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_1_Initialize(IDirect3D *iface,
+                           REFIID refiid)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+
+    TRACE("(%p)->(%s) no-op...\n", This, debugstr_guid(refiid));
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3D7::EnumDevices
+ *
+ * The EnumDevices method for IDirect3D7. It enumerates all supported
+ * D3D7 devices. Currently there's only one.
+ *
+ * Params:
+ *  Callback: Function to call for each enumerated device
+ *  Context: Pointer to pass back to the app
+ *
+ * Returns:
+ *  D3D_OK, or the return value of the GetCaps call
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_7_EnumDevices(IDirect3D7 *iface,
+                          LPD3DENUMDEVICESCALLBACK7 Callback,
+                          void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    char interface_name[] = "WINE Direct3D7 using WineD3D";
+    char device_name[] = "Wine D3D7 device";
+    D3DDEVICEDESC7 ddesc;
+    D3DDEVICEDESC oldDesc;
+    HRESULT hr;
+
+    TRACE("(%p)->(%p,%p)\n", This, Callback, Context);
+
+    TRACE("(%p) Enumerating WineD3D D3Device7 interface\n", This);
+    hr = IDirect3DImpl_GetCaps(This->wineD3D, &oldDesc, &ddesc);
+    if(hr != D3D_OK) return hr;
+    Callback(interface_name, device_name, &ddesc, Context);
+
+    TRACE("(%p) End of enumeration\n", This);
+    return D3D_OK;
+}
+
+/*****************************************************************************
+ * IDirect3D3::EnumDevices
+ *
+ * Enumerates all supported Direct3DDevice interfaces. This is the
+ * implementation for Direct3D 1 to Direc3D 3, Version 7 has it's own.
+ *
+ * Version 1, 2 and 3
+ *
+ * Params:
+ *  Callback: Application-provided routine to call for each enumerated device
+ *  Context: Pointer to pass to the callback
+ *
+ * Returns:
+ *  D3D_OK on success,
+ *  The result of IDirect3DImpl_GetCaps if it failed
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_3_EnumDevices(IDirect3D3 *iface,
+                            LPD3DENUMDEVICESCALLBACK Callback,
+                            void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    D3DDEVICEDESC dref, d1, d2;
+    D3DDEVICEDESC7 newDesc;
+    HRESULT hr;
+
+    /* Some games (Motoracer 2 demo) have the bad idea to modify the device name string.
+       Let's put the string in a sufficiently sized array in writable memory. */
+    char device_name[50];
+    strcpy(device_name,"direct3d");
+
+    TRACE("(%p)->(%p,%p)\n", This, Callback, Context);
+
+    hr = IDirect3DImpl_GetCaps(This->wineD3D, &dref, &newDesc);
+    if(hr != D3D_OK) return hr;
+
+    /* Do I have to enumerate the reference id? I try without. Note from old d3d7:
+     * "It seems that enumerating the reference IID on Direct3D 1 games
+     * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1
+     *
+     * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers, EnumReference
+     * which enables / disables enumerating the reference rasterizer. It's a DWORD,
+     * 0 means disabled, 2 means enabled. The enablerefrast.reg and disablerefrast.reg
+     * files in the DirectX 7.0 sdk demo directory suggest this.
+     */
+
+    TRACE("(%p) Enumerating WineD3D D3DDevice interface\n", This);
+    d1 = dref;
+    d2 = dref;
+    Callback( (LPIID) &IID_D3DDEVICE_WineD3D, "Wine D3DDevice using WineD3D and OpenGL", device_name, &d1, &d2, Context);
+    TRACE("(%p) End of enumeration\n", This);
+    if(hr != D3DENUMRET_OK) return D3D_OK;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_EnumDevices(IDirect3D2 *iface,
+                                  LPD3DENUMDEVICESCALLBACK Callback,
+                                  void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Callback, Context);
+    return IDirect3D3_EnumDevices(ICOM_INTERFACE(This, IDirect3D3),
+                                  Callback,
+                                  Context);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_EnumDevices(IDirect3D *iface,
+                                  LPD3DENUMDEVICESCALLBACK Callback,
+                                  void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Callback, Context);
+    return IDirect3D3_EnumDevices(ICOM_INTERFACE(This, IDirect3D3),
+                                  Callback,
+                                  Context);
+}
+
+/*****************************************************************************
+ * IDirect3D3::CreateLight
+ *
+ * Creates an IDirect3DLight interface. This interface is used in
+ * Direct3D3 or earlier for lighting. In Direct3D7 it has been replaced
+ * by the DIRECT3DLIGHT7 structure. Wine's Direct3DLight implementation
+ * uses the IDirect3DDevice7 interface with D3D7 lights.
+ *
+ * Version 1, 2 and 3
+ *
+ * Params:
+ *  Light: Address to store the new interface pointer
+ *  UnkOuter: Basically for aggregation, but ddraw doesn't support it.
+ *            Must be NULL
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if memory allocation failed
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_3_CreateLight(IDirect3D3 *iface,
+                            IDirect3DLight **Light,
+                            IUnknown *UnkOuter )
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    IDirect3DLightImpl *object;
+
+    TRACE("(%p)->(%p,%p)\n", This, Light, UnkOuter);
+
+    if(UnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DLightImpl));
+    if (object == NULL)
+        return DDERR_OUTOFMEMORY;
+
+    ICOM_INIT_INTERFACE(object, IDirect3DLight, IDirect3DLight_Vtbl);
+    object->ref = 1;
+    object->ddraw = This;
+    object->next = NULL;
+    object->active_viewport = NULL;
+
+    /* Update functions */
+    object->activate = light_update;
+    object->desactivate = light_activate;
+    object->update = light_desactivate;
+    object->active_viewport = NULL;
+
+    *Light = ICOM_INTERFACE(object, IDirect3DLight);
+
+    TRACE("(%p) creating implementation at %p.\n", This, object);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateLight(IDirect3D2 *iface,
+                                  IDirect3DLight **Direct3DLight,
+                                  IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DLight, UnkOuter);
+    return IDirect3D3_CreateLight(ICOM_INTERFACE(This, IDirect3D3),
+                                  Direct3DLight,
+                                  UnkOuter);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateLight(IDirect3D *iface,
+                                  IDirect3DLight **Direct3DLight,
+                                  IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DLight, UnkOuter);
+    return IDirect3D3_CreateLight(ICOM_INTERFACE(This, IDirect3D3),
+                                  Direct3DLight,
+                                  UnkOuter);
+}
+
+/*****************************************************************************
+ * IDirect3D3::CreateMaterial
+ *
+ * Creates an IDirect3DMaterial interface. This interface is used by Direct3D3
+ * and older versions. The IDirect3DMaterial implementation wraps it's
+ * functionality to IDirect3DDevice7::SetMaterial and friends.
+ *
+ * Version 1, 2 and 3
+ *
+ * Params:
+ *  Material: Address to store the new interface's pointer to
+ *  UnkOuter: Basically for aggregation, but ddraw doesn't support it.
+ *            Must be NULL
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if memory allocation failed
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_3_CreateMaterial(IDirect3D3 *iface,
+                               IDirect3DMaterial3 **Material,
+                               IUnknown *UnkOuter )
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    IDirect3DMaterialImpl *object;
+
+    TRACE("(%p)->(%p,%p)\n", This, Material, UnkOuter);
+
+    if(UnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl));
+    if (object == NULL)
+        return DDERR_OUTOFMEMORY;
+
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, IDirect3DMaterial3_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, IDirect3DMaterial2_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial, IDirect3DMaterial_Vtbl);
+    object->ref = 1;
+    object->ddraw = This;
+    object->activate = material_activate;
+
+    *Material = ICOM_INTERFACE(object, IDirect3DMaterial3);
+
+    TRACE("(%p) creating implementation at %p.\n", This, object);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateMaterial(IDirect3D2 *iface,
+                                     IDirect3DMaterial2 **Direct3DMaterial,
+                                     IUnknown* UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    HRESULT ret;
+    IDirect3DMaterial3 *ret_val;
+
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DMaterial, UnkOuter);
+    ret = IDirect3D3_CreateMaterial(ICOM_INTERFACE(This, IDirect3D3),
+                                    &ret_val,
+                                    UnkOuter);
+
+    *Direct3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, ret_val);
+
+    TRACE(" returning interface %p.\n", *Direct3DMaterial);
+
+    return ret;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateMaterial(IDirect3D *iface,
+                                     IDirect3DMaterial **Direct3DMaterial,
+                                     IUnknown* UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    HRESULT ret;
+    LPDIRECT3DMATERIAL3 ret_val;
+
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DMaterial, UnkOuter);
+    ret = IDirect3D3_CreateMaterial(ICOM_INTERFACE(This, IDirect3D3),
+                                    &ret_val,
+                                    UnkOuter);
+
+    *Direct3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, ret_val);
+
+    TRACE(" returning interface %p.\n", *Direct3DMaterial);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * IDirect3D3::CreateViewport
+ *
+ * Creates an IDirect3DViewport interface. This interface is used
+ * by Direct3D and earlier versions for Viewport management. In Direct3D7
+ * it has been replaced by a viewport structure and
+ * IDirect3DDevice7::*Viewport. Wine's IDirect3DViewport implementation
+ * uses the IDirect3DDevice7 methods for it's functionality
+ *
+ * Params:
+ *  Viewport: Address to store the new interface pointer
+ *  UnkOuter: Basically for aggregation, but ddraw doesn't support it.
+ *            Must be NULL
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if memory allocation failed
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_3_CreateViewport(IDirect3D3 *iface,
+                              IDirect3DViewport3 **Viewport,
+                              IUnknown *UnkOuter )
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    IDirect3DViewportImpl *object;
+
+    if(UnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
+    if (object == NULL)
+        return DDERR_OUTOFMEMORY;
+
+    ICOM_INIT_INTERFACE(object, IDirect3DViewport3, IDirect3DViewport3_Vtbl);
+    object->ref = 1;
+    object->ddraw = This;
+    object->activate = viewport_activate;
+    object->use_vp2 = 0xFF;
+    object->next = NULL;
+    object->lights = NULL;
+    object->num_lights = 0;
+    object->map_lights = 0;
+
+    *Viewport = ICOM_INTERFACE(object, IDirect3DViewport3);
+
+    TRACE("(%p) creating implementation at %p.\n",This, object);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateViewport(IDirect3D2 *iface,
+                                     IDirect3DViewport2 **D3DViewport2,
+                                     IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DViewport2, UnkOuter);
+
+    return IDirect3D3_CreateViewport(ICOM_INTERFACE(This, IDirect3D3),
+                                     (IDirect3DViewport3 **) D3DViewport2 /* No need to cast here */,
+                                     UnkOuter);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateViewport(IDirect3D *iface,
+                                     IDirect3DViewport **D3DViewport,
+                                     IUnknown* UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DViewport, UnkOuter);
+
+    return IDirect3D3_CreateViewport(ICOM_INTERFACE(This, IDirect3D3),
+                                     (IDirect3DViewport3 **) D3DViewport /* No need to cast here */,
+                                     UnkOuter);
+}
+
+/*****************************************************************************
+ * IDirect3D3::FindDevice
+ *
+ * This method finds a device with the requested properties and returns a
+ * device description
+ *
+ * Verion 1, 2 and 3
+ * Params:
+ *  D3DDFS: Describes the requested device charakteristics
+ *  D3DFDR: Returns the device description
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if no device was found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_3_FindDevice(IDirect3D3 *iface,
+                           D3DFINDDEVICESEARCH *D3DDFS,
+                           D3DFINDDEVICERESULT *D3DFDR)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    D3DDEVICEDESC desc;
+    D3DDEVICEDESC7 newDesc;
+    HRESULT hr;
+
+    TRACE("(%p)->(%p,%p)\n", This, D3DDFS, D3DFDR);
+
+    if ((D3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
+        (D3DDFS->dcmColorModel != D3DCOLOR_RGB))
+    {
+        TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
+        return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
+    }
+    if (D3DDFS->dwFlags & D3DFDS_GUID)
+    {
+        TRACE(" trying to match guid %s.\n", debugstr_guid(&(D3DDFS->guid)));
+        if ((IsEqualGUID(&IID_D3DDEVICE_WineD3D, &(D3DDFS->guid)) == 0) &&
+            (IsEqualGUID(&IID_IDirect3DHALDevice, &(D3DDFS->guid)) == 0) &&
+            (IsEqualGUID(&IID_IDirect3DRefDevice, &(D3DDFS->guid)) == 0))
+        {
+            TRACE(" no match for this GUID.\n");
+            return DDERR_INVALIDPARAMS;
+        }
+    }
+
+    /* Get the caps */
+    hr = IDirect3DImpl_GetCaps(This->wineD3D, &desc, &newDesc);
+    if(hr != D3D_OK) return hr;
+
+    /* Now return our own GUID */
+    D3DFDR->guid = IID_D3DDEVICE_WineD3D;
+    D3DFDR->ddHwDesc = desc;
+    D3DFDR->ddSwDesc = desc;
+
+    TRACE(" returning Wine's WineD3D device with (undumped) capabilities\n");
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_FindDevice(IDirect3D2 *iface,
+                                 D3DFINDDEVICESEARCH *D3DDFS,
+                                 D3DFINDDEVICERESULT *D3DFDR)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, D3DDFS, D3DFDR);
+    return IDirect3D3_FindDevice(ICOM_INTERFACE(This, IDirect3D3),
+                                 D3DDFS,
+                                 D3DFDR);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_1_FindDevice(IDirect3D *iface,
+                                D3DFINDDEVICESEARCH *D3DDFS,
+                                D3DFINDDEVICERESULT *D3DDevice)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DDFS, D3DDevice);
+    return IDirect3D3_FindDevice(ICOM_INTERFACE(This, IDirect3D3),
+                                 D3DDFS,
+                                 D3DDevice);
+}
+
+/*****************************************************************************
+ * IDirect3D7::CreateDevice
+ *
+ * Creates an IDirect3DDevice7 interface.
+ *
+ * Version 2, 3 and 7. IDirect3DDevice 1 interfaces are interfaces to
+ * DirectDraw surfaces and are created with
+ * IDirectDrawSurface::QueryInterface. This method uses CreateDevice to
+ * create the device object and QueryInterfaces for IDirect3DDevice
+ *
+ * Params:
+ *  refiid: IID of the device to create
+ *  Surface: Inititial rendertarget
+ *  Device: Address to return the interface pointer
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if memory allocation failed
+ *  DDERR_INVALIDPARAMS if a device exists already
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
+                             REFCLSID refiid,
+                             IDirectDrawSurface7 *Surface,
+                             IDirect3DDevice7 **Device)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    IDirect3DDeviceImpl *object;
+    IParentImpl *IndexBufferParent;
+    HRESULT hr;
+    IDirectDrawSurfaceImpl *target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Surface);
+    TRACE("(%p)->(%s,%p,%p)\n", iface, debugstr_guid(refiid), Surface, Device);
+
+    *Device = NULL;
+
+    /* Fail device creation if non-opengl surfaces are used */
+    if(This->ImplType != SURFACE_OPENGL)
+    {
+        ERR("The application wants to create a Direct3D device, but non-opengl surfaces are set in the registry. Please set the surface implementation to opengl or autodetection to allow 3D rendering\n");
+
+        /* We only hit this path if a default surface is set in the registry. Incorrect autodetection
+         * is caught in CreateSurface or QueryInterface
+         */
+        return DDERR_NO3D;
+    }
+
+    /* So far we can only create one device per ddraw object */
+    if(This->d3ddevice)
+    {
+        FIXME("(%p): Only one Direct3D device per DirectDraw object supported\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirect3DDeviceImpl));
+    if(!object)
+    {
+        ERR("Out of memory when allocating a IDirect3DDevice implementation\n");
+        return DDERR_OUTOFMEMORY;
+    }
+
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice7, IDirect3DDevice7_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice3, IDirect3DDevice3_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice2, IDirect3DDevice2_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice, IDirect3DDevice1_Vtbl);
+
+    object->ref = 1;
+    object->ddraw = This;
+    object->viewport_list = NULL;
+    object->current_viewport = NULL;
+    object->material = 0;
+    object->target = target;
+
+    /* This is for convenience */
+    object->wineD3DDevice = This->wineD3DDevice;
+
+    /* Create an index buffer, it's needed for indexed drawing */
+    IndexBufferParent = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl *));
+    if(!IndexBufferParent)
+    {
+        ERR("Allocating memory for an index buffer parent failed\n");
+        HeapFree(GetProcessHeap(), 0, object);
+        return DDERR_OUTOFMEMORY;
+    }
+    ICOM_INIT_INTERFACE(IndexBufferParent, IParent, IParent_Vtbl);
+    IndexBufferParent->ref = 1;
+
+    /* Create an Index Buffer. WineD3D needs one for Drawing indexed primitives
+     * Create a (hopefully) long enought buffer, and copy the indices into it
+     * Ideally, a IWineD3DIndexBuffer::SetData method could be created, which
+     * takes the pointer and avoids the memcpy
+     */
+    hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice,
+                                          0x40000, /* Lenght. Don't know how long it should be */
+                                          0, /* Usage */
+                                          WINED3DFMT_INDEX16, /* Format. D3D7 uses WORDS */
+                                          WINED3DPOOL_DEFAULT,
+                                          &object->indexbuffer,
+                                          0 /* Handle */,
+                                          (IUnknown *) ICOM_INTERFACE(IndexBufferParent, IParent));
+
+    if(FAILED(hr))
+    {
+        ERR("Failed to create an index buffer\n");
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+    IndexBufferParent->child = (IUnknown *) object->indexbuffer;
+
+    /* No need to set the indices, it's done when necessary */
+
+    /* AddRef the WineD3D Device */
+    IWineD3DDevice_AddRef(This->wineD3DDevice);
+
+    /* Don't forget to return the interface ;) */
+    *Device = ICOM_INTERFACE(object, IDirect3DDevice7);
+
+    TRACE(" (%p) Created an IDirect3DDeviceImpl object at %p\n", This, object);
+
+    /* This is for apps which create a non-flip, non-d3d primary surface
+     * and an offscreen D3DDEVICE surface, then render to the offscreen surface
+     * and do a Blt from the offscreen to the primary surface.
+     *
+     * Set the offscreen D3DDDEVICE surface(=target) as the back buffer,
+     * and the primary surface(=This->d3d_target) as the front buffer.
+     *
+     * This way the app will render to the D3DDEVICE surface and WineD3D
+     * will catch the Blt was Back Buffer -> Front buffer blt and perform
+     * a flip instead. This way we don't have to deal with a mixed GL / GDI
+     * environment.
+     *
+     * This should be checked against windowed apps. The only app tested with
+     * this is moto racer 2 during the loading screen.
+     */
+    TRACE("Isrendertarget: %s, d3d_target=%p\n", target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE ? "true" : "false", This->d3d_target);
+    if(!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
+       (This->d3d_target != target))
+    {
+        TRACE("(%p) Using %p as front buffer, %p as back buffer\n", This, This->d3d_target, target);
+        hr = IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
+                                                This->d3d_target->WineD3DSurface,
+                                                target->WineD3DSurface);
+        if(hr != D3D_OK)
+            ERR("(%p) Error %08lx setting the front and back buffer\n", This, hr);
+
+        object->OffScreenTarget = TRUE;
+    }
+    else
+    {
+        object->OffScreenTarget = FALSE;
+    }
+
+    /* AddRef the render target. Also AddRef the render target from ddraw,
+     * because if it released before the app releases the D3D device, the D3D capatiblities
+     * of WineD3D will be uninitialized, which has bad effects.
+     *
+     * In most cases, those surfaces are the surfaces are the same anyway, but this will simply
+     * add another ref which is released when the device is destroyed.
+     */
+    IDirectDrawSurface7_AddRef(Surface);
+    IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->d3d_target, IDirectDrawSurface7));
+
+    This->d3ddevice = object;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_3_CreateDevice(IDirect3D3 *iface,
+                                   REFCLSID refiid,
+                                   IDirectDrawSurface4 *Surface,
+                                   IDirect3DDevice3 **Device,
+                                   IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%s,%p,%p,%p): Thunking to IDirect3D7\n", This, debugstr_guid(refiid), Surface, Device, UnkOuter);
+
+    if(UnkOuter != NULL)
+        return CLASS_E_NOAGGREGATION;
+
+    hr =  IDirect3D7_CreateDevice(ICOM_INTERFACE(This, IDirect3D7),
+                                  refiid,
+                                  (IDirectDrawSurface7 *) Surface /* Same VTables */,
+                                  (IDirect3DDevice7 **) Device);
+
+    *Device = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice3, *Device);
+    return hr;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateDevice(IDirect3D2 *iface,
+                                   REFCLSID refiid,
+                                   IDirectDrawSurface *Surface,
+                                   IDirect3DDevice2 **Device)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%s,%p,%p): Thunking to IDirect3D7\n", This, debugstr_guid(refiid), Surface, Device);
+
+    hr =  IDirect3D7_CreateDevice(ICOM_INTERFACE(This, IDirect3D7),
+                                  refiid,
+                                  COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface3, IDirectDrawSurface7, Surface),
+                                  (IDirect3DDevice7 **) Device);
+
+    *Device = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice2, *Device);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirect3D7::CreateVertexBuffer
+ *
+ * Creates a new vertex buffer object and returns a IDirect3DVertexBuffer7
+ * interface.
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  Desc: Requested Vertex buffer properties
+ *  VertexBuffer: Address to return the interface pointer at
+ *  Flags: Some flags, must be 0
+ *
+ * Returns
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if memory allocation failed
+ *  The return value of IWineD3DDevice::CreateVertexBuffer if this call fails
+ *  DDERR_INVALIDPARAMS if Desc or VertexBuffer are NULL, or Flags != 0
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface,
+                                   D3DVERTEXBUFFERDESC *Desc,
+                                   IDirect3DVertexBuffer7 **VertexBuffer,
+                                   DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    IDirect3DVertexBufferImpl *object;
+    HRESULT hr;
+    TRACE("(%p)->(%p,%p,%08lx)\n", This, Desc, VertexBuffer, Flags);
+
+    TRACE("(%p) Vertex buffer description: \n", This);
+    TRACE("(%p)  dwSize=%ld\n", This, Desc->dwSize);
+    TRACE("(%p)  dwCaps=%08lx\n", This, Desc->dwCaps);
+    TRACE("(%p)  FVF=%08lx\n", This, Desc->dwFVF);
+    TRACE("(%p)  dwNumVertices=%ld\n", This, Desc->dwNumVertices);
+
+    /* D3D7 SDK: "No Flags are currently defined for this method. This
+     * parameter must be 0"
+     *
+     * Never trust the documentation - this is wrong
+    if(Flags != 0)
+    {
+        ERR("(%p) Flags is %08lx, returning DDERR_INVALIDPARAMS\n", This, Flags);
+        return DDERR_INVALIDPARAMS;
+    }
+     */
+
+    /* Well, this sounds sane */
+    if( (!VertexBuffer) || (!Desc) )
+        return DDERR_INVALIDPARAMS;
+
+    /* Now create the vertex buffer */
+    object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirect3DVertexBufferImpl));
+    if(!object)
+    {
+        ERR("(%p) Out of memory when allocating a IDirect3DVertexBufferImpl structure\n", This);
+        return DDERR_OUTOFMEMORY;
+    }
+
+    object->ref = 1;
+    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, IDirect3DVertexBuffer7_Vtbl);
+    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, IDirect3DVertexBuffer1_Vtbl);
+
+    object->Caps = Desc->dwCaps;
+
+    hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
+                                           get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
+                                           Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0,
+                                           Desc->dwFVF,
+                                           Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
+                                           &object->wineD3DVertexBuffer,
+                                           0 /* SharedHandle */,
+                                           (IUnknown *) ICOM_INTERFACE(object, IDirect3DVertexBuffer7));
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08lx\n", This, hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    /* Return the interface */
+    *VertexBuffer = ICOM_INTERFACE(object, IDirect3DVertexBuffer7);
+
+    TRACE("(%p) Created new vertex buffer implementation at %p, returning interface at %p\n", This, object, *VertexBuffer);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_3_CreateVertexBuffer(IDirect3D3 *iface,
+                                         D3DVERTEXBUFFERDESC *Desc,
+                                         IDirect3DVertexBuffer **VertexBuffer,
+                                         DWORD Flags,
+                                         IUnknown *UnkOuter)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    HRESULT hr;
+    TRACE("(%p)->(%p,%p,%08lx,%p): Relaying to IDirect3D7\n", This, Desc, VertexBuffer, Flags, UnkOuter);
+
+    if(UnkOuter != NULL) return CLASS_E_NOAGGREGATION;
+
+    hr = IDirect3D7_CreateVertexBuffer(ICOM_INTERFACE(This, IDirect3D7),
+                                       Desc,
+                                       (IDirect3DVertexBuffer7 **) VertexBuffer,
+                                       Flags);
+
+    *VertexBuffer = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, *VertexBuffer);
+    return hr;
+}
+
+/*****************************************************************************
+ * EnumZBufferFormatsCB
+ *
+ * Helper function for IDirect3D7::EnumZBufferFormats. Converts
+ * the WINED3DFORMAT into a DirectDraw pixelformat and calls the application
+ * callback
+ *
+ * Version 3 and 7
+ *
+ * Parameters:
+ *  Device: Parent of the IWineD3DDevice, our IDirectDraw7 interface
+ *  fmt: The enumerated pixel format
+ *  Context: Context passed to IWineD3DDevice::EnumZBufferFormat
+ *
+ * Returns:
+ *  The return value of the application-provided callback
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+EnumZBufferFormatsCB(IUnknown *Device,
+                     WINED3DFORMAT fmt,
+                     void *Context)
+{
+     struct EnumZBufferFormatsData *cbdata = (struct EnumZBufferFormatsData *) Context;
+     DDPIXELFORMAT pformat;
+
+     memset(&pformat, 0, sizeof(DDPIXELFORMAT));
+     pformat.dwSize=sizeof(DDPIXELFORMAT);
+     PixelFormat_WineD3DtoDD(&pformat, fmt);
+     return cbdata->Callback(&pformat, cbdata->Context);
+}
+
+/*****************************************************************************
+ * IDirect3D7::EnumZBufferFormats
+ *
+ * Enumerates all supported Z buffer pixel formats
+ *
+ * Version 3 and 7
+ *
+ * Params:
+ *  refiidDevice:
+ *  Callback: Callback to call for each pixel format
+ *  Context: Pointer to pass back to the callback
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Callback is NULL
+ *  For details, see IWineD3DDevice::EnumZBufferFormats
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_7_EnumZBufferFormats(IDirect3D7 *iface,
+                                   REFCLSID refiidDevice,
+                                   LPD3DENUMPIXELFORMATSCALLBACK Callback,
+                                   void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    struct EnumZBufferFormatsData cbdata = { Callback, Context };
+    TRACE("(%p)->(%s,%p,%p): Relay\n", iface, debugstr_guid(refiidDevice), Callback, Context);
+
+    if(!Callback)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DDevice_EnumZBufferFormats(This->wineD3DDevice, EnumZBufferFormatsCB, &cbdata);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EnumZBufferFormats(IDirect3D3 *iface,
+                                         REFCLSID riidDevice,
+                                         LPD3DENUMPIXELFORMATSCALLBACK Callback,
+                                         void *Context)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", This, debugstr_guid(riidDevice), Callback, Context);
+    return IDirect3D7_EnumZBufferFormats(ICOM_INTERFACE(This, IDirect3D7),
+                                         riidDevice,
+                                         Callback,
+                                         Context);
+}
+
+/*****************************************************************************
+ * IDirect3D7::EvictManagedTextures
+ *
+ * Removes all managed textures(=surfaces with DDSCAPS2_TEXTUREMANAGE or
+ * DDSCAPS2_D3DTEXTUREMANAGE caps) to be removed from video memory.
+ *
+ * Version 3 and 7
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DImpl_7_EvictManagedTextures(IDirect3D7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
+    FIXME("(%p): Stub!\n", This);
+
+    /* Implementation idea:
+     * Add an IWineD3DSurface method which sets the opengl texture
+     * priority low or even removes the opengl texture.
+     */
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EvictManagedTextures(IDirect3D3 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", This);
+    return IDirect3D7_EvictManagedTextures(ICOM_INTERFACE(This, IDirect3D7));
+}
+
+/*****************************************************************************
+ * IDirect3DImpl_GetCaps
+ *
+ * This function retrieves the device caps from wined3d
+ * and converts it into a D3D7 and D3D - D3D3 structure
+ * This is a helper function called from various places in ddraw
+ *
+ * Params:
+ *  WineD3D: The interface to get the caps from
+ *  Desc123: Old D3D <3 structure to fill(needed)
+ *  Desc7: D3D7 device desc structure to fill(needed)
+ *
+ * Returns
+ *  D3D_OK on success, or the return value of IWineD3D::GetCaps
+ *
+ *****************************************************************************/
+HRESULT
+IDirect3DImpl_GetCaps(IWineD3D *WineD3D,
+                      D3DDEVICEDESC *Desc123,
+                      D3DDEVICEDESC7 *Desc7)
+{
+    WINED3DCAPS WCaps;
+    HRESULT hr;
+
+    /* Some Variables to asign to the pointers in WCaps */
+    WINED3DDEVTYPE DevType;
+    UINT dummy_uint;
+    float dummy_float;
+    DWORD dummy_dword, MaxTextureBlendStages, MaxSimultaneousTextures;
+    DWORD MaxUserClipPlanes, MaxVertexBlendMatrices;
+
+    TRACE("()->(%p,%p,%p\n", WineD3D, Desc123, Desc7);
+
+    /* Asign the pointers in WCaps */
+    WCaps.DeviceType = &DevType;
+    WCaps.AdapterOrdinal = &dummy_uint;
+
+    WCaps.Caps = &dummy_dword;
+    WCaps.Caps2 = &dummy_dword;
+    WCaps.Caps3 = &dummy_dword;
+    WCaps.PresentationIntervals = &dummy_dword;
+
+    WCaps.CursorCaps = &dummy_dword;
+
+    WCaps.DevCaps = &Desc7->dwDevCaps;
+    WCaps.PrimitiveMiscCaps = &dummy_dword;
+    WCaps.RasterCaps = &Desc7->dpcLineCaps.dwRasterCaps;
+    WCaps.ZCmpCaps = &Desc7->dpcLineCaps.dwZCmpCaps;
+    WCaps.SrcBlendCaps = &Desc7->dpcLineCaps.dwSrcBlendCaps;
+    WCaps.DestBlendCaps = &Desc7->dpcLineCaps.dwDestBlendCaps;
+    WCaps.AlphaCmpCaps = &Desc7->dpcLineCaps.dwAlphaCmpCaps;
+    WCaps.ShadeCaps = &Desc7->dpcLineCaps.dwShadeCaps;
+    WCaps.TextureCaps = &Desc7->dpcLineCaps.dwTextureCaps;
+    WCaps.TextureFilterCaps = &Desc7->dpcLineCaps.dwTextureFilterCaps;
+    WCaps.CubeTextureFilterCaps = &dummy_dword;
+    WCaps.VolumeTextureFilterCaps = &dummy_dword;
+    WCaps.TextureAddressCaps = &Desc7->dpcLineCaps.dwTextureAddressCaps;
+    WCaps.VolumeTextureAddressCaps = &dummy_dword;
+
+    WCaps.LineCaps = &dummy_dword;
+    WCaps.MaxTextureWidth = &Desc7->dwMaxTextureWidth;
+    WCaps.MaxTextureHeight = &Desc7->dwMaxTextureHeight;
+    WCaps.MaxVolumeExtent = &dummy_dword;
+
+    WCaps.MaxTextureRepeat = &Desc7->dwMaxTextureRepeat;
+    WCaps.MaxTextureAspectRatio = &Desc7->dwMaxTextureAspectRatio;
+    WCaps.MaxAnisotropy = &Desc7->dwMaxAnisotropy;
+    WCaps.MaxVertexW = &Desc7->dvMaxVertexW;
+
+    WCaps.GuardBandLeft = &Desc7->dvGuardBandLeft;
+    WCaps.GuardBandTop = &Desc7->dvGuardBandTop;
+    WCaps.GuardBandRight = &Desc7->dvGuardBandRight;
+    WCaps.GuardBandBottom = &Desc7->dvGuardBandBottom;
+
+    WCaps.ExtentsAdjust = &Desc7->dvExtentsAdjust;
+    WCaps.StencilCaps = &Desc7->dwStencilCaps;
+
+    WCaps.FVFCaps = &Desc7->dwFVFCaps;
+    WCaps.TextureOpCaps = &Desc7->dwTextureOpCaps;
+    WCaps.MaxTextureBlendStages = &MaxTextureBlendStages;
+    WCaps.MaxSimultaneousTextures = &MaxSimultaneousTextures;
+
+    WCaps.VertexProcessingCaps = &Desc7->dwVertexProcessingCaps;
+    WCaps.MaxActiveLights = &Desc7->dwMaxActiveLights;
+    WCaps.MaxUserClipPlanes = &MaxUserClipPlanes;
+    WCaps.MaxVertexBlendMatrices = &MaxVertexBlendMatrices;
+    WCaps.MaxVertexBlendMatrixIndex = &dummy_dword;
+
+    WCaps.MaxPointSize = &dummy_float;
+    WCaps.MaxPrimitiveCount = &dummy_dword;
+    WCaps.MaxVertexIndex = &dummy_dword;
+    WCaps.MaxStreams = &dummy_dword;
+    WCaps.MaxStreamStride = &dummy_dword;
+
+    WCaps.VertexShaderVersion = &dummy_dword;
+    WCaps.MaxVertexShaderConst = &dummy_dword;
+
+    WCaps.PixelShaderVersion = &dummy_dword;
+    WCaps.PixelShader1xMaxValue = &dummy_float;
+
+    /* These are dx9 only, set them to NULL */
+    WCaps.DevCaps2 = NULL;
+    WCaps.MaxNpatchTessellationLevel = NULL;
+    WCaps.Reserved5 = NULL;
+    WCaps.MasterAdapterOrdinal = NULL;
+    WCaps.AdapterOrdinalInGroup = NULL;
+    WCaps.NumberOfAdaptersInGroup = NULL;
+    WCaps.DeclTypes = NULL;
+    WCaps.NumSimultaneousRTs = NULL;
+    WCaps.StretchRectFilterCaps = NULL;
+    /* WCaps.VS20Caps = NULL; */
+    /* WCaps.PS20Caps = NULL; */
+    WCaps.VertexTextureFilterCaps = NULL;
+    WCaps.MaxVShaderInstructionsExecuted = NULL;
+    WCaps.MaxPShaderInstructionsExecuted = NULL;
+    WCaps.MaxVertexShader30InstructionSlots = NULL;
+    WCaps.MaxPixelShader30InstructionSlots = NULL;
+    WCaps.Reserved2 = NULL;
+    WCaps.Reserved3 = NULL;
+
+    /* Now get the caps */
+    hr = IWineD3D_GetDeviceCaps(WineD3D, 0, WINED3DDEVTYPE_HAL, &WCaps);
+    if(hr != D3D_OK) return hr;
+
+    /* Fill the missing members, and do some fixup */
+    Desc7->dpcLineCaps.dwSize = sizeof(Desc7->dpcLineCaps);
+    Desc7->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_MODULATEMASK |
+                                            D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL |
+                                            D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
+                                            D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA;
+    Desc7->dpcLineCaps.dwStippleWidth = 32;
+    Desc7->dpcLineCaps.dwStippleHeight = 32;
+    /* Use the same for the TriCaps */
+    Desc7->dpcTriCaps = Desc7->dpcLineCaps;
+
+    Desc7->dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32;
+    Desc7->dwDeviceZBufferBitDepth = DDBD_16 | DDBD_24;
+    Desc7->dwMinTextureWidth = 1;
+    Desc7->dwMinTextureHeight = 1;
+
+    /* Convert DWORDs safely to WORDs */
+    if(MaxTextureBlendStages > 65535) Desc7->wMaxTextureBlendStages = 65535;
+    else Desc7->wMaxTextureBlendStages = (WORD) MaxTextureBlendStages;
+    if(MaxSimultaneousTextures > 65535) Desc7->wMaxSimultaneousTextures = 65535;
+    else Desc7->wMaxSimultaneousTextures = (WORD) MaxSimultaneousTextures;
+
+    if(MaxUserClipPlanes > 65535) Desc7->wMaxUserClipPlanes = 65535;
+    else Desc7->wMaxUserClipPlanes = (WORD) MaxUserClipPlanes;
+    if(MaxVertexBlendMatrices > 65535) Desc7->wMaxVertexBlendMatrices = 65535;
+    else Desc7->wMaxVertexBlendMatrices = (WORD) MaxVertexBlendMatrices;
+
+    Desc7->deviceGUID = IID_IDirect3DTnLHalDevice;
+
+    Desc7->dwReserved1 = 0;
+    Desc7->dwReserved2 = 0;
+    Desc7->dwReserved3 = 0;
+    Desc7->dwReserved4 = 0;
+
+    /* Fill the old structure */
+    memset(Desc123, 0x0, sizeof(D3DDEVICEDESC));
+    Desc123->dwSize = sizeof(D3DDEVICEDESC);
+    Desc123->dwFlags = D3DDD_COLORMODEL            |
+                       D3DDD_DEVCAPS               |
+                       D3DDD_TRANSFORMCAPS         |
+                       D3DDD_BCLIPPING             |
+                       D3DDD_LIGHTINGCAPS          |
+                       D3DDD_LINECAPS              |
+                       D3DDD_TRICAPS               |
+                       D3DDD_DEVICERENDERBITDEPTH  |
+                       D3DDD_DEVICEZBUFFERBITDEPTH |
+                       D3DDD_MAXBUFFERSIZE         |
+                       D3DDD_MAXVERTEXCOUNT;
+    Desc123->dcmColorModel = D3DCOLOR_RGB;
+    Desc123->dwDevCaps = Desc7->dwDevCaps;
+    Desc123->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
+    Desc123->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
+    Desc123->bClipping = TRUE;
+    Desc123->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
+    Desc123->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
+    Desc123->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
+    Desc123->dlcLightingCaps.dwNumLights = Desc7->dwMaxActiveLights;
+
+    Desc123->dpcLineCaps.dwSize = sizeof(D3DPRIMCAPS);
+    Desc123->dpcLineCaps.dwMiscCaps = Desc7->dpcLineCaps.dwMiscCaps;
+    Desc123->dpcLineCaps.dwRasterCaps = Desc7->dpcLineCaps.dwRasterCaps;
+    Desc123->dpcLineCaps.dwZCmpCaps = Desc7->dpcLineCaps.dwZCmpCaps;
+    Desc123->dpcLineCaps.dwSrcBlendCaps = Desc7->dpcLineCaps.dwSrcBlendCaps;
+    Desc123->dpcLineCaps.dwDestBlendCaps = Desc7->dpcLineCaps.dwDestBlendCaps;
+    Desc123->dpcLineCaps.dwShadeCaps = Desc7->dpcLineCaps.dwShadeCaps;
+    Desc123->dpcLineCaps.dwTextureCaps = Desc7->dpcLineCaps.dwTextureCaps;
+    Desc123->dpcLineCaps.dwTextureFilterCaps = Desc7->dpcLineCaps.dwTextureFilterCaps;
+    Desc123->dpcLineCaps.dwTextureBlendCaps = Desc7->dpcLineCaps.dwTextureBlendCaps;
+    Desc123->dpcLineCaps.dwTextureAddressCaps = Desc7->dpcLineCaps.dwTextureAddressCaps;
+    Desc123->dpcLineCaps.dwStippleWidth = Desc7->dpcLineCaps.dwStippleWidth;
+    Desc123->dpcLineCaps.dwAlphaCmpCaps = Desc7->dpcLineCaps.dwAlphaCmpCaps;
+
+    Desc123->dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS);
+    Desc123->dpcTriCaps.dwMiscCaps = Desc7->dpcTriCaps.dwMiscCaps;
+    Desc123->dpcTriCaps.dwRasterCaps = Desc7->dpcTriCaps.dwRasterCaps;
+    Desc123->dpcTriCaps.dwZCmpCaps = Desc7->dpcTriCaps.dwZCmpCaps;
+    Desc123->dpcTriCaps.dwSrcBlendCaps = Desc7->dpcTriCaps.dwSrcBlendCaps;
+    Desc123->dpcTriCaps.dwDestBlendCaps = Desc7->dpcTriCaps.dwDestBlendCaps;
+    Desc123->dpcTriCaps.dwShadeCaps = Desc7->dpcTriCaps.dwShadeCaps;
+    Desc123->dpcTriCaps.dwTextureCaps = Desc7->dpcTriCaps.dwTextureCaps;
+    Desc123->dpcTriCaps.dwTextureFilterCaps = Desc7->dpcTriCaps.dwTextureFilterCaps;
+    Desc123->dpcTriCaps.dwTextureBlendCaps = Desc7->dpcTriCaps.dwTextureBlendCaps;
+    Desc123->dpcTriCaps.dwTextureAddressCaps = Desc7->dpcTriCaps.dwTextureAddressCaps;
+    Desc123->dpcTriCaps.dwStippleWidth = Desc7->dpcTriCaps.dwStippleWidth;
+    Desc123->dpcTriCaps.dwAlphaCmpCaps = Desc7->dpcTriCaps.dwAlphaCmpCaps;
+
+    Desc123->dwDeviceRenderBitDepth = Desc7->dwDeviceRenderBitDepth;
+    Desc123->dwDeviceZBufferBitDepth = Desc7->dwDeviceZBufferBitDepth;
+    Desc123->dwMaxBufferSize = 0;
+    Desc123->dwMaxVertexCount = 65536;
+    Desc123->dwMinTextureWidth  = Desc7->dwMinTextureWidth;
+    Desc123->dwMinTextureHeight = Desc7->dwMinTextureHeight;
+    Desc123->dwMaxTextureWidth  = Desc7->dwMaxTextureWidth;
+    Desc123->dwMaxTextureHeight = Desc7->dwMaxTextureHeight;
+    Desc123->dwMinStippleWidth  = 1;
+    Desc123->dwMinStippleHeight = 1;
+    Desc123->dwMaxStippleWidth  = 32;
+    Desc123->dwMaxStippleHeight = 32;
+    Desc123->dwMaxTextureRepeat = Desc7->dwMaxTextureRepeat;
+    Desc123->dwMaxTextureAspectRatio = Desc7->dwMaxTextureAspectRatio;
+    Desc123->dwMaxAnisotropy = Desc7->dwMaxAnisotropy;
+    Desc123->dvGuardBandLeft = Desc7->dvGuardBandLeft;
+    Desc123->dvGuardBandRight = Desc7->dvGuardBandRight;
+    Desc123->dvGuardBandTop = Desc7->dvGuardBandTop;
+    Desc123->dvGuardBandBottom = Desc7->dvGuardBandBottom;
+    Desc123->dvExtentsAdjust = Desc7->dvExtentsAdjust;
+    Desc123->dwStencilCaps = Desc7->dwStencilCaps;
+    Desc123->dwFVFCaps = Desc7->dwFVFCaps;
+    Desc123->dwTextureOpCaps = Desc7->dwTextureOpCaps;
+    Desc123->wMaxTextureBlendStages = Desc7->wMaxTextureBlendStages;
+    Desc123->wMaxSimultaneousTextures = Desc7->wMaxSimultaneousTextures;
+
+    return DD_OK;
+}
+/*****************************************************************************
+ * IDirect3D vtables in various versions
+ *****************************************************************************/
+
+const IDirect3DVtbl IDirect3D1_Vtbl =
+{
+    /*** IUnknown methods ***/
+    Thunk_IDirect3DImpl_1_QueryInterface,
+    Thunk_IDirect3DImpl_1_AddRef,
+    Thunk_IDirect3DImpl_1_Release,
+    /*** IDirect3D methods ***/
+    IDirect3DImpl_1_Initialize,
+    Thunk_IDirect3DImpl_1_EnumDevices,
+    Thunk_IDirect3DImpl_1_CreateLight,
+    Thunk_IDirect3DImpl_1_CreateMaterial,
+    Thunk_IDirect3DImpl_1_CreateViewport,
+    Thunk_IDirect3DImpl_1_FindDevice
+};
+
+const IDirect3D2Vtbl IDirect3D2_Vtbl =
+{
+    /*** IUnknown methods ***/
+    Thunk_IDirect3DImpl_2_QueryInterface,
+    Thunk_IDirect3DImpl_2_AddRef,
+    Thunk_IDirect3DImpl_2_Release,
+    /*** IDirect3D2 methods ***/
+    Thunk_IDirect3DImpl_2_EnumDevices,
+    Thunk_IDirect3DImpl_2_CreateLight,
+    Thunk_IDirect3DImpl_2_CreateMaterial,
+    Thunk_IDirect3DImpl_2_CreateViewport,
+    Thunk_IDirect3DImpl_2_FindDevice,
+    Thunk_IDirect3DImpl_2_CreateDevice
+};
+
+const IDirect3D3Vtbl IDirect3D3_Vtbl =
+{
+    /*** IUnknown methods ***/
+    Thunk_IDirect3DImpl_3_QueryInterface,
+    Thunk_IDirect3DImpl_3_AddRef,
+    Thunk_IDirect3DImpl_3_Release,
+    /*** IDirect3D3 methods ***/
+    IDirect3DImpl_3_EnumDevices,
+    IDirect3DImpl_3_CreateLight,
+    IDirect3DImpl_3_CreateMaterial,
+    IDirect3DImpl_3_CreateViewport,
+    IDirect3DImpl_3_FindDevice,
+    Thunk_IDirect3DImpl_3_CreateDevice,
+    Thunk_IDirect3DImpl_3_CreateVertexBuffer,
+    Thunk_IDirect3DImpl_3_EnumZBufferFormats,
+    Thunk_IDirect3DImpl_3_EvictManagedTextures
+};
+
+const IDirect3D7Vtbl IDirect3D7_Vtbl =
+{
+    /*** IUnknown methods ***/
+    Thunk_IDirect3DImpl_7_QueryInterface,
+    Thunk_IDirect3DImpl_7_AddRef,
+    Thunk_IDirect3DImpl_7_Release,
+    /*** IDirect3D7 methods ***/
+    IDirect3DImpl_7_EnumDevices,
+    IDirect3DImpl_7_CreateDevice,
+    IDirect3DImpl_7_CreateVertexBuffer,
+    IDirect3DImpl_7_EnumZBufferFormats,
+    IDirect3DImpl_7_EvictManagedTextures
+};
diff --git a/dlls/ddraw/direct3d_main.c b/dlls/ddraw/direct3d_main.c
deleted file mode 100644
index 7f15d9f..0000000
--- a/dlls/ddraw/direct3d_main.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright 2000 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-
-#include "d3d_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-
-HRESULT WINAPI
-Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface,
-                                REFIID riid)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
-    TRACE("(%p/%p)->(%s) no-op...\n", This, iface, debugstr_guid(riid));
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface,
-                                       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-                                       LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
-                                       LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                       IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DLight, pUnkOuter);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
-					  LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
-					  IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
-					  LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
-					  IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpD3DViewport3, pUnkOuter);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
-				      LPD3DFINDDEVICESEARCH lpD3DDFS,
-				      LPD3DFINDDEVICERESULT lpD3DFDR)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DDFS, lpD3DFDR);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE lpDDS,
-                                  LPDIRECT3DDEVICE2* lplpD3DDevice2)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
-    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE4 lpDDS,
-                                  LPDIRECT3DDEVICE3* lplpD3DDevice3,
-                                  LPUNKNOWN lpUnk)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    FIXME("(%p/%p)->(%s,%p,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3, lpUnk);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
-                                           REFCLSID riidDevice,
-                                           LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-                                           LPVOID lpContext)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    FIXME("(%p/%p)->(): stub!\n", This, iface);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
-                                 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
-                                 LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
-                                  REFCLSID rclsid,
-                                  LPDIRECTDRAWSURFACE7 lpDDS,
-                                  LPDIRECT3DDEVICE7* lplpD3DDevice)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
-					   LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-					   LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
-					   DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_7_QueryInterface(LPDIRECT3D7 iface,
-                                     REFIID riid,
-                                     LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface),
-				       riid,
-				       obp);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface,
-                                     REFIID riid,
-                                     LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface),
-				       riid,
-				       obp);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface,
-                                     REFIID riid,
-                                     LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface),
-				       riid,
-				       obp);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface,
-                                     REFIID riid,
-                                     LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface),
-				       riid,
-				       obp);
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_7_AddRef(LPDIRECT3D7 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_7_Release(LPDIRECT3D7 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface)
-{
-    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
-    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface,
-                                         REFCLSID riidDevice,
-                                         LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-                                         LPVOID lpContext)
-{
-    TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
-    return IDirect3D7_EnumZBufferFormats(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface),
-                                         riidDevice,
-                                         lpEnumCallback,
-                                         lpContext);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface)
-{
-    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
-    return IDirect3D7_EvictManagedTextures(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
-                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-                                  LPVOID lpUserArg)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg);
-    return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
-                                  lpEnumDevicesCallback,
-                                  lpUserArg);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface,
-                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                  IUnknown* pUnkOuter)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
-    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
-                                  lplpDirect3DLight,
-                                  pUnkOuter);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface,
-                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                  IUnknown* pUnkOuter)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
-    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
-                                  lplpDirect3DLight,
-                                  pUnkOuter);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface,
-				     LPDIRECT3DMATERIAL* lplpDirect3DMaterial,
-				     IUnknown* pUnkOuter)
-{
-    HRESULT ret;
-    LPDIRECT3DMATERIAL3 ret_val;
-
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial, pUnkOuter);
-    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
-				    &ret_val,
-				    pUnkOuter);
-
-    *lplpDirect3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, ret_val);
-
-    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial);
-    
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface,
-				     LPDIRECT3DVIEWPORT* lplpD3DViewport,
-				     IUnknown* pUnkOuter)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport, pUnkOuter);
-    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
-				    (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport /* No need to cast here */,
-				    pUnkOuter);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface,
-				     LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2,
-				     IUnknown* pUnkOuter)
-{
-    HRESULT ret;
-    LPDIRECT3DMATERIAL3 ret_val;
-
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial2, pUnkOuter);
-    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
-				    &ret_val,
-				    pUnkOuter);
-
-    *lplpDirect3DMaterial2 = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, ret_val);
-
-    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial2);
-    
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface,
-				     LPDIRECT3DVIEWPORT2* lplpD3DViewport2,
-				     IUnknown* pUnkOuter)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport2, pUnkOuter);
-    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
-				     (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport2 /* No need to cast here */,
-				     pUnkOuter);
-}
-
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface,
-					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-					 LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
-					 DWORD dwFlags,
-					 LPUNKNOWN lpUnk)
-{
-    HRESULT ret;
-    LPDIRECT3DVERTEXBUFFER7 ret_val;
-
-    TRACE("(%p)->(%p,%p,%08lx,%p) thunking to IDirect3D7 interface.\n", iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags, lpUnk);
-    
-    /* dwFlags is not used in the D3D7 interface, use the vertex buffer description instead */
-    if (dwFlags & D3DDP_DONOTCLIP) lpD3DVertBufDesc->dwCaps |= D3DVBCAPS_DONOTCLIP;
-
-    ret = IDirect3D7_CreateVertexBuffer(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface),
-					lpD3DVertBufDesc,
-					&ret_val,
-					dwFlags);
-
-    *lplpD3DVertBuf = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, ret_val);
-
-    TRACE(" returning interface %p.\n", *lplpD3DVertBuf);
-    
-    return ret;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
-				 LPD3DFINDDEVICESEARCH lpD3DDFS,
-				 LPD3DFINDDEVICERESULT lplpD3DDevice)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lplpD3DDevice);
-    return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
-				 lpD3DDFS,
-				 lplpD3DDevice);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface,
-				 LPD3DFINDDEVICESEARCH lpD3DDFS,
-				 LPD3DFINDDEVICERESULT lpD3DFDR)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lpD3DFDR);
-    return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
-				 lpD3DDFS,
-				 lpD3DFDR);
-}
diff --git a/dlls/ddraw/direct3d_opengl.c b/dlls/ddraw/direct3d_opengl.c
deleted file mode 100644
index dfe79a8..0000000
--- a/dlls/ddraw/direct3d_opengl.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright 2000 Marcus Meissner
- * Copyright 2000 Peter Hunnisett
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <fcntl.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "d3d.h"
-#include "ddraw.h"
-#include "winerror.h"
-
-#include "ddraw_private.h"
-#include "d3d_private.h"
-#include "opengl_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-HRESULT WINAPI
-GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
-			       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-			       LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-
-    /* Call functions defined in d3ddevices.c */
-    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK)
-	return D3D_OK;
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
-				  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-				  LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-
-    /* Call functions defined in d3ddevices.c */
-    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 2) != D3DENUMRET_OK)
-	return D3D_OK;
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_EnumDevices(LPDIRECT3D3 iface,
-				  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
-				  LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-
-    /* Call functions defined in d3ddevices.c */
-    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK)
-	return D3D_OK;
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
-				     LPDIRECT3DLIGHT* lplpDirect3DLight,
-				     IUnknown* pUnkOuter)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    IDirect3DLightImpl *d3dlimpl;
-    HRESULT ret_value;
-    
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DLight, pUnkOuter);
-
-    ret_value = d3dlight_create(&d3dlimpl, This);
-    *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight);
-
-    return ret_value;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
-					LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
-					IUnknown* pUnkOuter)
-{
-    IDirect3DMaterialImpl *D3Dmat_impl;
-    HRESULT ret_value;
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
-    ret_value = d3dmaterial_create(&D3Dmat_impl, This);
-
-    *lplpDirect3DMaterial3 = ICOM_INTERFACE(D3Dmat_impl, IDirect3DMaterial3);
-
-    return ret_value;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
-					LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
-					IUnknown* pUnkOuter)
-{
-    IDirect3DViewportImpl *D3Dvp_impl;
-    HRESULT ret_value;
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpD3DViewport3, pUnkOuter);
-    ret_value = d3dviewport_create(&D3Dvp_impl, This);
-
-    *lplpD3DViewport3 = ICOM_INTERFACE(D3Dvp_impl, IDirect3DViewport3);
-
-    return ret_value;
-}
-
-static HRESULT
-create_device_helper(IDirectDrawImpl *This,
-		     REFCLSID iid,
-		     IDirectDrawSurfaceImpl *lpDDS,
-		     void **obj,
-		     int version) {
-    IDirect3DDeviceImpl *lpd3ddev;
-    HRESULT ret_value;
-
-    ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS, version);
-    if (FAILED(ret_value)) return ret_value;
-    
-    if ((iid == NULL) ||
-	(IsEqualGUID(&IID_D3DDEVICE_OpenGL, iid)) ||
-	(IsEqualGUID(&IID_IDirect3DHALDevice, iid)) ||
-	(IsEqualGUID(&IID_IDirect3DTnLHalDevice, iid)) ||
-	(IsEqualGUID(&IID_IDirect3DRGBDevice, iid)) ||
-	(IsEqualGUID(&IID_IDirect3DRefDevice, iid))) {
-        switch (version) {
-	    case 1:
-		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice);
-	        TRACE(" returning OpenGL D3DDevice %p.\n", *obj);
-		return D3D_OK;
-
-	    case 2:
-		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2);
-	        TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj);
-		return D3D_OK;
-
-	    case 3:
-		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3);
-	        TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj);
-		return D3D_OK;
-
-	    case 7:
-		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7);
-	        TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj);
-		return D3D_OK;
-        }
-    }
-
-    *obj = NULL;
-    ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid));
-    IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7));
-    return DDERR_INVALIDPARAMS;
-}
-     
-
-HRESULT WINAPI
-GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
-				REFCLSID rclsid,
-				LPDIRECTDRAWSURFACE lpDDS,
-				LPDIRECT3DDEVICE2* lplpD3DDevice2)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
-    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, lpDDS);
-    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
-    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice2, 2);
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
-				REFCLSID rclsid,
-				LPDIRECTDRAWSURFACE4 lpDDS,
-				LPDIRECT3DDEVICE3* lplpD3DDevice3,
-				LPUNKNOWN lpUnk)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
-    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3);
-    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice3, 3);
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
-				    LPD3DFINDDEVICESEARCH lpD3DDFS,
-				    LPD3DFINDDEVICERESULT lpD3DFDR)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DDFS, lpD3DFDR);
-    return d3ddevice_find(This, lpD3DDFS, lpD3DFDR);
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
-					 REFCLSID riidDevice,
-					 LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-					 LPVOID lpContext)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    DDPIXELFORMAT pformat;
-    
-    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
-
-    memset(&pformat, 0, sizeof(pformat));
-    pformat.dwSize = sizeof(DDPIXELFORMAT);
-    pformat.dwFourCC = 0;   
-    TRACE("Enumerating dummy ZBuffer format (16 bits)\n");
-    pformat.dwFlags = DDPF_ZBUFFER;
-    pformat.u1.dwZBufferBitDepth = 16;
-    pformat.u3.dwZBitMask =    0x0000FFFF;
-    pformat.u5.dwRGBZBitMask = 0x0000FFFF;
-
-    /* Whatever the return value, stop here.. */
-    lpEnumCallback(&pformat, lpContext);
-    
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
-			       LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
-			       LPVOID lpUserArg)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
-
-    if (d3ddevice_enumerate7(lpEnumDevicesCallback, lpUserArg) != D3DENUMRET_OK)
-	return D3D_OK;
-    
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
-				REFCLSID rclsid,
-				LPDIRECTDRAWSURFACE7 lpDDS,
-				LPDIRECT3DDEVICE7* lplpD3DDevice)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
-    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
-    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice, 7);
-}
-
-HRESULT WINAPI
-GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
-					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-					 LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
-					 DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
-    IDirect3DVertexBufferImpl *vbimpl;
-    HRESULT res;
-    
-    TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);
-
-    res = d3dvertexbuffer_create(&vbimpl, This, lpD3DVertBufDesc, dwFlags);
-
-    *lplpD3DVertBuf = ICOM_INTERFACE(vbimpl, IDirect3DVertexBuffer7);
-    
-    return res;
-}
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3D7.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3D7Vtbl VTABLE_IDirect3D7 =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DImpl_7_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DImpl_7_AddRef,
-    XCAST(Release) Thunk_IDirect3DImpl_7_Release,
-    XCAST(EnumDevices) GL_IDirect3DImpl_7_EnumDevices,
-    XCAST(CreateDevice) GL_IDirect3DImpl_7_CreateDevice,
-    XCAST(CreateVertexBuffer) GL_IDirect3DImpl_7_3T_CreateVertexBuffer,
-    XCAST(EnumZBufferFormats) GL_IDirect3DImpl_7_3T_EnumZBufferFormats,
-    XCAST(EvictManagedTextures) Main_IDirect3DImpl_7_3T_EvictManagedTextures,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3D3.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3D3Vtbl VTABLE_IDirect3D3 =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef,
-    XCAST(Release) Thunk_IDirect3DImpl_3_Release,
-    XCAST(EnumDevices) GL_IDirect3DImpl_3_EnumDevices,
-    XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight,
-    XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial,
-    XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport,
-    XCAST(FindDevice) GL_IDirect3DImpl_3_2T_1T_FindDevice,
-    XCAST(CreateDevice) GL_IDirect3DImpl_3_CreateDevice,
-    XCAST(CreateVertexBuffer) Thunk_IDirect3DImpl_3_CreateVertexBuffer,
-    XCAST(EnumZBufferFormats) Thunk_IDirect3DImpl_3_EnumZBufferFormats,
-    XCAST(EvictManagedTextures) Thunk_IDirect3DImpl_3_EvictManagedTextures,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3D2.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3D2Vtbl VTABLE_IDirect3D2 =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef,
-    XCAST(Release) Thunk_IDirect3DImpl_2_Release,
-    XCAST(EnumDevices) GL_IDirect3DImpl_2_EnumDevices,
-    XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight,
-    XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial,
-    XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport,
-    XCAST(FindDevice) Thunk_IDirect3DImpl_2_FindDevice,
-    XCAST(CreateDevice) GL_IDirect3DImpl_2_CreateDevice,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3D.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DVtbl VTABLE_IDirect3D =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DImpl_1_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef,
-    XCAST(Release) Thunk_IDirect3DImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DImpl_1_Initialize,
-    XCAST(EnumDevices) GL_IDirect3DImpl_1_EnumDevices,
-    XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight,
-    XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial,
-    XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport,
-    XCAST(FindDevice) Thunk_IDirect3DImpl_1_FindDevice,
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-static HRESULT d3d_add_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
-{
-    if  (This->current_device == NULL) {
-        /* Create delayed textures now that we have an OpenGL context...
-	   For that, go through all surface attached to our DDraw object and create
-	   OpenGL textures for all textures.. */
-        IDirectDrawSurfaceImpl *surf = This->surfaces;
-
-	while (surf != NULL) {
-	    if (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
-	        /* Found a texture.. Now create the OpenGL part */
-	        d3dtexture_create(This, surf, FALSE, surf->mip_main);
-	    }
-	    surf = surf->next_ddraw;
-	}
-    }
-    /* For the moment, only one device 'supported'... */
-    This->current_device = device;
-
-    return DD_OK;
-}
-
-static HRESULT d3d_remove_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
-{
-    This->current_device = NULL;
-    return DD_OK;
-}
-
-HRESULT direct3d_create(IDirectDrawImpl *This)
-{
-    IDirect3DGLImpl *globject;
-    
-    globject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DGLImpl));
-    if (globject == NULL) return DDERR_OUTOFMEMORY;
-
-    This->d3d_create_texture = d3dtexture_create;
-    This->d3d_added_device = d3d_add_device;
-    This->d3d_removed_device = d3d_remove_device;
-
-    ICOM_INIT_INTERFACE(This, IDirect3D,  VTABLE_IDirect3D);
-    ICOM_INIT_INTERFACE(This, IDirect3D2, VTABLE_IDirect3D2);
-    ICOM_INIT_INTERFACE(This, IDirect3D3, VTABLE_IDirect3D3);
-    ICOM_INIT_INTERFACE(This, IDirect3D7, VTABLE_IDirect3D7);
-
-    This->d3d_private = globject;
-
-    TRACE(" creating OpenGL private storage at %p.\n", globject);
-    
-    return D3D_OK;
-}
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c
index 274c2a0..683ffe3 100644
--- a/dlls/ddraw/executebuffer.c
+++ b/dlls/ddraw/executebuffer.c
@@ -1,8 +1,9 @@
 /* Direct3D ExecuteBuffer
  * Copyright (c) 1998-2004 Lionel ULMER
  * Copyright (c) 2002-2004 Christian Costa
+ * Copyright (c) 2006      Stefan Dösinger
  *
- * This file contains the implementation of Direct3DExecuteBuffer.
+ * This file contains the implementation of IDirect3DExecuteBuffer.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,38 +21,45 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
+#include <assert.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stdlib.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
+
+#include "ddraw_private.h"
 #include "wine/debug.h"
 
-#include "d3d_private.h"
-#include "opengl_private.h"
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
 
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
-
-static void _dump_d3dstatus(LPD3DSTATUS lpStatus) {
-
-}
+/*****************************************************************************
+ * _dump_executedata
+ * _dump_D3DEXECUTEBUFFERDESC
+ *
+ * Debug functions which write the executebuffer data to the console
+ *
+ *****************************************************************************/
 
 static void _dump_executedata(LPD3DEXECUTEDATA lpData) {
     DPRINTF("dwSize : %ld\n", lpData->dwSize);
     DPRINTF("Vertex      Offset : %ld  Count  : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
     DPRINTF("Instruction Offset : %ld  Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
     DPRINTF("HVertex     Offset : %ld\n", lpData->dwHVertexOffset);
-    _dump_d3dstatus(&(lpData->dsStatus));
 }
 
 static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc) {
@@ -62,9 +70,28 @@
     DPRINTF("lpData       : %p\n", lpDesc->lpData);
 }
 
-static void execute(IDirect3DExecuteBufferImpl *This,
-		    IDirect3DDeviceImpl *lpDevice,
-		    IDirect3DViewportImpl *lpViewport)
+/*****************************************************************************
+ * IDirect3DExecuteBufferImpl_Execute
+ *
+ * The main functionality of the execute buffer
+ * It transforms the vertices if necessary, and calls IDirect3DDevice7
+ * for drawing the vertices. It is called from
+ * IDirect3DDevice::Execute
+ *
+ * TODO: Perhaps some comments about the varios opcodes wouldn't hurt
+ *
+ * Don't declare this static, as it's called from device.c,
+ * IDirect3DDevice::Execute
+ *
+ * Params:
+ *  Device: 3D Device associated to use for drawing
+ *  Viewport: Viewport for this operation
+ *
+ *****************************************************************************/
+void
+IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
+                                   IDirect3DDeviceImpl *lpDevice,
+                                   IDirect3DViewportImpl *lpViewport)
 {
     /* DWORD bs = This->desc.dwBufferSize; */
     DWORD vs = This->data.dwVertexOffset;
@@ -81,7 +108,7 @@
     lpViewport->activate(lpViewport);
 
     TRACE("ExecuteData :\n");
-    if (TRACE_ON(ddraw))
+    if (TRACE_ON(d3d7))
       _dump_executedata(&(This->data));
 
     while (1) {
@@ -117,32 +144,39 @@
 			
 		for (i = 0; i < count; i++) {
                     LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr;
-		    TRACE_(ddraw_geom)("  v1: %d  v2: %d  v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3);
-		    TRACE_(ddraw_geom)("  Flags : ");
-		    if (TRACE_ON(ddraw)) {
+		    TRACE_(d3d7)("  v1: %d  v2: %d  v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3);
+		    TRACE_(d3d7)("  Flags : ");
+		    if (TRACE_ON(d3d7)) {
 			/* Wireframe */
 			if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
-	        	    TRACE_(ddraw_geom)("EDGEENABLE1 ");
+	        	    TRACE_(d3d7)("EDGEENABLE1 ");
 	    		if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2)
-	        	    TRACE_(ddraw_geom)("EDGEENABLE2 ");
+	        	    TRACE_(d3d7)("EDGEENABLE2 ");
 	    		if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
-	        	    TRACE_(ddraw_geom)("EDGEENABLE3 ");
+	        	    TRACE_(d3d7)("EDGEENABLE3 ");
 	    		/* Strips / Fans */
 	    		if (ci->wFlags == D3DTRIFLAG_EVEN)
-	        	    TRACE_(ddraw_geom)("EVEN ");
+	        	    TRACE_(d3d7)("EVEN ");
 	    		if (ci->wFlags == D3DTRIFLAG_ODD)
-	        	    TRACE_(ddraw_geom)("ODD ");
+	        	    TRACE_(d3d7)("ODD ");
 	    		if (ci->wFlags == D3DTRIFLAG_START)
-	        	    TRACE_(ddraw_geom)("START ");
+	        	    TRACE_(d3d7)("START ");
 	    		if ((ci->wFlags > 0) && (ci->wFlags < 30))
-	       		    TRACE_(ddraw_geom)("STARTFLAT(%d) ", ci->wFlags);
-	    		TRACE_(ddraw_geom)("\n");
+	       		    TRACE_(d3d7)("STARTFLAT(%d) ", ci->wFlags);
+	    		TRACE_(d3d7)("\n");
         	    }
 		    This->indices[(i * 3)    ] = ci->u1.v1;
 		    This->indices[(i * 3) + 1] = ci->u2.v2;
 		    This->indices[(i * 3) + 2] = ci->u3.v3;
                     instr += size;
 		}
+                /* IDirect3DDevices have color keying always enabled -
+                 * enable it before drawing. This overwrites any ALPHA*
+                 * render state
+                 */
+                IWineD3DDevice_SetRenderState(lpDevice->wineD3DDevice,
+                                              WINED3DRS_COLORKEYENABLE,
+                                              1);
                 IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(lpDevice,IDirect3DDevice7),
 				                      D3DPT_TRIANGLELIST,D3DFVF_TLVERTEX,tl_vx,0,This->indices,count*3,0);
 	    } break;
@@ -264,9 +298,27 @@
 		}
 	    } break;
 
-	    case D3DOP_PROCESSVERTICES: {
-	        int i;
-		TRACE("PROCESSVERTICES  (%d)\n", count);
+            case D3DOP_PROCESSVERTICES:
+            {
+                /* TODO: Share code with IDirect3DVertexBuffer::ProcessVertices and / or
+                 * IWineD3DDevice::ProcessVertices
+                 */
+                int i;
+                D3DMATRIX view_mat, world_mat, proj_mat;
+                TRACE("PROCESSVERTICES  (%d)\n", count);
+
+                /* Get the transform and world matrix */
+                IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice,
+                                            D3DTRANSFORMSTATE_VIEW,
+                                            &view_mat);
+
+                IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice,
+                                            D3DTRANSFORMSTATE_PROJECTION,
+                                            &proj_mat);
+
+                IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice,
+                                            D3DTRANSFORMSTATE_WORLD,
+                                            &world_mat);
 
 		for (i = 0; i < count; i++) {
 		    LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;
@@ -274,7 +326,7 @@
 		    TRACE("  Start : %d Dest : %d Count : %ld\n",
 			  ci->wStart, ci->wDest, ci->dwCount);
 		    TRACE("  Flags : ");
-		    if (TRACE_ON(ddraw)) {
+		    if (TRACE_ON(d3d7)) {
 		        if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
 			    TRACE("COPY ");
 			if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
@@ -321,22 +373,22 @@
 		        unsigned int nb;
 			D3DVERTEX  *src = ((LPD3DVERTEX)  ((char *)This->desc.lpData + vs)) + ci->wStart;
 			D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (This->vertex_data)) + ci->wDest;
-			D3DMATRIX *mat2 = lpDevice->world_mat;
+			D3DMATRIX *mat2 = &world_mat;
 			D3DMATRIX mat;
 			D3DVALUE nx,ny,nz;
 			D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1;
 			
-			if (TRACE_ON(ddraw)) {
-			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
-			    dump_D3DMATRIX(lpDevice->proj_mat);
-			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
-			    dump_D3DMATRIX(lpDevice->view_mat);
-			    TRACE("  World Matrix : (%p)\n", lpDevice->world_mat);
-			    dump_D3DMATRIX(lpDevice->world_mat);
+			if (TRACE_ON(d3d7)) {
+			    TRACE("  Projection Matrix : (%p)\n", &proj_mat);
+			    dump_D3DMATRIX(&proj_mat);
+			    TRACE("  View       Matrix : (%p)\n", &view_mat);
+			    dump_D3DMATRIX(&view_mat);
+			    TRACE("  World Matrix : (%p)\n", &world_mat);
+			    dump_D3DMATRIX(&world_mat);
 			}
 
-			multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat);
-			multiply_matrix(&mat,lpDevice->proj_mat,&mat);
+                        multiply_matrix(&mat,&view_mat,&world_mat);
+                        multiply_matrix(&mat,&proj_mat,&mat);
 
 			for (nb = 0; nb < ci->dwCount; nb++) {
 			    /* Normals transformation */
@@ -375,17 +427,17 @@
 			D3DMATRIX mat;
 			D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1;
 			
-			if (TRACE_ON(ddraw)) {
-			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
-			    dump_D3DMATRIX(lpDevice->proj_mat);
-			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
-			    dump_D3DMATRIX(lpDevice->view_mat);
+			if (TRACE_ON(d3d7)) {
+			    TRACE("  Projection Matrix : (%p)\n", &proj_mat);
+			    dump_D3DMATRIX(&proj_mat);
+			    TRACE("  View       Matrix : (%p)\n",&view_mat);
+			    dump_D3DMATRIX(&view_mat);
 			    TRACE("  World Matrix : (%p)\n", &mat);
 			    dump_D3DMATRIX(&mat);
 			}
 
-			multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat);
-			multiply_matrix(&mat,lpDevice->proj_mat,&mat);
+			multiply_matrix(&mat,&view_mat,&world_mat);
+			multiply_matrix(&mat,&proj_mat,&mat);
 
 			for (nb = 0; nb < ci->dwCount; nb++) {
 			    dst->u5.color = src->u4.color;
@@ -490,50 +542,85 @@
     ;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface,
-                                                 REFIID riid,
-                                                 LPVOID* obp)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::QueryInterface
+ *
+ * Well, a usual QueryInterface function. Don't know fur sure which
+ * interfaces it can Query.
+ *
+ * Params:
+ *  riid: The interface ID queried for
+ *  obj: Address to return the interface pointer at
+ *
+ * Returns:
+ *  D3D_OK in case of a success (S_OK? Think it's the same)
+ *  OLE_E_ENUM_NOMORE if the interface wasn't found.
+ *   (E_NOINTERFACE?? Don't know what I really need)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_QueryInterface(IDirect3DExecuteBuffer *iface,
+                                          REFIID riid,
+                                          void **obj)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
-    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obj);
 
-    *obp = NULL;
+    *obj = NULL;
 
     if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
         IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
-	*obp = iface;
-	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	*obj = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obj);
 	return S_OK;
     }
     if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) {
         IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
-        *obp = ICOM_INTERFACE(This, IDirect3DExecuteBuffer);
-	TRACE("  Creating IDirect3DExecuteBuffer interface %p\n", *obp);
+        *obj = ICOM_INTERFACE(This, IDirect3DExecuteBuffer);
+	TRACE("  Creating IDirect3DExecuteBuffer interface %p\n", *obj);
 	return S_OK;
     }
     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
+    return E_NOINTERFACE;
 }
 
-ULONG WINAPI
-Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface)
+
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::AddRef
+ *
+ * A normal AddRef method, nothing special
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DExecuteBufferImpl_AddRef(IDirect3DExecuteBuffer *iface)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
-    FIXME("(%p/%p)->()incrementing from %lu.\n", This, iface, ref - 1);
+    FIXME("(%p)->()incrementing from %lu.\n", This, ref - 1);
 
     return ref;
 }
 
-ULONG WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Release
+ *
+ * A normal Release method, nothing special
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DExecuteBufferImpl_Release(IDirect3DExecuteBuffer *iface)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p/%p)->()decrementing from %lu.\n", This, iface, ref + 1);
+    TRACE("(%p)->()decrementing from %lu.\n", This, ref + 1);
 
     if (!ref) {
         if (This->need_free)
@@ -547,50 +634,96 @@
     return ref;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface,
-                                             LPDIRECT3DDEVICE lpDirect3DDevice,
-                                             LPD3DEXECUTEBUFFERDESC lpDesc)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Initialize
+ *
+ * Initializes the Execute Buffer. This method exists for COM compliance
+ * Nothing to do here.
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_Initialize(IDirect3DExecuteBuffer *iface,
+                                        IDirect3DDevice *lpDirect3DDevice,
+                                        D3DEXECUTEBUFFERDESC *lpDesc)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
-    TRACE("(%p/%p)->(%p,%p) no-op....\n", This, iface, lpDirect3DDevice, lpDesc);
-    return DD_OK;
+    TRACE("(%p)->(%p,%p) no-op....\n", This, lpDirect3DDevice, lpDesc);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface,
-                                       LPD3DEXECUTEBUFFERDESC lpDesc)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Lock
+ *
+ * Locks the buffer, so the app can write into it.
+ *
+ * Params:
+ *  Desc: Pointer to return the buffer description. This Description contains
+ *        a pointer to the buffer data.
+ *
+ * Returns:
+ *  This implementation always returns D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_Lock(IDirect3DExecuteBuffer *iface,
+                                D3DEXECUTEBUFFERDESC *lpDesc)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     DWORD dwSize;
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDesc);
+    TRACE("(%p)->(%p)\n", This, lpDesc);
 
     dwSize = lpDesc->dwSize;
     memset(lpDesc, 0, dwSize);
     memcpy(lpDesc, &This->desc, dwSize);
     
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  Returning description :\n");
 	_dump_D3DEXECUTEBUFFERDESC(lpDesc);
     }
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Unlock
+ *
+ * Unlocks the buffer. We don't have anything to do here
+ *
+ * Returns:
+ *  This implementation always returns D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_Unlock(IDirect3DExecuteBuffer *iface)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
-    TRACE("(%p/%p)->() no-op...\n", This, iface);
-    return DD_OK;
+    TRACE("(%p)->() no-op...\n", This);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
-                                                 LPD3DEXECUTEDATA lpData)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::SetExecuteData
+ *
+ * Sets the execute data. This data is used to describe the buffer's content
+ *
+ * Params:
+ *  Data: Pointer to a D3DEXECUTEDATA structure containing the data to
+ *  assign
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_OUTOFMEMORY if the vertex buffer allocation failed
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_SetExecuteData(IDirect3DExecuteBuffer *iface,
+                                          D3DEXECUTEDATA *lpData)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     DWORD nbvert;
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+    TRACE("(%p)->(%p)\n", This, lpData);
 
     memcpy(&This->data, lpData, lpData->dwSize);
 
@@ -601,26 +734,38 @@
     HeapFree(GetProcessHeap(), 0, This->vertex_data);
     This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX));
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         _dump_executedata(lpData);
     }
 
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
-                                                 LPD3DEXECUTEDATA lpData)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::GetExecuteData
+ *
+ * Returns the data in the execute buffer
+ *
+ * Params:
+ *  Data: Pointer to a D3DEXECUTEDATA structure used to return data
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_GetExecuteData(IDirect3DExecuteBuffer *iface,
+                                          D3DEXECUTEDATA *lpData)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     DWORD dwSize;
-    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpData);
+    TRACE("(%p)->(%p): stub!\n", This, lpData);
 
     dwSize = lpData->dwSize;
     memset(lpData, 0, dwSize);
     memcpy(lpData, &This->data, dwSize);
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("Returning data :\n");
 	_dump_executedata(lpData);
     }
@@ -628,96 +773,63 @@
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface,
-                                           LPDWORD lpdwOffset,
-                                           LPD3DVALIDATECALLBACK lpFunc,
-                                           LPVOID lpUserArg,
-                                           DWORD dwReserved)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Validate
+ *
+ * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
+ * currently implemented"
+ *
+ * Params:
+ *  ?
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED, because it's not implemented in Windows.
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_Validate(IDirect3DExecuteBuffer *iface,
+                                    DWORD *Offset,
+                                    LPD3DVALIDATECALLBACK Func,
+                                    void *UserArg,
+                                    DWORD Reserved)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
-    FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This, iface, lpdwOffset, lpFunc, lpUserArg, dwReserved);
-    return DD_OK;
+    TRACE("(%p)->(%p,%p,%p,%08lx): Unimplemented!\n", This, Offset, Func, UserArg, Reserved);
+    return DDERR_UNSUPPORTED; /* Unchecked */
 }
 
-HRESULT WINAPI
-Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface,
-                                           DWORD dwDummy)
+/*****************************************************************************
+ * IDirect3DExecuteBuffer::Optimize
+ *
+ * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
+ * currently supported"
+ *
+ * Params:
+ *  Dummy: Seems to be an unused dummy ;)
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED, because it's not implemented in Windows.
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DExecuteBufferImpl_Optimize(IDirect3DExecuteBuffer *iface,
+                                    DWORD Dummy)
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
-    TRACE("(%p/%p)->(%08lx) no-op...\n", This, iface, dwDummy);
-    return DD_OK;
+    TRACE("(%p)->(%08lx): Unimplemented\n", This, Dummy);
+    return DDERR_UNSUPPORTED; /* Unchecked */
 }
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DExecuteBuffer.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DExecuteBufferVtbl VTABLE_IDirect3DExecuteBuffer =
+const IDirect3DExecuteBufferVtbl IDirect3DExecuteBuffer_Vtbl =
 {
-    XCAST(QueryInterface) Main_IDirect3DExecuteBufferImpl_1_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DExecuteBufferImpl_1_AddRef,
-    XCAST(Release) Main_IDirect3DExecuteBufferImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DExecuteBufferImpl_1_Initialize,
-    XCAST(Lock) Main_IDirect3DExecuteBufferImpl_1_Lock,
-    XCAST(Unlock) Main_IDirect3DExecuteBufferImpl_1_Unlock,
-    XCAST(SetExecuteData) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData,
-    XCAST(GetExecuteData) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData,
-    XCAST(Validate) Main_IDirect3DExecuteBufferImpl_1_Validate,
-    XCAST(Optimize) Main_IDirect3DExecuteBufferImpl_1_Optimize,
+    IDirect3DExecuteBufferImpl_QueryInterface,
+    IDirect3DExecuteBufferImpl_AddRef,
+    IDirect3DExecuteBufferImpl_Release,
+    IDirect3DExecuteBufferImpl_Initialize,
+    IDirect3DExecuteBufferImpl_Lock,
+    IDirect3DExecuteBufferImpl_Unlock,
+    IDirect3DExecuteBufferImpl_SetExecuteData,
+    IDirect3DExecuteBufferImpl_GetExecuteData,
+    IDirect3DExecuteBufferImpl_Validate,
+    IDirect3DExecuteBufferImpl_Optimize,
 };
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
-{
-    IDirect3DExecuteBufferImpl* object;
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
-
-    ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, VTABLE_IDirect3DExecuteBuffer);
-    
-    object->ref = 1;
-    object->d3d = d3d;
-    object->d3ddev = d3ddev;
-
-    /* Initializes memory */
-    memcpy(&object->desc, lpDesc, lpDesc->dwSize);
-
-    /* No buffer given */
-    if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
-        object->desc.lpData = NULL;
-
-    /* No buffer size given */
-    if ((lpDesc->dwFlags & D3DDEB_BUFSIZE) == 0)
-        object->desc.dwBufferSize = 0;
-
-    /* Create buffer if asked */
-    if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0)) {
-        object->need_free = TRUE;
-	object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
-    } else {
-        object->need_free = FALSE;
-    }
-
-    /* No vertices for the moment */
-    object->vertex_data = NULL;
-
-    object->desc.dwFlags |= D3DDEB_LPDATA;
-
-    object->execute = execute;
-
-    object->indices = NULL;
-    object->nb_indices = 0;
-
-    *obj = object;
-
-    TRACE(" creating implementation at %p.\n", *obj);
-
-    return DD_OK;
-}
diff --git a/dlls/ddraw/gamma.c b/dlls/ddraw/gamma.c
new file mode 100644
index 0000000..0f3692b
--- /dev/null
+++ b/dlls/ddraw/gamma.c
@@ -0,0 +1,213 @@
+/* DirectDrawGammaControl implementation
+ *
+ * Copyright 2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
+
+/**********************************************************
+ * IUnkown parts follow
+ **********************************************************/
+
+/**********************************************************
+ * IDirectDrawGammaControl::QueryInterface
+ *
+ * QueryInterface, thunks to IDirectDrawSurface
+ *
+ * Params:
+ *  riid: Interface id queried for
+ *  obj: Returns the interface pointer
+ *
+ * Returns:
+ *  S_OK or E_NOINTERFACE: See IDirectDrawSurface7::QueryInterface
+ *
+ **********************************************************/
+static HRESULT WINAPI
+IDirectDrawGammaControlImpl_QueryInterface(IDirectDrawGammaControl *iface, REFIID riid,
+                                           void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p): Thunking to IDirectDrawSurface7\n", This, debugstr_guid(riid), obj);
+
+    return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7),
+                                              riid,
+                                              obj);
+}
+
+/**********************************************************
+ * IDirectDrawGammaControl::AddRef
+ *
+ * Addref, thunks to IDirectDrawSurface
+ *
+ * Returns:
+ *  The new refcount
+ *
+ **********************************************************/
+static ULONG WINAPI
+IDirectDrawGammaControlImpl_AddRef(IDirectDrawGammaControl *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
+    TRACE_(ddraw_thunk)("(%p)->() Thunking to IDirectDrawSurface7\n", This);
+
+    return IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
+}
+
+/**********************************************************
+ * IDirectDrawGammaControl::Release
+ *
+ * Release, thunks to IDirectDrawSurface
+ *
+ * Returns:
+ *  The new refcount
+ *
+ **********************************************************/
+static ULONG WINAPI
+IDirectDrawGammaControlImpl_Release(IDirectDrawGammaControl *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
+    TRACE_(ddraw_thunk)("(%p)->() Thunking to IDirectDrawSurface7\n", This);
+
+    return IDirectDrawSurface7_Release(ICOM_INTERFACE(This, IDirectDrawSurface7));
+}
+
+/**********************************************************
+ * IDirectDrawGammaControl
+ **********************************************************/
+
+/**********************************************************
+ * IDirectDrawGammaControl::GetGammaRamp
+ *
+ * Returns the current gamma ramp for a surface
+ *
+ * Params:
+ *  Flags: Ignored
+ *  GammaRamp: Address to write the ramp to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if GammaRamp is NULL
+ *
+ **********************************************************/
+static HRESULT WINAPI
+IDirectDrawGammaControlImpl_GetGammaRamp(IDirectDrawGammaControl *iface,
+                                         DWORD Flags,
+                                         DDGAMMARAMP *GammaRamp)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
+    TRACE("(%p)->(%08lx,%p)\n", This,Flags,GammaRamp);
+
+    /* This looks sane */
+    if(!GammaRamp)
+    {
+        ERR("(%p) GammaRamp is NULL, returning DDERR_INVALIDPARAMS\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+        /* This returns a void */
+        IWineD3DDevice_GetGammaRamp(This->ddraw->wineD3DDevice,
+                                    0 /* Swapchain */,
+                                    (WINED3DGAMMARAMP *) GammaRamp);
+    }
+    else
+    {
+        ERR("(%p) Unimplemented for non-primary surfaces\n", This);
+    }
+
+    return DD_OK;
+}
+
+/**********************************************************
+ * IDirectDrawGammaControl::SetGammaRamp
+ *
+ * Sets the red, green and blue gamma ramps for
+ *
+ * Params:
+ *  Flags: Can be DDSGR_CALIBRATE to request calibration
+ *  GammaRamp: Structure containing the new gamma ramp
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if GammaRamp is NULL
+ *
+ **********************************************************/
+static HRESULT WINAPI
+IDirectDrawGammaControlImpl_SetGammaRamp(IDirectDrawGammaControl *iface,
+                                         DWORD Flags,
+                                         DDGAMMARAMP *GammaRamp)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
+    TRACE("(%p)->(%08lx,%p)\n", This,Flags,GammaRamp);
+
+    /* This looks sane */
+    if(!GammaRamp)
+    {
+        ERR("(%p) GammaRamp is NULL, returning DDERR_INVALIDPARAMS\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+        /* This returns a void */
+        IWineD3DDevice_SetGammaRamp(This->ddraw->wineD3DDevice,
+                                    0 /* Swapchain */,
+                                    Flags,
+                                    (WINED3DGAMMARAMP *) GammaRamp);
+    }
+    else
+    {
+        ERR("(%p) Unimplemented for non-primary surfaces\n", This);
+    }
+
+    return DD_OK;
+}
+
+const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl =
+{
+    IDirectDrawGammaControlImpl_QueryInterface,
+    IDirectDrawGammaControlImpl_AddRef,
+    IDirectDrawGammaControlImpl_Release,
+    IDirectDrawGammaControlImpl_GetGammaRamp,
+    IDirectDrawGammaControlImpl_SetGammaRamp
+};
diff --git a/dlls/ddraw/gl_api.h b/dlls/ddraw/gl_api.h
deleted file mode 100644
index 05735e4..0000000
--- a/dlls/ddraw/gl_api.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* GL API list
- * Copyright (c) 2003 Lionel Ulmer / Mike McCormack
- *
- * This file contains all structures that are not exported
- * through d3d.h and all common macros.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/* Note : this file is NOT protected against double-inclusion for pretty good
-          reasons :-) */
-
-#ifndef GL_API_FUNCTION
-#error "This file should be included with GL_API_FUNCTION defined !"
-#endif
-
-GL_API_FUNCTION(glAlphaFunc)
-GL_API_FUNCTION(glBegin)
-GL_API_FUNCTION(glBindTexture)
-GL_API_FUNCTION(glBlendFunc)
-GL_API_FUNCTION(glClear)
-GL_API_FUNCTION(glClearColor)
-GL_API_FUNCTION(glClearDepth)
-GL_API_FUNCTION(glClearStencil)
-GL_API_FUNCTION(glClipPlane)
-GL_API_FUNCTION(glColor3f)
-GL_API_FUNCTION(glColor3ub)
-GL_API_FUNCTION(glColor4ub)
-GL_API_FUNCTION(glColorMask)
-GL_API_FUNCTION(glColorMaterial)
-GL_API_FUNCTION(glColorPointer)
-GL_API_FUNCTION(glCopyPixels)
-GL_API_FUNCTION(glCopyTexSubImage2D)
-GL_API_FUNCTION(glCullFace)
-GL_API_FUNCTION(glDeleteTextures)
-GL_API_FUNCTION(glDepthFunc)
-GL_API_FUNCTION(glDepthMask)
-GL_API_FUNCTION(glDepthRange)
-GL_API_FUNCTION(glDisable)
-GL_API_FUNCTION(glDisableClientState)
-GL_API_FUNCTION(glDrawArrays)
-GL_API_FUNCTION(glDrawBuffer)
-GL_API_FUNCTION(glDrawElements)
-GL_API_FUNCTION(glDrawPixels)
-GL_API_FUNCTION(glEnable)
-GL_API_FUNCTION(glEnableClientState)
-GL_API_FUNCTION(glEnd)
-GL_API_FUNCTION(glFlush)
-GL_API_FUNCTION(glFogf)
-GL_API_FUNCTION(glFogfv)
-GL_API_FUNCTION(glFogi)
-GL_API_FUNCTION(glFrontFace)
-GL_API_FUNCTION(glGenTextures)
-GL_API_FUNCTION(glGetBooleanv)
-GL_API_FUNCTION(glGetError)
-GL_API_FUNCTION(glGetFloatv)
-GL_API_FUNCTION(glGetIntegerv)
-GL_API_FUNCTION(glGetString)
-GL_API_FUNCTION(glGetTexEnviv)
-GL_API_FUNCTION(glGetTexParameteriv)
-GL_API_FUNCTION(glHint)
-GL_API_FUNCTION(glLightModelfv)
-GL_API_FUNCTION(glLightModeli)
-GL_API_FUNCTION(glLightfv)
-GL_API_FUNCTION(glLoadIdentity)
-GL_API_FUNCTION(glLoadMatrixf)
-GL_API_FUNCTION(glMaterialf)
-GL_API_FUNCTION(glMaterialfv)
-GL_API_FUNCTION(glMatrixMode)
-GL_API_FUNCTION(glMultMatrixf)
-GL_API_FUNCTION(glNormal3f)
-GL_API_FUNCTION(glNormal3fv)
-GL_API_FUNCTION(glNormalPointer)
-GL_API_FUNCTION(glOrtho)
-GL_API_FUNCTION(glPixelStorei)
-GL_API_FUNCTION(glPolygonMode)
-GL_API_FUNCTION(glPolygonOffset)
-GL_API_FUNCTION(glPopMatrix)
-GL_API_FUNCTION(glPushMatrix)
-GL_API_FUNCTION(glRasterPos2i)
-GL_API_FUNCTION(glRasterPos3d)
-GL_API_FUNCTION(glReadBuffer)
-GL_API_FUNCTION(glReadPixels)
-GL_API_FUNCTION(glScissor)
-GL_API_FUNCTION(glShadeModel)
-GL_API_FUNCTION(glStencilFunc)
-GL_API_FUNCTION(glStencilMask)
-GL_API_FUNCTION(glStencilOp)
-GL_API_FUNCTION(glTexCoord1fv)
-GL_API_FUNCTION(glTexCoord2f)
-GL_API_FUNCTION(glTexCoord2fv)
-GL_API_FUNCTION(glTexCoord3fv)
-GL_API_FUNCTION(glTexCoord4fv)
-GL_API_FUNCTION(glTexCoordPointer)
-GL_API_FUNCTION(glTexEnvf)
-GL_API_FUNCTION(glTexEnvfv)
-GL_API_FUNCTION(glTexEnvi)
-GL_API_FUNCTION(glTexImage2D)
-GL_API_FUNCTION(glTexParameteri)
-GL_API_FUNCTION(glTexParameterfv)
-GL_API_FUNCTION(glTexSubImage2D)
-GL_API_FUNCTION(glTranslatef)
-GL_API_FUNCTION(glVertex3d)
-GL_API_FUNCTION(glVertex3f)
-GL_API_FUNCTION(glVertex3fv)
-GL_API_FUNCTION(glVertex4f)
-GL_API_FUNCTION(glVertexPointer)
-GL_API_FUNCTION(glViewport)
-GL_API_FUNCTION(glXCreateContext)
-GL_API_FUNCTION(glXDestroyContext)
-GL_API_FUNCTION(glXMakeCurrent)
-GL_API_FUNCTION(glXQueryExtensionsString)
-GL_API_FUNCTION(glXSwapBuffers)
diff --git a/dlls/ddraw/gl_private.h b/dlls/ddraw/gl_private.h
deleted file mode 100644
index 7b9daca..0000000
--- a/dlls/ddraw/gl_private.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* GL 'hack' private include file
- * Copyright (c) 2003 Lionel Ulmer / Mike McCormack
- *
- * This file contains all structures that are not exported
- * through d3d.h and all common macros.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __GRAPHICS_WINE_GL_PRIVATE_H
-#define __GRAPHICS_WINE_GL_PRIVATE_H
-
-#ifdef HAVE_OPENGL
-
-#undef APIENTRY
-#undef CALLBACK
-#undef WINAPI
-
-#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */
-#include <GL/gl.h>
-#include <GL/glx.h>
-#ifdef HAVE_GL_GLEXT_H
-# include <GL/glext.h>
-#endif
-#undef  XMD_H
-
-#undef APIENTRY
-#undef CALLBACK
-#undef WINAPI
-
-/* Redefines the constants */
-#define CALLBACK    __stdcall
-#define WINAPI      __stdcall
-#define APIENTRY    WINAPI
-
-#define GL_API_FUNCTION(f) extern typeof(f) * p##f;
-#include "gl_api.h"
-#undef GL_API_FUNCTION
-
-/* This is also where I store our private extension defines...
-   I know that Raphael won't like it, but well, I prefer doing that than battling 10 different headers :-)
-
-   Note: this is perfectly 'legal' as the three variants of the enum have exactly the same value
-*/
-#define GL_MIRRORED_REPEAT_WINE                 0x8370
-#define GL_TEXTURE_FILTER_CONTROL_WINE          0x8500
-#define GL_TEXTURE_LOD_BIAS_WINE                0x8501
-#define GL_TEXTURE0_WINE                        0x84C0
-#define GL_TEXTURE1_WINE                        0x84C1
-#define GL_TEXTURE2_WINE                        0x84C2
-#define GL_TEXTURE3_WINE                        0x84C3
-#define GL_TEXTURE4_WINE                        0x84C4
-#define GL_TEXTURE5_WINE                        0x84C5
-#define GL_TEXTURE6_WINE                        0x84C6
-#define GL_TEXTURE7_WINE                        0x84C7
-#define GL_MAX_TEXTURE_UNITS_WINE               0x84E2
-
-#ifndef GLPRIVATE_NO_REDEFINE
-
-#define glAlphaFunc pglAlphaFunc
-#define glBegin pglBegin
-#define glBindTexture pglBindTexture
-#define glBlendFunc pglBlendFunc
-#define glClear pglClear
-#define glClearColor pglClearColor
-#define glClearDepth pglClearDepth
-#define glClearStencil pglClearStencil
-#define glClipPlane pglClipPlane
-#define glColor3f pglColor3f
-#define glColor3ub pglColor3ub
-#define glColor4ub pglColor4ub
-#define glColorMask pglColorMask
-#define glColorPointer pglColorPointer
-#define glCopyPixels pglCopyPixels
-#define glCopyTexSubImage2D pglCopyTexSubImage2D
-#define glColorMaterial pglColorMaterial
-#define glCullFace pglCullFace
-#define glDeleteTextures pglDeleteTextures
-#define glDepthFunc pglDepthFunc
-#define glDepthMask pglDepthMask
-#define glDepthRange pglDepthRange
-#define glDisable pglDisable
-#define glDisableClientState pglDisableClientState
-#define glDrawArrays pglDrawArrays
-#define glDrawBuffer pglDrawBuffer
-#define glDrawElements pglDrawElements
-#define glDrawPixels pglDrawPixels
-#define glEnable pglEnable
-#define glEnableClientState pglEnableClientState
-#define glEnd pglEnd
-#define glFlush pglFlush
-#define glFogf pglFogf
-#define glFogfv pglFogfv
-#define glFogi pglFogi
-#define glFrontFace pglFrontFace
-#define glGenTextures pglGenTextures
-#define glGetBooleanv pglGetBooleanv
-#define glGetError pglGetError
-#define glGetFloatv pglGetFloatv
-#define glGetIntegerv pglGetIntegerv
-#define glGetString pglGetString
-#define glGetTexEnviv pglGetTexEnviv
-#define glGetTexParameteriv pglGetTexParameteriv
-#define glHint pglHint
-#define glLightModelfv pglLightModelfv
-#define glLightModeli pglLightModeli
-#define glLightfv pglLightfv
-#define glLoadIdentity pglLoadIdentity
-#define glLoadMatrixf pglLoadMatrixf
-#define glMaterialf pglMaterialf
-#define glMaterialfv pglMaterialfv
-#define glMatrixMode pglMatrixMode
-#define glMultMatrixf pglMultMatrixf
-#define glNormal3f pglNormal3f
-#define glNormal3fv pglNormal3fv
-#define glNormalPointer pglNormalPointer
-#define glOrtho pglOrtho
-#define glPixelStorei pglPixelStorei
-#define glPolygonMode pglPolygonMode
-#define glPolygonOffset pglPolygonOffset
-#define glPopMatrix pglPopMatrix
-#define glPushMatrix pglPushMatrix
-#define glRasterPos2i pglRasterPos2i
-#define glRasterPos3d pglRasterPos3d
-#define glReadBuffer pglReadBuffer
-#define glReadPixels pglReadPixels
-#define glScissor pglScissor
-#define glShadeModel pglShadeModel
-#define glStencilFunc pglStencilFunc
-#define glStencilMask pglStencilMask
-#define glStencilOp pglStencilOp
-#define glTexCoord1fv pglTexCoord1fv
-#define glTexCoord2f pglTexCoord2f
-#define glTexCoord2fv pglTexCoord2fv
-#define glTexCoord3fv pglTexCoord3fv
-#define glTexCoord4fv pglTexCoord4fv
-#define glTexCoordPointer pglTexCoordPointer
-#define glTexEnvf pglTexEnvf
-#define glTexEnvfv pglTexEnvfv
-#define glTexEnvi pglTexEnvi
-#define glTexImage2D pglTexImage2D
-#define glTexParameteri pglTexParameteri
-#define glTexParameterfv pglTexParameterfv
-#define glTexSubImage2D pglTexSubImage2D
-#define glTranslatef pglTranslatef
-#define glVertex3d pglVertex3d
-#define glVertex3f pglVertex3f
-#define glVertex3fv pglVertex3fv
-#define glVertex4f pglVertex4f
-#define glVertexPointer pglVertexPointer
-#define glViewport pglViewport
-#define glXCreateContext pglXCreateContext
-#define glXDestroyContext pglXDestroyContext
-#define glXMakeCurrent pglXMakeCurrent
-#define glXQueryExtensionsString pglXQueryExtensionsString
-#define glXSwapBuffers pglXSwapBuffers
-
-#endif /* GLPRIVATE_NO_REDEFINE */
-
-#endif /* HAVE_OPENGL */
-
-#endif /* __GRAPHICS_WINE_GL_PRIVATE_H */
diff --git a/dlls/ddraw/light.c b/dlls/ddraw/light.c
index 82484e6..d5b7dd6 100644
--- a/dlls/ddraw/light.c
+++ b/dlls/ddraw/light.c
@@ -1,5 +1,6 @@
 /* Direct3D Light
  * Copyright (c) 1998 / 2002 Lionel ULMER
+ * Copyright (c) 2006        Stefan DÖSINGER
  *
  * This file contains the implementation of Direct3DLight.
  *
@@ -19,55 +20,96 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
 
+#include <assert.h>
 #include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
 
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
+#define COBJMACROS
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
-#include "wine/debug.h"
 
-#include "d3d_private.h"
-#include "opengl_private.h"
+#include "ddraw_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
 
-/* First, the 'main' interface... */
-HRESULT WINAPI
-Main_IDirect3DLightImpl_1_QueryInterface(LPDIRECT3DLIGHT iface,
-                                         REFIID riid,
-                                         LPVOID* obp)
+/*****************************************************************************
+ * IUnknown Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DLight::QueryInterface
+ *
+ * Queries the object for different interfaces. Unimplemented for this
+ * object at the moment
+ *
+ * Params:
+ *  riid: Interface id asked for
+ *  obj: Address to return the resulting pointer at.
+ *
+ * Returns:
+ *  E_NOINTERFACE, because it's a stub
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DLightImpl_QueryInterface(IDirect3DLight *iface,
+                                  REFIID riid,
+                                  void **obp)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
-    FIXME("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
-    return DD_OK;
+    FIXME("(%p)->(%s,%p): stub!\n", This, debugstr_guid(riid), obp);
+    *obp = NULL;
+    return E_NOINTERFACE;
 }
 
-ULONG WINAPI
-Main_IDirect3DLightImpl_1_AddRef(LPDIRECT3DLIGHT iface)
+/*****************************************************************************
+ * IDirect3DLight::AddRef
+ *
+ * Increases the refcount by 1
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DLightImpl_AddRef(IDirect3DLight *iface)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
-    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
 
     return ref;
 }
 
-ULONG WINAPI
-Main_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface)
+/*****************************************************************************
+ * IDirect3DLight::Release
+ *
+ * Reduces the refcount by one. If the refcount falls to 0, the object
+ * is destroyed
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DLightImpl_Release(IDirect3DLight *iface)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
 
     if (!ref) {
         HeapFree(GetProcessHeap(), 0, This);
@@ -76,16 +118,46 @@
     return ref;
 }
 
-HRESULT WINAPI
-Main_IDirect3DLightImpl_1_Initialize(LPDIRECT3DLIGHT iface,
-                                     LPDIRECT3D lpDirect3D)
+/*****************************************************************************
+ * IDirect3DLight Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DLight::Initialize
+ *
+ * Initializes the interface. This implementation is a no-op, because
+ * initialization takes place at creation time
+ *
+ * Params:
+ *  Direct3D: Pointer to an IDirect3D interface.
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DLightImpl_Initialize(IDirect3DLight *iface,
+                              IDirect3D *lpDirect3D)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
-    TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
-    return DD_OK;
+    IDirectDrawImpl *d3d = ICOM_OBJECT(IDirectDrawImpl, IDirect3D, lpDirect3D);
+    TRACE("(%p)->(%p) no-op...\n", This, d3d);
+    return D3D_OK;
 }
 
-/*** IDirect3DLight methods ***/
+/*****************************************************************************
+ * IDirect3DLight::SetLight
+ *
+ * Assigns a lighting value to this object
+ *
+ * Params:
+ *  Light: Lighting parametes to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Light is NULL
+ *
+ *****************************************************************************/
 static void dump_light(LPD3DLIGHT2 light)
 {
     DPRINTF("    - dwSize : %ld\n", light->dwSize);
@@ -95,14 +167,14 @@
     0.0, 0.0, 0.0, 0.0
 };
 
-HRESULT WINAPI
-Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface,
-                                   LPD3DLIGHT lpLight)
+static HRESULT WINAPI
+IDirect3DLightImpl_SetLight(IDirect3DLight *iface,
+                            D3DLIGHT *lpLight)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
     LPD3DLIGHT7 light7 = &(This->light7);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpLight);
-    if (TRACE_ON(ddraw)) {
+    TRACE("(%p)->(%p)\n", This, lpLight);
+    if (TRACE_ON(d3d7)) {
         TRACE("  Light definition :\n");
 	dump_light((LPD3DLIGHT2) lpLight);
     }
@@ -135,16 +207,28 @@
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
         This->update(This);        
     }
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DLightImpl_1_GetLight(LPDIRECT3DLIGHT iface,
-                                   LPD3DLIGHT lpLight)
+/*****************************************************************************
+ * IDirect3DLight::GetLight
+ *
+ * Returns the parameters currently assigned to the IDirect3DLight object
+ *
+ * Params:
+ *  Light: Pointer to an D3DLIGHT structure to store the parameters
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Light is NULL
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DLightImpl_GetLight(IDirect3DLight *iface,
+                            D3DLIGHT *lpLight)
 {
     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
     TRACE("(%p/%p)->(%p)\n", This, iface, lpLight);
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  Returning light definition :\n");
 	dump_light(&This->light);
     }
@@ -152,11 +236,13 @@
     return DD_OK;
 }
 
-/*******************************************************************************
- *				Light static functions
- */
-
-static void update(IDirect3DLightImpl* This)
+/*****************************************************************************
+ * light_update
+ *
+ * Updates the Direct3DDevice7 lighting parameters
+ *
+ *****************************************************************************/
+void light_update(IDirect3DLightImpl* This)
 {
     IDirect3DDeviceImpl* device;
 
@@ -169,7 +255,13 @@
     IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, &(This->light7));
 }
 
-static void activate(IDirect3DLightImpl* This)
+/*****************************************************************************
+ * light_activate
+ *
+ * Uses the Direct3DDevice7::LightEnable method to active the light
+ *
+ *****************************************************************************/
+void light_activate(IDirect3DLightImpl* This)
 {
     IDirect3DDeviceImpl* device;
 
@@ -179,7 +271,7 @@
         return;
     device =  This->active_viewport->active_device;
     
-    update(This);
+    light_update(This);
     /* If was not active, activate it */
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
         IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, TRUE);
@@ -187,7 +279,14 @@
     }
 }
 
-static void desactivate(IDirect3DLightImpl* This)
+/*****************************************************************************
+ *
+ * light_desactivate
+ *
+ * Uses the Direct3DDevice7::LightEnable method to deactivate the light
+ *
+ *****************************************************************************/
+void light_desactivate(IDirect3DLightImpl* This)
 {
     IDirect3DDeviceImpl* device;
 
@@ -204,64 +303,14 @@
     }
 }
 
-ULONG WINAPI
-GL_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface)
+const IDirect3DLightVtbl IDirect3DLight_Vtbl =
 {
-    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
-    ULONG ref = InterlockedDecrement(&This->ref);
-    
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
-
-    if (!ref) {
-        HeapFree(GetProcessHeap(), 0, This);
-	return 0;
-    }
-    return ref;
-}
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DLight.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DLightVtbl VTABLE_IDirect3DLight =
-{
-    XCAST(QueryInterface) Main_IDirect3DLightImpl_1_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DLightImpl_1_AddRef,
-    XCAST(Release) GL_IDirect3DLightImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DLightImpl_1_Initialize,
-    XCAST(SetLight) Main_IDirect3DLightImpl_1_SetLight,
-    XCAST(GetLight) Main_IDirect3DLightImpl_1_GetLight,
+    /*** IUnknown Methods ***/
+    IDirect3DLightImpl_QueryInterface,
+    IDirect3DLightImpl_AddRef,
+    IDirect3DLightImpl_Release,
+    /*** IDirect3DLight Methods ***/
+    IDirect3DLightImpl_Initialize,
+    IDirect3DLightImpl_SetLight,
+    IDirect3DLightImpl_GetLight
 };
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-
-
-HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d)
-{
-    IDirect3DLightImpl *object;
-    
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DLightImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
-    
-    object->ref = 1;
-    object->d3d = d3d;
-    object->next = NULL;
-    object->activate = activate;
-    object->desactivate = desactivate;
-    object->update = update;
-    object->active_viewport = NULL;
-    
-    ICOM_INIT_INTERFACE(object, IDirect3DLight, VTABLE_IDirect3DLight);
-
-    *obj = object;
-
-    TRACE(" creating implementation at %p.\n", *obj);
-    
-    return D3D_OK;
-}
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 96b7568..84f8823 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -1,8 +1,9 @@
-/*		DirectDraw Base Functions
+/*        DirectDraw Base Functions
  *
  * Copyright 1997-1999 Marcus Meissner
- * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
+ * Copyright 1998 Lionel Ulmer
  * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger
  *
  * This file contains the (internal) driver registration functions,
  * driver enumeration APIs and DirectDraw creation functions.
@@ -22,10 +23,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#define GLPRIVATE_NO_REDEFINE
-
 #include "config.h"
 #include "wine/port.h"
+#include "wine/debug.h"
 
 #include <assert.h>
 #include <stdarg.h>
@@ -41,518 +41,603 @@
 #include "wingdi.h"
 #include "wine/exception.h"
 #include "excpt.h"
+#include "winreg.h"
 
 #include "ddraw.h"
 #include "d3d.h"
 
-/* This for all the enumeration and creation of D3D-related objects */
 #include "ddraw_private.h"
-#include "wine/debug.h"
-#include "wine/library.h"
-
-#include "gl_private.h"
-
-#undef GLPRIVATE_NO_REDEFINE
-
-#define MAX_DDRAW_DRIVERS 3
-static const ddraw_driver* DDRAW_drivers[MAX_DDRAW_DRIVERS];
-static int DDRAW_num_drivers; /* = 0 */
-static int DDRAW_default_driver;
-
-void (*wine_tsx11_lock_ptr)(void) = NULL;
-void (*wine_tsx11_unlock_ptr)(void) = NULL;
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-/**********************************************************************/
+/* The driver's guid */
+GUID guid = {0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}};
 
-typedef struct {
-    LPVOID lpCallback;
-    LPVOID lpContext;
-} DirectDrawEnumerateProcData;
+/* The configured default surface */
+WINED3DSURFTYPE DefaultSurfaceType = SURFACE_UNKNOWN;
 
-BOOL opengl_initialized = 0;
-
-#ifdef HAVE_OPENGL
-
-#include "opengl_private.h"
-
-static void *gl_handle = NULL;
-
-#define GL_API_FUNCTION(f) typeof(f) * p##f;
-#include "gl_api.h"
-#undef GL_API_FUNCTION
-
-#ifndef SONAME_LIBGL
-#define SONAME_LIBGL "libGL.so"
-#endif
-
-static BOOL DDRAW_bind_to_opengl( void )
-{
-    const char *glname = SONAME_LIBGL;
-
-    gl_handle = wine_dlopen(glname, RTLD_NOW, NULL, 0);
-    if (!gl_handle) {
-        WARN("Wine cannot find the OpenGL graphics library (%s).\n",glname);
-	return FALSE;
-    }
-
-#define GL_API_FUNCTION(f)  \
-    if((p##f = wine_dlsym(gl_handle, #f, NULL, 0)) == NULL) \
-    { \
-        WARN("Can't find symbol %s\n", #f); \
-        goto sym_not_found; \
-    }
-#include "gl_api.h"
-#undef GL_API_FUNCTION
-
-    /* And now calls the function to initialize the various fields for the rendering devices */
-    return d3ddevice_init_at_startup(gl_handle);
-    
-sym_not_found:
-    WARN("Wine cannot find certain functions that it needs inside the OpenGL\n"
-	 "graphics library.  To enable Wine to use OpenGL please upgrade\n"
-	 "your OpenGL libraries\n");
-    wine_dlclose(gl_handle, NULL, 0);
-    gl_handle = NULL;
-    return FALSE;
-}
-
-#endif /* HAVE_OPENGL */
-
-BOOL s3tc_initialized = 0;
-
-static void *s3tc_handle = NULL;
-
-FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1;
-FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3;
-FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5;
-
-#ifndef SONAME_LIBTXC_DXTN
-#define SONAME_LIBTXC_DXTN "libtxc_dxtn.so"
-#endif
-
-static BOOL DDRAW_bind_to_s3tc( void )
-{
-    const char * const s3tcname = SONAME_LIBTXC_DXTN;
-
-    s3tc_handle = wine_dlopen(s3tcname, RTLD_NOW, NULL, 0);
-    if (!s3tc_handle) {
-        TRACE("No S3TC software decompression library seems to be present (%s).\n",s3tcname);
-	return FALSE;
-    }
-    TRACE("Found S3TC software decompression library (%s).\n",s3tcname);
-
-#define API_FUNCTION(f)  \
-    if((f = wine_dlsym(s3tc_handle, #f, NULL, 0)) == NULL) \
-    { \
-        WARN("Can't find symbol %s\n", #f); \
-        goto sym_not_found; \
-    }
-    API_FUNCTION(fetch_2d_texel_rgba_dxt1);
-    API_FUNCTION(fetch_2d_texel_rgba_dxt3);
-    API_FUNCTION(fetch_2d_texel_rgba_dxt5);
-#undef API_FUNCTION
-
-    return TRUE;
-    
-sym_not_found:
-    WARN("Wine cannot find functions that are necessary for S3TC software decompression\n");
-    wine_dlclose(s3tc_handle, NULL, 0);
-    s3tc_handle = NULL;
-    return FALSE;
-}
-
-/*******************************************************************************
- * DirectDrawEnumerateExA (DDRAW.@)
+/***********************************************************************
  *
- * Enumerates all DirectDraw devices installed on the system.
+ * Helper function for DirectDrawCreate and friends
+ * Creates a new DDraw interface with the given REFIID
  *
- * PARAMS
- *  lpCallback [I] DDEnumCallbackEx function to be called with a description of 
- *		   each enumerated HAL.
- *  lpContext  [I] application-defined value to be passed to the callback.
- *  dwFlags    [I] Specifies the enumeration scope. see msdn.
+ * Interfaces that can be created:
+ *  IDirectDraw, IDirectDraw2, IDirectDraw4, IDirectDraw7
+ *  IDirect3D, IDirect3D2, IDirect3D3, IDirect3D7. (Does Windows return
+ *  IDirect3D interfaces?)
  *
- * RETURNS
- *  Success: DD_OK.
- *  Failure: DDERR_INVALIDPARAMS
- */
-HRESULT WINAPI DirectDrawEnumerateExA(
-    LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
+ * Arguments:
+ *  guid: ID of the requested driver, NULL for the default driver.
+ *        The GUID can be queried with DirectDrawEnumerate(Ex)A/W
+ *  DD: Used to return the pointer to the created object
+ *  UnkOuter: For aggregation, which is unsupported. Must be NULL
+ *  iid: requested version ID.
+ *
+ * Returns:
+ *  DD_OK if the Interface was created sucessfully
+ *  CLASS_E_NOAGGREGATION if UnkOuter is not NULL
+ *  E_OUTOFMEMORY if some allocation failed
+ *
+ ***********************************************************************/
+static HRESULT
+DDRAW_Create(GUID *guid,
+             void **DD,
+             IUnknown *UnkOuter,
+             REFIID iid)
 {
-    int i;
-    BOOL stop = FALSE;
-    TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
+    IDirectDrawImpl *This = NULL;
+    HRESULT hr;
+    IWineD3D *wineD3D = NULL;
+    IWineD3DDevice *wineD3DDevice = NULL;
+    HDC hDC;
+    WINED3DDEVTYPE devicetype;
 
-    if (TRACE_ON(ddraw)) {
-	TRACE("  Flags : ");
-	if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
-	    TRACE("DDENUM_ATTACHEDSECONDARYDEVICES ");
-	if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
-	    TRACE("DDENUM_DETACHEDSECONDARYDEVICES ");
-	if (dwFlags & DDENUM_NONDISPLAYDEVICES)
-	    TRACE("DDENUM_NONDISPLAYDEVICES ");
-	TRACE("\n");
-    }
+    TRACE("(%s,%p,%p)\n", debugstr_guid(guid), DD, UnkOuter);
 
-    for (i=0; i<DDRAW_num_drivers; i++)
+    /* We don't care about this guids. Well, there's no special guid anyway
+     * OK, we could
+     */
+    if (guid == (GUID *) DDCREATE_EMULATIONONLY)
     {
-        TRACE("Enumerating %s/%s interface\n",
-	      DDRAW_drivers[i]->info->szDriver,
-	      DDRAW_drivers[i]->info->szDescription);
-
-	/* We have to pass NULL from the primary display device.
-	 * RoadRage chapter 6's enumeration routine expects it. */
-        __TRY
-        {
-            if (!lpCallback((DDRAW_default_driver == i) ? NULL
-                            :(LPGUID)&DDRAW_drivers[i]->info->guidDeviceIdentifier,
-                            (LPSTR)DDRAW_drivers[i]->info->szDescription,
-                            (LPSTR)DDRAW_drivers[i]->info->szDriver,
-                            lpContext, 0))
-                stop = TRUE;
-        }
-        __EXCEPT_PAGE_FAULT
-        {
-            return E_INVALIDARG;
-        }
-        __ENDTRY
-        if (stop) return DD_OK;
+        /* Use the reference device id. This doesn't actually change anything,
+         * WineD3D always uses OpenGL for D3D rendering. One could make it request
+         * indirect rendering
+         */
+        devicetype = WINED3DDEVTYPE_REF;
+    }
+    else if(guid == (GUID *) DDCREATE_HARDWAREONLY)
+    {
+        devicetype = WINED3DDEVTYPE_HAL;
+    }
+    else
+    {
+        devicetype = 0;
     }
 
-    /* Unsupported flags */
-    if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
-	FIXME("no non-display devices supported.\n");
-    }
-    if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) {
-	FIXME("no detached secondary devices supported.\n");
+    /* DDraw doesn't support aggreation, according to msdn */
+    if (UnkOuter != NULL)
+        return CLASS_E_NOAGGREGATION;
+
+    /* DirectDraw creation comes here */
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
+    if(!This)
+    {
+        ERR("Out of memory when creating DirectDraw\n");
+        return E_OUTOFMEMORY;
     }
 
+    /* The interfaces:
+     * IDirectDraw and IDirect3D are the same object,
+     * QueryInterface is used to get other interfaces.
+     */
+    ICOM_INIT_INTERFACE(This, IDirectDraw,  IDirectDraw1_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirectDraw2, IDirectDraw2_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirectDraw4, IDirectDraw4_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirectDraw7, IDirectDraw7_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirect3D,  IDirect3D1_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirect3D2, IDirect3D2_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirect3D3, IDirect3D3_Vtbl);
+    ICOM_INIT_INTERFACE(This, IDirect3D7, IDirect3D7_Vtbl);
+    This->ref = 1;
+
+    /* See comments in IDirectDrawImpl_CreateNewSurface for a description
+     * of this member.
+     * Read from a registry key, should add a winecfg option later
+     */
+    This->ImplType = DefaultSurfaceType;
+
+    /* Get the current screen settings */
+    hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
+    This->orig_bpp = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
+    DeleteDC(hDC);
+    This->orig_width = GetSystemMetrics(SM_CXSCREEN);
+    This->orig_height = GetSystemMetrics(SM_CYSCREEN);
+
+    /* Initialize WineD3D
+     *
+     * All Rendering (2D and 3D) is relayed to WineD3D,
+     * but DirectDraw specific management, like DDSURFACEDESC and DDPIXELFORMAT
+     * structure handling is handled in this lib.
+     */
+    wineD3D = WineDirect3DCreate(0 /* SDKVersion */, 7 /* DXVersion */, (IUnknown *) This /* Parent */);
+    if(!wineD3D)
+    {
+        ERR("Failed to initialise WineD3D\n");
+        hr = E_OUTOFMEMORY;
+        goto err_out;
+    }
+    This->wineD3D = wineD3D;
+    TRACE("WineD3D created at %p\n", wineD3D);
+
+    /* Initialized member...
+     *
+     * It is set to false at creation time, and set to true in
+     * IDirectDraw7::Initialize. It's sole purpose is to return DD_OK on
+     * initialize only once
+     */
+    This->initialized = FALSE;
+
+    /* Initialize WineD3DDevice
+     *
+     * It is used for screen setup, surface and palette creation
+     * When a Direct3DDevice7 is created, the D3D capatiblities of WineD3D are
+     * initialized
+     */
+    hr = IWineD3D_CreateDevice(wineD3D,
+                               0 /*D3D_ADAPTER_DEFAULT*/,
+                               devicetype,
+                               NULL, /* FocusWindow, don't know yet */
+                               0, /* BehaviorFlags */
+                               &wineD3DDevice,
+                               (IUnknown *) ICOM_INTERFACE(This, IDirectDraw7));
+    if(FAILED(hr))
+    {
+        ERR("Failed to create a wineD3DDevice, result = %lx\n", hr);
+        goto err_out;
+    }
+    This->wineD3DDevice = wineD3DDevice;
+    TRACE("wineD3DDevice created at %p\n", This->wineD3DDevice);
+
+    /* Register the window class
+     *
+     * It is used to create a hidden window for D3D
+     * rendering, if the application didn't pass one.
+     * It can also be used for Creating a device window
+     * from SetCooperativeLevel
+     *
+     * The name: DDRAW_<address>. The classname is
+     * 32 bit long, so a 64 bit address will fit nicely
+     * (Will this be compiled for 64 bit anyway?)
+     *
+     */
+    sprintf(This->classname, "DDRAW_%p", This);
+
+    memset(&This->wnd_class, 0, sizeof(This->wnd_class));
+    This->wnd_class.style = CS_HREDRAW | CS_VREDRAW;
+    This->wnd_class.lpfnWndProc = DefWindowProcA;
+    This->wnd_class.cbClsExtra = 0;
+    This->wnd_class.cbWndExtra = 0;
+    This->wnd_class.hInstance = GetModuleHandleA(0);
+    This->wnd_class.hIcon = 0;
+    This->wnd_class.hCursor = 0;
+    This->wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
+    This->wnd_class.lpszMenuName = NULL;
+    This->wnd_class.lpszClassName = This->classname;
+    if(!RegisterClassA(&This->wnd_class))
+    {
+        ERR("RegisterClassA failed!\n");
+        goto err_out;
+    }
+
+    /* Get the amount of video memory */
+    This->total_vidmem = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice);
+
+    /* Initialize the caps */
+    This->caps.dwSize = sizeof(This->caps);
+#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 |DDCAPS_ALIGNBOUNDARYSRC )
+#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;
+
+    This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED |
+                          DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES |
+                          DDCAPS2_CANRENDERWINDOWED;
+    This->caps.dwCKeyCaps |= CKEY_CAPS;
+    This->caps.dwFXCaps |= FX_CAPS;
+    This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
+    This->caps.dwVidMemTotal = This->total_vidmem;
+    This->caps.dwVidMemFree = This->total_vidmem;
+    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;
+    /* Hacks for D3D code */
+    /* TODO: Check if WineD3D has 3D enabled
+       Need opengl surfaces or auto for 3D
+     */
+    if(This->ImplType == 0 || This->ImplType == SURFACE_OPENGL)
+    {
+        This->caps.dwCaps |= DDCAPS_3D;
+        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
+
+    /* Add the object to the ddraw cleanup list */
+    This->next = ddraw_list;
+    ddraw_list = This;
+
+    /* Call QueryInterface to get the pointer to the requested interface */
+    hr = IDirectDraw7_QueryInterface( ICOM_INTERFACE(This, IDirectDraw7), iid, DD);
+    IDirectDraw7_Release( ICOM_INTERFACE(This, IDirectDraw7) );
+    if(SUCCEEDED(hr)) return DD_OK;
+
+err_out:
+    /* Let's hope we never need this ;) */
+    if(wineD3DDevice) IWineD3DDevice_Release(wineD3DDevice);
+    if(wineD3D) IWineD3D_Release(wineD3D);
+    if(This) HeapFree(GetProcessHeap(), 0, This);
+    return hr;
+}
+
+/***********************************************************************
+ * DirectDrawCreate (DDRAW.@)
+ *
+ * Creates legacy DirectDraw Interfaces. Can't create IDirectDraw7
+ * interfaces in theory
+ *
+ * Arguments, return values: See DDRAW_Create
+ *
+ ***********************************************************************/
+HRESULT WINAPI
+DirectDrawCreate(GUID *GUID,
+                 IDirectDraw **DD,
+                 IUnknown *UnkOuter)
+{
+    TRACE("(%s,%p,%p)\n", debugstr_guid(GUID), DD, UnkOuter);
+
+    return DDRAW_Create(GUID, (void **) DD, UnkOuter, &IID_IDirectDraw);
+}
+
+/***********************************************************************
+ * DirectDrawCreateEx (DDRAW.@)
+ *
+ * Only creates new IDirectDraw7 interfaces, supposed to fail if legacy
+ * interfaces are requested.
+ *
+ * Arguments, return values: See DDRAW_Create
+ *
+ ***********************************************************************/
+HRESULT WINAPI
+DirectDrawCreateEx(GUID *GUID,
+                   void **DD,
+                   REFIID iid,
+                   IUnknown *UnkOuter)
+{
+    TRACE("(%s,%p,%s,%p)\n", debugstr_guid(GUID), DD, debugstr_guid(iid), UnkOuter);
+
+    if (!IsEqualGUID(iid, &IID_IDirectDraw7))
+        return DDERR_INVALIDPARAMS;
+
+    return DDRAW_Create(GUID, DD, UnkOuter, iid);
+}
+
+/***********************************************************************
+ * DirectDrawEnumerateA (DDRAW.@)
+ *
+ * Enumerates legacy ddraw drivers, ascii version. We only have one
+ * driver, which relays to WineD3D. If we were sufficiently cool,
+ * we could offer various interfaces, which use a different default surface
+ * implementation, but I think it's better to offer this choice in
+ * winecfg, because some apps use the default driver, so we would need
+ * a winecfg option anyway, and there shouldn't be 2 ways to set one setting
+ *
+ * Arguments:
+ *  Callback: Callback function from the app
+ *  Context: Argument to the call back.
+ *
+ * Returns:
+ *  DD_OK on success
+ *  E_INVALIDARG if the Callback caused a page fault
+ *
+ *
+ ***********************************************************************/
+HRESULT WINAPI
+DirectDrawEnumerateA(LPDDENUMCALLBACKA Callback,
+                     void *Context)
+{
+    BOOL stop = FALSE;
+
+    TRACE(" Enumerating default DirectDraw HAL interface\n");
+    /* We only have one driver */
+    __TRY
+    {
+        stop = !Callback(NULL, "DirectDraw HAL", "display", Context);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        return E_INVALIDARG;
+    }
+    __ENDTRY
+
+    TRACE(" End of enumeration\n");
     return DD_OK;
 }
 
-/*******************************************************************************
+/***********************************************************************
+ * DirectDrawEnumerateExA (DDRAW.@)
+ *
+ * Enumerates DirectDraw7 drivers, ascii version. See
+ * the comments above DirectDrawEnumerateA for more details.
+ *
+ * The Flag member is not supported right now.
+ *
+ ***********************************************************************/
+HRESULT WINAPI
+DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA Callback,
+                       void *Context,
+                       DWORD Flags)
+{
+    BOOL stop = FALSE;
+    TRACE("Enumerating default DirectDraw HAL interface\n");
+
+    /* We only have one driver by now */
+    __TRY
+    {
+        /* QuickTime expects the description "DirectDraw HAL" */
+        stop = !Callback(NULL, "DirectDraw HAL", "display", Context, 0);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        return E_INVALIDARG;
+    }
+    __ENDTRY;
+
+    TRACE("End of enumeration\n");
+    return DD_OK;
+}
+
+/***********************************************************************
+ * DirectDrawEnumerateW (DDRAW.@)
+ *
+ * Enumerates legacy drivers, unicode version. See
+ * the comments above DirectDrawEnumerateA for more details.
+ *
+ * The Flag member is not supported right now.
+ *
+ ***********************************************************************/
+
+/***********************************************************************
  * DirectDrawEnumerateExW (DDRAW.@)
- */
-
-static BOOL CALLBACK DirectDrawEnumerateExProcW(
-    GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
-    LPVOID lpContext, HMONITOR hm)
-{
-    INT len;
-    BOOL bResult;
-    LPWSTR lpDriverDescriptionW, lpDriverNameW;
-    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
-
-    len = MultiByteToWideChar( CP_ACP, 0, lpDriverDescription, -1, NULL, 0 );
-    lpDriverDescriptionW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-    MultiByteToWideChar( CP_ACP, 0, lpDriverDescription, -1, lpDriverDescriptionW, len );
-
-    len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 );
-    lpDriverNameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-    MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, lpDriverNameW, len );
-
-    bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(lpGUID, lpDriverDescriptionW,
-                                                          lpDriverNameW, pEPD->lpContext, hm);
-
-    HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
-    HeapFree(GetProcessHeap(), 0, lpDriverNameW);
-    return bResult;
-}
-
-HRESULT WINAPI DirectDrawEnumerateExW(
-  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
-{
-    DirectDrawEnumerateProcData epd;
-    epd.lpCallback = (LPVOID) lpCallback;
-    epd.lpContext = lpContext;
-
-    return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, (LPVOID) &epd, 0);
-}
+ *
+ * Enumerates DirectDraw7 drivers, unicode version. See
+ * the comments above DirectDrawEnumerateA for more details.
+ *
+ * The Flag member is not supported right now.
+ *
+ ***********************************************************************/
 
 /***********************************************************************
- *		DirectDrawEnumerateA (DDRAW.@)
- */
-
-static BOOL CALLBACK DirectDrawEnumerateProcA(
-	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
-	LPVOID lpContext, HMONITOR hm)
-{
-    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
-
-    return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
-	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
-}
-
-HRESULT WINAPI DirectDrawEnumerateA(
-  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
-{
-    DirectDrawEnumerateProcData epd;
-    epd.lpCallback = (LPVOID) lpCallback;
-    epd.lpContext = lpContext;
-
-    return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, (LPVOID) &epd, 0);
-}
+ * Classfactory implementation.
+ ***********************************************************************/
 
 /***********************************************************************
- *		DirectDrawEnumerateW (DDRAW.@)
- */
-
-static BOOL WINAPI DirectDrawEnumerateProcW(
-  GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
-  LPVOID lpContext, HMONITOR hm)
+ * CF_CreateDirectDraw
+ *
+ * DDraw creation function for the class factory
+ *
+ * Params:
+ *  UnkOuter: Set to NULL
+ *  iid: ID of the wanted interface
+ *  obj: Address to pass the interface pointer back
+ *
+ * Returns
+ *  DD_OK / DDERR*, see DDRAW_Create
+ *
+ ***********************************************************************/
+static HRESULT
+CF_CreateDirectDraw(IUnknown* UnkOuter, REFIID iid,
+                    void **obj)
 {
-    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
-
-    return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
-	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
-}
-
-HRESULT WINAPI DirectDrawEnumerateW(
-  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
-{
-    DirectDrawEnumerateProcData epd;
-    epd.lpCallback = (LPVOID) lpCallback;
-    epd.lpContext = lpContext;
-
-    return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, (LPVOID) &epd, 0);
-}
-
-/***********************************************************************
- *		DirectDrawCreate (DDRAW.@)
- */
-
-const ddraw_driver* DDRAW_FindDriver(const GUID* pGUID)
-{
-    static const GUID zeroGUID; /* gets zero-inited */
-
-    TRACE("(%s)\n", pGUID ? debugstr_guid(pGUID) : "(null)");
-
-    if (DDRAW_num_drivers == 0) return NULL;
-
-    if (pGUID == (LPGUID)DDCREATE_EMULATIONONLY
-	|| pGUID == (LPGUID)DDCREATE_HARDWAREONLY)
-	pGUID = NULL;
-
-    if (pGUID == NULL || memcmp(pGUID, &zeroGUID, sizeof(GUID)) == 0)
-    {
-	/* Use the default driver. */
-	return DDRAW_drivers[DDRAW_default_driver];
-    }
-    else
-    {
-	/* Look for a matching GUID. */
-
-	int i;
-	for (i=0; i < DDRAW_num_drivers; i++)
-	{
-	    if (IsEqualGUID(pGUID,
-			    &DDRAW_drivers[i]->info->guidDeviceIdentifier))
-		break;
-	}
-
-	if (i < DDRAW_num_drivers)
-	{
-	    return DDRAW_drivers[i];
-	}
-	else
-	{
-	    ERR("(%s): did not recognize requested GUID.\n",debugstr_guid(pGUID));
-	    return NULL;
-	}
-    }
-}
-
-static HRESULT DDRAW_Create(
-	LPGUID lpGUID, LPVOID *lplpDD, LPUNKNOWN pUnkOuter, REFIID iid, BOOL ex
-) {
-    const ddraw_driver* driver;
-    LPDIRECTDRAW7 pDD;
     HRESULT hr;
 
-    TRACE("(%s,%p,%p,%d)\n", debugstr_guid(lpGUID), lplpDD, pUnkOuter, ex);
+    TRACE("(%p,%s,%p)\n", UnkOuter, debugstr_guid(iid), obj);
 
-    if (DDRAW_num_drivers == 0)
-    {
-	WARN("no DirectDraw drivers registered\n");
-	return DDERR_INVALIDDIRECTDRAWGUID;
-    }
-
-    if (lpGUID == (LPGUID)DDCREATE_EMULATIONONLY
-	|| lpGUID == (LPGUID)DDCREATE_HARDWAREONLY)
-	lpGUID = NULL;
-
-    if (pUnkOuter != NULL)
-	return DDERR_INVALIDPARAMS; /* CLASS_E_NOAGGREGATION? */
-
-    driver = DDRAW_FindDriver(lpGUID);
-    if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID;
-
-    hr = driver->create(lpGUID, &pDD, pUnkOuter, ex);
-    if (FAILED(hr)) return hr;
-
-    hr = IDirectDraw7_QueryInterface(pDD, iid, lplpDD);
-    IDirectDraw7_Release(pDD);
+    hr = DDRAW_Create(NULL, obj, UnkOuter, iid);
     return hr;
 }
 
 /***********************************************************************
- *		DirectDrawCreate (DDRAW.@)
+ * CF_CreateDirectDraw
  *
- * Only creates legacy IDirectDraw interfaces.
- * Cannot create IDirectDraw7 interfaces.
- * In theory.
- */
-HRESULT WINAPI DirectDrawCreate(
-	LPGUID lpGUID, LPDIRECTDRAW* lplpDD, LPUNKNOWN pUnkOuter
-) {
-    TRACE("(%s,%p,%p)\n", debugstr_guid(lpGUID), lplpDD, pUnkOuter);
-    return DDRAW_Create(lpGUID, (LPVOID*) lplpDD, pUnkOuter, &IID_IDirectDraw, FALSE);
-}
-
-/***********************************************************************
- *		DirectDrawCreateEx (DDRAW.@)
+ * Clipper creation function for the class factory
  *
- * Only creates new IDirectDraw7 interfaces.
- * Supposed to fail if legacy interfaces are requested.
- * In theory.
- */
-HRESULT WINAPI DirectDrawCreateEx(
-	LPGUID lpGUID, LPVOID* lplpDD, REFIID iid, LPUNKNOWN pUnkOuter
-) {
-    TRACE("(%s,%p,%s,%p)\n", debugstr_guid(lpGUID), lplpDD, debugstr_guid(iid), pUnkOuter);
-
-    if (!IsEqualGUID(iid, &IID_IDirectDraw7))
-	return DDERR_INVALIDPARAMS;
-
-    return DDRAW_Create(lpGUID, lplpDD, pUnkOuter, iid, TRUE);
-}
-
-extern HRESULT Uninit_DirectDraw_Create(const GUID*, LPDIRECTDRAW7*,
-					LPUNKNOWN, BOOL);
-
-/* This is for the class factory. */
-static HRESULT DDRAW_CreateDirectDraw(IUnknown* pUnkOuter, REFIID iid,
-				      LPVOID* ppObj)
+ * Params:
+ *  UnkOuter: Set to NULL
+ *  iid: ID of the wanted interface
+ *  obj: Address to pass the interface pointer back
+ *
+ * Returns
+ *  DD_OK / DDERR*, see DDRAW_Create
+ *
+ ***********************************************************************/
+static HRESULT
+CF_CreateDirectDrawClipper(IUnknown* UnkOuter, REFIID riid,
+                              void **obj)
 {
-    LPDIRECTDRAW7 pDD;
     HRESULT hr;
-    BOOL ex;
+    IDirectDrawClipper *Clip;
 
-    TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppObj);
-    
-    /* This is a mighty hack :-) */
-    if (IsEqualGUID(iid, &IID_IDirectDraw7))
-	ex = TRUE;
-    else
-        ex = FALSE;
-    
-    hr = Uninit_DirectDraw_Create(NULL, &pDD, pUnkOuter, ex);
-    if (FAILED(hr)) return hr;
+    hr = DirectDrawCreateClipper(0, &Clip, UnkOuter);
+    if (hr != DD_OK) return hr;
 
-    hr = IDirectDraw7_QueryInterface(pDD, iid, ppObj);
-    IDirectDraw_Release(pDD);
+    hr = IDirectDrawClipper_QueryInterface(Clip, riid, obj);
+    IDirectDrawClipper_Release(Clip);
     return hr;
 }
 
-/******************************************************************************
- * DirectDraw ClassFactory
- */
-typedef struct {
-    ICOM_VFIELD_MULTI(IClassFactory);
-
-    LONG ref;
-    HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid,
-				 LPVOID *ppObj);
-} IClassFactoryImpl;
-
-struct object_creation_info
-{
-    const CLSID *clsid;
-    HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid,
-				 LPVOID *ppObj);
-};
-
-/* There should be more, but these are the only ones listed in the header
- * file. */
-extern HRESULT DDRAW_CreateDirectDrawClipper(IUnknown *pUnkOuter, REFIID riid,
-					     LPVOID *ppObj);
-
 static const struct object_creation_info object_creation[] =
 {
-    { &CLSID_DirectDraw,       	DDRAW_CreateDirectDraw },
-    { &CLSID_DirectDraw7,	DDRAW_CreateDirectDraw },
-    { &CLSID_DirectDrawClipper,	DDRAW_CreateDirectDrawClipper }
+    { &CLSID_DirectDraw,        CF_CreateDirectDraw },
+    { &CLSID_DirectDraw7,       CF_CreateDirectDraw },
+    { &CLSID_DirectDrawClipper, CF_CreateDirectDrawClipper }
 };
 
+/*******************************************************************************
+ * IDirectDrawClassFactory::QueryInterface
+ *
+ * QueryInterface for the class factory
+ *
+ * PARAMS
+ *    riid   Reference to identifier of queried interface
+ *    ppv    Address to return the interface pointer at
+ *
+ * RETURNS
+ *    Success: S_OK
+ *    Failure: E_NOINTERFACE
+ *
+ *******************************************************************************/
 static HRESULT WINAPI
-DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
+IDirectDrawClassFactoryImpl_QueryInterface(IClassFactory *iface,
+                    REFIID riid,
+                    void **obj)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface);
 
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
-    
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj);
+
     if (IsEqualGUID(riid, &IID_IUnknown)
-	|| IsEqualGUID(riid, &IID_IClassFactory))
+        || IsEqualGUID(riid, &IID_IClassFactory))
     {
-	IClassFactory_AddRef(iface);
-	*ppobj = This;
-	return S_OK;
+        IClassFactory_AddRef(iface);
+        *obj = This;
+        return S_OK;
     }
 
-    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),obj);
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI DDCF_AddRef(LPCLASSFACTORY iface)
+/*******************************************************************************
+ * IDirectDrawClassFactory::AddRef
+ *
+ * AddRef for the class factory
+ *
+ * RETURNS
+ *  The new refcount
+ *
+ *******************************************************************************/
+static ULONG WINAPI
+IDirectDrawClassFactoryImpl_AddRef(IClassFactory *iface)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
     TRACE("(%p)->() incrementing from %ld.\n", This, ref - 1);
-    
+
     return ref;
 }
 
-static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface)
+/*******************************************************************************
+ * IDirectDrawClassFactory::Release
+ *
+ * Release for the class factory. If the refcount falls to 0, the object
+ * is destroyed
+ *
+ * RETURNS
+ *  The new refcount
+ *
+ *******************************************************************************/
+static ULONG WINAPI
+IDirectDrawClassFactoryImpl_Release(IClassFactory *iface)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
     TRACE("(%p)->() decrementing from %ld.\n", This, ref+1);
 
     if (ref == 0)
-	HeapFree(GetProcessHeap(), 0, This);
+        HeapFree(GetProcessHeap(), 0, This);
 
     return ref;
 }
 
 
-static HRESULT WINAPI DDCF_CreateInstance(
-	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
-)
+/*******************************************************************************
+ * IDirectDrawClassFactory::CreateInstance
+ *
+ * What is this? Seems to create DirectDraw objects...
+ *
+ * Params
+ *  The ususal things???
+ *
+ * RETURNS
+ *  ???
+ *
+ *******************************************************************************/
+static HRESULT WINAPI
+IDirectDrawClassFactoryImpl_CreateInstance(IClassFactory *iface,
+                                           IUnknown *UnkOuter,
+                                           REFIID riid,
+                                           void **obj)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface);
 
-    TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+    TRACE("(%p)->(%p,%s,%p)\n",This,UnkOuter,debugstr_guid(riid),obj);
 
-    return This->pfnCreateInstance(pOuter, riid, ppobj);
+    return This->pfnCreateInstance(UnkOuter, riid, obj);
 }
 
-static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
+/*******************************************************************************
+ * IDirectDrawClassFactory::LockServer
+ *
+ * What is this?
+ *
+ * Params
+ *  ???
+ *
+ * RETURNS
+ *  S_OK, because it's a stub
+ *
+ *******************************************************************************/
+static HRESULT WINAPI
+IDirectDrawClassFactoryImpl_LockServer(IClassFactory *iface,BOOL dolock)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface);
     FIXME("(%p)->(%d),stub!\n",This,dolock);
     return S_OK;
 }
 
-static const IClassFactoryVtbl DDCF_Vtbl =
+/*******************************************************************************
+ * The class factory VTable
+ *******************************************************************************/
+static const IClassFactoryVtbl IClassFactory_Vtbl =
 {
-    DDCF_QueryInterface,
-    DDCF_AddRef,
-    DDCF_Release,
-    DDCF_CreateInstance,
-    DDCF_LockServer
+    IDirectDrawClassFactoryImpl_QueryInterface,
+    IDirectDrawClassFactoryImpl_AddRef,
+    IDirectDrawClassFactoryImpl_Release,
+    IDirectDrawClassFactoryImpl_CreateInstance,
+    IDirectDrawClassFactoryImpl_LockServer
 };
 
 /*******************************************************************************
@@ -595,10 +680,10 @@
 	return CLASS_E_CLASSNOTAVAILABLE;
     }
 
-    factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
+    factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory));
     if (factory == NULL) return E_OUTOFMEMORY;
 
-    ICOM_INIT_INTERFACE(factory, IClassFactory, DDCF_Vtbl);
+    ICOM_INIT_INTERFACE(factory, IClassFactory, IClassFactory_Vtbl);
     factory->ref = 1;
 
     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
@@ -621,103 +706,190 @@
     return S_FALSE;
 }
 
-/******************************************************************************
- * Initialisation
- */
-
-/* Choose which driver is considered the primary display driver. It will
- * be created when we get a NULL guid for the DirectDrawCreate(Ex). */
-static int DDRAW_ChooseDefaultDriver(void)
+/*******************************************************************************
+ * DestroyCallback
+ *
+ * Callback function for the EnumSurfaces call in DllMain.
+ * Dumps some surface info and releases the surface
+ *
+ * Params:
+ *  surf: The enumerated surface
+ *  desc: it's description
+ *  context: Pointer to the ddraw impl
+ *
+ * Returns:
+ *  DDENUMRET_OK;
+ *******************************************************************************/
+HRESULT WINAPI
+DestroyCallback(IDirectDrawSurface7 *surf,
+                DDSURFACEDESC2 *desc,
+                void *context)
 {
-    int i;
-    int best = 0;
-    int best_score = 0;
+    IDirectDrawSurfaceImpl *Impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, surf);
+    IDirectDrawImpl *ddraw = (IDirectDrawImpl *) context;
+    ULONG ref;
 
-    assert(DDRAW_num_drivers > 0);
+    ref = IDirectDrawSurface7_Release(surf);  /* For the EnumSurfaces */
+    WARN("Surface %p has an reference count of %ld\n", Impl, ref);
 
-    /* This algorithm is really stupid. */
-    for (i=0; i < DDRAW_num_drivers; i++)
-    {
-	if (DDRAW_drivers[i]->preference > best_score)
-	{
-	    best_score = DDRAW_drivers[i]->preference;
-	    best = i;
-	}
-    }
+    /* Skip surfaces which are attached somewhere or which are
+     * part of a complex compound. They will get released when destroying
+     * the root
+     */
+    if( (Impl->first_complex != Impl) || (Impl->first_attached != Impl) )
+        return DDENUMRET_OK;
+    /* Skip our depth stencil surface, it will be released with the render target */
+    if( Impl == ddraw->DepthStencilBuffer)
+        return DDENUMRET_OK;
 
-    assert(best_score > 0);
+    /* Destroy the surface */
+    while(ref) ref = IDirectDrawSurface7_Release(surf);
 
-    return best;
+    return DDENUMRET_OK;
 }
 
 /***********************************************************************
- *		DllMain (DDRAW.0)
- */
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+ * get_config_key
+ *
+ * Reads a config key from the registry. Taken from WineD3D
+ *
+ ***********************************************************************/
+inline static DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, char* buffer, DWORD size)
 {
-    /* If we were sufficiently cool, DDraw drivers would just be COM
-     * objects, registered with a particular component category. */
+    if (0 != appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
+    if (0 != defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
+    return ERROR_FILE_NOT_FOUND;
+}
 
-    DDRAW_HAL_Init(hInstDLL, fdwReason, lpv);
-    DDRAW_User_Init(hInstDLL, fdwReason, lpv);
+/***********************************************************************
+ * DllMain (DDRAW.0)
+ *
+ * Could be used to register DirectDraw drivers, if we have more than
+ * one. Also used to destroy any objects left at unload if the
+ * app didn't release them properly(Gothic 2, Diablo 2, Moto racer, ...)
+ *
+ ***********************************************************************/
+BOOL WINAPI
+DllMain(HINSTANCE hInstDLL,
+        DWORD Reason,
+        void *lpv)
+{
+    static LONG counter = 0;
 
-    if (fdwReason == DLL_PROCESS_ATTACH)
+    TRACE("(%p,%lx,%p)\n", hInstDLL, Reason, lpv);
+    if (Reason == DLL_PROCESS_ATTACH)
     {
-        HMODULE mod;
+        char buffer[MAX_PATH+10];
+        DWORD size = sizeof(buffer);
+        HKEY hkey = 0;
+        HKEY appkey = 0;
+        DWORD len;
+
+       /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
+       if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
+
+       len = GetModuleFileNameA( 0, buffer, MAX_PATH );
+       if (len && len < MAX_PATH)
+       {
+            HKEY tmpkey;
+            /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */
+            if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
+            {
+                char *p, *appname = buffer;
+                if ((p = strrchr( appname, '/' ))) appname = p + 1;
+                if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+                strcat( appname, "\\Direct3D" );
+                TRACE("appname = [%s]\n", appname);
+                if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+                RegCloseKey( tmpkey );
+            }
+       }
+
+       if ( 0 != hkey || 0 != appkey )
+       {
+            if ( !get_config_key( hkey, appkey, "DirectDrawRenderer", buffer, size) )
+            {
+                if (!strcmp(buffer,"gdi"))
+                {
+                    TRACE("Defaulting to GDI surfaces\n");
+                    DefaultSurfaceType = SURFACE_GDI;
+                }
+                else if (!strcmp(buffer,"opengl"))
+                {
+                    TRACE("Defaulting to opengl surfaces\n");
+                    DefaultSurfaceType = SURFACE_OPENGL;
+                }
+                else
+                {
+                    ERR("Unknown default surface type. Supported are:\n gdi, opengl");
+                }
+            }
+        }
 
         DisableThreadLibraryCalls(hInstDLL);
+        TRACE("Attach counter: %ld\n", InterlockedIncrement(&counter));
+    }
+    else if (Reason == DLL_PROCESS_DETACH)
+    {
+        TRACE("Attach counter: %ld\n", InterlockedDecrement(&counter));
 
-        mod = GetModuleHandleA( "winex11.drv" );
-        if (mod)
+        if(counter == 0)
         {
-            wine_tsx11_lock_ptr   = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
-            wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
-        }
-#ifdef HAVE_OPENGL
-        opengl_initialized = DDRAW_bind_to_opengl();
-#endif /* HAVE_OPENGL */
-        s3tc_initialized = DDRAW_bind_to_s3tc();
+            if(ddraw_list)
+            {
+                IDirectDrawImpl *ddraw;
+                WARN("There are still existing DirectDraw interfaces. Wine bug or buggy application?\n");
 
-        if (DDRAW_num_drivers > 0)
-            DDRAW_default_driver = DDRAW_ChooseDefaultDriver();
+                for(ddraw = ddraw_list; ddraw; ddraw = ddraw->next)
+                {
+                    HRESULT hr;
+                    DDSURFACEDESC2 desc;
+                    int i;
+
+                    WARN("DDraw %p has a refcount of %ld\n", ddraw, ddraw->ref);
+
+                    ddraw->DoNotDestroy = TRUE; /* Avoid to destroy the object too early */
+
+                    /* Does a D3D device exist? Destroy it
+                     * TODO: Destroy all Vertex buffers, Lights, Materials
+                     * and execture buffers too
+                     */
+                    if(ddraw->d3ddevice)
+                    {
+                        WARN("DDraw %p has d3ddevice %p attached\n", ddraw, ddraw->d3ddevice);
+                        while(IDirect3DDevice7_Release(ICOM_INTERFACE(ddraw->d3ddevice, IDirect3DDevice7)));
+                    }
+
+                    /* Try to release the objects
+                     * Do an EnumSurfaces to find any hanging surfaces
+                     */
+                    memset(&desc, 0, sizeof(desc));
+                    desc.dwSize = sizeof(desc);
+                    for(i = 0; i <= 1; i++)
+                    {
+                        hr = IDirectDraw7_EnumSurfaces(ICOM_INTERFACE(ddraw, IDirectDraw7),
+                                                        DDENUMSURFACES_ALL,
+                                                        &desc,
+                                                        (void *) ddraw,
+                                                        DestroyCallback);
+                        if(hr != D3D_OK)
+                            ERR("(%p) EnumSurfaces failed, prepare for trouble\n", ddraw);
+                    }
+
+                    /* Check the surface count */
+                    if(ddraw->surfaces > 0)
+                        ERR("DDraw %p still has %ld surfaces attached\n", ddraw, ddraw->surfaces);
+
+                    /* Restore the cooperative level */
+                    IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(ddraw, IDirectDraw7),
+                                                      NULL,
+                                                      DDSCL_NORMAL);
+                    ddraw->DoNotDestroy = FALSE;
+                    IDirectDrawImpl_Destroy(ddraw);
+                }
+            }
+        }
     }
 
     return TRUE;
 }
-
-/* Register a direct draw driver. This should be called from your init
- * function. (That's why there is no locking: your init func is called from
- * our DllInit, which is serialised.) */
-void DDRAW_register_driver(const ddraw_driver *driver)
-{
-    int i;
-
-    for (i = 0; i < DDRAW_num_drivers; i++)
-    {
-	if (DDRAW_drivers[i] == driver)
-	{
-	    ERR("Driver reregistering %p\n", driver);
-	    return;
-	}
-    }
-
-    if (DDRAW_num_drivers == sizeof(DDRAW_drivers)/sizeof(DDRAW_drivers[0]))
-    {
-	ERR("too many DDRAW drivers\n");
-	return;
-    }
-
-    DDRAW_drivers[DDRAW_num_drivers++] = driver;
-}
-
-/* This totally doesn't belong here. */
-LONG DDRAW_width_bpp_to_pitch(DWORD width, DWORD bpp)
-{
-    LONG pitch;
-
-    assert(bpp != 0); /* keeps happening... */
-
-    if (bpp == 15) bpp = 16;
-    pitch = width * (bpp / 8);
-    return pitch + (8 - (pitch % 8)) % 8;
-}
diff --git a/dlls/ddraw/material.c b/dlls/ddraw/material.c
index 5ddd20d..df5783d 100644
--- a/dlls/ddraw/material.c
+++ b/dlls/ddraw/material.c
@@ -1,5 +1,6 @@
 /* Direct3D Material
  * Copyright (c) 2002 Lionel ULMER
+ * Copyright (c) 2006 Stefan DÖSINGER
  *
  * This file contains the implementation of Direct3DMaterial.
  *
@@ -19,38 +20,64 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
+#include <assert.h>
 #include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
+
+#include "ddraw_private.h"
 #include "wine/debug.h"
 
-#include "d3d_private.h"
-#include "opengl_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
+WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
 
 static void dump_material(LPD3DMATERIAL mat)
 {
     DPRINTF("  dwSize : %ld\n", mat->dwSize);
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface(LPDIRECT3DMATERIAL3 iface,
-                                                  REFIID riid,
-                                                  LPVOID* obp)
+/*****************************************************************************
+ * IUnknown Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DMaterial3::QueryInterface
+ *
+ * QueryInterface for IDirect3DMaterial. Can query all IDirect3DMaterial
+ * versions.
+ *
+ * Params:
+ *  riid: Interface id queried for
+ *  obj: Address to pass the interface pointer back
+ *
+ * Returns:
+ *  S_OK on success
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_QueryInterface(IDirect3DMaterial3 *iface,
+                                     REFIID riid,
+                                     LPVOID* obp)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
-    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obp);
 
     *obp = NULL;
 
@@ -79,27 +106,46 @@
 	return S_OK;
     }
     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
+    return E_NOINTERFACE;
 }
 
-ULONG WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_AddRef(LPDIRECT3DMATERIAL3 iface)
+/*****************************************************************************
+ * IDirect3DMaterial3::AddRef
+ *
+ * Increases the refcount.
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DMaterialImpl_AddRef(IDirect3DMaterial3 *iface)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
-    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
 
     return ref;
 }
 
-ULONG WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_Release(LPDIRECT3DMATERIAL3 iface)
+/*****************************************************************************
+ * IDirect3DMaterial3::Release
+ *
+ * Reduces the refcount by one. If the refcount falls to 0, the object
+ * is destroyed
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DMaterialImpl_Release(IDirect3DMaterial3 *iface)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
 
     if (!ref) {
         HeapFree(GetProcessHeap(), 0, This);
@@ -108,38 +154,90 @@
     return ref;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_1_Initialize(LPDIRECT3DMATERIAL iface,
-                                        LPDIRECT3D lpDirect3D)
+/*****************************************************************************
+ * IDirect3DMaterial Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DMaterial::Initialize
+ *
+ * A no-op initialization
+ *
+ * Params:
+ *  Direct3D: Pointer to a Direct3D interface
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_Initialize(IDirect3DMaterial *iface,
+                                  IDirect3D *Direct3D)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
-    TRACE("(%p/%p)->(%p) no-op...!\n", This, iface, lpDirect3D);
-    return DD_OK;
+
+    TRACE("(%p)->(%p) no-op...!\n", This, Direct3D);
+
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_1_Reserve(LPDIRECT3DMATERIAL iface)
+/*****************************************************************************
+ * IDirect3DMaterial::Reserve
+ *
+ * DirectX 5 sdk: "The IDirect3DMaterial2::Reserve method is not implemented"
+ * Odd. They seem to have mixed their interfaces.
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_Reserve(IDirect3DMaterial *iface)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
-    TRACE("(%p/%p)->() not implemented.\n", This, iface);
-    return DD_OK;
+    TRACE("(%p)->() not implemented\n", This);
+
+    return DDERR_UNSUPPORTED;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_1_Unreserve(LPDIRECT3DMATERIAL iface)
+/*****************************************************************************
+ * IDirect3DMaterial::Unreserve
+ *
+ * Not supported too
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_Unreserve(IDirect3DMaterial *iface)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
-    FIXME("(%p/%p)->() not implemented.\n", This, iface);
-    return DD_OK;
+    TRACE("(%p)->() not implemented.\n", This);
+
+    return DDERR_UNSUPPORTED;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial(LPDIRECT3DMATERIAL3 iface,
-                                               LPD3DMATERIAL lpMat)
+/*****************************************************************************
+ * IDirect3DMaterial3::SetMaterial
+ *
+ * Sets the material description
+ *
+ * Params:
+ *  Mat: Material to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Mat is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_SetMaterial(IDirect3DMaterial3 *iface,
+                                  D3DMATERIAL *lpMat)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
-    if (TRACE_ON(ddraw))
+    TRACE("(%p)->(%p)\n", This, lpMat);
+    if (TRACE_ON(d3d7))
         dump_material(lpMat);
 
     /* Stores the material */
@@ -149,14 +247,27 @@
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial(LPDIRECT3DMATERIAL3 iface,
-                                               LPD3DMATERIAL lpMat)
+/*****************************************************************************
+ * IDirect3DMaterial3::GetMaterial
+ *
+ * Returns the material assigned to this interface
+ *
+ * Params:
+ *  Mat: Pointer to a D3DMATERIAL structure to store the material description
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Mat is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_GetMaterial(IDirect3DMaterial3 *iface,
+                                  D3DMATERIAL *lpMat)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
     DWORD dwSize;
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
-    if (TRACE_ON(ddraw)) {
+    TRACE("(%p)->(%p)\n", This, lpMat);
+    if (TRACE_ON(d3d7)) {
         TRACE("  Returning material : ");
         dump_material(&This->mat);
     }
@@ -169,10 +280,25 @@
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle(LPDIRECT3DMATERIAL3 iface,
-					     LPDIRECT3DDEVICE3 lpDirect3DDevice3,
-					     LPD3DMATERIALHANDLE lpHandle)
+/*****************************************************************************
+ * IDirect3DMaterial3::GetHandle
+ *
+ * Returns a handle for the material interface. The handle is simply a
+ * pointer to the material implementation
+ *
+ * Params:
+ *  Direct3DDevice3: The device this handle is assigned to
+ *  Handle: Address to write the handle to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Handle is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DMaterialImpl_GetHandle(IDirect3DMaterial3 *iface,
+                                IDirect3DDevice3 *lpDirect3DDevice3,
+                                D3DMATERIALHANDLE *lpHandle)
 {
     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice3, lpHandle);
@@ -191,7 +317,7 @@
 					LPDIRECT3DDEVICE2 lpDirect3DDevice2,
 					LPD3DMATERIALHANDLE lpHandle)
 {
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle);
     return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
 					COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, lpDirect3DDevice2),
 					lpHandle);
@@ -202,7 +328,7 @@
 					LPDIRECT3DDEVICE lpDirect3DDevice,
 					LPD3DMATERIALHANDLE lpHandle)
 {
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle);
     return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
 					COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, lpDirect3DDevice),
 					lpHandle);
@@ -213,7 +339,7 @@
                                              REFIID riid,
                                              LPVOID* obp)
 {
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
     return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
                                              riid,
                                              obp);
@@ -224,195 +350,136 @@
                                              REFIID riid,
                                              LPVOID* obp)
 {
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
     return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
                                              riid,
                                              obp);
 }
 
-ULONG WINAPI
+static ULONG WINAPI
 Thunk_IDirect3DMaterialImpl_2_AddRef(LPDIRECT3DMATERIAL2 iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
     return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
 }
 
-ULONG WINAPI
+static ULONG WINAPI
 Thunk_IDirect3DMaterialImpl_1_AddRef(LPDIRECT3DMATERIAL iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
     return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
 }
 
-ULONG WINAPI
+static ULONG WINAPI
 Thunk_IDirect3DMaterialImpl_2_Release(LPDIRECT3DMATERIAL2 iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
     return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
 }
 
-ULONG WINAPI
+static ULONG WINAPI
 Thunk_IDirect3DMaterialImpl_1_Release(LPDIRECT3DMATERIAL iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
     return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
 }
 
-HRESULT WINAPI
+static HRESULT WINAPI
 Thunk_IDirect3DMaterialImpl_2_SetMaterial(LPDIRECT3DMATERIAL2 iface,
                                           LPD3DMATERIAL lpMat)
 {
-    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
     return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
                                           lpMat);
 }
 
-HRESULT WINAPI
+static HRESULT WINAPI
 Thunk_IDirect3DMaterialImpl_1_SetMaterial(LPDIRECT3DMATERIAL iface,
                                           LPD3DMATERIAL lpMat)
 {
-    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
     return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
                                           lpMat);
 }
 
-HRESULT WINAPI
+static HRESULT WINAPI
 Thunk_IDirect3DMaterialImpl_2_GetMaterial(LPDIRECT3DMATERIAL2 iface,
                                           LPD3DMATERIAL lpMat)
 {
-    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
     return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
                                           lpMat);
 }
 
-HRESULT WINAPI
+static HRESULT WINAPI
 Thunk_IDirect3DMaterialImpl_1_GetMaterial(LPDIRECT3DMATERIAL iface,
                                           LPD3DMATERIAL lpMat)
 {
-    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
     return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
                                           lpMat);
 }
 
-/*******************************************************************************
- *				Matrial2 static functions
- */
-static void activate(IDirect3DMaterialImpl* This) {
+
+/*****************************************************************************
+ * material_activate
+ *
+ * Uses IDirect3DDevice7::SetMaterial to activate the material
+ *
+ * Params:
+ *  This: Pointer to the material implementation to activate
+ *
+ *****************************************************************************/
+void material_activate(IDirect3DMaterialImpl* This)
+{
+    D3DMATERIAL7 d3d7mat;
+
     TRACE("Activating material %p\n", This);
+    d3d7mat.u.diffuse = This->mat.u.diffuse;
+    d3d7mat.u1.ambient = This->mat.u1.ambient;
+    d3d7mat.u2.specular = This->mat.u2.specular;
+    d3d7mat.u3.emissive = This->mat.u3.emissive;
+    d3d7mat.u4.power = This->mat.u4.power;
 
-    /* Set the current Material */
-    ENTER_GL();
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_DIFFUSE,
-		 (float *) &(This->mat.u.diffuse));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_AMBIENT,
-		 (float *) &(This->mat.u1.ambient));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_SPECULAR,
-		 (float *) &(This->mat.u2.specular));
-    glMaterialfv(GL_FRONT_AND_BACK,
-		 GL_EMISSION,
-		 (float *) &(This->mat.u3.emissive));
-    LEAVE_GL();
-
-    if (TRACE_ON(ddraw)) {
-	DPRINTF(" - size  : %ld\n", This->mat.dwSize);
-	DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(This->mat.u.diffuse)); DPRINTF("\n");
-	DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(This->mat.u1.ambient)); DPRINTF("\n");
-	DPRINTF(" - specular: "); dump_D3DCOLORVALUE(&(This->mat.u2.specular)); DPRINTF("\n");
-	DPRINTF(" - emissive: "); dump_D3DCOLORVALUE(&(This->mat.u3.emissive)); DPRINTF("\n");
-	DPRINTF(" - power : %f\n", This->mat.u4.power);
-	DPRINTF(" - texture handle : %08lx\n", (DWORD)This->mat.hTexture);
-    }
+    IDirect3DDevice7_SetMaterial(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
+                                 &d3d7mat);
 }
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial3.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DMaterial3Vtbl VTABLE_IDirect3DMaterial3 =
+const IDirect3DMaterial3Vtbl IDirect3DMaterial3_Vtbl =
 {
-    XCAST(QueryInterface) Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DMaterialImpl_3_2T_1T_AddRef,
-    XCAST(Release) Main_IDirect3DMaterialImpl_3_2T_1T_Release,
-    XCAST(SetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial,
-    XCAST(GetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial,
-    XCAST(GetHandle) Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle,
+    /*** IUnknown Methods ***/
+    IDirect3DMaterialImpl_QueryInterface,
+    IDirect3DMaterialImpl_AddRef,
+    IDirect3DMaterialImpl_Release,
+    /*** IDirect3DMaterial3 Methods ***/
+    IDirect3DMaterialImpl_SetMaterial,
+    IDirect3DMaterialImpl_GetMaterial,
+    IDirect3DMaterialImpl_GetHandle,
 };
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial2.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DMaterial2Vtbl VTABLE_IDirect3DMaterial2 =
+const IDirect3DMaterial2Vtbl IDirect3DMaterial2_Vtbl =
 {
-    XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_2_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DMaterialImpl_2_AddRef,
-    XCAST(Release) Thunk_IDirect3DMaterialImpl_2_Release,
-    XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_2_SetMaterial,
-    XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_2_GetMaterial,
-    XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_2_GetHandle,
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DMaterialImpl_2_QueryInterface,
+    Thunk_IDirect3DMaterialImpl_2_AddRef,
+    Thunk_IDirect3DMaterialImpl_2_Release,
+    /*** IDirect3DMaterial2 Methods ***/
+    Thunk_IDirect3DMaterialImpl_2_SetMaterial,
+    Thunk_IDirect3DMaterialImpl_2_GetMaterial,
+    Thunk_IDirect3DMaterialImpl_2_GetHandle,
 };
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DMaterialVtbl VTABLE_IDirect3DMaterial =
+const IDirect3DMaterialVtbl IDirect3DMaterial_Vtbl =
 {
-    XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_1_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DMaterialImpl_1_AddRef,
-    XCAST(Release) Thunk_IDirect3DMaterialImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DMaterialImpl_1_Initialize,
-    XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_1_SetMaterial,
-    XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_1_GetMaterial,
-    XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_1_GetHandle,
-    XCAST(Reserve) Main_IDirect3DMaterialImpl_1_Reserve,
-    XCAST(Unreserve) Main_IDirect3DMaterialImpl_1_Unreserve,
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DMaterialImpl_1_QueryInterface,
+    Thunk_IDirect3DMaterialImpl_1_AddRef,
+    Thunk_IDirect3DMaterialImpl_1_Release,
+    /*** IDirect3DMaterial1 Methods ***/
+    IDirect3DMaterialImpl_Initialize,
+    Thunk_IDirect3DMaterialImpl_1_SetMaterial,
+    Thunk_IDirect3DMaterialImpl_1_GetMaterial,
+    Thunk_IDirect3DMaterialImpl_1_GetHandle,
+    IDirect3DMaterialImpl_Reserve,
+    IDirect3DMaterialImpl_Unreserve
 };
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-
-
-HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d)
-{
-    IDirect3DMaterialImpl *object;
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
-
-    object->ref = 1;
-    object->d3d = d3d;
-    object->activate = activate;
-    
-    ICOM_INIT_INTERFACE(object, IDirect3DMaterial,  VTABLE_IDirect3DMaterial);
-    ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, VTABLE_IDirect3DMaterial2);
-    ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, VTABLE_IDirect3DMaterial3);
-
-    *obj = object;
-    
-    TRACE(" creating implementation at %p.\n", *obj);
-    
-    return D3D_OK;
-}
diff --git a/dlls/ddraw/opengl_private.h b/dlls/ddraw/opengl_private.h
deleted file mode 100644
index e29afd4..0000000
--- a/dlls/ddraw/opengl_private.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* MESA private include file
- * Copyright (c) 1998 Lionel ULMER
- *
- * This file contains all structures that are not exported
- * through d3d.h and all common macros.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __GRAPHICS_WINE_MESA_PRIVATE_H
-#define __GRAPHICS_WINE_MESA_PRIVATE_H
-
-#include "d3d_private.h"
-
-#ifdef HAVE_OPENGL
-
-#include "gl_private.h"
-
-/* X11 locking */
-
-extern void (*wine_tsx11_lock_ptr)(void);
-extern void (*wine_tsx11_unlock_ptr)(void);
-
-/* As GLX relies on X, this is needed */
-#define ENTER_GL() wine_tsx11_lock_ptr()
-#define LEAVE_GL() wine_tsx11_unlock_ptr()
-
-extern const GUID IID_D3DDEVICE_OpenGL;
-
-typedef enum {
-    SURFACE_GL,
-    SURFACE_MEMORY,
-    SURFACE_MEMORY_DIRTY
-} SURFACE_STATE;
-
-/* This structure is used for the 'd3d_private' field of the IDirectDraw structure */
-typedef struct IDirect3DGLImpl
-{
-    int dummy; /* Empty for the moment */
-} IDirect3DGLImpl;
-
-/* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */
-typedef struct IDirect3DTextureGLImpl
-{
-    GLuint tex_name;
-    BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
-    IDirectDrawSurfaceImpl *main; /* Pointer to the 'main' surface of the mip-map set */
-    
-    /* Texture upload management */
-    BOOLEAN initial_upload_done;
-    SURFACE_STATE dirty_flag;
-
-    /* This is used to optimize dirty checking in case of mipmapping.
-       Note that a bitmap could have been used but it was not worth the pain as it will be very rare
-       to have only one mipmap level change...
-
-       The __global_dirty_flag will only be set for the main mipmap level.
-    */
-    SURFACE_STATE __global_dirty_flag;
-    SURFACE_STATE *global_dirty_flag;
-    
-    /* This is to optimize the 'per-texture' parameters. */
-    DWORD *tex_parameters;
-    
-    /* Surface optimization */
-    void *surface_ptr;
-
-    /* Used to detect a change in internal format when going from non-CK texture to CK-ed texture */
-    GLenum current_internal_format;
-    
-    /* This is for now used to override 'standard' surface stuff to be as transparent as possible */
-    void (*final_release)(struct IDirectDrawSurfaceImpl *This);
-    void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
-    void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
-    void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal);
-} IDirect3DTextureGLImpl;
-
-typedef enum {
-    GL_TRANSFORM_NONE = 0,
-    GL_TRANSFORM_ORTHO,
-    GL_TRANSFORM_NORMAL,
-    GL_TRANSFORM_VERTEXBUFFER
-} GL_TRANSFORM_STATE;
-
-typedef enum {
-    WINE_GL_BUFFER_BACK = 0,
-    WINE_GL_BUFFER_FRONT
-} WINE_GL_BUFFER_TYPE;
-
-typedef struct IDirect3DDeviceGLImpl
-{
-    struct IDirect3DDeviceImpl parent;
-    
-    GLXContext gl_context;
-
-    /* This stores the textures which are actually bound to the GL context */
-    IDirectDrawSurfaceImpl *current_bound_texture[MAX_TEXTURES];
-
-    /* The last type of vertex drawn */
-    GL_TRANSFORM_STATE transform_state;
-
-    /* Used to handle fogging faster... */
-    BYTE fog_table[3 * 0x10000]; /* 3 is for R, G and B
-				    0x10000 is 0xFF for the vertex color and
-				               0xFF for the fog intensity */
-    
-    Display  *display;
-    Drawable drawable;
-
-    /* Variables used for the flush to frame-buffer code using the texturing code */
-    GLuint unlock_tex;
-    void *surface_ptr;
-    GLenum current_internal_format;
-
-    /* 0 is back-buffer, 1 is front-buffer */
-    SURFACE_STATE state[2];
-    IDirectDrawSurfaceImpl *lock_surf[2];
-    RECT lock_rect[2];
-    /* This is just here to print-out a nice warning if we have two successive locks */
-    BOOLEAN lock_rect_valid[2];
-
-    /* This is used to optimize some stuff */
-    DWORD prev_clear_color;
-    DWORD prev_clear_stencil;
-    D3DVALUE prev_clear_Z;
-    BOOLEAN depth_mask, depth_test, alpha_test, stencil_test, cull_face, lighting, blending, fogging;
-    GLenum current_alpha_test_func;
-    GLclampf current_alpha_test_ref;
-    GLenum current_tex_env;
-    GLenum current_active_tex_unit;
-} IDirect3DDeviceGLImpl;
-
-/* This is for the OpenGL additions... */
-typedef struct {
-    struct IDirect3DVertexBufferImpl parent;
-
-    DWORD dwVertexTypeDesc;
-    D3DMATRIX world_mat, view_mat, proj_mat;
-    LPVOID vertices;
-} IDirect3DVertexBufferGLImpl;
-
-/* This is for GL extension support.
-   
-   This can contain either only a boolean if no function pointer exists or a set
-   of function pointers.
-*/
-typedef struct {
-    /* Mirrored Repeat */
-    BOOLEAN mirrored_repeat;
-    /* Mipmap lod-bias */
-    BOOLEAN mipmap_lodbias;
-    /* Multi-texturing */
-    GLint max_texture_units;
-    void (*glActiveTexture)(GLenum texture);
-    void (*glMultiTexCoord[4])(GLenum target, const GLfloat *v);
-    void (*glClientActiveTexture)(GLenum texture);
-    /* S3TC/DXTN compressed texture */
-    BOOLEAN s3tc_compressed_texture;
-    void (*glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width,
-                                 GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
-    void (*glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                    GLsizei width, GLsizei height, GLsizei imageSize, const GLvoid *data);
-} GL_EXTENSIONS_LIST; 
-extern GL_EXTENSIONS_LIST GL_extensions;
-
-/* All non-static functions 'exported' by various sub-objects */
-extern HRESULT direct3d_create(IDirectDrawImpl *This);
-extern HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);
-extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d);
-extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
-extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d);
-extern HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d);
-extern HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags);
-extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version);
-
-/* Used for Direct3D to request the device to enumerate itself */
-extern HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) ;
-extern HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context) ;
-extern HRESULT d3ddevice_find(IDirectDrawImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lplpD3DDevice);
-
-/* Used by the DLL init routine to set-up the GL context and stuff properly */
-extern BOOL d3ddevice_init_at_startup(void *gl_handle);
-
-/* Used to upload the texture */
-extern HRESULT gltex_upload_texture(IDirectDrawSurfaceImpl *This, IDirect3DDeviceImpl *d3ddev, DWORD stage) ;
-
-/* Used to get the texture name */
-extern GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *This) ;
-
-/* Used to set-up our orthographic projection */
-extern void d3ddevice_set_ortho(IDirect3DDeviceImpl *This) ;
-
-/* Rendering state management functions */
-extern void set_render_state(IDirect3DDeviceImpl* This, D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock);
-extern void store_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK* lpStateBlock);
-extern void get_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK* lpStateBlock);
-extern void apply_render_state(IDirect3DDeviceImpl* This, STATEBLOCK* lpStateBlock);
-
-/* Memory to texture conversion code. Split in three functions to do some optimizations. */
-extern HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surface, GLuint level, GLenum *prev_internal_format,
-						 BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height);
-extern HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer);
-extern HRESULT upload_surface_to_tex_memory_release(void);
-
-/* Some utilities functions needed to be shared.. */
-extern GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState) ;
-
-#endif /* HAVE_OPENGL */
-
-#endif /* __GRAPHICS_WINE_MESA_PRIVATE_H */
diff --git a/dlls/ddraw/opengl_utils.c b/dlls/ddraw/opengl_utils.c
deleted file mode 100644
index a2b0219..0000000
--- a/dlls/ddraw/opengl_utils.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-/* Direct3D Common functions
- * Copyright (c) 1998 Lionel ULMER
- *
- * This file contains all MESA common code
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <stdarg.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#include "windef.h"
-#include "winbase.h"
-#include "objbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "wine/debug.h"
-
-#include "opengl_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState)
-{
-    switch (dwRenderState) {
-        case D3DCMP_NEVER: return GL_NEVER;
-	case D3DCMP_LESS: return GL_LESS;
-	case D3DCMP_EQUAL: return GL_EQUAL;
-	case D3DCMP_LESSEQUAL: return GL_LEQUAL;
-	case D3DCMP_GREATER: return GL_GREATER;
-	case D3DCMP_NOTEQUAL: return GL_NOTEQUAL;
-	case D3DCMP_GREATEREQUAL: return GL_GEQUAL;
-	case D3DCMP_ALWAYS: return GL_ALWAYS;
-	default: ERR("Unexpected compare type %d !\n", dwRenderState);
-    }
-    return GL_ALWAYS;
-}
-
-GLenum convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState)
-{
-    switch (dwRenderState) {
-        case D3DSTENCILOP_KEEP: return GL_KEEP;
-        case D3DSTENCILOP_ZERO: return GL_ZERO;
-        case D3DSTENCILOP_REPLACE: return GL_REPLACE;
-        case D3DSTENCILOP_INCRSAT: return GL_INCR;
-        case D3DSTENCILOP_DECRSAT: return GL_DECR;
-        case D3DSTENCILOP_INVERT: return GL_INVERT;
-        case D3DSTENCILOP_INCR: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR;
-        case D3DSTENCILOP_DECR: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR;
-        default: ERR("Unexpected compare type %d !\n", dwRenderState);      
-    }
-    return GL_KEEP;
-}
-
-GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState)
-{
-    switch ((D3DBLEND) dwRenderState) {
-        case D3DBLEND_ZERO: return GL_ZERO;
-        case D3DBLEND_ONE: return GL_ONE;
-	case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA;
-	case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
-	case D3DBLEND_DESTALPHA: return GL_DST_ALPHA;
-	case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA;
-	case D3DBLEND_DESTCOLOR: return GL_DST_COLOR;
-	case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR;
-	case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
-	case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR;
-	case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
-        default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO;
-    }
-}
-
-void set_render_state(IDirect3DDeviceImpl* This,
-		      D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock)
-{
-    DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    
-    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
-
-    /* First, all the stipple patterns */
-    if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
-	(dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
-        ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
-    } else {
-        ENTER_GL();
-
-	/* All others state variables */
-	switch (dwRenderStateType) {
-	    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
-	        IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
-		
-		IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
-					    0, 
-					    ICOM_INTERFACE(tex, IDirectDrawSurface7));
-	    } break;
-
-	    case D3DRENDERSTATE_ANTIALIAS:        /*  2 */
-	        if (dwRenderState)
-		    ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n");
-	        break;
-	      
-	    case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
-	    case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
-	    case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
-	        D3DTEXTURESTAGESTATETYPE d3dTexStageStateType;
-
-		if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS;
-		else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
-		else d3dTexStageStateType = D3DTSS_ADDRESSV;
-
-		IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
-						      0, d3dTexStageStateType,
-						      dwRenderState);
-	    } break;
-	      
-	    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
-	        if (dwRenderState)
-		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
-		else
-		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
-	        break;
-
-	    case D3DRENDERSTATE_WRAPU: /* 5 */
-	    case D3DRENDERSTATE_WRAPV: /* 6 */
-	    case D3DRENDERSTATE_WRAP0: /* 128 */
-	    case D3DRENDERSTATE_WRAP1: /* 129 */
-	    case D3DRENDERSTATE_WRAP2: /* 130 */
-	    case D3DRENDERSTATE_WRAP3: /* 131 */
-	    case D3DRENDERSTATE_WRAP4: /* 132 */
-	    case D3DRENDERSTATE_WRAP5: /* 133 */
-	    case D3DRENDERSTATE_WRAP6: /* 134 */
-	    case D3DRENDERSTATE_WRAP7: /* 135 */
-	        if (dwRenderState)
-		    ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n");
-	        break;
-
-	    case D3DRENDERSTATE_ZENABLE:          /*  7 */
-	        /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
-		   updated either.. No idea about what happens in D3D.
-		   
-		   Maybe replacing the Z function by ALWAYS would be a better idea. */
-	        if (dwRenderState == D3DZB_TRUE) {
-		    if (glThis->depth_test == FALSE) {
-			glEnable(GL_DEPTH_TEST);
-			glThis->depth_test = TRUE;
-		    }
-		} else if (dwRenderState == D3DZB_FALSE) {
-		    if (glThis->depth_test) {
-			glDisable(GL_DEPTH_TEST);
-			glThis->depth_test = FALSE;
-		    }
-		} else {
-		    if (glThis->depth_test == FALSE) {
-			glEnable(GL_DEPTH_TEST);
-			glThis->depth_test = TRUE;
-		    }
-		    WARN(" w-buffering not supported.\n");
-		}
-	        break;
-
-	    case D3DRENDERSTATE_FILLMODE:           /*  8 */
-	        switch ((D3DFILLMODE) dwRenderState) {
-		    case D3DFILL_POINT:
-		        glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
-			break;
-		    case D3DFILL_WIREFRAME:
-			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
-			break;
-		    case D3DFILL_SOLID:
-			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
-			break;
-		    default:
-			ERR("Unhandled fill mode %ld !\n",dwRenderState);
-		 }
-	         break;
-
-	    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
-	        switch ((D3DSHADEMODE) dwRenderState) {
-		    case D3DSHADE_FLAT:
-		        glShadeModel(GL_FLAT);
-			break;
-		    case D3DSHADE_GOURAUD:
-			glShadeModel(GL_SMOOTH);
-			break;
-		    default:
-			ERR("Unhandled shade mode %ld !\n",dwRenderState);
-		}
-	        break;
-
-	    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
-	        if ((dwRenderState != FALSE) && (glThis->depth_mask == FALSE))
-		    glDepthMask(GL_TRUE);
-		else if ((dwRenderState == FALSE) && (glThis->depth_mask != FALSE))
-		    glDepthMask(GL_FALSE);
-	        glThis->depth_mask = dwRenderState;
-	        break;
-	      
-	    case D3DRENDERSTATE_ALPHATESTENABLE:  /* 15 */
-	        if ((dwRenderState != 0) && (glThis->alpha_test == FALSE))
-		    glEnable(GL_ALPHA_TEST);
-	        else if ((dwRenderState == 0) && (glThis->alpha_test != FALSE))
-		    glDisable(GL_ALPHA_TEST);
-		glThis->alpha_test = dwRenderState;
-	        break;
-
-	    case D3DRENDERSTATE_TEXTUREMAG: {     /* 17 */
-	        DWORD tex_mag = 0xFFFFFFFF;
-
-	        switch ((D3DTEXTUREFILTER) dwRenderState) {
-		    case D3DFILTER_NEAREST:
-		        tex_mag = D3DTFG_POINT;
-			break;
-		    case D3DFILTER_LINEAR:
-		        tex_mag = D3DTFG_LINEAR;
-			break;
-		    default:
-			ERR("Unhandled texture mag %ld !\n",dwRenderState);
-	        }
-
-		if (tex_mag != 0xFFFFFFFF) {
-		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
-		}
-	    } break;
-
-	    case D3DRENDERSTATE_TEXTUREMIN: {       /* 18 */
-	        DWORD tex_min = 0xFFFFFFFF;
-
-	        switch ((D3DTEXTUREFILTER) dwRenderState) {
-		    case D3DFILTER_NEAREST:
-		        tex_min = D3DTFN_POINT;
-			break;
-		    case D3DFILTER_LINEAR:
-		        tex_min = D3DTFN_LINEAR;
-			break;
-		    default:
-			ERR("Unhandled texture min %ld !\n",dwRenderState);
-	        }
-
-		if (tex_min != 0xFFFFFFFF) {
-		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
-		}
-	    } break;
-
-	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
-	    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
-	        glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]),
-			    convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1]));
-	        break;
-
-	    case D3DRENDERSTATE_TEXTUREMAPBLEND: {  /* 21 */
-		IDirect3DDevice7 *d3ddev = ICOM_INTERFACE(This, IDirect3DDevice7);
-		
-	        switch ((D3DTEXTUREBLEND) dwRenderState) {
-		    case D3DTBLEND_DECAL:
-		        if (glThis->current_tex_env != GL_REPLACE) {
-			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-			    glThis->current_tex_env = GL_REPLACE;
-			}
-			break;
-		    case D3DTBLEND_DECALALPHA:
-			if (glThis->current_tex_env != GL_REPLACE) {
-			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
-			    glThis->current_tex_env = GL_DECAL;
-			}
-			break;
-		    case D3DTBLEND_MODULATE:
-			if (glThis->current_tex_env != GL_MODULATE) {
-			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-			    glThis->current_tex_env = GL_MODULATE;
-			}
-			break;
-		    case D3DTBLEND_MODULATEALPHA:
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
-			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
-			break;
-		    default:
-		        ERR("Unhandled texture environment %ld !\n",dwRenderState);
-		}
-	    } break;
-
-	    case D3DRENDERSTATE_CULLMODE:           /* 22 */
-	        switch ((D3DCULL) dwRenderState) {
-		    case D3DCULL_NONE:
-		         if (glThis->cull_face != 0) {
-			     glDisable(GL_CULL_FACE);
-			     glThis->cull_face = 0;
-			 }
-			 break;
-		    case D3DCULL_CW:
-			 if (glThis->cull_face == 0) {
-			     glEnable(GL_CULL_FACE);
-			     glThis->cull_face = 1;
-			 }
-			 glFrontFace(GL_CCW);
-			 glCullFace(GL_BACK);
-			 break;
-		    case D3DCULL_CCW:
-			 if (glThis->cull_face == 0) {
-			     glEnable(GL_CULL_FACE);
-			     glThis->cull_face = 1;
-			 }
-			 glFrontFace(GL_CW);
-			 glCullFace(GL_BACK);
-			 break;
-		    default:
-			 ERR("Unhandled cull mode %ld !\n",dwRenderState);
-		}
-	        break;
-
-	    case D3DRENDERSTATE_ZFUNC:            /* 23 */
-	        glDepthFunc(convert_D3D_compare_to_GL(dwRenderState));
-	        break;
-	      
-	    case D3DRENDERSTATE_ALPHAREF:    /* 24 */
-	    case D3DRENDERSTATE_ALPHAFUNC: { /* 25 */
-		    GLenum func = convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]);
-		    GLclampf ref = (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0;
-
-		    if ((func != glThis->current_alpha_test_func) || (ref != glThis->current_alpha_test_ref)) {
-			glAlphaFunc(func, ref);
-			glThis->current_alpha_test_func = func;
-			glThis->current_alpha_test_ref = ref;
-		    }
-	        }
-	        break;
-
-	    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
-	        if (dwRenderState)
-		    glEnable(GL_DITHER);
-		else
-		    glDisable(GL_DITHER);
-	        break;
-
-	    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
-	        if ((dwRenderState != 0) && (glThis->blending == 0)) {
-		    glEnable(GL_BLEND);
-		} else if ((dwRenderState == 0) && (glThis->blending != 0)) {
-		    glDisable(GL_BLEND);
-		}
-	        glThis->blending = dwRenderState;
-
-	        /* Hack for some old games ... */
-	        if (glThis->parent.version == 1) {
-		    lpStateBlock->render_state[D3DRENDERSTATE_COLORKEYENABLE - 1] = dwRenderState;
-		}
-	        break;
-	      
-	    case D3DRENDERSTATE_FOGENABLE: /* 28 */
-	        /* Nothing to do here. Only the storage matters :-) */
-	        break;
-
-	    case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
-	        if (dwRenderState)
-		    ERR(" Specular Lighting not supported yet.\n");
-	        break;
-	      
-	    case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
-	    case D3DRENDERSTATE_SUBPIXELX: /* 32 */
-	        /* We do not support this anyway, so why protest :-) */
-	        break; 
-
- 	    case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */
-	        if (dwRenderState)
-		    ERR(" Stippled Alpha not supported yet.\n");
-		break;
-
-	    case D3DRENDERSTATE_FOGCOLOR: { /* 34 */
-	        GLfloat color[4];
-		color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f;
-		color[1] = ((dwRenderState >>  8) & 0xFF)/255.0f;
-		color[2] = ((dwRenderState >>  0) & 0xFF)/255.0f;
-		color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f;
-		glFogfv(GL_FOG_COLOR,color);
-		/* Note: glFogiv does not seem to work */
-	    } break;
-
- 	    case D3DRENDERSTATE_FOGTABLEMODE:  /* 35 */
- 	    case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */
- 	    case D3DRENDERSTATE_FOGSTART:      /* 36 */
-	    case D3DRENDERSTATE_FOGEND:        /* 37 */
-	        /* Nothing to do here. Only the storage matters :-) */
-		break;
-
-	    case D3DRENDERSTATE_FOGDENSITY:    /* 38 */
-		glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState);
-		break;
-
-	    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
-	        /* Nothing done here, only storage matters. */
-	        break;
-
-	    case D3DRENDERSTATE_MIPMAPLODBIAS: /* 46 */
-	        IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
-						      0, D3DTSS_MIPMAPLODBIAS,
-						      dwRenderState);
-	        break;
-	      
-	    case D3DRENDERSTATE_ZBIAS: /* 47 */
-	        /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
-	        if (dwRenderState == 0) {
-		    glDisable(GL_POLYGON_OFFSET_FILL);
-		    glDisable(GL_POLYGON_OFFSET_LINE);
-		    glDisable(GL_POLYGON_OFFSET_POINT);
-		} else {
-		    glEnable(GL_POLYGON_OFFSET_FILL);
-		    glEnable(GL_POLYGON_OFFSET_LINE);
-		    glEnable(GL_POLYGON_OFFSET_POINT);
-		    glPolygonOffset(1.0, dwRenderState * 1.0);
-		}
-	        break;
-	      
-	    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
-	        break;
-
-	    case D3DRENDERSTATE_STENCILENABLE:    /* 52 */
-	        if ((dwRenderState != 0) && (glThis->stencil_test == 0))
-		    glEnable(GL_STENCIL_TEST);
-		else if ((dwRenderState == 0) && (glThis->stencil_test != 0))
-		    glDisable(GL_STENCIL_TEST);
-	        glThis->stencil_test = dwRenderState;
-		break;
-	    
-	    case D3DRENDERSTATE_STENCILFAIL:      /* 53 */
-	    case D3DRENDERSTATE_STENCILZFAIL:     /* 54 */
-	    case D3DRENDERSTATE_STENCILPASS:      /* 55 */
-		glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]),
-			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]),
-			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1]));
-		break;
-
-	    case D3DRENDERSTATE_STENCILFUNC:      /* 56 */
-	    case D3DRENDERSTATE_STENCILREF:       /* 57 */
-	    case D3DRENDERSTATE_STENCILMASK:      /* 58 */
-		glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]),
-			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1],
-			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]);
-		break;
-	  
-	    case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */
-	        glStencilMask(dwRenderState);
-	        break;
-
-	    case D3DRENDERSTATE_TEXTUREFACTOR:      /* 60 */
-	        /* Only the storage matters... */
-	        break;
-
-	    case D3DRENDERSTATE_CLIPPING:          /* 136 */
-	    case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */
-		    GLint i;
-		    DWORD mask, runner;
-		    
-		    if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) {
-			mask = ((dwRenderState) ?
-				(This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x00000000));
-		    } else {
-			mask = dwRenderState;
-		    }
-		    for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) {
-			if (mask & runner) {
-			    GLint enabled;
-			    glGetIntegerv(GL_CLIP_PLANE0 + i, &enabled);
-			    if (enabled == GL_FALSE) {
-			        glEnable(GL_CLIP_PLANE0 + i);
-				/* Need to force a transform change so that this clipping plane parameters are sent
-				 * properly to GL.
-				 */
-				glThis->transform_state = GL_TRANSFORM_NONE;
-			    }
-			} else {
-			    glDisable(GL_CLIP_PLANE0 + i);
-			}
-		    }
-		}
-	        break;
-
-	    case D3DRENDERSTATE_LIGHTING:    /* 137 */
-	        /* Nothing to do, only storage matters... */
-	        break;
-		
-	    case D3DRENDERSTATE_AMBIENT: {            /* 139 */
-	        float light[4];
-
-		light[0] = ((dwRenderState >> 16) & 0xFF) / 255.0;
-		light[1] = ((dwRenderState >>  8) & 0xFF) / 255.0;
-		light[2] = ((dwRenderState >>  0) & 0xFF) / 255.0;
-		light[3] = ((dwRenderState >> 24) & 0xFF) / 255.0;
-		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
-	    } break;
-
-	    case D3DRENDERSTATE_COLORVERTEX:          /* 141 */
-	          /* Nothing to do here.. Only storage matters */
-	          break;
-		  
-	    case D3DRENDERSTATE_LOCALVIEWER:          /* 142 */
-	        if (dwRenderState)
-		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
-		else
-		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
-		break;
-
-	    case D3DRENDERSTATE_NORMALIZENORMALS:     /* 143 */
-	        if (dwRenderState) {
-		    glEnable(GL_NORMALIZE);
-		    glEnable(GL_RESCALE_NORMAL);
-		} else {
-		    glDisable(GL_NORMALIZE);
-		    glDisable(GL_RESCALE_NORMAL);
-		}
-		break;
-
-	    case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:    /* 145 */
-	    case D3DRENDERSTATE_SPECULARMATERIALSOURCE:   /* 146 */
-	    case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:    /* 147 */
-	    case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:   /* 148 */
-	        /* Nothing to do here. Only the storage matters :-) */
-		break;
-
-	    default:
-	        ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n",
-		    _get_renderstate(dwRenderStateType), dwRenderStateType, dwRenderState);
-	}
-	LEAVE_GL();
-    }
-}
-
-void store_render_state(IDirect3DDeviceImpl *This,
-			D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock)
-{
-    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
-    
-    /* Some special cases first.. */
-    if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) {
-        if (dwRenderState == D3DBLEND_BOTHSRCALPHA) {
-	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA;
-	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA;
-	    return;
-	} else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) {
-	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA;
-	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA;
-	    return;
-	}
-    } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) {
-        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState;
-        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState;
-    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPU) {
-        if (dwRenderState) 
-	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_U;
-	else
-	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U;
-    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPV) {
-        if (dwRenderState) 
-	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_V;
-	else
-	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V;
-    }
-    
-    /* Default case */
-    lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState;
-}
-
-void get_render_state(IDirect3DDeviceImpl *This,
-		      D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock)
-{
-    *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
-    if (TRACE_ON(ddraw))
-        TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
-}
-
-void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock)
-{
-    DWORD i;
-    TRACE("(%p,%p)\n", This, lpStateBlock);
-    for(i = 0; i < HIGHEST_RENDER_STATE; i++)
-	if (lpStateBlock->set_flags.render_state[i])
-            set_render_state(This, i + 1, lpStateBlock);
-}
-
-
-/* Texture management code.
-
-    - upload_surface_to_tex_memory_init initialize the code and computes the GL formats 
-      according to the surface description.
-
-    - upload_surface_to_tex_memory does the real upload. If one buffer is split over
-      multiple textures, this can be called multiple times after the '_init' call. 'rect'
-      can be NULL if the whole buffer needs to be upload.
-
-    - upload_surface_to_tex_memory_release does the clean-up.
-
-   These functions are called in the following cases :
-    - texture management (ie to upload a D3D texture to GL when it changes).
-    - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture
-      engine.
-    - use of the texture engine to simulate Blits to the 3D Device.
-*/
-typedef enum {
-    NO_CONVERSION,
-    CONVERT_PALETTED,
-    CONVERT_CK_565,
-    CONVERT_CK_5551,
-    CONVERT_CK_4444,
-    CONVERT_CK_4444_ARGB,
-    CONVERT_CK_1555,
-    CONVERT_555,
-    CONVERT_CK_RGB24,
-    CONVERT_CK_8888,
-    CONVERT_CK_8888_ARGB,
-    CONVERT_RGB32_888
-} CONVERT_TYPES;
-
-/* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things
-   may happen :-) */
-static GLenum current_format;
-static GLenum current_pixel_format;
-static CONVERT_TYPES convert_type;
-static IDirectDrawSurfaceImpl *current_surface;
-static GLuint current_level;
-static DWORD current_tex_width;
-static DWORD current_tex_height;
-static GLuint current_alignement_constraints;
-static int current_storage_width;
-
-HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLuint level, GLenum *current_internal_format,
-					  BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height)
-{
-    const DDPIXELFORMAT * const src_pf = &(surf_ptr->surface_desc.u4.ddpfPixelFormat);
-    BOOL error = FALSE;
-    BOOL colorkey_active = need_alpha_ck && (surf_ptr->surface_desc.dwFlags & DDSD_CKSRCBLT);
-    GLenum internal_format = GL_LUMINANCE; /* A bogus value to be sure to have a nice Mesa warning :-) */
-    BYTE bpp = GET_BPP(surf_ptr->surface_desc);
-    BOOL sub_texture = TRUE;
-
-    current_surface = surf_ptr;
-    current_level = level;
-
-    if (src_pf->dwFlags & DDPF_FOURCC) {
-	GLenum retVal;
-	int size = surf_ptr->surface_desc.u1.dwLinearSize;
-	int width = surf_ptr->surface_desc.dwWidth;
-	int height = surf_ptr->surface_desc.dwHeight;
-	LPVOID buffer = surf_ptr->surface_desc.lpSurface;
-
-	switch (src_pf->dwFourCC) {
-	    case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
-	    case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
-	    case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
-	    default:
-		FIXME("FourCC Not supported\n");
-		return DD_OK;
-	}
-
-	if (GL_extensions.s3tc_compressed_texture) {
-	    GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width, height, 0, size, buffer);
-	} else
-	    ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
-
-	return DD_OK;
-    }
-
-    /* First, do some sanity checks ... */
-    if ((surf_ptr->surface_desc.u1.lPitch % bpp) != 0) {
-	FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
-    } else {
-	/* In that case, no need to have any alignement constraints... */
-	if (current_alignement_constraints != 1) {
-	    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-	    current_alignement_constraints = 1;
-	}
-    }
-
-    /* Note: we only check width here as you cannot have width non-zero while height is set to zero */
-    if (tex_width == 0) {
-	sub_texture = FALSE;
-	
-	tex_width = surf_ptr->surface_desc.dwWidth;
-	tex_height = surf_ptr->surface_desc.dwHeight;
-    }
-
-    current_tex_width = tex_width;
-    current_tex_height = tex_height;
-
-    if (src_pf->dwFlags & DDPF_PALETTEINDEXED8) {
-	/* ****************
-	   Paletted Texture
-	   **************** */
-	current_format = GL_RGBA;
-	internal_format = GL_RGBA;
-	current_pixel_format = GL_UNSIGNED_BYTE;
-	convert_type = CONVERT_PALETTED;
-    } else if (src_pf->dwFlags & DDPF_RGB) {
-	/* ************
-	   RGB Textures
-	   ************ */
-	if (src_pf->u1.dwRGBBitCount == 8) {
-	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
-		(src_pf->u5.dwRGBAlphaBitMask != 0x00)) {
-		error = TRUE;
-	    } else {
-		if ((src_pf->u2.dwRBitMask == 0xE0) &&
-		    (src_pf->u3.dwGBitMask == 0x1C) &&
-		    (src_pf->u4.dwBBitMask == 0x03)) {
-		    /* **********************
-		       GL_UNSIGNED_BYTE_3_3_2
-		       ********************** */
-		    if (colorkey_active) {
-			/* This texture format will never be used.. So do not care about color keying
-			   up until the point in time it will be needed :-) */
-			FIXME(" ColorKeying not supported in the RGB 332 format !\n");
-		    }
-		    current_format = GL_RGB;
-		    internal_format = GL_RGB;
-		    current_pixel_format = GL_UNSIGNED_BYTE_3_3_2;
-		    convert_type = NO_CONVERSION;
-		} else {
-		    error = TRUE;
-		}
-	    }
-	} else if (src_pf->u1.dwRGBBitCount == 16) {
-	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
-		(src_pf->u5.dwRGBAlphaBitMask != 0x0000)) {
-		if ((src_pf->u2.dwRBitMask ==        0xF800) &&
-		    (src_pf->u3.dwGBitMask ==        0x07C0) &&
-		    (src_pf->u4.dwBBitMask ==        0x003E) &&
-		    (src_pf->u5.dwRGBAlphaBitMask == 0x0001)) {
-		    current_format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_5551;
-		    } else {
-			convert_type = NO_CONVERSION;
-		    }
-		} else if ((src_pf->u2.dwRBitMask ==        0xF000) &&
-			   (src_pf->u3.dwGBitMask ==        0x0F00) &&
-			   (src_pf->u4.dwBBitMask ==        0x00F0) &&
-			   (src_pf->u5.dwRGBAlphaBitMask == 0x000F)) {
-		    current_format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_4444;
-		    } else {
-			convert_type = NO_CONVERSION;
-		    }
-		} else if ((src_pf->u2.dwRBitMask ==        0x0F00) &&
-			   (src_pf->u3.dwGBitMask ==        0x00F0) &&
-			   (src_pf->u4.dwBBitMask ==        0x000F) &&
-			   (src_pf->u5.dwRGBAlphaBitMask == 0xF000)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_4444_ARGB;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_BGRA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		    }
-		} else if ((src_pf->u2.dwRBitMask ==        0x7C00) &&
-			   (src_pf->u3.dwGBitMask ==        0x03E0) &&
-			   (src_pf->u4.dwBBitMask ==        0x001F) &&
-			   (src_pf->u5.dwRGBAlphaBitMask == 0x8000)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_1555;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_BGRA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		    }
-		} else {
-		    error = TRUE;
-		}
-	    } else {
-		if ((src_pf->u2.dwRBitMask == 0xF800) &&
-		    (src_pf->u3.dwGBitMask == 0x07E0) &&
-		    (src_pf->u4.dwBBitMask == 0x001F)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_565;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_RGB;
-			internal_format = GL_RGB;
-			current_pixel_format = GL_UNSIGNED_SHORT_5_6_5;
-		    }
-		} else if ((src_pf->u2.dwRBitMask == 0x7C00) &&
-			   (src_pf->u3.dwGBitMask == 0x03E0) &&
-			   (src_pf->u4.dwBBitMask == 0x001F)) {
-		    convert_type = CONVERT_555;
-		    current_format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		} else {
-		    error = TRUE;
-		}
-	    }
-	} else if (src_pf->u1.dwRGBBitCount == 24) {
-	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
-		(src_pf->u5.dwRGBAlphaBitMask != 0x000000)) {
-		error = TRUE;
-	    } else {
-		if ((src_pf->u2.dwRBitMask == 0xFF0000) &&
-		    (src_pf->u3.dwGBitMask == 0x00FF00) &&
-		    (src_pf->u4.dwBBitMask == 0x0000FF)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_RGB24;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_BGR;
-			internal_format = GL_RGB;
-			current_pixel_format = GL_UNSIGNED_BYTE;
-		    }
-		} else {
-		    error = TRUE;
-		}
-	    }
-	} else if (src_pf->u1.dwRGBBitCount == 32) {
-	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
-		(src_pf->u5.dwRGBAlphaBitMask != 0x00000000)) {
-		if ((src_pf->u2.dwRBitMask ==        0xFF000000) &&
-		    (src_pf->u3.dwGBitMask ==        0x00FF0000) &&
-		    (src_pf->u4.dwBBitMask ==        0x0000FF00) &&
-		    (src_pf->u5.dwRGBAlphaBitMask == 0x000000FF)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_8888;
-		    } else {
-			convert_type = NO_CONVERSION;
-		    }
-		    current_format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		} else if ((src_pf->u2.dwRBitMask ==        0x00FF0000) &&
-			   (src_pf->u3.dwGBitMask ==        0x0000FF00) &&
-			   (src_pf->u4.dwBBitMask ==        0x000000FF) &&
-			   (src_pf->u5.dwRGBAlphaBitMask == 0xFF000000)) {
-		    if (colorkey_active) {
-			convert_type = CONVERT_CK_8888_ARGB;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_BGRA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
-		    }
-		} else {
-		    error = TRUE;
-		}
-	    } else {
-		if ((src_pf->u2.dwRBitMask == 0x00FF0000) &&
-		    (src_pf->u3.dwGBitMask == 0x0000FF00) &&
-		    (src_pf->u4.dwBBitMask == 0x000000FF)) {
-		    if (need_alpha_ck) {
-			convert_type = CONVERT_RGB32_888;
-			current_format = GL_RGBA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		    } else {
-			convert_type = NO_CONVERSION;
-			current_format = GL_BGRA;
-			internal_format = GL_RGBA;
-			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
-		    }
-		} else {
-		    error = TRUE;
-		}
-	    }
-	} else {
-	    error = TRUE;
-	}
-    } else {
-	error = TRUE;
-    } 
-
-    if (error) {
-	ERR("Unsupported pixel format for textures :\n");
-	if (ERR_ON(ddraw)) {
-	    DDRAW_dump_pixelformat(src_pf);
-	}
-	return DDERR_INVALIDPIXELFORMAT;
-    } else {
-	if ((need_to_alloc) ||
-	    (internal_format != *current_internal_format)) {
-	    glTexImage2D(GL_TEXTURE_2D, level, internal_format,
-			 tex_width, tex_height, 0,
-			 current_format, current_pixel_format, NULL);
-	    *current_internal_format = internal_format;
-	}
-    }
-
-    if (sub_texture && (convert_type == NO_CONVERSION)) {
-	current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
-    } else {
-	if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) {
-	    current_storage_width = 0;
-	} else {
-	    current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
-	}	
-    }
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, current_storage_width);
-
-    TRACE(" initialized texture upload for level %d with conversion %d.\n", current_level, convert_type);
-    
-    return DD_OK;
-}
-
-HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer)
-{
-    const DDSURFACEDESC * const src_d = (DDSURFACEDESC *)&(current_surface->surface_desc);
-    void *surf_buffer = NULL;
-    RECT lrect;
-    DWORD width, height;
-    BYTE bpp = GET_BPP(current_surface->surface_desc);
-    int line_increase;
-    
-    if (rect == NULL) {
-	lrect.top = 0;
-	lrect.left = 0;
-	lrect.bottom = current_tex_height;
-	lrect.right = current_tex_width;
-	rect = &lrect;
-    }
-
-    width = rect->right - rect->left;
-    height = rect->bottom - rect->top;
-
-    if (current_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
-	GLint retVal;
-	int size = current_surface->surface_desc.u1.dwLinearSize;
-	int width_ = current_surface->surface_desc.dwWidth;
-	int height_ = current_surface->surface_desc.dwHeight;
-	LPVOID buffer = current_surface->surface_desc.lpSurface;
-
-	switch (current_surface->surface_desc.u4.ddpfPixelFormat.dwFourCC) {
-	    case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
-	    case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
-	    case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
-	    default:
-		FIXME("Not supported\n");
-		return DD_OK;
-	}
-
-	if (GL_extensions.s3tc_compressed_texture) {
-	    /* GL_extensions.glCompressedTexSubImage2D(GL_TEXTURE_2D, current_level, xoffset, yoffset, width, height, retVal, (unsigned char*)temp_buffer); */
-	    GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width_, height_, 0, size, buffer);
-	} else
-	    ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
-
-	return DD_OK;
-    }
-    
-    /* Used when converting stuff */
-    line_increase = src_d->u1.lPitch - (width * bpp);
-
-    switch (convert_type) {
-        case CONVERT_PALETTED: {
-	    IDirectDrawPaletteImpl* pal = current_surface->palette;
-	    BYTE table[256][4];
-	    unsigned int i;
-	    unsigned int x, y;
-	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (pal == NULL) {
-		/* Upload a black texture. The real one will be uploaded on palette change */
-		WARN("Palettized texture Loading with a NULL palette !\n");
-		memset(table, 0, 256 * 4);
-	    } else {
-		/* Get the surface's palette */
-		for (i = 0; i < 256; i++) {
-		    table[i][0] = pal->palents[i].peRed;
-		    table[i][1] = pal->palents[i].peGreen;
-		    table[i][2] = pal->palents[i].peBlue;
-		    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
-			(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
-			(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			/* We should maybe here put a more 'neutral' color than the standard bright purple
-			   one often used by application to prevent the nice purple borders when bi-linear
-			   filtering is on */
-			table[i][3] = 0x00;
-		    else
-			table[i][3] = 0xFF;
-		}
-	    }
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
-					 current_tex_width * current_tex_height * sizeof(DWORD));
-	    dst = (BYTE *) *temp_buffer;
-
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    BYTE color = *src++;
-		    *dst++ = table[color][0];
-		    *dst++ = table[color][1];
-		    *dst++ = table[color][2];
-		    *dst++ = table[color][3];
-		}
-		src += line_increase;
-	    }
-	} break;
-
-        case CONVERT_CK_565: {
-	    /* Converting the 565 format in 5551 packed to emulate color-keying.
-	       
-	       Note : in all these conversion, it would be best to average the averaging
-	              pixels to get the color of the pixel that will be color-keyed to
-		      prevent 'color bleeding'. This will be done later on if ever it is
-		      too visible.
-		      
-	       Note2: when using color-keying + alpha, are the alpha bits part of the
-	              color-space or not ?
-	    */
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    WORD color = *src++;
-		    *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= 0x0001;
-		    dst++;
-		}
-		src = (WORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_CK_5551: {
-	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    WORD color = *src++;
-		    *dst = color & 0xFFFE;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= color & 0x0001;
-		    dst++;
-		}
-		src = (WORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_CK_4444: {
-	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    WORD color = *src++;
-		    *dst = color & 0xFFF0;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= color & 0x000F;
-		    dst++;
-		}
-		src = (WORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_CK_4444_ARGB: {
-	    /* Move the four Alpha bits... */
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    WORD color = *src++;
-		    *dst = (color & 0x0FFF) << 4;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= (color & 0xF000) >> 12;
-		    dst++;
-		}
-		src = (WORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_CK_1555: {
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    WORD color = *src++;
-		    *dst = (color & 0x7FFF) << 1;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= (color & 0x8000) >> 15;
-		    dst++;
-		}
-		src = (WORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_555: {
-	    /* Converting the 0555 format in 5551 packed */
-	    unsigned int x, y;
-	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(WORD));
-	    dst = (WORD *) *temp_buffer;
-	    
-	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-		for (y = 0; y < height; y++) {
-		    for (x = 0; x < width; x++) {
-			WORD color = *src++;
-			*dst = (color & 0x7FFF) << 1;
-			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			    *dst |= 0x0001;
-			dst++;
-		    }
-		    src = (WORD *) (((BYTE *) src) + line_increase);
-		}
-	    } else {
-		for (y = 0; y < height; y++) {
-		    for (x = 0; x < width; x++) {
-			WORD color = *src++;
-			*dst++ = ((color & 0x7FFF) << 1) | 0x0001;
-		    }
-		    src = (WORD *) (((BYTE *) src) + line_increase);
-		}
-	    }
-	    
-	} break;
-	
-        case CONVERT_CK_RGB24: {
-	    /* This is a pain :-) */
-	    unsigned int x, y;
-	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
-	    DWORD *dst;
-
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(DWORD));
-	    dst = (DWORD *) *temp_buffer;
-
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    DWORD color = *((DWORD *) src) & 0x00FFFFFF;
-		    src += 3;
-		    *dst = color << 8;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= 0xFF;
-		    dst++;
-		}
-		src += line_increase;
-	    }
-	} break;
-
-        case CONVERT_CK_8888: {
-	    /* Just use the alpha component to handle color-keying... */
-	    unsigned int x, y;
-	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(DWORD));	    
-	    dst = (DWORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    DWORD color = *src++;
-		    *dst = color & 0xFFFFFF00;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= color & 0x000000FF;
-		    dst++;
-		}
-		src = (DWORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_CK_8888_ARGB: {
-	    unsigned int x, y;
-	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(DWORD));	    
-	    dst = (DWORD *) *temp_buffer;
-	    
-	    for (y = 0; y < height; y++) {
-		for (x = 0; x < width; x++) {
-		    DWORD color = *src++;
-		    *dst = (color & 0x00FFFFFF) << 8;
-		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			*dst |= (color & 0xFF000000) >> 24;
-		    dst++;
-		}
-		src = (DWORD *) (((BYTE *) src) + line_increase);
-	    }
-	} break;
-	
-        case CONVERT_RGB32_888: {
-	    /* Just add an alpha component and handle color-keying... */
-	    unsigned int x, y;
-	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
-	    
-	    if (*temp_buffer == NULL)
-		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					 current_tex_width * current_tex_height * sizeof(DWORD));	    
-	    dst = (DWORD *) *temp_buffer;
-	    
-	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-		for (y = 0; y < height; y++) {
-		    for (x = 0; x < width; x++) {
-			DWORD color = *src++;
-			*dst = color << 8;
-			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			    *dst |= 0xFF;
-			dst++;
-		    }
-		    src = (DWORD *) (((BYTE *) src) + line_increase);
-		}
-	    } else {
-		for (y = 0; y < height; y++) {
-		    for (x = 0; x < width; x++) {
-			*dst++ = (*src++ << 8) | 0xFF;
-		    }
-		    src = (DWORD *) (((BYTE *) src) + line_increase);
-		}
-	    }
-	} break;
-
-        case NO_CONVERSION:
-	    /* Nothing to do here as the name suggests... Just set-up the buffer correctly */
-	    surf_buffer = (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
-	    break;
-    }
-
-    if (convert_type != NO_CONVERSION) {
-	/* When doing conversion, the storage is always of width 'width' as there will never
-	   be any Pitch issue... For now :-)
-	*/
-	surf_buffer = *temp_buffer;
-	if (width != current_storage_width) {
-	    glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
-	    current_storage_width = width;
-	}
-    }
-    
-    glTexSubImage2D(GL_TEXTURE_2D,
-		    current_level,
-		    xoffset, yoffset,
-		    width, height,
-		    current_format,
-		    current_pixel_format,
-		    surf_buffer);
-
-    return DD_OK;
-}
-
-HRESULT upload_surface_to_tex_memory_release(void)
-{
-    current_surface = NULL;
-
-    return DD_OK;
-}
diff --git a/dlls/ddraw/palette.c b/dlls/ddraw/palette.c
new file mode 100644
index 0000000..66b8844
--- /dev/null
+++ b/dlls/ddraw/palette.c
@@ -0,0 +1,240 @@
+/*		DirectDraw - IDirectPalette base interface
+ *
+ * Copyright 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "winerror.h"
+#include "wine/debug.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/*****************************************************************************
+ * IDirectDrawPalette::QueryInterface
+ *
+ * A usual QueryInterface implementation. Can only Query IUnknown and
+ * IDirectDrawPalette
+ *
+ * Params:
+ *  refiid: The interface id queried for
+ *  obj: Address to return the interface pointer at
+ *
+ * Returns:
+ *  S_OK on success
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawPaletteImpl_QueryInterface(IDirectDrawPalette *iface,
+                                      REFIID refiid,
+                                      void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+
+    if (IsEqualGUID(refiid, &IID_IUnknown)
+        || IsEqualGUID(refiid, &IID_IDirectDrawPalette))
+    {
+        *obj = iface;
+        IDirectDrawPalette_AddRef(iface);
+        return S_OK;
+    }
+    else
+    {
+        *obj = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDrawPaletteImpl::AddRef
+ *
+ * Increases the refcount.
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawPaletteImpl_AddRef(IDirectDrawPalette *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawPaletteImpl::Release
+ *
+ * Reduces the refcount. If the refcount falls to 0, the object is destroyed
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawPaletteImpl_Release(IDirectDrawPalette *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
+
+    if (ref == 0)
+    {
+        IWineD3DPalette_Release(This->wineD3DPalette);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawPalette::Initialize
+ *
+ * Initializes the palette. As we start initialized, return
+ * DDERR_ALREADYINITIALIZED
+ *
+ * Params:
+ *  DD: DirectDraw interface this palette is asigned to
+ *  Flags: Some flags, as usual
+ *  ColorTable: The startup color table
+ *
+ * Returns:
+ *  DDERR_ALREADYINITIALIZED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawPaletteImpl_Initialize(IDirectDrawPalette *iface,
+                                  IDirectDraw *DD,
+                                  DWORD Flags,
+                                  PALETTEENTRY *ColorTable)
+{
+    TRACE("(%p)->(%p,%lx,%p)\n", iface, DD, Flags, ColorTable);
+    return DDERR_ALREADYINITIALIZED;
+}
+
+/*****************************************************************************
+ * IDirectDrawPalette::GetCaps
+ *
+ * Returns the palette description
+ *
+ * Params:
+ *  Caps: Address to store the caps at
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Caps is NULL
+ *  For more details, see IWineD3DPalette::GetCaps
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawPaletteImpl_GetCaps(IDirectDrawPalette *iface,
+                               DWORD *Caps)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    TRACE("(%p)->(%p): Relay\n", This, Caps);
+
+    return IWineD3DPalette_GetCaps(This->wineD3DPalette, Caps);
+}
+
+/*****************************************************************************
+ * IDirectDrawPalette::SetEntries
+ *
+ * Sets the palette entries from a PALETTEENTRY structure. WineD3D takes
+ * care for updating the surface.
+ *
+ * Params:
+ *  Flags: Flags, as usual
+ *  Start: First palette entry to set
+ *  Count: Number of entries to set
+ *  PalEnt: Source entries
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if PalEnt is NULL
+ *  For details, see IWineD3DDevice::SetEntries
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawPaletteImpl_SetEntries(IDirectDrawPalette *iface,
+                                  DWORD Flags,
+                                  DWORD Start,
+                                  DWORD Count,
+                                  PALETTEENTRY *PalEnt)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    TRACE("(%p)->(%lx,%ld,%ld,%p): Relay\n", This, Flags, Start, Count, PalEnt);
+
+    if(!PalEnt)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DPalette_SetEntries(This->wineD3DPalette, Flags, Start, Count, PalEnt);
+}
+
+/*****************************************************************************
+ * IDirectDrawPalette::GetEntries
+ *
+ * Returns the entries stored in this interface.
+ *
+ * Params:
+ *  Flags: Flags :)
+ *  Start: First entry to return
+ *  Count: The number of entries to return
+ *  PalEnt: PALETTEENTRY structure to write the entries to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if PalEnt is NULL
+ *  For details, see IWineD3DDevice::SetEntries
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawPaletteImpl_GetEntries(IDirectDrawPalette *iface,
+                                  DWORD Flags,
+                                  DWORD Start,
+                                  DWORD Count,
+                                  PALETTEENTRY *PalEnt)
+{
+    ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface);
+    TRACE("(%p)->(%lx,%ld,%ld,%p): Relay\n", This, Flags, Start, Count, PalEnt);
+
+    if(!PalEnt)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DPalette_GetEntries(This->wineD3DPalette, Flags, Start, Count, PalEnt);
+}
+
+const IDirectDrawPaletteVtbl IDirectDrawPalette_Vtbl =
+{
+    /*** IUnknown ***/
+    IDirectDrawPaletteImpl_QueryInterface,
+    IDirectDrawPaletteImpl_AddRef,
+    IDirectDrawPaletteImpl_Release,
+    /*** IDirectDrawPalette ***/
+    IDirectDrawPaletteImpl_GetCaps,
+    IDirectDrawPaletteImpl_GetEntries,
+    IDirectDrawPaletteImpl_Initialize,
+    IDirectDrawPaletteImpl_SetEntries
+};
diff --git a/dlls/ddraw/palette_hal.c b/dlls/ddraw/palette_hal.c
deleted file mode 100644
index 070642a..0000000
--- a/dlls/ddraw/palette_hal.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*	DirectDrawPalette 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "winerror.h"
-#include "wine/debug.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static const IDirectDrawPaletteVtbl DDRAW_HAL_Palette_VTable;
-
-/******************************************************************************
- *			IDirectDrawPalette
- */
-HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
-					IDirectDrawImpl* pDD, DWORD dwFlags)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
-    DDHAL_CREATEPALETTEDATA data;
-    HRESULT hr;
-
-    hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags);
-    if (FAILED(hr)) return hr;
-
-    This->final_release = HAL_DirectDrawPalette_final_release;
-    ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_HAL_Palette_VTable);
-
-    /* initialize HAL palette */
-    data.lpDD = dd_gbl;
-    data.lpDDPalette = &This->global;
-    data.lpColorTable = NULL;
-    data.ddRVal = 0;
-    data.CreatePalette = dd_gbl->lpDDCBtmp->HALDD.CreatePalette;
-    if (data.CreatePalette)
-	data.CreatePalette(&data);
-
-    return DD_OK;
-}
-
-HRESULT
-HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
-			     LPDIRECTDRAWPALETTE* ppPalette,
-			     LPUNKNOWN pUnkOuter)
-{
-    IDirectDrawPaletteImpl* This;
-    HRESULT hr;
-
-    if (pUnkOuter != NULL)
-	return CLASS_E_NOAGGREGATION; /* unchecked */
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    hr = HAL_DirectDrawPalette_Construct(This, pDD, dwFlags);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette);
-
-    return hr;
-}
-
-HRESULT WINAPI
-HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				 DWORD dwStart, DWORD dwCount,
-				 LPPALETTEENTRY palent)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl;
-    DDHAL_SETENTRIESDATA data;
-
-    TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
-	  palent);
-
-    data.lpDD = dd_gbl;
-    data.lpDDPalette = &This->global;
-    data.dwBase = dwStart;
-    data.dwNumEntries = dwCount;
-    data.lpEntries = palent;
-    data.ddRVal = 0;
-    data.SetEntries = dd_gbl->lpDDCBtmp->HALDDPalette.SetEntries;
-    if (data.SetEntries)
-	data.SetEntries(&data);
-
-    return Main_DirectDrawPalette_SetEntries(iface, dwFlags, dwStart, dwCount, palent);
-}
-
-void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl;
-    DDHAL_DESTROYPALETTEDATA data;
-
-    /* destroy HAL palette */
-    data.lpDD = dd_gbl;
-    data.lpDDPalette = &This->global;
-    data.ddRVal = 0;
-    data.DestroyPalette = dd_gbl->lpDDCBtmp->HALDDPalette.DestroyPalette;
-    if (data.DestroyPalette)
-	data.DestroyPalette(&data);
-
-    Main_DirectDrawPalette_final_release(This);
-}
-
-static const IDirectDrawPaletteVtbl DDRAW_HAL_Palette_VTable =
-{
-    Main_DirectDrawPalette_QueryInterface,
-    Main_DirectDrawPalette_AddRef,
-    Main_DirectDrawPalette_Release,
-    Main_DirectDrawPalette_GetCaps,
-    Main_DirectDrawPalette_GetEntries,
-    Main_DirectDrawPalette_Initialize,
-    HAL_DirectDrawPalette_SetEntries
-};
diff --git a/dlls/ddraw/palette_main.c b/dlls/ddraw/palette_main.c
deleted file mode 100644
index 50fb0de..0000000
--- a/dlls/ddraw/palette_main.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*		DirectDraw - IDirectPalette base interface
- *
- * Copyright 1997-2000 Marcus Meissner
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "winerror.h"
-#include "wine/debug.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-#define SIZE_BITS (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT)
-
-/* For unsigned x. 0 is not a power of 2. */
-#define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
-
-static const IDirectDrawPaletteVtbl DDRAW_Main_Palette_VTable;
-
-/******************************************************************************
- *			IDirectDrawPalette
- */
-HRESULT Main_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
-					 IDirectDrawImpl* pDD, DWORD dwFlags)
-{
-    if (!IS_POW_2(dwFlags & SIZE_BITS)) return DDERR_INVALIDPARAMS;
-
-    if (dwFlags & DDPCAPS_8BITENTRIES)
-	WARN("creating palette with 8 bit entries\n");
-
-    This->palNumEntries = Main_DirectDrawPalette_Size(dwFlags);
-    This->ref = 1;
-
-    This->local.lpGbl = &This->global;
-    This->local.lpDD_lcl = &pDD->local;
-    This->global.lpDD_lcl = &pDD->local;
-    This->global.dwProcessId = GetCurrentProcessId();
-    This->global.dwFlags = dwFlags;
-
-    This->final_release = Main_DirectDrawPalette_final_release;
-    ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_Main_Palette_VTable);
-
-    /* we could defer hpal creation until we need it,
-     * but does anyone have a case where it would be useful? */
-    This->hpal = CreatePalette((const LOGPALETTE*)&(This->palVersion));
-
-    Main_DirectDraw_AddPalette(pDD, This);
-
-    return DD_OK;
-}
-
-HRESULT
-Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
-			      LPDIRECTDRAWPALETTE* ppPalette,
-			      LPUNKNOWN pUnkOuter)
-{
-    IDirectDrawPaletteImpl* This;
-    HRESULT hr;
-
-    if (pUnkOuter != NULL)
-	return CLASS_E_NOAGGREGATION; /* unchecked */
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette);
-
-    return hr;
-}
-
-DWORD Main_DirectDrawPalette_Size(DWORD dwFlags)
-{
-    switch (dwFlags & SIZE_BITS)
-    {
-    case DDPCAPS_1BIT: return 2;
-    case DDPCAPS_2BIT: return 4;
-    case DDPCAPS_4BIT: return 16;
-    case DDPCAPS_8BIT: return 256;
-    default: assert(0); return 256;
-    }
-}
-
-HRESULT WINAPI
-Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				  DWORD dwStart, DWORD dwCount,
-				  LPPALETTEENTRY palent)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-
-    TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
-	  palent);
-
-    if (dwFlags != 0) return DDERR_INVALIDPARAMS; /* unchecked */
-    if (dwStart + dwCount > Main_DirectDrawPalette_Size(This->global.dwFlags))
-	return DDERR_INVALIDPARAMS;
-
-    if (This->global.dwFlags & DDPCAPS_8BITENTRIES)
-    {
-	unsigned int i;
-	LPBYTE entry = (LPBYTE)palent;
-
-	for (i=dwStart; i < dwCount+dwStart; i++)
-	    *entry++ = This->palents[i].peRed;
-    }
-    else
-	memcpy(palent, This->palents+dwStart, dwCount * sizeof(PALETTEENTRY));
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
-				  DWORD dwStart, DWORD dwCount,
-				  LPPALETTEENTRY palent)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-
-    TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
-	  palent);
-
-    if (This->global.dwFlags & DDPCAPS_8BITENTRIES)
-    {
-	unsigned int i;
-	const BYTE* entry = (const BYTE*)palent;
-
-	for (i=dwStart; i < dwCount+dwStart; i++)
-	    This->palents[i].peRed = *entry++;
-    }
-    else {
-	memcpy(This->palents+dwStart, palent, dwCount * sizeof(PALETTEENTRY));
-
-	if (This->hpal)
-	    SetPaletteEntries(This->hpal, dwStart, dwCount, This->palents+dwStart);
-
-	if (This->global.dwFlags & DDPCAPS_PRIMARYSURFACE) {
-	    /* update physical palette */
-	    LPDIRECTDRAWSURFACE7 psurf = NULL;
-	    IDirectDraw7_GetGDISurface(ICOM_INTERFACE(This->ddraw_owner,IDirectDraw7), &psurf);
-	    if (psurf) {
-		IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-							   IDirectDrawSurface7, psurf);
-		surf->update_palette(surf, This, dwStart, dwCount, palent);
-		IDirectDrawSurface7_Release(psurf);
-	    }
-	    else ERR("can't find GDI surface!!\n");
-	}
-    }
-
-#if 0
-    /* Now, if we are in 'depth conversion mode', update the screen palette */
-    /* FIXME: we need to update the image or we won't get palette fading. */
-    if (This->ddraw->d->palette_convert != NULL)
-	This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
-#endif
-
-    return DD_OK;
-}
-
-void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This)
-{
-    Main_DirectDraw_RemovePalette(This->ddraw_owner, This);
-
-    if (This->hpal) DeleteObject(This->hpal);
-}
-
-static void Main_DirectDrawPalette_Destroy(IDirectDrawPaletteImpl* This)
-{
-    This->final_release(This);
-
-    if (This->private != This+1)
-	HeapFree(GetProcessHeap(), 0, This->private);
-
-    HeapFree(GetProcessHeap(),0,This);
-}
-
-void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This)
-{
-    WARN("deleting palette %p with refcnt %lu\n", This, This->ref);
-    Main_DirectDrawPalette_Destroy(This);
-}
-
-ULONG WINAPI
-Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
-
-    if (!ref)
-    {
-	Main_DirectDrawPalette_Destroy(This);
-	return 0;
-    }
-
-    return ref;
-}
-
-ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface) {
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
-
-    return ref;
-}
-
-HRESULT WINAPI
-Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface,
-				  LPDIRECTDRAW ddraw, DWORD dwFlags,
-				  LPPALETTEENTRY palent)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-    TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, dwFlags, palent);
-    return DDERR_ALREADYINITIALIZED;
-}
-
-HRESULT WINAPI
-Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps)
-{
-   IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-   TRACE("(%p)->(%p)\n",This,lpdwCaps);
-
-   *lpdwCaps = This->global.dwFlags;
-
-   return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface,
-				      REFIID refiid, LPVOID *obj)
-{
-    IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface;
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-
-    if (IsEqualGUID(refiid, &IID_IUnknown)
-	|| IsEqualGUID(refiid, &IID_IDirectDrawPalette))
-    {
-	*obj = iface;
-	IDirectDrawPalette_AddRef(iface);
-	return S_OK;
-    }
-    else
-    {
-	return E_NOINTERFACE;
-    }
-}
-
-static const IDirectDrawPaletteVtbl DDRAW_Main_Palette_VTable =
-{
-    Main_DirectDrawPalette_QueryInterface,
-    Main_DirectDrawPalette_AddRef,
-    Main_DirectDrawPalette_Release,
-    Main_DirectDrawPalette_GetCaps,
-    Main_DirectDrawPalette_GetEntries,
-    Main_DirectDrawPalette_Initialize,
-    Main_DirectDrawPalette_SetEntries
-};
diff --git a/dlls/ddraw/parent.c b/dlls/ddraw/parent.c
new file mode 100644
index 0000000..3b7b3d8
--- /dev/null
+++ b/dlls/ddraw/parent.c
@@ -0,0 +1,152 @@
+/*
+ * IParent implementation
+ *
+ * Copyright (c) 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * A universal parent interface for everything in WineD3D that doesn't have
+ * a DDraw counterpart
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+const GUID IID_IParent = {0xc20e4c88, 0x74e7, 0x4940, {0xba, 0x9f, 0x2e, 0x32, 0x3f, 0x9d, 0xc9, 0x81}};
+
+/*****************************************************************************
+ * IUnknown methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IParent::Queryinterface
+ *
+ * It can't query any interfaces, and it's not used for anything. So
+ * it just returns E_NOINTERFACE
+ *
+ * Params:
+ *  riid: guid of queried interface
+ *  obj: returns a pointer to the interface
+ *
+ * Return values
+ *  This implementation always returns E_NOINTERFACE and NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IParentImpl_QueryInterface(IParent *iface,
+                           REFIID riid,
+                           void **obj)
+{
+    ICOM_THIS_FROM(IParentImpl, IParent, iface);
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj);
+
+    *obj = NULL;
+    if ( IsEqualGUID( &IID_IUnknown, riid ) ||
+         IsEqualGUID( &IID_IParent, riid ) )
+    {
+        *obj = ICOM_INTERFACE(This, IParent);
+        IParent_AddRef(ICOM_INTERFACE(This, IParent));
+        return DD_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+/*****************************************************************************
+ * IParent::AddRef
+ *
+ * Increases the refcount
+ *
+ * Params:
+ *
+ * Return values
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IParentImpl_AddRef(IParent *iface)
+{
+    ICOM_THIS_FROM(IParentImpl, IParent, iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+
+    return ref;
+}
+
+
+/*****************************************************************************
+ * IParent::Release
+ *
+ * Releases the refcount, and destroys the object if the refcount falls to 0
+ * Also releases the child object, if destroyed. That's almost the whole sense
+ * of this interface.
+ *
+ * Params:
+ *
+ * Return values
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI 
+IParentImpl_Release(IParent *iface)
+{
+    ICOM_THIS_FROM(IParentImpl, IParent, iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+
+    if (ref == 0)
+    {
+        TRACE("(%p) Releasing child at %p\n", This, This->child);
+        if(This->child)
+            IUnknown_Release(This->child);
+        HeapFree(GetProcessHeap(), 0, This);
+        TRACE("Released\n");
+    }
+    return ref;
+}
+
+/*****************************************************************************
+ * The VTable
+ *****************************************************************************/
+const IParentVtbl IParent_Vtbl =
+{
+     IParentImpl_QueryInterface,
+     IParentImpl_AddRef,
+     IParentImpl_Release,
+};
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
new file mode 100644
index 0000000..113ec5f
--- /dev/null
+++ b/dlls/ddraw/surface.c
@@ -0,0 +1,2091 @@
+/* DirectDraw Surface Implementation
+ *
+ * Copyright (c) 1997-2000 Marcus Meissner
+ * Copyright (c) 1998-2000 Lionel Ulmer
+ * Copyright (c) 2000-2001 TransGaming Technologies Inc.
+ * Copyright (c) 2006 Stefan Dösinger
+ *
+ * This file contains the (internal) driver registration functions,
+ * driver enumeration APIs and DirectDraw creation functions.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/*****************************************************************************
+ * IUnkown parts follow
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDrawSurface7::QueryInterface
+ *
+ * A normal QueryInterface implementation. For QueryInterface rules
+ * see ddraw.c, IDirectDraw7::QueryInterface. This method
+ * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
+ * in all versions, the IDirectDrawGammaControl interface and it can
+ * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
+ *
+ * Params:
+ *  riid: The interface id queried for
+ *  obj: Address to write the pointer to
+ *
+ * Returns:
+ *  S_OK on success
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface,
+                                      REFIID riid,
+                                      void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
+    *obj = NULL;
+
+    if(!riid)
+        return DDERR_INVALIDPARAMS;
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj);
+    if (IsEqualGUID(riid, &IID_IUnknown)
+     || IsEqualGUID(riid, &IID_IDirectDrawSurface7)
+     || IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
+    {
+        IUnknown_AddRef(iface);
+        *obj = ICOM_INTERFACE(This, IDirectDrawSurface7);
+        TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
+        return S_OK;
+    }
+    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3)
+          || IsEqualGUID(riid, &IID_IDirectDrawSurface2)
+          || IsEqualGUID(riid, &IID_IDirectDrawSurface) )
+    {
+        IUnknown_AddRef(iface);
+        *obj = ICOM_INTERFACE(This, IDirectDrawSurface3);
+        TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
+        return S_OK;
+    }
+    else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) )
+    {
+        IUnknown_AddRef(iface);
+        *obj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
+        TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj);
+        return S_OK;
+    }
+    else if( IsEqualGUID(riid, &IID_D3DDEVICE_WineD3D) ||
+             IsEqualGUID(riid, &IID_IDirect3DHALDevice) )
+    {
+        IDirect3DDevice7 *d3d;
+
+        /* Call into IDirect3D7 for creation */
+        IDirect3D7_CreateDevice(ICOM_INTERFACE(This->ddraw, IDirect3D7),
+                                riid,
+                                ICOM_INTERFACE(This, IDirectDrawSurface7),
+                                &d3d);
+
+        *obj = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice, d3d);
+        TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
+
+        return S_OK;
+    }
+    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
+             IsEqualGUID( &IID_IDirect3DTexture2, riid ))
+    {
+        if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
+        {
+            *obj = ICOM_INTERFACE(This, IDirect3DTexture);
+            TRACE(" returning Direct3DTexture interface at %p.\n", *obj);
+        }
+        else
+        {
+            *obj = ICOM_INTERFACE(This, IDirect3DTexture2);
+            TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj);
+        }
+        IUnknown_AddRef( (IUnknown *) *obj);
+        return S_OK;
+    }
+
+    ERR("No interface\n");
+    return E_NOINTERFACE;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::AddRef
+ *
+ * A normal addref implementation
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
+    return refCount;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurfaceImpl_Destroy
+ *
+ * A helper function for IDirectDrawSurface7::Release
+ *
+ * Frees the surface, regardless of it's refcount.
+ *  See IDirectDrawSurface7::Release for more information
+ *
+ * Params:
+ *  This: Surface to free
+ *
+ *****************************************************************************/
+static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This)
+{
+    TRACE("(%p)\n", This);
+
+    /* Check the refcount and give a warning */
+    if(This->ref > 1)
+    {
+        /* This can happen when a complex surface is destroyed,
+         * because the 2nd surface was addref()ed when the app
+         * called GetAttachedSurface
+         */
+        WARN("(%p): Destroying surface with refount %ld\n", This, This->ref);
+    }
+
+    /* Check for attached surfaces and detach them */
+    if(This->first_attached != This)
+    {
+        /* Well, this shouldn't happen: The surface beeing attached is addref()ed
+          * in AddAttachedSurface, so it shouldn't be released until DeleteAttachedSurface
+          * is called, because the refcount is hold. It looks like the app released()
+          * it often enought to force this
+          */
+        IDirectDrawSurface7 *root = ICOM_INTERFACE(This->first_attached, IDirectDrawSurface7);
+        IDirectDrawSurface7 *detach = ICOM_INTERFACE(This, IDirectDrawSurface7);
+
+        FIXME("(%p) Freeing a surface that is attached to surface %p\n", This, This->first_attached);
+
+        /* The refcount will drop to -1 here */
+        if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK)
+        {
+            ERR("(%p) DeleteAttachedSurface failed!\n", This);
+        }
+    }
+
+    while(This->next_attached != NULL)
+    {
+        IDirectDrawSurface7 *root = ICOM_INTERFACE(This, IDirectDrawSurface7);
+        IDirectDrawSurface7 *detach = ICOM_INTERFACE(This->next_attached, IDirectDrawSurface7);
+
+        if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK)
+        {
+            ERR("(%p) DeleteAttachedSurface failed!\n", This);
+            assert(0);
+        }
+    }
+
+    /* Now destroy the surface. Wait: It could have been released if we are a texture */
+    if(This->WineD3DSurface)
+        IWineD3DSurface_Release(This->WineD3DSurface);
+
+    /* Reduce the ddraw surface count */
+    InterlockedDecrement(&This->ddraw->surfaces);
+    if(This->prev)
+        This->prev->next = This->next;
+    else
+    {
+        assert(This->ddraw->surface_list == This);
+        This->ddraw->surface_list = This->next;
+    }
+    if(This->next)
+        This->next->prev = This->prev;
+
+    HeapFree(GetProcessHeap(), 0, This);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Release
+ *
+ * Reduces the surface's refcount by 1. If the refcount falls to 0, the
+ * surface is destroyed.
+ *
+ * Destroying the surface is a bit tricky. For the connection between
+ * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
+ * It has a nice graph explaining the connection.
+ *
+ * What happens here is basically this:
+ * When a surface is destroyed, it's WineD3DSurface is released,
+ * and the refcount of the DirectDraw interface is reduced by 1. If it has
+ * complex surfaces attached to it, then these surfaces are destroyed too,
+ * regardless of their refcount. If any surface beeing destroyed has another
+ * surface attached to it(with a "soft" attachment, not complex), then
+ * this surface is detached with DeleteAttachedSurface.
+ *
+ * When the surface is a texture, the WineD3DTexture is released.
+ * If the surface is the Direct3D render target, then the D3D
+ * capatiblities of the WineD3DDevice are uninitialized, which causes the
+ * swapchain to be released.
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    ULONG ref;
+    TRACE("(%p) : Releasing from %ld\n", This, This->ref);
+    ref = InterlockedDecrement(&This->ref);
+
+    if (ref == 0)
+    {
+
+        IDirectDrawSurfaceImpl *surf;
+        IDirectDrawImpl *ddraw;
+
+        /* Destroy all complex attached surfaces
+         * Therefore, start with the first surface,
+         * except for textures. Not entirely sure what has
+         * to happen exactly in this case
+         */
+        if( (This->first_complex != This) && !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE))
+        {
+            FIXME("(%p) Destroying a surface which is a attached to a complex root %p\n", This, This->first_complex);
+        }
+        ddraw = This->ddraw;
+
+        /* If it's a texture, destroy the WineD3DTexture.
+         * WineD3D will destroy the IParent interfaces
+         * of the sublevels, which destroys the WineD3DSurfaces.
+         * Set the surfaces to NULL to avoid destroying them again later
+         */
+        if(This->wineD3DTexture)
+        {
+            IWineD3DTexture_Release(This->wineD3DTexture);
+        }
+        /* If it's the RenderTarget, destroy the d3ddevice */
+        else if( (ddraw->d3d_initialized) && (This == ddraw->d3d_target))
+        {
+            TRACE("(%p) Destroying the render target, uninitializing D3D\n", This);
+
+            /* Unset any index buffer, just to be sure */
+            IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, 0);
+
+            if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice) != D3D_OK)
+            {
+                /* Not good */
+                ERR("(%p) Failed to uninit 3D\n", This);
+            }
+            else
+            {
+                /* Free the d3d window if one was created */
+                if(ddraw->d3d_window != 0)
+                {
+                    TRACE(" (%p) Destroying the hidden render window %p\n", This, ddraw->d3d_window);
+                    DestroyWindow(ddraw->d3d_window);
+                    ddraw->d3d_window = 0;
+                }
+                /* Unset the pointers */
+            }
+
+            ddraw->d3d_initialized = FALSE;
+            ddraw->d3d_target = NULL;
+
+            /* Write a trace because D3D unloading was the reason for many
+             * crashes during development.
+             */
+            TRACE("(%p) D3D unloaded\n", This);
+        }
+        else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
+                                                     DDSCAPS_3DDEVICE       |
+                                                     DDSCAPS_TEXTURE        ) )
+        {
+            /* It's a render target, but no swapchain was created.
+             * The IParent interfaces have to be released manually.
+             * The same applies for textures without an
+             * IWineD3DTexture object attached
+             */
+            surf = This;
+            while(surf)
+            {
+                IParent *Parent;
+
+                IWineD3DSurface_GetParent(surf->WineD3DSurface,
+                                          (IUnknown **) &Parent);
+                IParent_Release(Parent);  /* For the getParent */
+                IParent_Release(Parent);  /* To release it */
+                surf = surf->next_complex;
+            }
+        }
+
+        /* Loop through all complex attached surfaces,
+         * and destroy them
+         */
+        while( (surf = This->next_complex) )
+        {
+            This->next_complex = surf->next_complex;  /* Unchain it from the complex listing */
+            IDirectDrawSurfaceImpl_Destroy(surf);     /* Destroy it */
+        }
+
+        /* Destroy the surface.
+         */
+        IDirectDrawSurfaceImpl_Destroy(This);
+
+        /* Reduce the ddraw refcount */
+        IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7));
+    }
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetAttachedSurface
+ *
+ * Returns an attached surface with the requested caps. Surface attchment
+ * and complex surfaces are not clearly described by the MSDN or sdk,
+ * so this method is tricky and likely to contain problems.
+ * This implementation searches the complex chain first, then the
+ * attachment chain, and then it checks if the caps match to itself.
+ *
+ * The chains are searched from This down to the last surface in the chain,
+ * not from the first element in the chain. The first surface found is
+ * returned. The MSDN says that this method fails if more than one surface
+ * matches the caps, but apparently this is incorrect.
+ *
+ * The found surface is AddRefed before it's returned.
+ *
+ * Params:
+ *  Caps: Pointer to a DDCAPS2 structure describing the caps asked for
+ *  Surface: Address to store the found surface
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Caps or Surface is NULL
+ *  DDERR_NOTFOUND if no surface was found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface,
+                                          DDSCAPS2 *Caps,
+                                          IDirectDrawSurface7 **Surface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *surf;
+    DDSCAPS2 our_caps;
+
+    TRACE("(%p)->(%p,%p)\n", This, Caps, Surface);
+
+    our_caps = *Caps;
+
+    if(This->version < 7)
+    {
+        /* Earlier dx apps put garbage into these members, clear them */
+        our_caps.dwCaps2 = 0;
+        our_caps.dwCaps3 = 0;
+        our_caps.dwCaps4 = 0;
+    }
+
+    TRACE("(%p): Looking for caps: %lx,%lx,%lx,%lx\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.dwCaps4); /* FIXME: Better debugging */
+
+    /* First, look at the complex chain */
+    surf = This;
+
+    while( (surf = surf->next_complex) )
+    {
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf,
+                   surf->surface_desc.ddsCaps.dwCaps,
+                   surf->surface_desc.ddsCaps.dwCaps2,
+                   surf->surface_desc.ddsCaps.dwCaps3,
+                   surf->surface_desc.ddsCaps.dwCaps4);
+        }
+
+        if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
+            ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
+
+            /* MSDN: "This method fails if more than one surface is attached
+             * that matches the capabilities requested."
+             *
+             * The mipmap demo of the DirectX7 sdk shows what to do here:
+             * aparently apps expect the first found surface to be returned.
+             */
+
+            TRACE("(%p): Returning surface %p\n", This, surf);
+            TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level);
+            *Surface = ICOM_INTERFACE(surf, IDirectDrawSurface7);
+            IDirectDrawSurface7_AddRef(*Surface);
+            return DD_OK;
+        }
+    }
+
+    /* Next, look at the attachment chain */
+    surf = This;
+
+    while( (surf = surf->next_attached) )
+    {
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf,
+                   surf->surface_desc.ddsCaps.dwCaps,
+                   surf->surface_desc.ddsCaps.dwCaps2,
+                   surf->surface_desc.ddsCaps.dwCaps3,
+                   surf->surface_desc.ddsCaps.dwCaps4);
+        }
+
+        if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
+            ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
+
+            /* MSDN: "This method fails if more than one surface is attached
+             * that matches the capabilities requested."
+             *
+             * The mipmap demo of the DirectX7 sdk shows what to do here:
+             * aparently apps expect the first found surface to be returned.
+             */
+
+            TRACE("(%p): Returning surface %p\n", This, surf);
+            *Surface = ICOM_INTERFACE(surf, IDirectDrawSurface7);
+            IDirectDrawSurface7_AddRef(*Surface);
+            return DD_OK;
+        }
+    }
+
+    /* Is this valid? */
+#if 0
+    if (((This->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
+        ((This->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2) && 
+        This == This->first_complex)
+    {
+
+        TRACE("(%p): Returning surface %p\n", This, This);
+        *Surface = ICOM_INTERFACE(This, IDirectDrawSurface7);
+        IDirectDrawSurface7_AddRef(*Surface);
+        return DD_OK;
+    }
+#endif
+
+    /* What to do here? Continue with the surface root?? */
+
+    TRACE("(%p) Didn't find a valid surface\n", This);
+    return DDERR_NOTFOUND;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Lock
+ *
+ * Locks the surface and returnes a pointer to the surface's memory
+ *
+ * Params:
+ *  Rect: Rectangle to lock. If NULL, the whole surface is locked
+ *  DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
+ *  Flags: Locking flags, e.g Read only or write only
+ *  h: An event handle that's not used and must be NULL
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if DDSD is NULL
+ *  For more details, see IWineD3DSurface::LockRect
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface,
+                            RECT *Rect,
+                            DDSURFACEDESC2 *DDSD,
+                            DWORD Flags,
+                            HANDLE h)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    WINED3DLOCKED_RECT LockedRect;
+    HRESULT hr;
+    TRACE("(%p)->(%p,%p,%lx,%p)\n", This, Rect, DDSD, Flags, h);
+
+    if(!DDSD)
+        return DDERR_INVALIDPARAMS;
+
+    /* Should I check for the handle to be NULL?
+     *
+     * The DDLOCK flags and the D3DLOCK flags are equal
+     * for the supported values. The others are ignored by WineD3D
+     */
+
+    /* Hmm. Anarchy online passes an uninitialized surface descriptor,
+     * that means it doesn't have dwSize set. Init it to some sane
+     * value
+     */
+    if(DDSD->dwSize <= sizeof(DDSURFACEDESC))
+    {
+        DDSD->dwSize = sizeof(DDSURFACEDESC);
+    }
+    else
+    {
+        DDSD->dwSize = sizeof(DDSURFACEDESC2);
+    }
+
+    DD_STRUCT_COPY_BYSIZE(DDSD,&(This->surface_desc));
+    hr = IWineD3DSurface_LockRect(This->WineD3DSurface,
+                                  &LockedRect,
+                                  Rect,
+                                  Flags);
+    if(hr != D3D_OK) return hr;
+
+    /* Override the memory area and the pitch */
+    DDSD->dwFlags |= DDSD_LPSURFACE;
+    DDSD->lpSurface = LockedRect.pBits;
+    DDSD->dwFlags |= DDSD_PITCH;
+    DDSD->u1.lPitch = LockedRect.Pitch;
+
+    TRACE("locked surface returning description :\n");
+    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Unlock
+ *
+ * Unlocks an locked surface
+ *
+ * Params:
+ *  Rect: Not used by this implementation
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For more details, see IWineD3DSurface::UnlockRect
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Unlock(IDirectDrawSurface7 *iface,
+                              RECT *pRect)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n", This, pRect);
+
+    return IWineD3DSurface_UnlockRect(This->WineD3DSurface);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Flip
+ *
+ * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
+ * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
+ * the flip target is passed to WineD3D, even if the app didn't specify one
+ *
+ * Params:
+ *  DestOverride: Specifies the surface that will become the new front
+ *                buffer. If NULL, the current back buffer is used
+ *  Flags: some DirectDraw flags, see include/ddraw.h
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_NOTFLIPPABLE if no flip target could be found
+ *  DDERR_INVALIDOBJECT if the surface isn't a front buffer
+ *  For more details, see IWineD3DSurface::Flip
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7 *iface,
+                            IDirectDrawSurface7 *DestOverride,
+                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Override = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestOverride);
+    IDirectDrawSurface7 *Override7;
+    HRESULT hr;
+    TRACE("(%p)->(%p,%lx)\n", This, DestOverride, Flags);
+
+    /* Flip has to be called from a front buffer
+     * What about overlay surfaces, AFAIK they can flip too?
+     */
+    if( !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
+        return DDERR_INVALIDOBJECT; /* Unckecked */
+
+    /* WineD3D doesn't keep track of attached surface, so find the target */
+    if(!Override)
+    {
+        DDSCAPS2 Caps;
+
+        memset(&Caps, 0, sizeof(Caps));
+        Caps.dwCaps |= DDSCAPS_BACKBUFFER;
+        hr = IDirectDrawSurface7_GetAttachedSurface(iface, &Caps, &Override7);
+        if(hr != DD_OK)
+        {
+            ERR("Can't find a flip target\n");
+            return DDERR_NOTFLIPPABLE; /* Unchecked */
+        }
+        Override = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Override7);
+
+        /* For the GetAttachedSurface */
+        IDirectDrawSurface7_Release(Override7);
+    }
+
+    return  IWineD3DSurface_Flip(This->WineD3DSurface,
+                                 Override->WineD3DSurface,
+                                 Flags);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Blt
+ *
+ * Performs a blit on the surface
+ *
+ * Params:
+ *  DestRect: Destination rectangle, can be NULL
+ *  SrcSurface: Source surface, can be NULL
+ *  SrcRect: Source rectange, can be NULL
+ *  Flags: Blt flags
+ *  DDBltFx: Some extended blt parameters, connected to the flags
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  See IWineD3DSurface::Blt for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
+                           RECT *DestRect,
+                           IDirectDrawSurface7 *SrcSurface,
+                           RECT *SrcRect,
+                           DWORD Flags,
+                           DDBLTFX *DDBltFx)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcSurface);
+    TRACE("(%p)->(%p,%p,%p,%lx,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
+
+    return IWineD3DSurface_Blt(This->WineD3DSurface,
+                               DestRect,
+                               Src ? Src->WineD3DSurface : NULL,
+                               SrcRect,
+                               Flags,
+                               DDBltFx);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::AddAttachedSurface
+ *
+ * Attaches an surface to another surface. Surface attachments are
+ * incorrectly described in the SDK and the MSDN, and this method
+ * is prone to bugs. The surface that is attached is AddRefed.
+ *
+ * The attachment list consists of a first surface(first_attached) and
+ * for each surface a pointer to the next attached surface (next_attached).
+ * For the first surface, and a surface that has no attachments
+ * first_attached points to the surface itself. A surface that has
+ * no successors in the chain has next_attached set to NULL.
+ *
+ * Newly attached surfaces are attached right after the root surface. The
+ * complex chains are handled seperately in a simmilar chain, with
+ * first_complex and next_complex. If a surface is attached to a complex
+ * surface compound, it's attached to the surface that the app requested,
+ * not the complex root. See GetAttachedSurface for a description
+ * how surfaces are found.
+ *
+ * This is how the current implementation works, and it was coded by looking
+ * at the needs of the applications.
+ *
+ * So far only Z-Buffer attachments are tested, but there's no code yet
+ * to activate them. Mipmaps could be tricky to activate in WineD3D.
+ * Back buffers should work in 2D mode, but they are not tested.
+ * Rendering to the primary surface and switching between that and
+ * double buffering is not yet implemented in WineD3D, so for 3D it might
+ * have unexpected results.
+ *
+ * Params:
+ *  Attach: Surface to attach to iface
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface,
+                                          IDirectDrawSurface7 *Attach)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach);
+    TRACE("(%p)->(%p)\n", This, Surf);
+
+    /* Should I make sure to add it to the first complex surface? */
+
+    if(Surf == This)
+        return DDERR_CANNOTATTACHSURFACE; /* unchecked */
+
+    /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
+     * But apparently backbuffers and mipmaps can be attached too. */
+
+    /* Set MIPMAPSUBLEVEL if this seems to be one */
+    if (This->surface_desc.ddsCaps.dwCaps &
+        Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+    {
+        Surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
+        /* FIXME: we should probably also add to dwMipMapCount of this
+          * and all parent surfaces (update create_texture if you do) */
+    }
+
+    /* Check if the surface is already attached somewhere */
+    if( (Surf->next_attached != NULL) ||
+        (Surf->first_attached != Surf) )
+    {
+         ERR("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This, Surf, Surf->next_attached, Surf->first_attached);
+        return DDERR_CANNOTATTACHSURFACE;
+    }
+
+    /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
+    Surf->next_attached = This->next_attached;
+    Surf->first_attached = This->first_attached;
+    This->next_attached = Surf;
+
+    /* MSDN: 
+     * "This method increments the reference count of the surface being attached."
+     */
+    IDirectDrawSurface7_AddRef(Attach);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::DeleteAttachedSurface
+ *
+ * Removes a surface from the attachment chain. The surface's refcount
+ * is decreased by one after it has been removed
+ *
+ * Params:
+ *  Flags: Some flags, not used by this implementation
+ *  Attach: Surface to detach
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_SURFACENOTATTACHED if the surface isn't attached to
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7 *iface,
+                                             DWORD Flags,
+                                             IDirectDrawSurface7 *Attach)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach);
+    IDirectDrawSurfaceImpl *Prev = This;
+    TRACE("(%p)->(%08lx,%p)\n", This, Flags, Surf);
+
+    if (!Surf || (Surf->first_attached != This) || (Surf == This) )
+        return DDERR_SURFACENOTATTACHED; /* unchecked */
+
+    /* Remove MIPMAPSUBLEVEL if this seemed to be one */
+    if (This->surface_desc.ddsCaps.dwCaps &
+        Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+    {
+        Surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
+        /* FIXME: we should probably also subtract from dwMipMapCount of this
+         * and all parent surfaces */
+    }
+
+    /* Find the Precessor of the detached surface */
+    while(Prev)
+    {
+        if(Prev->next_attached == Surf) break;
+        Prev = Prev->next_attached;
+    }
+
+    /* There must be a surface, otherwise there's a bug */
+    assert(Prev != NULL);
+
+    /* Unchain the surface */
+    Prev->next_attached = Surf->next_attached;
+    Surf->next_attached = NULL;
+    Surf->first_attached = Surf;
+
+    IDirectDrawSurface7_Release(Attach);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::AddOverlayDirtyRect
+ *
+ * "This method is not currently implemented"
+ *
+ * Params:
+ *  Rect: ?
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7 *iface,
+                                           LPRECT Rect)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n",This,Rect);
+
+    /* MSDN says it's not implemented. I could forward it to WineD3D, 
+     * then we'd implement it, but I don't think that's a good idea
+     * (Stefan Dösinger)
+     */
+#if 0
+    return IWineD3DSurface_AddOverlayDirtyRect(This->WineD3DSurface, pRect);
+#endif
+    return DDERR_UNSUPPORTED; /* unchecked */
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetDC
+ *
+ * Returns a GDI device context for the surface
+ *
+ * Params:
+ *  hdc: Address of a HDC variable to store the dc to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if hdc is NULL
+ *  For details, see IWineD3DSurface::GetDC
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetDC(IDirectDrawSurface7 *iface,
+                             HDC *hdc)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p): Relay\n", This, hdc);
+
+    if(!hdc)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DSurface_GetDC(This->WineD3DSurface,
+                                 hdc);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::ReleaseDC
+ *
+ * Releases the DC that was constructed with GetDC
+ *
+ * Params:
+ *  hdc: HDC to release
+ *
+ * Returns:
+ *  DD_OK on success
+ *  For more details, see IWineD3DSurface::ReleaseDC
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_ReleaseDC(IDirectDrawSurface7 *iface,
+                                 HDC hdc)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p): Relay\n", This, hdc);
+
+    return IWineD3DSurface_ReleaseDC(This->WineD3DSurface, hdc);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetCaps
+ *
+ * Returns the surface's caps
+ *
+ * Params:
+ *  Caps: Address to write the caps to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Caps is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetCaps(IDirectDrawSurface7 *iface,
+                               DDSCAPS2 *Caps)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n",This,Caps);
+
+    if(!Caps)
+        return DDERR_INVALIDPARAMS;
+
+    *Caps = This->surface_desc.ddsCaps;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetPriority
+ *
+ * Sets a texture priority for managed textures.
+ *
+ * Params:
+ *  Priority: The new priority
+ *
+ * Returns:
+ *  DD_OK on success
+ *  For more details, see IWineD3DSurface::SetPriority
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetPriority(IDirectDrawSurface7 *iface, DWORD Priority)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%ld): Relay!\n",This,Priority);
+
+    return IWineD3DSurface_SetPriority(This->WineD3DSurface, Priority);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetPriority
+ *
+ * Returns the surface's priority
+ *
+ * Params:
+ *  Priority: Address of a variable to write the priority to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Priority == NULL
+ *  For more details, see IWineD3DSurface::GetPriority
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetPriority(IDirectDrawSurface7 *iface,
+                                   DWORD *Priority)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p): Relay\n",This,Priority);
+
+    if(!Priority)
+        return DDERR_INVALIDPARAMS;
+
+    *Priority = IWineD3DSurface_GetPriority(This->WineD3DSurface);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetPrivateData
+ *
+ * Stores some data in the surface that is intended for the application's
+ * use.
+ *
+ * Params:
+ *  tag: GUID that identifies the data
+ *  Data: Pointer to the private data
+ *  Size: Size of the private data
+ *  Flags: Some flags
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For more details, see IWineD3DSurface::SetPrivateData
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetPrivateData(IDirectDrawSurface7 *iface,
+                                      REFGUID tag,
+                                      void *Data,
+                                      DWORD Size,
+                                      DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%s,%p,%ld,%lx): Relay\n", This, debugstr_guid(tag), Data, Size, Flags);
+
+    return IWineD3DSurface_SetPrivateData(This->WineD3DSurface,
+                                          tag,
+                                          Data,
+                                          Size,
+                                          Flags);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetPrivateData
+ *
+ * Returnes the private data set with IDirectDrawSurface7::SetPrivateData
+ *
+ * Params:
+ *  tag: GUID of the data to return
+ *  Data: Address where to write the data to
+ *  Size: Size of the buffer at Data
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *  For more details, see IWineD3DSurface::GetPrivateData
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetPrivateData(IDirectDrawSurface7 *iface,
+                                      REFGUID tag,
+                                      void *Data,
+                                      DWORD *Size)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%s,%p,%p): Relay\n", This, debugstr_guid(tag), Data, Size);
+
+    if(!Data)
+        return DDERR_INVALIDPARAMS;
+
+    return IWineD3DSurface_GetPrivateData(This->WineD3DSurface,
+                                          tag,
+                                          Data,
+                                          Size);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::FreePrivateData
+ *
+ * Frees private stored in the surface
+ *
+ * Params:
+ *  tag: Tag of the data to free
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  For more details, see IWineD3DSurface::FreePrivateData
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_FreePrivateData(IDirectDrawSurface7 *iface,
+                                       REFGUID tag)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%s): Relay\n", This, debugstr_guid(tag));
+
+    return IWineD3DSurface_FreePrivateData(This->WineD3DSurface, tag);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::PageLock
+ *
+ * Prevents a sysmem surface from being paged out
+ *
+ * Params:
+ *  Flags: Not used, must be 0(unchecked)
+ *
+ * Returns:
+ *  DD_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_PageLock(IDirectDrawSurface7 *iface,
+                                DWORD Flags)
+{
+    TRACE("(%p)->(%lx)\n", iface, Flags);
+
+    /* This is Windows memory management related - we don't need this */
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::PageUnlock
+ *
+ * Allows a sysmem surface to be paged out
+ *
+ * Params:
+ *  Flags: Not used, must be 0(unckeched)
+ *
+ * Returns:
+ *  DD_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_PageUnlock(IDirectDrawSurface7 *iface,
+                                  DWORD Flags)
+{
+    TRACE("(%p)->(%lx)\n", iface, Flags);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::BltBatch
+ *
+ * An unimplemented function
+ *
+ * Params:
+ *  ?
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+HRESULT WINAPI IDirectDrawSurfaceImpl_BltBatch(IDirectDrawSurface7 *iface, DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
+{
+    TRACE("(%p)->(%p,%ld,%08lx)\n",iface,Batch,Count,Flags);
+
+    /* MSDN: "not currently implemented" */
+    return DDERR_UNSUPPORTED;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::EnumAttachedSurfaces
+ *
+ * Enumerates all surfaces attached to this surface
+ *
+ * Params:
+ *  context: Pointer to pass unmodified to the callback
+ *  cb: Callback function to call for each surface
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if cb is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7 *iface,
+                                            void *context,
+                                            LPDDENUMSURFACESCALLBACK7 cb)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *surf;
+    DDSURFACEDESC2 desc;
+
+    /* Attached surfaces aren't handled in WineD3D */
+    TRACE("(%p)->(%p,%p)\n",This,context,cb);
+
+    if(!cb)
+        return DDERR_INVALIDPARAMS;
+
+    for (surf = This->next_complex; surf != NULL; surf = surf->next_complex)
+    {
+        IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7));
+        desc = surf->surface_desc;
+        /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
+        if (cb(ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, context) == DDENUMRET_CANCEL)
+            return DD_OK;
+    }
+
+    for (surf = This->next_attached; surf != NULL; surf = surf->next_attached)
+    {
+        IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7));
+        desc = surf->surface_desc;
+        /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
+        if (cb( ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, context) == DDENUMRET_CANCEL)
+            return DD_OK;
+    }
+
+    TRACE(" end of enumeration.\n");
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::EnumOverlayZOrders
+ *
+ * "Enumerates the overlay surfaces on the specified destination"
+ *
+ * Params:
+ *  Flags: DDENUMOVERLAYZ_BACKTOFRONT  or DDENUMOVERLAYZ_FRONTTOBACK
+ *  context: context to pass back to the callback
+ *  cb: callback function to call for each enumerated surface
+ *
+ * Returns:
+ *  DD_OK, because it's a stub
+ *
+ *****************************************************************************/
+HRESULT WINAPI
+IDirectDrawSurfaceImpl_EnumOverlayZOrders(IDirectDrawSurface7 *iface,
+                                          DWORD Flags,
+                                          void *context,
+                                          LPDDENUMSURFACESCALLBACK7 cb)
+{
+     FIXME("(%p)->(%lx,%p,%p): Stub!\n", iface, Flags, context, cb);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetBltStatus
+ *
+ * Returns the blitting status
+ *
+ * Params:
+ *  Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
+ *
+ * Returns:
+ *  See IWineD3DSurface::Blt
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetBltStatus(IDirectDrawSurface7 *iface,
+                                    DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%lx): Relay\n", This, Flags);
+
+    return IWineD3DSurface_GetBltStatus(This->WineD3DSurface, Flags);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetColorKey
+ *
+ * Returns the color key assigned to the surface
+ *
+ * Params:
+ *  Flags: Some flags
+ *  CKey: Address to store the key to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if CKey is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetColorKey(IDirectDrawSurface7 *iface,
+                                   DWORD Flags,
+                                   DDCOLORKEY *CKey)
+{
+    /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
+     * isn't there? That's like saying that an int isn't there. (Which MS
+     * has done in other docs.) */
+
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    if(!CKey)
+        return DDERR_INVALIDPARAMS;
+
+    switch (Flags)
+    {
+    case DDCKEY_DESTBLT:
+        *CKey = This->surface_desc.ddckCKDestBlt;
+        break;
+
+    case DDCKEY_DESTOVERLAY:
+        *CKey = This->surface_desc.u3.ddckCKDestOverlay;
+        break;
+
+    case DDCKEY_SRCBLT:
+        *CKey = This->surface_desc.ddckCKSrcBlt;
+        break;
+
+    case DDCKEY_SRCOVERLAY:
+        *CKey = This->surface_desc.ddckCKSrcOverlay;
+        break;
+
+    default:
+        return DDERR_INVALIDPARAMS;
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetFlipStatus
+ *
+ * Returns the flipping status of the surface
+ *
+ * Params:
+ *  Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
+ *
+ * Returns:
+ *  See IWineD3DSurface::GetFlipStatus
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetFlipStatus(IDirectDrawSurface7 *iface,
+                                     DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%lx): Relay\n", This, Flags);
+
+    return IWineD3DSurface_GetFlipStatus(This->WineD3DSurface, Flags);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetOverlayPosition
+ *
+ * Returns the display coordinates of a visible and active overlay surface
+ *
+ * Params:
+ *  X
+ *  Y
+ *
+ * Returns:
+ *  DDERR_NOTAOVERLAYSURFACE, because it's a stub
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetOverlayPosition(IDirectDrawSurface7 *iface,
+                                          LONG *X,
+                                          LONG *Y) {
+    FIXME("(%p)->(%p,%p): Stub!\n", iface, X, Y);
+
+    return DDERR_NOTAOVERLAYSURFACE;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetPixelFormat
+ *
+ * Returns the pixel format of the Surface
+ *
+ * Params:
+ *  PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
+ *               format should be written
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if PixelFormat is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetPixelFormat(IDirectDrawSurface7 *iface,
+                                      DDPIXELFORMAT *PixelFormat)
+{
+    /* What is DDERR_INVALIDSURFACETYPE for here? */
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n",This,PixelFormat);
+
+    if(!PixelFormat)
+        return DDERR_INVALIDPARAMS;
+
+    DD_STRUCT_COPY_BYSIZE(PixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
+
+    return DD_OK;
+}
+
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetSurfaceDesc
+ *
+ * Returns the description of this surface
+ *
+ * Params:
+ *  DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
+ *        surface desc
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if DDSD is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetSurfaceDesc(IDirectDrawSurface7 *iface,
+                                      DDSURFACEDESC2 *DDSD)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    TRACE("(%p)->(%p)\n",This,DDSD);
+
+    if(!DDSD)
+        return DDERR_INVALIDPARAMS;
+
+    if ((DDSD->dwSize < sizeof(DDSURFACEDESC)) ||
+        (DDSD->dwSize > sizeof(DDSURFACEDESC2)))
+    {
+        ERR("Impossible/Strange struct size %ld.\n",DDSD->dwSize);
+        return DDERR_GENERIC;
+    }
+
+    DD_STRUCT_COPY_BYSIZE(DDSD,&This->surface_desc);
+    TRACE("Returning surface desc:\n");
+    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Initialize
+ *
+ * Initializes the surface. This is a no-op in Wine
+ *
+ * Params:
+ *  DD: Pointer to an DirectDraw interface
+ *  DDSD: Surface description for initialization
+ *
+ * Returns:
+ *  DDERR_ALREADYINITIALIZED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Initialize(IDirectDrawSurface7 *iface,
+                                  IDirectDraw *DD,
+                                  DDSURFACEDESC2 *DDSD)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawImpl *ddimpl = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, DD);
+    TRACE("(%p)->(%p,%p)\n",This,ddimpl,DDSD);
+
+    return DDERR_ALREADYINITIALIZED;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::IsLost
+ *
+ * Checks if the surface is lost
+ *
+ * Returns:
+ *  DD_OK, if the surface is useable
+ *  DDERR_ISLOST if the surface is lost
+ *  See IWineD3DSurface::IsLost for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_IsLost(IDirectDrawSurface7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)\n", This);
+
+    /* We lose the surface if the implementation was changed */
+    if(This->ImplType != This->ddraw->ImplType)
+    {
+        /* But this shouldn't happen. When we change the implementation,
+         * all surfaces are re-created automatically, and their content
+         * is copied
+         */
+        ERR(" (%p) Implementation was changed from %d to %d\n", This, This->ImplType, This->ddraw->ImplType);
+        return DDERR_SURFACELOST;
+    }
+
+    return IWineD3DSurface_IsLost(This->WineD3DSurface);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::Restore
+ *
+ * Restores a lost surface. This makes the surface usable again, but
+ * doesn't reload its old contents
+ *
+ * Returns:
+ *  DD_OK on success
+ *  See IWineD3DSurface::Restore for more details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)\n", This);
+
+    if(This->ImplType != This->ddraw->ImplType)
+    {
+        /* Call the recreation callback. Make sure to AddRef first */
+        IDirectDrawSurface_AddRef(iface);
+        IDirectDrawImpl_RecreateSurfacesCallback(iface,
+                                                 &This->surface_desc,
+                                                 NULL /* Not needed */);
+    }
+    return IWineD3DSurface_Restore(This->WineD3DSurface);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetOverlayPosition
+ *
+ * Changes the display coordinates of an overlay surface
+ *
+ * Params:
+ *  X:
+ *  Y:
+ *
+ * Returns:
+ *   DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetOverlayPosition(IDirectDrawSurface7 *iface,
+                                          LONG X,
+                                          LONG Y)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    FIXME("(%p)->(%ld,%ld): Stub!\n", This, X, Y);
+    return DDERR_NOTAOVERLAYSURFACE;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::UpdateOverlay
+ *
+ * Modifies the attributes of an overlay surface.
+ *
+ * Params:
+ *  SrcRect: The section of the source being used for the overlay
+ *  DstSurface: Address of the surface that is overlaid
+ *  DstRect: Place of the overlay
+ *  Flags: some DDOVER_* flags
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED, because we don't support overlays
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_UpdateOverlay(IDirectDrawSurface7 *iface,
+                                     LPRECT SrcRect,
+                                     IDirectDrawSurface7 *DstSurface,
+                                     LPRECT DstRect,
+                                     DWORD Flags,
+                                     LPDDOVERLAYFX FX)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Dst = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DstSurface);
+    FIXME("(%p)->(%p,%p,%p,%lx,%p): Stub!\n", This, SrcRect, Dst, DstRect, Flags, FX);
+    return DDERR_UNSUPPORTED;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::UpdateOverlayDisplay
+ *
+ * The DX7 sdk says that it's not implemented
+ *
+ * Params:
+ *  Flags: ?
+ *
+ * Returns: DDERR_UNSUPPORTED, because we don't support overlays
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_UpdateOverlayDisplay(IDirectDrawSurface7 *iface,
+                                            DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%lx)\n", This, Flags);
+    return DDERR_UNSUPPORTED;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::UpdateOverlayZOrder
+ *
+ * Sets an overlay's Z order
+ *
+ * Params:
+ *  Flags: DDOVERZ_* flags
+ *  DDSRef: Defines the relative position in the overlay chain
+ *
+ * Returns:
+ *  DDERR_NOTOVERLAYSURFACE, because we don't support overlays
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_UpdateOverlayZOrder(IDirectDrawSurface7 *iface,
+                                           DWORD Flags,
+                                           IDirectDrawSurface7 *DDSRef)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *Ref = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DDSRef);
+    FIXME("(%p)->(%lx,%p)\n", This, Flags, Ref);
+    return DDERR_NOTAOVERLAYSURFACE;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetDDInterface
+ *
+ * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
+ * surface belongs to
+ *
+ * Params:
+ *  DD: Address to write the interface pointer to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if DD is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface,
+                                      void **DD)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    TRACE("(%p)->(%p)\n",This,DD);
+
+    if(!DD)
+        return DDERR_INVALIDPARAMS;
+
+    *((IDirectDraw7 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
+    IDirectDraw7_AddRef( (IDirectDraw7 *) *DD);
+
+    return DD_OK;
+}
+
+/* This seems also windows implementation specific - I don't think WineD3D needs this */
+HRESULT WINAPI IDirectDrawSurfaceImpl_ChangeUniquenessValue(IDirectDrawSurface7 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    volatile IDirectDrawSurfaceImpl* vThis = This;
+
+    TRACE("(%p)\n",This);
+    /* A uniquness value of 0 is apparently special.
+    * This needs to be checked. */
+    while (1) {
+        DWORD old_uniqueness_value = vThis->uniqueness_value;
+        DWORD new_uniqueness_value = old_uniqueness_value+1;
+
+        if (old_uniqueness_value == 0) break;
+        if (new_uniqueness_value == 0) new_uniqueness_value = 1;
+
+        if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
+                                      old_uniqueness_value,
+                                      new_uniqueness_value)
+            == old_uniqueness_value)
+            break;
+    }
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurfaceImpl_GetUniquenessValue(IDirectDrawSurface7 *iface, LPDWORD pValue)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    TRACE("(%p)->(%p)\n",This,pValue);
+    *pValue = This->uniqueness_value;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetLOD
+ *
+ * Sets the level of detail of a texture
+ *
+ * Params:
+ *  MaxLOD: LOD to set
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDOBJECT if the surface is invalid for this method
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetLOD(IDirectDrawSurface7 *iface,
+                              DWORD MaxLOD)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%ld)\n", This, MaxLOD);
+
+    if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
+        return DDERR_INVALIDOBJECT;
+
+    if(!This->wineD3DTexture)
+    {
+        ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This);
+        return DDERR_INVALIDOBJECT;
+    }
+
+    return IWineD3DTexture_SetLOD(This->wineD3DTexture,
+                                  MaxLOD);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetLOD
+ *
+ * Returns the level of detail of a Direct3D texture
+ *
+ * Params:
+ *  MaxLOD: Address to write the LOD to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if MaxLOD is NULL
+ *  DDERR_INVALIDOBJECT if the surface is invalid for this method
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetLOD(IDirectDrawSurface7 *iface,
+                              DWORD *MaxLOD)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n", This, MaxLOD);
+
+    if(!MaxLOD)
+        return DDERR_INVALIDPARAMS;
+
+    if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
+        return DDERR_INVALIDOBJECT;
+
+    *MaxLOD = IWineD3DTexture_GetLOD(This->wineD3DTexture);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::BltFast
+ *
+ * Performs a fast Blit.
+ *
+ * Params:
+ *  dstx: The x coordinate to blit to on the destination
+ *  dsty: The y coordinate to blit to on the destination
+ *  Source: The source surface
+ *  rsrc: The source rectangle
+ *  trans: Type of transfer. Some DDBLTFAST_* flags
+ *
+ * Returns:
+ *  DD_OK on success
+ *  For more details, see IWineD3DSurface::BltFast
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7 *iface,
+                               DWORD dstx,
+                               DWORD dsty,
+                               IDirectDrawSurface7 *Source,
+                               RECT *rsrc,
+                               DWORD trans)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Source);
+    TRACE("(%p)->(%ld,%ld,%p,%p,%ld): Relay\n", This, dstx, dsty, Source, rsrc, trans);
+
+    return IWineD3DSurface_BltFast(This->WineD3DSurface,
+                                   dstx, dsty,
+                                   src ? src->WineD3DSurface : NULL,
+                                   rsrc,
+                                   trans);
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetClipper
+ *
+ * Returns the IDirectDrawClipper interface of the clipper assigned to this
+ * surface
+ *
+ * Params:
+ *  Clipper: Address to store the interface pointer at
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Clipper is NULL
+ *  DDERR_NOCLIPPERATTACHED if there's no clipper attached
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetClipper(IDirectDrawSurface7 *iface,
+                                  IDirectDrawClipper **Clipper)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    TRACE("(%p)->(%p)\n", This, Clipper);
+
+    if(!Clipper)
+        return DDERR_INVALIDPARAMS;
+
+    if(This->clipper == NULL)
+        return DDERR_NOCLIPPERATTACHED;
+
+    *Clipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
+    IDirectDrawClipper_AddRef(*Clipper);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetClipper
+ *
+ * Sets a clipper for the surface
+ *
+ * Params:
+ *  Clipper: IDirectDrawClipper interface of the clipper to set
+ *
+ * Returns:
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetClipper(IDirectDrawSurface7 *iface,
+                                  IDirectDrawClipper *Clipper)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+
+    TRACE("(%p)->(%p)\n",This,Clipper);
+    if (ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper, Clipper) == This->clipper)
+        return DD_OK;
+
+    if (This->clipper != NULL)
+        IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper, IDirectDrawClipper) );
+
+    This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper, Clipper);
+    if (Clipper != NULL)
+        IDirectDrawClipper_AddRef(Clipper);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetSurfaceDesc
+ *
+ * Sets the surface description. It can override the pixel format, the surface
+ * memory, ...
+ * It's not really tested.
+ *
+ * Params:
+ * DDSD: Pointer to the new surface description to set
+ * Flags: Some flags
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if DDSD is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7 *iface,
+                                      DDSURFACEDESC2 *DDSD,
+                                      DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    BYTE *newSurface = NULL;
+    DWORD newSize = 0;
+    WINED3DFORMAT newFormat = WINED3DFMT_UNKNOWN;
+    HRESULT hr;
+    FIXME("(%p)->(%p,%lx)\n", This, DDSD, Flags);
+    assert(0);
+
+    if(!DDSD)
+        return DDERR_INVALIDPARAMS;
+
+    if (DDSD->dwFlags & DDSD_PIXELFORMAT)
+    {
+        newFormat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
+    }
+    if (DDSD->dwFlags & DDSD_LPSURFACE)
+    {
+        newSurface = DDSD->lpSurface;
+        newSize = DDSD->u1.dwLinearSize;
+        /* to avoid unpredictable things */
+        assert(newSize != 0);
+    }
+
+    /* Better: Use SetFormat */
+    hr = IWineD3DSurface_SetPixelFormat(This->WineD3DSurface,
+                                        newFormat,
+                                        newSurface,
+                                        newSize);
+    if(hr != DD_OK) return hr;
+
+    /* Store the new data. Not really necessary, as WineD3D stores it too,
+     * but for completeness
+     */
+    if(newFormat != WINED3DFMT_UNKNOWN)
+    {
+        This->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
+        This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat;
+    }
+    if(newSurface != NULL)
+    {
+        This->surface_desc.lpSurface = newSurface;
+        This->surface_desc.u1.dwLinearSize = newSize;
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::GetPalette
+ *
+ * Returns the IDirectDrawPalette interface of the palette currently assigned
+ * to the surface
+ *
+ * Params:
+ *  Pal: Address to write the interface pointer to
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Pal is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7 *iface,
+                                  IDirectDrawPalette **Pal)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IWineD3DPalette *wPal;
+    HRESULT hr;
+    TRACE("(%p)->(%p): Relay\n", This, Pal);
+
+    if(!Pal)
+        return DDERR_INVALIDPARAMS;
+
+    hr = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wPal);
+    if(hr != DD_OK) return hr;
+
+    if(wPal)
+    {
+        hr = IWineD3DPalette_GetParent(wPal, (IUnknown **) Pal);
+    }
+    else
+    {
+        *Pal = NULL;
+    }
+
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetColorKey
+ *
+ * Sets the color keying options for the surface. Observations showed that
+ * in case of complex surfaces the color key has to be assigned to all
+ * sublevels.
+ *
+ * Params:
+ *  Flags: DDCKEY_*
+ *  CKey: The new color key
+ *
+ * Returns:
+ *  DD_OK on success
+ *  See IWineD3DSurface::SetColorKey for details
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7 *iface,
+                                   DWORD Flags,
+                                   DDCOLORKEY *CKey)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawSurfaceImpl *surf;
+    HRESULT hr;
+    TRACE("(%p)->(%lx,%p)\n", This, Flags, CKey);
+
+    for(surf = This->first_complex; surf; surf = surf->next_complex)
+    {
+        hr = IWineD3DSurface_SetColorKey(surf->WineD3DSurface,
+                                         Flags,
+                                         CKey);
+        if(FAILED(hr))
+        {
+            WARN("IWineD3DSurface::SetColorKey for surface %p failed with hr=%08lx\n",
+                 surf->WineD3DSurface, hr);
+            return hr;
+        }
+    }
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawSurface7::SetPalette
+ *
+ * Assigns a DirectDrawPalette object to the surface
+ *
+ * Params:
+ *  Pal: Interface to the palette to set
+ *
+ * Returns:
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7 *iface,
+                                  IDirectDrawPalette *Pal)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
+    IDirectDrawPalette *oldPal;
+    IDirectDrawSurfaceImpl *surf;
+    IDirectDrawPaletteImpl *PalImpl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, Pal);
+    HRESULT hr;
+    TRACE("(%p)->(%p)\n", This, Pal);
+
+    /* Find the old palette */
+    hr = IDirectDrawSurface_GetPalette(iface, &oldPal);
+    if(hr != DD_OK) return hr;
+    if(oldPal) IDirectDrawPalette_Release(oldPal);  /* For the GetPalette */
+
+    /* Set the new Palette */
+    IWineD3DSurface_SetPalette(This->WineD3DSurface,
+                               PalImpl ? PalImpl->wineD3DPalette : NULL);
+    /* AddRef the Palette */
+    if(Pal) IDirectDrawPalette_AddRef(Pal);
+
+    /* Release the old palette */
+    if(oldPal) IDirectDrawPalette_Release(oldPal);
+
+    /* If this is a front buffer, also update the back buffers */
+    if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
+    {
+        for(surf = This->next_complex; surf != NULL; surf = surf->next_complex)
+        {
+            IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(surf, IDirectDrawSurface7),
+                                           Pal);
+        }
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * The VTable
+ *****************************************************************************/
+
+const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl =
+{
+    /*** IUnknown ***/
+    IDirectDrawSurfaceImpl_QueryInterface,
+    IDirectDrawSurfaceImpl_AddRef,
+    IDirectDrawSurfaceImpl_Release,
+    /*** IDirectDrawSurface ***/
+    IDirectDrawSurfaceImpl_AddAttachedSurface,
+    IDirectDrawSurfaceImpl_AddOverlayDirtyRect,
+    IDirectDrawSurfaceImpl_Blt,
+    IDirectDrawSurfaceImpl_BltBatch,
+    IDirectDrawSurfaceImpl_BltFast,
+    IDirectDrawSurfaceImpl_DeleteAttachedSurface,
+    IDirectDrawSurfaceImpl_EnumAttachedSurfaces,
+    IDirectDrawSurfaceImpl_EnumOverlayZOrders,
+    IDirectDrawSurfaceImpl_Flip,
+    IDirectDrawSurfaceImpl_GetAttachedSurface,
+    IDirectDrawSurfaceImpl_GetBltStatus,
+    IDirectDrawSurfaceImpl_GetCaps,
+    IDirectDrawSurfaceImpl_GetClipper,
+    IDirectDrawSurfaceImpl_GetColorKey,
+    IDirectDrawSurfaceImpl_GetDC,
+    IDirectDrawSurfaceImpl_GetFlipStatus,
+    IDirectDrawSurfaceImpl_GetOverlayPosition,
+    IDirectDrawSurfaceImpl_GetPalette,
+    IDirectDrawSurfaceImpl_GetPixelFormat,
+    IDirectDrawSurfaceImpl_GetSurfaceDesc,
+    IDirectDrawSurfaceImpl_Initialize,
+    IDirectDrawSurfaceImpl_IsLost,
+    IDirectDrawSurfaceImpl_Lock,
+    IDirectDrawSurfaceImpl_ReleaseDC,
+    IDirectDrawSurfaceImpl_Restore,
+    IDirectDrawSurfaceImpl_SetClipper,
+    IDirectDrawSurfaceImpl_SetColorKey,
+    IDirectDrawSurfaceImpl_SetOverlayPosition,
+    IDirectDrawSurfaceImpl_SetPalette,
+    IDirectDrawSurfaceImpl_Unlock,
+    IDirectDrawSurfaceImpl_UpdateOverlay,
+    IDirectDrawSurfaceImpl_UpdateOverlayDisplay,
+    IDirectDrawSurfaceImpl_UpdateOverlayZOrder,
+    /*** IDirectDrawSurface2 ***/
+    IDirectDrawSurfaceImpl_GetDDInterface,
+    IDirectDrawSurfaceImpl_PageLock,
+    IDirectDrawSurfaceImpl_PageUnlock,
+    /*** IDirectDrawSurface3 ***/
+    IDirectDrawSurfaceImpl_SetSurfaceDesc,
+    /*** IDirectDrawSurface4 ***/
+    IDirectDrawSurfaceImpl_SetPrivateData,
+    IDirectDrawSurfaceImpl_GetPrivateData,
+    IDirectDrawSurfaceImpl_FreePrivateData,
+    IDirectDrawSurfaceImpl_GetUniquenessValue,
+    IDirectDrawSurfaceImpl_ChangeUniquenessValue,
+    /*** IDirectDrawSurface7 ***/
+    IDirectDrawSurfaceImpl_SetPriority,
+    IDirectDrawSurfaceImpl_GetPriority,
+    IDirectDrawSurfaceImpl_SetLOD,
+    IDirectDrawSurfaceImpl_GetLOD
+};
diff --git a/dlls/ddraw/surface_dib.c b/dlls/ddraw/surface_dib.c
deleted file mode 100644
index c3a8ab1..0000000
--- a/dlls/ddraw/surface_dib.c
+++ /dev/null
@@ -1,1483 +0,0 @@
-/*		DIBSection DirectDrawSurface driver
- *
- * Copyright 1997-2000 Marcus Meissner
- * Copyright 1998-2000 Lionel Ulmer
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "wine/debug.h"
-#include "ddraw_private.h"
-#include "d3d_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-/* FIXME */
-extern HBITMAP DIB_CreateDIBSection( HDC hdc, const BITMAPINFO *bmi, UINT usage, VOID **bits,
-                                     HANDLE section, DWORD offset, DWORD ovr_pitch );
-
-static const IDirectDrawSurface7Vtbl DIB_IDirectDrawSurface7_VTable;
-
-/* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. */
-inline static int get_dib_width_bytes( int width, int depth )
-{
-    int words;
-
-    switch(depth)
-    {
-    case 1:  words = (width + 31) / 32; break;
-    case 4:  words = (width + 7) / 8; break;
-    case 8:  words = (width + 3) / 4; break;
-    case 15:
-    case 16: words = (width + 1) / 2; break;
-    case 24: words = (width * 3 + 3)/4; break;
-    default:
-        WARN("(%d): Unsupported depth\n", depth );
-        /* fall through */
-    case 32: words = width; break;
-    }
-    return 4 * words;
-}
-
-
-static HRESULT create_dib(IDirectDrawSurfaceImpl* This)
-{
-    BITMAPINFO* b_info;
-    UINT usage;
-    HDC ddc;
-    DIB_DirectDrawSurfaceImpl* priv = This->private;
-
-    assert(This->surface_desc.lpSurface != NULL);
-
-    switch (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount)
-    {
-    case 16:
-    case 32:
-	/* Allocate extra space to store the RGB bit masks. */
-	b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                           sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
-	break;
-
-    case 24:
-	b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                           sizeof(BITMAPINFOHEADER));
-	break;
-
-    default:
-	/* Allocate extra space for a palette. */
-	b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                           sizeof(BITMAPINFOHEADER)
-                           + sizeof(RGBQUAD)
-                           * (1 << This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount));
-	break;
-    }
-
-    b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    b_info->bmiHeader.biWidth = This->surface_desc.dwWidth;
-    b_info->bmiHeader.biHeight = -This->surface_desc.dwHeight;
-    b_info->bmiHeader.biPlanes = 1;
-    b_info->bmiHeader.biBitCount = This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
-
-    if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount != 16)
-	&& (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount != 32))
-        b_info->bmiHeader.biCompression = BI_RGB;
-    else
-        b_info->bmiHeader.biCompression = BI_BITFIELDS;
-
-    b_info->bmiHeader.biSizeImage
-	= (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8)
-	* This->surface_desc.dwWidth * This->surface_desc.dwHeight;
-
-    b_info->bmiHeader.biXPelsPerMeter = 0;
-    b_info->bmiHeader.biYPelsPerMeter = 0;
-    b_info->bmiHeader.biClrUsed = 0;
-    b_info->bmiHeader.biClrImportant = 0;
-
-    if (!This->surface_desc.u1.lPitch) {
-	/* This can't happen, right? */
-	/* or use GDI_GetObj to get it from the created DIB? */
-	This->surface_desc.u1.lPitch = get_dib_width_bytes(b_info->bmiHeader.biWidth, b_info->bmiHeader.biBitCount);
-	This->surface_desc.dwFlags |= DDSD_PITCH;
-    }
-    
-    switch (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount)
-    {
-    case 16:
-    case 32:
-    {
-	DWORD *masks = (DWORD *) &(b_info->bmiColors);
-
-	usage = 0;
-	masks[0] = This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
-	masks[1] = This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
-	masks[2] = This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
-    }
-    break;
-
-    case 24:
-	/* Nothing to do */
-	usage = DIB_RGB_COLORS;
-	break;
-
-    default:
-	/* Don't know palette */
-	usage = 0;
-	break;
-    }
-
-    ddc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-    if (ddc == 0)
-    {
-	HeapFree(GetProcessHeap(), 0, b_info);
-	return HRESULT_FROM_WIN32(GetLastError());
-    }
-
-    priv->dib.DIBsection
-	= DIB_CreateDIBSection(ddc, b_info, usage, &(priv->dib.bitmap_data), 0,
-			       (DWORD)This->surface_desc.lpSurface,
-			       This->surface_desc.u1.lPitch);
-    DeleteDC(ddc);
-    if (!priv->dib.DIBsection) {
-	ERR("CreateDIBSection failed!\n");
-	HeapFree(GetProcessHeap(), 0, b_info);
-	return HRESULT_FROM_WIN32(GetLastError());
-    }
-
-    TRACE("DIBSection at : %p\n", priv->dib.bitmap_data);
-
-    if (!This->surface_desc.lpSurface) {
-	This->surface_desc.lpSurface = priv->dib.bitmap_data;
-	This->surface_desc.dwFlags |= DDSD_LPSURFACE;
-    }
-
-    HeapFree(GetProcessHeap(), 0, b_info);
-
-    /* I don't think it's worth checking for this. */
-    if (priv->dib.bitmap_data != This->surface_desc.lpSurface)
-	ERR("unexpected error creating DirectDrawSurface DIB section\n");
-
-    /* this seems like a good place to put the handle for HAL driver use */
-    This->global_more.hKernelSurface = (ULONG_PTR)priv->dib.DIBsection;
-
-    return S_OK;
-}
-
-void DIB_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
-{
-    DIB_DirectDrawSurfaceImpl* priv = This->private;
-
-    DeleteObject(priv->dib.DIBsection);
-
-    if (!priv->dib.client_memory)
-	VirtualFree(This->surface_desc.lpSurface, 0, MEM_RELEASE);
-
-    Main_DirectDrawSurface_final_release(This);
-}
-
-HRESULT DIB_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						LPDIRECTDRAWSURFACE7* ppDup)
-{
-    return DIB_DirectDrawSurface_Create(This->ddraw_owner,
-					&This->surface_desc, ppDup, NULL);
-}
-
-HRESULT DIB_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
-					IDirectDrawImpl *pDD,
-					const DDSURFACEDESC2 *pDDSD)
-{
-    HRESULT hr;
-    DIB_DirectDrawSurfaceImpl* priv = This->private;
-
-    TRACE("(%p)->(%p,%p)\n",This,pDD,pDDSD);
-    hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr)) return hr;
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
-			DIB_IDirectDrawSurface7_VTable);
-
-    This->final_release = DIB_DirectDrawSurface_final_release;
-    This->duplicate_surface = DIB_DirectDrawSurface_duplicate_surface;
-    This->flip_data = DIB_DirectDrawSurface_flip_data;
-
-    This->get_dc     = DIB_DirectDrawSurface_get_dc;
-    This->release_dc = DIB_DirectDrawSurface_release_dc;
-    This->hDC = NULL;
-
-    This->set_palette    = DIB_DirectDrawSurface_set_palette;
-    This->update_palette = DIB_DirectDrawSurface_update_palette;
-
-    TRACE("(%ldx%ld, pitch=%ld)\n",
-	  This->surface_desc.dwWidth, This->surface_desc.dwHeight,
-	  This->surface_desc.u1.lPitch);
-    /* XXX load dwWidth and dwHeight from pDD if they are not specified? */
-
-    if (This->surface_desc.dwFlags & DDSD_LPSURFACE)
-    {
-	/* "Client memory": it is managed by the application. */
-	/* XXX What if lPitch is not set? Use dwWidth or fail? */
-
-	priv->dib.client_memory = TRUE;
-    }
-    else
-    {
-	if (!(This->surface_desc.dwFlags & DDSD_PITCH))
-	{
-	    int pitch = This->surface_desc.u1.lPitch;
-	    if (pitch % 8 != 0)
-		pitch += 8 - (pitch % 8);
-	}
-	/* XXX else: how should lPitch be verified? */
-
-	This->surface_desc.dwFlags |= DDSD_LPSURFACE;
-
-	/* Ensure that DDSD_PITCH is respected for DDPF_FOURCC surfaces too */
- 	if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC && !(This->surface_desc.dwFlags & DDSD_PITCH)) {
-	    This->surface_desc.lpSurface
-		= VirtualAlloc(NULL, This->surface_desc.u1.dwLinearSize, MEM_COMMIT, PAGE_READWRITE);
-	    This->surface_desc.dwFlags |= DDSD_LINEARSIZE;
-	} else {
-	    This->surface_desc.lpSurface
-		= VirtualAlloc(NULL, This->surface_desc.u1.lPitch
-			   * This->surface_desc.dwHeight + 4, /* The + 4 here is for dumb games reading after the end of the surface
-								 when reading the last byte / half using word access */
-			   MEM_COMMIT, PAGE_READWRITE);
-	    This->surface_desc.dwFlags |= DDSD_PITCH;
-	}
-
-	if (This->surface_desc.lpSurface == NULL)
-	{
-	    Main_DirectDrawSurface_final_release(This);
-	    return HRESULT_FROM_WIN32(GetLastError());
-	}
-
-	priv->dib.client_memory = FALSE;
-    }
-
-    hr = create_dib(This);
-    if (FAILED(hr))
-    {
-	if (!priv->dib.client_memory)
-	    VirtualFree(This->surface_desc.lpSurface, 0, MEM_RELEASE);
-
-	Main_DirectDrawSurface_final_release(This);
-
-	return hr;
-    }
-
-    return DD_OK;
-}
-
-/* Not an API */
-HRESULT DIB_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-				     const DDSURFACEDESC2 *pDDSD,
-				     LPDIRECTDRAWSURFACE7 *ppSurf,
-				     IUnknown *pUnkOuter)
-{
-    IDirectDrawSurfaceImpl* This;
-    HRESULT hr;
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(*This) + sizeof(DIB_DirectDrawSurfaceImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    This->private = (DIB_DirectDrawSurfaceImpl*)(This+1);
-
-    hr = DIB_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
-
-    return hr;
-
-}
-
-/* AddAttachedSurface: generic */
-/* AddOverlayDirtyRect: generic, unimplemented */
-
-static HRESULT _Blt_ColorFill(
-    LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color
-) {
-    int x, y;
-    LPBYTE first;
-
-    /* Do first row */
-
-#define COLORFILL_ROW(type) { \
-    type *d = (type *) buf; \
-    for (x = 0; x < width; x++) \
-	d[x] = (type) color; \
-    break; \
-}
-
-    switch(bpp) {
-    case 1: COLORFILL_ROW(BYTE)
-    case 2: COLORFILL_ROW(WORD)
-    case 3: { BYTE *d = (BYTE *) buf;
-              for (x = 0; x < width; x++,d+=3) {
-                d[0] = (color    ) & 0xFF;
-                d[1] = (color>> 8) & 0xFF;
-                d[2] = (color>>16) & 0xFF;
-              }
-              break;}
-    case 4: COLORFILL_ROW(DWORD)
-    default:
-	FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
-	return DDERR_UNSUPPORTED;
-    }
-
-#undef COLORFILL_ROW
-
-    /* Now copy first row */
-    first = buf;
-    for (y = 1; y < height; y++) {
-	buf += lPitch;
-	memcpy(buf, first, width * bpp);
-    }
-    return DD_OK;
-}
-
-static void ComputeShifts(DWORD mask, DWORD* lshift, DWORD* rshift)
-{
-    int pos = 0;
-    int bits = 0;
-    *lshift = 0;
-    *rshift = 0;
-    
-    if (!mask)
-	return;
-    
-    while(!(mask & (1 << pos)))
-	pos++; 
-    
-    while(mask & (1 << (pos+bits)))
-	bits++;
-    
-    *lshift = pos;
-    *rshift = 8 - bits;
-}
-
-/* This is used to factorize the decompression between the Blt and BltFast code */
-static void DoDXTCDecompression(const DDSURFACEDESC2 *sdesc, const DDSURFACEDESC2 *ddesc)
-{
-    DWORD rs,rb,rm;
-    DWORD gs,gb,gm;
-    DWORD bs,bb,bm;
-    DWORD as,ab,am;
-
-    if (!s3tc_initialized) {
-	/* FIXME: We may fake this by rendering the texture into the framebuffer using OpenGL functions and reading back
-	 *        the framebuffer. This will be slow and somewhat ugly. */ 
-	FIXME("Manual S3TC decompression is not supported in native mode\n");
-	return;
-    }
-    
-    rm = ddesc->u4.ddpfPixelFormat.u2.dwRBitMask;
-    ComputeShifts(rm, &rs, &rb);
-    gm = ddesc->u4.ddpfPixelFormat.u3.dwGBitMask;
-    ComputeShifts(gm, &gs, &gb);
-    bm = ddesc->u4.ddpfPixelFormat.u4.dwBBitMask;
-    ComputeShifts(bm, &bs, &bb);
-    am = ddesc->u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask;
-    ComputeShifts(am, &as, &ab);
-    if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','1')) {
-	int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
-	int pitch = ddesc->u1.lPitch;
-	int width = ddesc->dwWidth;
-	int height = ddesc->dwHeight;
-	int x,y;
-	unsigned char* dst = (unsigned char*) ddesc->lpSurface;
-	unsigned char* src = (unsigned char*) sdesc->lpSurface;
-	for (x = 0; x < width; x++)
-	    for (y =0; y < height; y++) {
-		DWORD pixel = 0;
-		BYTE data[4];
-		(*fetch_2d_texel_rgba_dxt1)(width, src, x, y, data);
-		pixel = 0;
-		pixel |= ((data[0] >> rb) << rs) & rm;
-		pixel |= ((data[1] >> gb) << gs) & gm;
-		pixel |= ((data[2] >> bb) << bs) & bm;
-		pixel |= ((data[3] >> ab) << as) & am;
-		if (is16)
-		    *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-		else
-		    *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-	    }
-    } else if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','3')) {
-	int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
-	int pitch = ddesc->u1.lPitch;
-	int width = ddesc->dwWidth;
-	int height = ddesc->dwHeight;
-	int x,y;
-	unsigned char* dst = (unsigned char*) ddesc->lpSurface;
-	unsigned char* src = (unsigned char*) sdesc->lpSurface;
-	for (x = 0; x < width; x++)
-	    for (y =0; y < height; y++) {
-		DWORD pixel = 0;
-		BYTE data[4];
-		(*fetch_2d_texel_rgba_dxt3)(width, src, x, y, data);
-		pixel = 0;
-		pixel |= ((data[0] >> rb) << rs) & rm;
-		pixel |= ((data[1] >> gb) << gs) & gm;
-		pixel |= ((data[2] >> bb) << bs) & bm;
-		pixel |= ((data[3] >> ab) << as) & am;
-		if (is16)
-		    *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-		else
-		    *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-	    }
-    } else if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','5')) {
-	int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
-	int pitch = ddesc->u1.lPitch;
-	int width = ddesc->dwWidth;
-	int height = ddesc->dwHeight;
-	int x,y;
-	unsigned char* dst = (unsigned char*) ddesc->lpSurface;
-	unsigned char* src = (unsigned char*) sdesc->lpSurface;
-	for (x = 0; x < width; x++)
-	    for (y =0; y < height; y++) {
-		DWORD pixel = 0;
-		BYTE data[4];
-		(*fetch_2d_texel_rgba_dxt5)(width, src, x, y, data);
-		pixel = 0;
-		pixel |= ((data[0] >> rb) << rs) & rm;
-		pixel |= ((data[1] >> gb) << gs) & gm;
-		pixel |= ((data[2] >> bb) << bs) & bm;
-		pixel |= ((data[3] >> ab) << as) & am;
-		if (is16)
-		    *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-		else
-		    *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
-	    }
-    }
-#if 0 /* Useful for debugging */
-    {
-	static int idx;
-	char texname[255];
-	FILE* f;
-	sprintf(texname, "dxt_%d.pnm", idx++);
-	f = fopen(texname,"w");
-	DDRAW_dump_surface_to_disk(This, f, 1);
-	fclose(f);
-    }
-#endif
-}
-
-HRESULT WINAPI
-DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,
-			  LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
-			  DWORD dwFlags, LPDDBLTFX lpbltfx)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    RECT		xdst,xsrc;
-    DDSURFACEDESC2	ddesc,sdesc;
-    HRESULT		ret = DD_OK;
-    int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
-    int x, y;
-    LPBYTE dbuf, sbuf;
-    
-    TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
-
-    if (TRACE_ON(ddraw)) {
-	if (rdst) TRACE("\tdestrect :%ldx%ld-%ldx%ld\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
-	if (rsrc) TRACE("\tsrcrect  :%ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	TRACE("\tflags: ");
-	DDRAW_dump_DDBLT(dwFlags);
-	if (dwFlags & DDBLT_DDFX) {
-	    TRACE("\tblitfx: ");
-	    DDRAW_dump_DDBLTFX(lpbltfx->dwDDFX);
-	}
-    }
-
-    if ((This->locked) || ((src != NULL) && (((IDirectDrawSurfaceImpl *)src)->locked))) {
-        WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
-        return DDERR_SURFACEBUSY;
-    }
-
-    /* First, check if the possible override function handles this case */
-    if (This->aux_blt != NULL) {
-        if (This->aux_blt(This, rdst, src, rsrc, dwFlags, lpbltfx) == DD_OK) return DD_OK;
-    }
-
-    DD_STRUCT_INIT(&ddesc);
-    DD_STRUCT_INIT(&sdesc);
-
-    sdesc.dwSize = sizeof(sdesc);
-    ddesc.dwSize = sizeof(ddesc);
-
-    if (src == iface) {
-        IDirectDrawSurface7_Lock(iface, NULL, &ddesc, 0, 0);
-        DD_STRUCT_COPY_BYSIZE(&sdesc, &ddesc);
-    } else {
-        if (src) IDirectDrawSurface7_Lock(src, NULL, &sdesc, DDLOCK_READONLY, 0);
-        IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
-    }
-
-    if (!lpbltfx || !(lpbltfx->dwDDFX)) dwFlags &= ~DDBLT_DDFX;
-
-    if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
-	(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) {
-	if (sdesc.u4.ddpfPixelFormat.dwFourCC != sdesc.u4.ddpfPixelFormat.dwFourCC) {
-	    FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
-	    ret = DDERR_INVALIDPIXELFORMAT;
-	    goto release;
-	}
-	memcpy(ddesc.lpSurface, sdesc.lpSurface, ddesc.u1.dwLinearSize);
-	goto release;
-    }
-
-    if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
-	(!(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC))) {
-	DoDXTCDecompression(&sdesc, &ddesc);
-	goto release;
-    }
-    
-    if (rdst) {
-	memcpy(&xdst,rdst,sizeof(xdst));
-    } else {
-	xdst.top	= 0;
-	xdst.bottom	= ddesc.dwHeight;
-	xdst.left	= 0;
-	xdst.right	= ddesc.dwWidth;
-    }
-
-    if (rsrc) {
-	memcpy(&xsrc,rsrc,sizeof(xsrc));
-    } else {
-	if (src) {
-	    xsrc.top	= 0;
-	    xsrc.bottom	= sdesc.dwHeight;
-	    xsrc.left	= 0;
-	    xsrc.right	= sdesc.dwWidth;
-	} else {
-	    memset(&xsrc,0,sizeof(xsrc));
-	}
-    }
-
-    /* First check for the validity of source / destination rectangles. This was
-       verified using a test application + by MSDN.
-    */
-    if ((src != NULL) &&
-	((xsrc.bottom > sdesc.dwHeight) || (xsrc.bottom < 0) ||
-	 (xsrc.top > sdesc.dwHeight) || (xsrc.top < 0) ||
-	 (xsrc.left > sdesc.dwWidth) || (xsrc.left < 0) ||
-	 (xsrc.right > sdesc.dwWidth) || (xsrc.right < 0) ||
-	 (xsrc.right < xsrc.left) || (xsrc.bottom < xsrc.top))) {
-        WARN("Application gave us bad source rectangle for Blt.\n");
-	ret = DDERR_INVALIDRECT;
-	goto release;
-    }
-    /* For the Destination rect, it can be out of bounds on the condition that a clipper
-       is set for the given surface.
-    */
-    if ((This->clipper == NULL) &&
-	((xdst.bottom > ddesc.dwHeight) || (xdst.bottom < 0) ||
-	 (xdst.top > ddesc.dwHeight) || (xdst.top < 0) ||
-	 (xdst.left > ddesc.dwWidth) || (xdst.left < 0) ||
-	 (xdst.right > ddesc.dwWidth) || (xdst.right < 0) ||
-	 (xdst.right < xdst.left) || (xdst.bottom < xdst.top))) {
-        WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");
-	ret = DDERR_INVALIDRECT;
-	goto release;
-    }
-    
-    /* Now handle negative values in the rectangles. Warning: only supported for now
-       in the 'simple' cases (ie not in any stretching / rotation cases).
-
-       First, the case where nothing is to be done.
-    */
-    if (((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth)) ||
-        ((src != NULL) &&
-         ((xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth))))
-    {
-        TRACE("Nothing to be done !\n");
-        goto release;
-    }
-
-    /* The easy case : the source-less blits.... */
-    if (src == NULL) {
-        RECT full_rect;
-        RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */
-
-	full_rect.left   = 0;
-	full_rect.top    = 0;
-	full_rect.right  = ddesc.dwWidth;
-	full_rect.bottom = ddesc.dwHeight;
-        IntersectRect(&temp_rect, &full_rect, &xdst);
-        xdst = temp_rect;
-    } else {
-        /* Only handle clipping on the destination rectangle */
-        int clip_horiz = (xdst.left < 0) || (xdst.right  > (int) ddesc.dwWidth );
-        int clip_vert  = (xdst.top  < 0) || (xdst.bottom > (int) ddesc.dwHeight);
-        if (clip_vert || clip_horiz) {
-            /* Now check if this is a special case or not... */
-            if ((((xdst.bottom - xdst.top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) ||
-                (((xdst.right  - xdst.left) != (xsrc.right  - xsrc.left)) && clip_horiz) ||
-                (dwFlags & DDBLT_DDFX)) {
-                WARN("Out of screen rectangle in special case. Not handled right now.\n");
-                goto release;
-            }
-
-            if (clip_horiz) {
-              if (xdst.left < 0) { xsrc.left -= xdst.left; xdst.left = 0; }
-              if (xdst.right > ddesc.dwWidth) { xsrc.right -= (xdst.right - (int) ddesc.dwWidth); xdst.right = (int) ddesc.dwWidth; }
-            }
-            if (clip_vert) {
-                if (xdst.top < 0) { xsrc.top -= xdst.top; xdst.top = 0; }
-                if (xdst.bottom > ddesc.dwHeight) { xsrc.bottom -= (xdst.bottom - (int) ddesc.dwHeight); xdst.bottom = (int) ddesc.dwHeight; }
-            }
-            /* And check if after clipping something is still to be done... */
-            if ((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth) ||
-                (xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth)) {
-                TRACE("Nothing to be done after clipping !\n");
-                goto release;
-            }
-        }
-    }
-
-    bpp = GET_BPP(ddesc);
-    srcheight = xsrc.bottom - xsrc.top;
-    srcwidth = xsrc.right - xsrc.left;
-    dstheight = xdst.bottom - xdst.top;
-    dstwidth = xdst.right - xdst.left;
-    width = (xdst.right - xdst.left) * bpp;
-
-    assert(width <= ddesc.u1.lPitch);
-
-    dbuf = (BYTE*)ddesc.lpSurface+(xdst.top*ddesc.u1.lPitch)+(xdst.left*bpp);
-
-    if (dwFlags & DDBLT_WAIT) {
-	static BOOL displayed = FALSE;
-	if (!displayed)
-	    FIXME("Can't handle DDBLT_WAIT flag right now.\n");
-	displayed = TRUE;
-	dwFlags &= ~DDBLT_WAIT;
-    }
-    if (dwFlags & DDBLT_ASYNC) {
-	static BOOL displayed = FALSE;
-	if (!displayed)
-	    FIXME("Can't handle DDBLT_ASYNC flag right now.\n");
-	displayed = TRUE;
-	dwFlags &= ~DDBLT_ASYNC;
-    }
-    if (dwFlags & DDBLT_DONOTWAIT) {
-	/* DDBLT_DONOTWAIT appeared in DX7 */
-	static BOOL displayed = FALSE;
-	if (!displayed)
-	    FIXME("Can't handle DDBLT_DONOTWAIT flag right now.\n");
-	displayed = TRUE;
-	dwFlags &= ~DDBLT_DONOTWAIT;
-    }
-
-    /* First, all the 'source-less' blits */
-    if (dwFlags & DDBLT_COLORFILL) {
-	ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
-			     ddesc.u1.lPitch, lpbltfx->u5.dwFillColor);
-	dwFlags &= ~DDBLT_COLORFILL;
-    }
-
-    if (dwFlags & DDBLT_DEPTHFILL)
-	FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
-    if (dwFlags & DDBLT_ROP) {
-	/* Catch some degenerate cases here */
-	switch(lpbltfx->dwROP) {
-	case BLACKNESS:
-	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,0);
-	    break;
-	case 0xAA0029: /* No-op */
-	    break;
-	case WHITENESS:
-	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,~0);
-	    break;
-	case SRCCOPY: /* well, we do that below ? */
-	    break;
-	default:
-	    FIXME("Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u5.lpDDSPattern);
-	    goto error;
-	}
-	dwFlags &= ~DDBLT_ROP;
-    }
-    if (dwFlags & DDBLT_DDROPS) {
-	FIXME("\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u5.lpDDSPattern);
-    }
-    /* Now the 'with source' blits */
-    if (src) {
-	LPBYTE sbase;
-	int sx, xinc, sy, yinc;
-
-	if (!dstwidth || !dstheight) /* hmm... stupid program ? */
-	    goto release;
-	sbase = (BYTE*)sdesc.lpSurface+(xsrc.top*sdesc.u1.lPitch)+xsrc.left*bpp;
-	xinc = (srcwidth << 16) / dstwidth;
-	yinc = (srcheight << 16) / dstheight;
-
-	if (!dwFlags) {
-	    /* No effects, we can cheat here */
-	    if (dstwidth == srcwidth) {
-		if (dstheight == srcheight) {
-		    /* No stretching in either direction. This needs to be as
-		     * fast as possible */
-		    sbuf = sbase;
-
-                    /* check for overlapping surfaces */
-                    if (src != iface || xdst.top < xsrc.top ||
-                        xdst.right <= xsrc.left || xsrc.right <= xdst.left)
-                    {
-                        /* no overlap, or dst above src, so copy from top downwards */
-                        for (y = 0; y < dstheight; y++)
-                        {
-                            memcpy(dbuf, sbuf, width);
-                            sbuf += sdesc.u1.lPitch;
-                            dbuf += ddesc.u1.lPitch;
-                        }
-                    }
-                    else if (xdst.top > xsrc.top)  /* copy from bottom upwards */
-                    {
-                        sbuf += (sdesc.u1.lPitch*dstheight);
-                        dbuf += (ddesc.u1.lPitch*dstheight);
-                        for (y = 0; y < dstheight; y++)
-                        {
-                            sbuf -= sdesc.u1.lPitch;
-                            dbuf -= ddesc.u1.lPitch;
-                            memcpy(dbuf, sbuf, width);
-                        }
-                    }
-                    else /* src and dst overlapping on the same line, use memmove */
-                    {
-                        for (y = 0; y < dstheight; y++)
-                        {
-                            memmove(dbuf, sbuf, width);
-                            sbuf += sdesc.u1.lPitch;
-                            dbuf += ddesc.u1.lPitch;
-                        }
-                    }
-		} else {
-		    /* Stretching in Y direction only */
-		    for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-			sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;
-			memcpy(dbuf, sbuf, width);
-			dbuf += ddesc.u1.lPitch;
-		    }
-		}
-	    } else {
-		/* Stretching in X direction */
-		int last_sy = -1;
-		for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-		    sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;
-
-		    if ((sy >> 16) == (last_sy >> 16)) {
-			/* this sourcerow is the same as last sourcerow -
-			 * copy already stretched row
-			 */
-			memcpy(dbuf, dbuf - ddesc.u1.lPitch, width);
-		    } else {
-#define STRETCH_ROW(type) { \
-		    type *s = (type *) sbuf, *d = (type *) dbuf; \
-		    for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
-		    d[x] = s[sx >> 16]; \
-		    break; }
-
-		    switch(bpp) {
-		    case 1: STRETCH_ROW(BYTE)
-		    case 2: STRETCH_ROW(WORD)
-		    case 4: STRETCH_ROW(DWORD)
-		    case 3: {
-			LPBYTE s,d = dbuf;
-			for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
-			    DWORD pixel;
-
-			    s = sbuf+3*(sx>>16);
-			    pixel = s[0]|(s[1]<<8)|(s[2]<<16);
-			    d[0] = (pixel    )&0xff;
-			    d[1] = (pixel>> 8)&0xff;
-			    d[2] = (pixel>>16)&0xff;
-			    d+=3;
-			}
-			break;
-		    }
-		    default:
-			FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
-			ret = DDERR_UNSUPPORTED;
-			goto error;
-		    }
-#undef STRETCH_ROW
-		    }
-		    dbuf += ddesc.u1.lPitch;
-		    last_sy = sy;
-		}
-	    }
-	} else {
-           LONG dstyinc = ddesc.u1.lPitch, dstxinc = bpp;
-           DWORD keylow = 0xFFFFFFFF, keyhigh = 0, keymask = 0xFFFFFFFF;
-           if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) {
-
-	      if (dwFlags & DDBLT_KEYSRC) {
-		 keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
-		 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
-	      } else if (dwFlags & DDBLT_KEYDEST){
-		 keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
-		 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
-	      } else if (dwFlags & DDBLT_KEYSRCOVERRIDE) {
-		 keylow  = lpbltfx->ddckSrcColorkey.dwColorSpaceLowValue;
-		 keyhigh = lpbltfx->ddckSrcColorkey.dwColorSpaceHighValue;
-	      } else {
-		 keylow  = lpbltfx->ddckDestColorkey.dwColorSpaceLowValue;
-		 keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue;
-	      }
-
-		if(bpp == 1)
-			keymask = 0xff;
-		else
-			keymask = sdesc.u4.ddpfPixelFormat.u2.dwRBitMask | sdesc.u4.ddpfPixelFormat.u3.dwGBitMask |
-			          sdesc.u4.ddpfPixelFormat.u4.dwBBitMask;
-
-	      dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE);
-           }
-
-           if (dwFlags & DDBLT_DDFX)  {
-              LPBYTE dTopLeft, dTopRight, dBottomLeft, dBottomRight, tmp;
-              LONG tmpxy;
-              dTopLeft     = dbuf;
-              dTopRight    = dbuf+((dstwidth-1)*bpp);
-              dBottomLeft  = dTopLeft+((dstheight-1)*ddesc.u1.lPitch);
-              dBottomRight = dBottomLeft+((dstwidth-1)*bpp);
-
-              if (lpbltfx->dwDDFX & DDBLTFX_ARITHSTRETCHY){
-                 /* I don't think we need to do anything about this flag */
-                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ARITHSTRETCHY\n");
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_MIRRORLEFTRIGHT) {
-                 tmp          = dTopRight;
-                 dTopRight    = dTopLeft;
-                 dTopLeft     = tmp;
-                 tmp          = dBottomRight;
-                 dBottomRight = dBottomLeft;
-                 dBottomLeft  = tmp;
-                 dstxinc = dstxinc *-1;
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_MIRRORUPDOWN) {
-                 tmp          = dTopLeft;
-                 dTopLeft     = dBottomLeft;
-                 dBottomLeft  = tmp;
-                 tmp          = dTopRight;
-                 dTopRight    = dBottomRight;
-                 dBottomRight = tmp;
-                 dstyinc = dstyinc *-1;
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_NOTEARING) {
-                 /* I don't think we need to do anything about this flag */
-                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_NOTEARING\n");
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE180) {
-                 tmp          = dBottomRight;
-                 dBottomRight = dTopLeft;
-                 dTopLeft     = tmp;
-                 tmp          = dBottomLeft;
-                 dBottomLeft  = dTopRight;
-                 dTopRight    = tmp;
-                 dstxinc = dstxinc * -1;
-                 dstyinc = dstyinc * -1;
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE270) {
-                 tmp          = dTopLeft;
-                 dTopLeft     = dBottomLeft;
-                 dBottomLeft  = dBottomRight;
-                 dBottomRight = dTopRight;
-                 dTopRight    = tmp;
-                 tmpxy   = dstxinc;
-                 dstxinc = dstyinc;
-                 dstyinc = tmpxy;
-                 dstxinc = dstxinc * -1;
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE90) {
-                 tmp          = dTopLeft;
-                 dTopLeft     = dTopRight;
-                 dTopRight    = dBottomRight;
-                 dBottomRight = dBottomLeft;
-                 dBottomLeft  = tmp;
-                 tmpxy   = dstxinc;
-                 dstxinc = dstyinc;
-                 dstyinc = tmpxy;
-                 dstyinc = dstyinc * -1;
-              }
-              if (lpbltfx->dwDDFX & DDBLTFX_ZBUFFERBASEDEST) {
-                 /* I don't think we need to do anything about this flag */
-                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ZBUFFERBASEDEST\n");
-              }
-              dbuf = dTopLeft;
-              dwFlags &= ~(DDBLT_DDFX);
-           }
-
-#define COPY_COLORKEY_FX(type) { \
-	    type *s, *d = (type *) dbuf, *dx, tmp; \
-            for (y = sy = 0; y < dstheight; y++, sy += yinc) { \
-               s = (type*)(sbase + (sy >> 16) * sdesc.u1.lPitch); \
-               dx = d; \
-	       for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
-		  tmp = s[sx >> 16]; \
-		  if ((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) dx[0] = tmp; \
-                  dx = (type*)(((LPBYTE)dx)+dstxinc); \
-	       } \
-               d = (type*)(((LPBYTE)d)+dstyinc); \
-	    } \
-            break; }
-
-	    switch (bpp) {
-	    case 1: COPY_COLORKEY_FX(BYTE)
-	    case 2: COPY_COLORKEY_FX(WORD)
-	    case 4: COPY_COLORKEY_FX(DWORD)
- 	    case 3: {LPBYTE s,d = dbuf, dx;
-		for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-		    sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;
-		    dx = d;
-		    for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
-			DWORD pixel;
-			s = sbuf+3*(sx>>16);
-			pixel = s[0]|(s[1]<<8)|(s[2]<<16);
-                        if ((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) {
-		            dx[0] = (pixel    )&0xff;
-			    dx[1] = (pixel>> 8)&0xff;
-			    dx[2] = (pixel>>16)&0xff;
-                        }
-		        dx+= dstxinc;
-		    }
-		    d += dstyinc;
-                }
-                break;}
-	    default:
-	       FIXME("%s color-keyed blit not implemented for bpp %d!\n",
-	          (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
-		  ret = DDERR_UNSUPPORTED;
-		  goto error;
-#undef COPY_COLORKEY_FX
-            }
-	}
-    }
-
-error:
-    if (dwFlags && FIXME_ON(ddraw)) {
-	FIXME("\tUnsupported flags: ");
-	DDRAW_dump_DDBLT(dwFlags);
-    }
-
-release:
-    IDirectDrawSurface7_Unlock(iface,NULL);
-    if (src && src != iface) IDirectDrawSurface7_Unlock(src,NULL);
-    return ret;
-}
-
-/* BltBatch: generic, unimplemented */
-
-HRESULT WINAPI
-DIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx,
-			      DWORD dsty, LPDIRECTDRAWSURFACE7 src,
-			      LPRECT rsrc, DWORD trans)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    int			bpp, w, h, x, y;
-    DDSURFACEDESC2	ddesc,sdesc;
-    HRESULT		ret = DD_OK;
-    LPBYTE		sbuf, dbuf;
-    RECT		rsrc2;
-    RECT                lock_src, lock_dst, lock_union;
-
-    if (TRACE_ON(ddraw)) {
-	TRACE("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
-		This,dstx,dsty,src,rsrc,trans
-	);
-	TRACE("\ttrans:");
-	if (FIXME_ON(ddraw))
-	  DDRAW_dump_DDBLTFAST(trans);
-	if (rsrc)
-	  TRACE("\tsrcrect: %ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	else
-	  TRACE(" srcrect: NULL\n");
-    }
-
-    if ((This->locked) || ((src != NULL) && (((IDirectDrawSurfaceImpl *)src)->locked))) {
-        WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
-        return DDERR_SURFACEBUSY;
-    }
-
-    /* First, check if the possible override function handles this case */
-    if (This->aux_bltfast != NULL) {
-        if (This->aux_bltfast(This, dstx, dsty, src, rsrc, trans) == DD_OK) return DD_OK;
-    }
-
-    /* Get the surface description without locking to first compute the width / height */
-    ddesc = This->surface_desc;
-    sdesc = (ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src))->surface_desc;
-
-    if (!rsrc) {
-	WARN("rsrc is NULL!\n");
-	rsrc = &rsrc2;
-	rsrc->left = rsrc->top = 0;
-	rsrc->right = sdesc.dwWidth;
-	rsrc->bottom = sdesc.dwHeight;
-    }
-
-    /* Check source rect for validity. Copied from normal Blt. Fixes Baldur's Gate.*/
-    if ((rsrc->bottom > sdesc.dwHeight) || (rsrc->bottom < 0) ||
-	(rsrc->top > sdesc.dwHeight) || (rsrc->top < 0) ||
-	(rsrc->left > sdesc.dwWidth) || (rsrc->left < 0) ||
-	(rsrc->right > sdesc.dwWidth) || (rsrc->right < 0) ||
-	(rsrc->right < rsrc->left) || (rsrc->bottom < rsrc->top)) {
-        WARN("Application gave us bad source rectangle for BltFast.\n");
-	return DDERR_INVALIDRECT;
-    }
- 
-    h=rsrc->bottom-rsrc->top;
-    if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
-    if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
-    if (h<=0) return DDERR_INVALIDRECT;
-
-    w=rsrc->right-rsrc->left;
-    if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
-    if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
-    if (w<=0) return DDERR_INVALIDRECT;
-
-    /* Now compute the locking rectangle... */
-    lock_src.left = rsrc->left;
-    lock_src.top = rsrc->top;
-    lock_src.right = lock_src.left + w;
-    lock_src.bottom = lock_src.top + h;
-
-    lock_dst.left = dstx;
-    lock_dst.top = dsty;
-    lock_dst.right = dstx + w;
-    lock_dst.bottom = dsty + h;
-    
-    bpp = GET_BPP(This->surface_desc);
-
-    /* We need to lock the surfaces, or we won't get refreshes when done. */
-    if (src == iface) {
-        int pitch;
-
-        UnionRect(&lock_union, &lock_src, &lock_dst);
-
-        /* Lock the union of the two rectangles */
-        IDirectDrawSurface7_Lock(iface, &lock_union, &ddesc, 0, 0);
-
-        pitch = This->surface_desc.u1.lPitch;
-
-        /* Since sdesc was originally copied from this surface's description, we can just reuse it */
-        sdesc.lpSurface = (BYTE *)This->surface_desc.lpSurface + lock_src.top * pitch + lock_src.left * bpp; 
-        ddesc.lpSurface = (BYTE *)This->surface_desc.lpSurface + lock_dst.top * pitch + lock_dst.left * bpp; 
-    } else {
-        sdesc.dwSize = sizeof(sdesc);
-        IDirectDrawSurface7_Lock(src, &lock_src, &sdesc, DDLOCK_READONLY, 0);
-        ddesc.dwSize = sizeof(ddesc);
-        IDirectDrawSurface7_Lock(iface, &lock_dst, &ddesc, DDLOCK_WRITEONLY, 0);
-    }
-
-    /* Handle first the FOURCC surfaces... */
-    if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && (ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) {
-	if (trans)
-	    FIXME("trans arg not supported when a FOURCC surface is involved\n");
-	if (dstx || dsty)
-	    FIXME("offset for destination surface is not supported\n");
-	if (sdesc.u4.ddpfPixelFormat.dwFourCC != sdesc.u4.ddpfPixelFormat.dwFourCC) {
-	    FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
-	    ret = DDERR_INVALIDPIXELFORMAT;
-	    goto error;
-	}
-	memcpy(ddesc.lpSurface, sdesc.lpSurface, ddesc.u1.dwLinearSize);
-	goto error;
-    }
-    if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
-	(!(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC))) {
-	DoDXTCDecompression(&sdesc, &ddesc);
-	goto error;
-    }
-    
-    sbuf = (BYTE *) sdesc.lpSurface;
-    dbuf = (BYTE *) ddesc.lpSurface;
-    
-    if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
-	DWORD keylow, keyhigh;
-	if (trans & DDBLTFAST_SRCCOLORKEY) {
-	    keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
-	    keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
-	} else {
-	    /* I'm not sure if this is correct */
-	    FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
-	    keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
-	    keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
-	}
-
-#define COPYBOX_COLORKEY(type) { \
-            type *d, *s, tmp; \
-            s = (type *) sdesc.lpSurface; \
-            d = (type *) ddesc.lpSurface; \
-            for (y = 0; y < h; y++) { \
-	        for (x = 0; x < w; x++) { \
-	            tmp = s[x]; \
-	            if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
-	        } \
-	        s = (type *)((BYTE *)s + sdesc.u1.lPitch); \
-	        d = (type *)((BYTE *)d + ddesc.u1.lPitch); \
-            } \
-            break; \
-        }
-
-        switch (bpp) {
-	    case 1: COPYBOX_COLORKEY(BYTE)
-	    case 2: COPYBOX_COLORKEY(WORD)
-	    case 4: COPYBOX_COLORKEY(DWORD)
-	    case 3:
-            {
-                BYTE *d, *s;
-                DWORD tmp;
-                s = (BYTE *) sdesc.lpSurface;
-                d = (BYTE *) ddesc.lpSurface;
-                for (y = 0; y < h; y++) {
-                    for (x = 0; x < w * 3; x += 3) {
-                        tmp = (DWORD)s[x] + ((DWORD)s[x + 1] << 8) + ((DWORD)s[x + 2] << 16);
-                        if (tmp < keylow || tmp > keyhigh) {
-                            d[x + 0] = s[x + 0];
-                            d[x + 1] = s[x + 1];
-                            d[x + 2] = s[x + 2];
-                        }
-                    }
-                    s += sdesc.u1.lPitch;
-                    d += ddesc.u1.lPitch;
-                }
-                break;
-            }
-	    default:
-		FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
-	        ret = DDERR_UNSUPPORTED;
-	        goto error;
-	}
-#undef COPYBOX_COLORKEY
-    } else {
-	int width = w * bpp;
-
-	for (y = 0; y < h; y++) {
-	    memcpy(dbuf, sbuf, width);
-	    sbuf += sdesc.u1.lPitch;
-	    dbuf += ddesc.u1.lPitch;
-	}
-    }
-    
-error:
-    if (src == iface) {
-        IDirectDrawSurface7_Unlock(iface, &lock_union);
-    } else {
-        IDirectDrawSurface7_Unlock(iface, &lock_dst);
-        IDirectDrawSurface7_Unlock(src, &lock_src);
-    }
-
-    return ret;
-}
-
-/* ChangeUniquenessValue: generic */
-/* DeleteAttachedSurface: generic */
-/* EnumAttachedSurfaces: generic */
-/* EnumOverlayZOrders: generic, unimplemented */
-
-BOOL DIB_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				     IDirectDrawSurfaceImpl* back,
-				     DWORD dwFlags)
-{
-    DIB_DirectDrawSurfaceImpl* front_priv = front->private;
-    DIB_DirectDrawSurfaceImpl* back_priv = back->private;
-
-    TRACE("(%p,%p)\n",front,back);
-
-    {
-	HBITMAP tmp;
-	tmp = front_priv->dib.DIBsection;
-	front_priv->dib.DIBsection = back_priv->dib.DIBsection;
-	back_priv->dib.DIBsection = tmp;
-    }
-
-    {
-	void* tmp;
-	tmp = front_priv->dib.bitmap_data;
-	front_priv->dib.bitmap_data = back_priv->dib.bitmap_data;
-	back_priv->dib.bitmap_data = tmp;
-
-	tmp = front->surface_desc.lpSurface;
-	front->surface_desc.lpSurface = back->surface_desc.lpSurface;
-	back->surface_desc.lpSurface = tmp;
-    }
-
-    /* client_memory should not be different, but just in case */
-    {
-	BOOL tmp;
-	tmp = front_priv->dib.client_memory;
-	front_priv->dib.client_memory = back_priv->dib.client_memory;
-	back_priv->dib.client_memory = tmp;
-    }
-
-    return Main_DirectDrawSurface_flip_data(front, back, dwFlags);
-}
-
-/* Flip: generic */
-/* FreePrivateData: generic */
-/* GetAttachedSurface: generic */
-/* GetBltStatus: generic */
-/* GetCaps: generic (Returns the caps from This->surface_desc.) */
-/* GetClipper: generic */
-/* GetColorKey: generic */
-
-HRESULT DIB_DirectDrawSurface_alloc_dc(IDirectDrawSurfaceImpl* This, HDC* phDC)
-{
-    DIB_PRIV_VAR(priv, This);
-    HDC hDC;
-
-    TRACE("Grabbing a DC for surface: %p\n", This);
-
-    hDC = CreateCompatibleDC(0);
-    priv->dib.holdbitmap = SelectObject(hDC, priv->dib.DIBsection);
-    if (This->palette)
-	SelectPalette(hDC, This->palette->hpal, FALSE);
-
-    *phDC = hDC;
-
-    return S_OK;
-}
-
-HRESULT DIB_DirectDrawSurface_free_dc(IDirectDrawSurfaceImpl* This, HDC hDC)
-{
-    DIB_PRIV_VAR(priv, This);
-
-    TRACE("Releasing DC for surface: %p\n", This);
-
-    SelectObject(hDC, priv->dib.holdbitmap);
-    DeleteDC(hDC);
-
-    return S_OK;
-}
-
-HRESULT DIB_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC)
-{
-    return DIB_DirectDrawSurface_alloc_dc(This, phDC);
-}
-
-HRESULT DIB_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, HDC hDC)
-{
-    return DIB_DirectDrawSurface_free_dc(This, hDC);
-}
-
-/* GetDDInterface: generic */
-/* GetFlipStatus: generic */
-/* GetLOD: generic */
-/* GetOverlayPosition: generic */
-/* GetPalette: generic */
-/* GetPixelFormat: generic */
-/* GetPriority: generic */
-/* GetPrivateData: generic */
-/* GetSurfaceDesc: generic */
-/* GetUniquenessValue: generic */
-/* Initialize: generic */
-/* IsLost: generic */
-/* Lock: generic with callback? */
-/* PageLock: generic */
-/* PageUnlock: generic */
-
-HRESULT WINAPI
-DIB_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface)
-{
-    TRACE("(%p)\n",iface);
-    return DD_OK;	/* ??? */
-}
-
-/* SetClipper: generic */
-/* SetColorKey: generic */
-/* SetLOD: generic */
-/* SetOverlayPosition: generic */
-
-void DIB_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-				       IDirectDrawPaletteImpl* pal)
-{
-    if (!pal) return;
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-	This->update_palette(This, pal,
-			     0, pal->palNumEntries,
-			     pal->palents);
-}
-
-void DIB_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					  IDirectDrawPaletteImpl* pal,
-					  DWORD dwStart, DWORD dwCount,
-					  LPPALETTEENTRY palent)
-{
-    RGBQUAD col[256];
-    unsigned int n;
-    HDC dc;
-
-    TRACE("updating primary palette\n");
-    for (n=0; n<dwCount; n++) {
-      col[n].rgbRed   = palent[n].peRed;
-      col[n].rgbGreen = palent[n].peGreen;
-      col[n].rgbBlue  = palent[n].peBlue;
-      col[n].rgbReserved = 0;
-    }
-    This->get_dc(This, &dc);
-    SetDIBColorTable(dc, dwStart, dwCount, col);
-    This->release_dc(This, dc);
-
-    /* Propagate change to backbuffers if there are any */
-    /* Basically this is a modification of the Flip code to find the backbuffer */
-    /* and duplicate the palette update there as well */
-    if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	== (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-    {
-	static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
-	LPDIRECTDRAWSURFACE7 tgt;
-
-	HRESULT hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This,IDirectDrawSurface7),
-							    &back_caps, &tgt);
-	if (!FAILED(hr))
-	{
-	    IDirectDrawSurfaceImpl* target = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-							 IDirectDrawSurface7,tgt);
-	    IDirectDrawSurface7_Release(tgt);
-	    target->get_dc(target, &dc);
-	    SetDIBColorTable(dc, dwStart, dwCount, col);
-	    target->release_dc(target, dc);
-	}
-    }
-}
-
-/* SetPalette: generic */
-/* SetPriority: generic */
-/* SetPrivateData: generic */
-
-HRESULT WINAPI
-DIB_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
-				     LPDDSURFACEDESC2 pDDSD, DWORD dwFlags)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    DIB_PRIV_VAR(priv, This);
-    HRESULT hr = DD_OK;
-    DWORD flags = pDDSD->dwFlags;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE("(%p)->(%p,%08lx)\n",iface,pDDSD,dwFlags);
-        DDRAW_dump_surface_desc(pDDSD);
-    }
-
-    if (pDDSD->dwFlags & DDSD_PIXELFORMAT) {
-        flags &= ~DDSD_PIXELFORMAT;
-	if (flags & DDSD_LPSURFACE) {
-	    This->surface_desc.u4.ddpfPixelFormat = pDDSD->u4.ddpfPixelFormat;
-	} else {
-	    FIXME("Change of pixel format without surface re-allocation is not supported !\n");
-	}
-    }
-    if (pDDSD->dwFlags & DDSD_LPSURFACE) {
-	HBITMAP oldbmp = priv->dib.DIBsection;
-	LPVOID oldsurf = This->surface_desc.lpSurface;
-	BOOL oldc = priv->dib.client_memory;
-
-	flags &= ~DDSD_LPSURFACE;
-
-	TRACE("new lpSurface=%p\n",pDDSD->lpSurface);
-	This->surface_desc.lpSurface = pDDSD->lpSurface;
-	priv->dib.client_memory = TRUE;
-
-	hr = create_dib(This);
-	if (FAILED(hr))
-	{
-	    priv->dib.DIBsection = oldbmp;
-	    This->surface_desc.lpSurface = oldsurf;
-	    priv->dib.client_memory = oldc;
-	    return hr;
-	}
-
-	DeleteObject(oldbmp);
-
-	if (!oldc)
-	    VirtualFree(oldsurf, 0, MEM_RELEASE);
-    }
-    if (flags) {
-        WARN("Unhandled flags : %08lx\n", flags);
-    }
-    return hr;
-}
-
-/* Unlock: ???, need callback */
-/* UpdateOverlay: generic */
-/* UpdateOverlayDisplay: generic */
-/* UpdateOverlayZOrder: generic */
-
-static const IDirectDrawSurface7Vtbl DIB_IDirectDrawSurface7_VTable =
-{
-    Main_DirectDrawSurface_QueryInterface,
-    Main_DirectDrawSurface_AddRef,
-    Main_DirectDrawSurface_Release,
-    Main_DirectDrawSurface_AddAttachedSurface,
-    Main_DirectDrawSurface_AddOverlayDirtyRect,
-    DIB_DirectDrawSurface_Blt,
-    Main_DirectDrawSurface_BltBatch,
-    DIB_DirectDrawSurface_BltFast,
-    Main_DirectDrawSurface_DeleteAttachedSurface,
-    Main_DirectDrawSurface_EnumAttachedSurfaces,
-    Main_DirectDrawSurface_EnumOverlayZOrders,
-    Main_DirectDrawSurface_Flip,
-    Main_DirectDrawSurface_GetAttachedSurface,
-    Main_DirectDrawSurface_GetBltStatus,
-    Main_DirectDrawSurface_GetCaps,
-    Main_DirectDrawSurface_GetClipper,
-    Main_DirectDrawSurface_GetColorKey,
-    Main_DirectDrawSurface_GetDC,
-    Main_DirectDrawSurface_GetFlipStatus,
-    Main_DirectDrawSurface_GetOverlayPosition,
-    Main_DirectDrawSurface_GetPalette,
-    Main_DirectDrawSurface_GetPixelFormat,
-    Main_DirectDrawSurface_GetSurfaceDesc,
-    Main_DirectDrawSurface_Initialize,
-    Main_DirectDrawSurface_IsLost,
-    Main_DirectDrawSurface_Lock,
-    Main_DirectDrawSurface_ReleaseDC,
-    DIB_DirectDrawSurface_Restore,
-    Main_DirectDrawSurface_SetClipper,
-    Main_DirectDrawSurface_SetColorKey,
-    Main_DirectDrawSurface_SetOverlayPosition,
-    Main_DirectDrawSurface_SetPalette,
-    Main_DirectDrawSurface_Unlock,
-    Main_DirectDrawSurface_UpdateOverlay,
-    Main_DirectDrawSurface_UpdateOverlayDisplay,
-    Main_DirectDrawSurface_UpdateOverlayZOrder,
-    Main_DirectDrawSurface_GetDDInterface,
-    Main_DirectDrawSurface_PageLock,
-    Main_DirectDrawSurface_PageUnlock,
-    DIB_DirectDrawSurface_SetSurfaceDesc,
-    Main_DirectDrawSurface_SetPrivateData,
-    Main_DirectDrawSurface_GetPrivateData,
-    Main_DirectDrawSurface_FreePrivateData,
-    Main_DirectDrawSurface_GetUniquenessValue,
-    Main_DirectDrawSurface_ChangeUniquenessValue,
-    Main_DirectDrawSurface_SetPriority,
-    Main_DirectDrawSurface_GetPriority,
-    Main_DirectDrawSurface_SetLOD,
-    Main_DirectDrawSurface_GetLOD
-};
diff --git a/dlls/ddraw/surface_fakezbuffer.c b/dlls/ddraw/surface_fakezbuffer.c
deleted file mode 100644
index e021bb1..0000000
--- a/dlls/ddraw/surface_fakezbuffer.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*		DirectDraw/Direct3D Z-Buffer stand in
- *
- * Copyright 2000 TransGaming Technologies Inc.
- *
- * This class provides a DirectDrawSurface implementation that represents
- * a Z-Buffer surface. However it does not store an image and does not
- * support Lock/Unlock or GetDC. It is merely a placeholder required by the
- * Direct3D architecture.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "ddraw.h"
-#include "d3d.h"
-
-#include "wine/debug.h"
-
-#include "ddcomimpl.h"
-#include "ddraw_private.h"
-#include "d3d_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static const IDirectDrawSurface7Vtbl FakeZBuffer_IDirectDrawSurface7_VTable;
-
-#ifdef HAVE_OPENGL
-static void zbuffer_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
-{
-    /* Note that this does not do anything for now... At least it's not needed for Grim Fandango :-) */
-}
-
-static void zbuffer_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
-{
-    ((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = TRUE;
-}
-
-static BOOLEAN zbuffer_get_dirty_status(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
-{
-    if (((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory) {
-	((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = FALSE;
-	return TRUE;
-    }
-    return FALSE;
-}
-#endif
-
-HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
-						IDirectDrawImpl *pDD,
-						const DDSURFACEDESC2 *pDDSD)
-{
-    HRESULT hr;
-    BYTE zdepth = 16; /* Default value.. Should use the one from GL */
-    
-    assert(pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER);
-
-    hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr)) return hr;
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
-			FakeZBuffer_IDirectDrawSurface7_VTable);
-
-    This->final_release = FakeZBuffer_DirectDrawSurface_final_release;
-    This->duplicate_surface = FakeZBuffer_DirectDrawSurface_duplicate_surface;
-
-#ifdef HAVE_OPENGL     
-    if (opengl_initialized) {
-	This->lock_update = zbuffer_lock_update;
-	This->unlock_update = zbuffer_unlock_update;
-	This->get_dirty_status = zbuffer_get_dirty_status;
-    }
-#endif
-	
-    
-    /* Beginning of some D3D hacks :-) */
-    if (This->surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
-	zdepth = This->surface_desc.u2.dwMipMapCount; /* This is where the Z buffer depth is stored in 'old' versions */
-    }
-    
-    if ((This->surface_desc.dwFlags & DDSD_PIXELFORMAT) == 0) {
-	This->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
-	This->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(This->surface_desc.u4.ddpfPixelFormat);
-	This->surface_desc.u4.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
-	This->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth = zdepth;
-    }
-    if ((This->surface_desc.dwFlags & DDSD_PITCH) == 0) {
-	This->surface_desc.dwFlags |= DDSD_PITCH;
-	This->surface_desc.u1.lPitch = ((zdepth + 7) / 8) * This->surface_desc.dwWidth;
-    }
-    This->surface_desc.lpSurface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-					     This->surface_desc.u1.lPitch * This->surface_desc.dwHeight);
-    
-    return DD_OK;
-}
-
-/* Not an API */
-HRESULT FakeZBuffer_DirectDrawSurface_Create(IDirectDrawImpl* pDD,
-					     const DDSURFACEDESC2* pDDSD,
-					     LPDIRECTDRAWSURFACE7* ppSurf,
-					     IUnknown* pUnkOuter)
-{
-    IDirectDrawSurfaceImpl* This;
-    HRESULT hr;
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(*This)
-		     + sizeof(FakeZBuffer_DirectDrawSurfaceImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    This->private = (FakeZBuffer_DirectDrawSurfaceImpl*)(This+1);
-
-    hr = FakeZBuffer_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
-
-    return hr;
-}
-
-void
-FakeZBuffer_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
-{
-    Main_DirectDrawSurface_final_release(This);
-}
-
-HRESULT
-FakeZBuffer_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						LPDIRECTDRAWSURFACE7* ppDup)
-{
-    return FakeZBuffer_DirectDrawSurface_Create(This->ddraw_owner,
-						&This->surface_desc, ppDup,
-						NULL);
-}
-
-/* put your breakpoint/abort call here */
-static HRESULT cant_do_that(const char *s)
-{
-    FIXME("attempt to %s fake z-buffer\n", s);
-    return DDERR_UNSUPPORTED;
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,
-				  LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
-				  DWORD dwFlags, LPDDBLTFX lpbltfx)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
-	if (rdst) TRACE("\tdestrect :%ldx%ld-%ldx%ld\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
-	if (rsrc) TRACE("\tsrcrect  :%ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	TRACE("\tflags: ");
-	DDRAW_dump_DDBLT(dwFlags);
-	if (dwFlags & DDBLT_DDFX) {
-	    TRACE("\tblitfx: ");
-	    DDRAW_dump_DDBLTFX(lpbltfx->dwDDFX);
-	}
-    }
-
-    /* We only support the BLT with DEPTH_FILL for now */
-    if ((dwFlags & DDBLT_DEPTHFILL) && (This->ddraw_owner->d3d_private != NULL)) {
-        if (This->ddraw_owner->current_device != NULL) {
-	    D3DRECT rect;
-	    if (rdst) {
-	        rect.u1.x1 = rdst->left;
-		rect.u2.y1 = rdst->top;
-		rect.u3.x2 = rdst->right;
-		rect.u4.y2 = rdst->bottom;
-	    }
-	    This->ddraw_owner->current_device->clear(This->ddraw_owner->current_device,
-						     (rdst == NULL ? 0 : 1), &rect,
-						     D3DCLEAR_ZBUFFER,
-						     0x00000000,
-						     ((double) lpbltfx->u5.dwFillDepth) / 4294967295.0,
-						     0x00000000);
-	    return DD_OK;
-	}
-    }
-
-    return cant_do_that("blt to a");
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx,
-				      DWORD dsty, LPDIRECTDRAWSURFACE7 src,
-				      LPRECT rsrc, DWORD trans)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    if (TRACE_ON(ddraw)) {
-	FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
-		This,dstx,dsty,src,rsrc,trans
-	);
-	FIXME("\ttrans:");
-	if (FIXME_ON(ddraw))
-	  DDRAW_dump_DDBLTFAST(trans);
-	if (rsrc)
-	  FIXME("\tsrcrect: %ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	else
-	  FIXME(" srcrect: NULL\n");
-    }
-
-    return cant_do_that("bltfast to a");
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
-{
-    return cant_do_that("get a DC for a");
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
-{
-    return cant_do_that("release a DC for a");
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface)
-{
-    return DD_OK;
-}
-
-HRESULT WINAPI
-FakeZBuffer_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
-					     LPDDSURFACEDESC2 pDDSD,
-					     DWORD dwFlags)
-{
-    /* XXX */
-    abort();
-    return E_FAIL;
-}
-
-
-static const IDirectDrawSurface7Vtbl FakeZBuffer_IDirectDrawSurface7_VTable=
-{
-    Main_DirectDrawSurface_QueryInterface,
-    Main_DirectDrawSurface_AddRef,
-    Main_DirectDrawSurface_Release,
-    Main_DirectDrawSurface_AddAttachedSurface,
-    Main_DirectDrawSurface_AddOverlayDirtyRect,
-    FakeZBuffer_DirectDrawSurface_Blt,
-    Main_DirectDrawSurface_BltBatch,
-    FakeZBuffer_DirectDrawSurface_BltFast,
-    Main_DirectDrawSurface_DeleteAttachedSurface,
-    Main_DirectDrawSurface_EnumAttachedSurfaces,
-    Main_DirectDrawSurface_EnumOverlayZOrders,
-    Main_DirectDrawSurface_Flip,
-    Main_DirectDrawSurface_GetAttachedSurface,
-    Main_DirectDrawSurface_GetBltStatus,
-    Main_DirectDrawSurface_GetCaps,
-    Main_DirectDrawSurface_GetClipper,
-    Main_DirectDrawSurface_GetColorKey,
-    FakeZBuffer_DirectDrawSurface_GetDC,
-    Main_DirectDrawSurface_GetFlipStatus,
-    Main_DirectDrawSurface_GetOverlayPosition,
-    Main_DirectDrawSurface_GetPalette,
-    Main_DirectDrawSurface_GetPixelFormat,
-    Main_DirectDrawSurface_GetSurfaceDesc,
-    Main_DirectDrawSurface_Initialize,
-    Main_DirectDrawSurface_IsLost,
-    Main_DirectDrawSurface_Lock,
-    FakeZBuffer_DirectDrawSurface_ReleaseDC,
-    FakeZBuffer_DirectDrawSurface_Restore,
-    Main_DirectDrawSurface_SetClipper,
-    Main_DirectDrawSurface_SetColorKey,
-    Main_DirectDrawSurface_SetOverlayPosition,
-    Main_DirectDrawSurface_SetPalette,
-    Main_DirectDrawSurface_Unlock,
-    Main_DirectDrawSurface_UpdateOverlay,
-    Main_DirectDrawSurface_UpdateOverlayDisplay,
-    Main_DirectDrawSurface_UpdateOverlayZOrder,
-    Main_DirectDrawSurface_GetDDInterface,
-    Main_DirectDrawSurface_PageLock,
-    Main_DirectDrawSurface_PageUnlock,
-    FakeZBuffer_DirectDrawSurface_SetSurfaceDesc,
-    Main_DirectDrawSurface_SetPrivateData,
-    Main_DirectDrawSurface_GetPrivateData,
-    Main_DirectDrawSurface_FreePrivateData,
-    Main_DirectDrawSurface_GetUniquenessValue,
-    Main_DirectDrawSurface_ChangeUniquenessValue,
-    Main_DirectDrawSurface_SetPriority,
-    Main_DirectDrawSurface_GetPriority,
-    Main_DirectDrawSurface_SetLOD,
-    Main_DirectDrawSurface_GetLOD
-};
diff --git a/dlls/ddraw/surface_gamma.c b/dlls/ddraw/surface_gamma.c
deleted file mode 100644
index 4e5f16c..0000000
--- a/dlls/ddraw/surface_gamma.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*		DirectDrawGammaControl implementation
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "winerror.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "wine/debug.h"
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-#define CONVERT(pddgc) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,	\
-					  IDirectDrawGammaControl,	\
-					  IDirectDrawSurface7,		\
-					  (pddgc))
-
-static HRESULT WINAPI
-DirectDrawGammaControl_QueryInterface(LPDIRECTDRAWGAMMACONTROL iface, REFIID riid,
-				      LPVOID *ppObj)
-{
-    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppObj);
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-DirectDrawGammaControl_AddRef(LPDIRECTDRAWGAMMACONTROL iface)
-{
-    return IDirectDrawSurface7_AddRef(CONVERT(iface));
-}
-
-static ULONG WINAPI
-DirectDrawGammaControl_Release(LPDIRECTDRAWGAMMACONTROL iface)
-{
-    return IDirectDrawSurface7_Release(CONVERT(iface));
-}
-
-static HRESULT WINAPI
-DirectDrawGammaControl_GetGammaRamp(LPDIRECTDRAWGAMMACONTROL iface, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
-    TRACE("(%p)->(%08lx,%p)\n", iface,dwFlags,lpGammaRamp);
-    return This->get_gamma_ramp(This, dwFlags, lpGammaRamp);
-}
-
-static HRESULT WINAPI
-DirectDrawGammaControl_SetGammaRamp(LPDIRECTDRAWGAMMACONTROL iface, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface);
-    TRACE("(%p)->(%08lx,%p)\n", iface,dwFlags,lpGammaRamp);
-    return This->set_gamma_ramp(This, dwFlags, lpGammaRamp);
-}
-
-const IDirectDrawGammaControlVtbl DDRAW_IDDGC_VTable =
-{
-    DirectDrawGammaControl_QueryInterface,
-    DirectDrawGammaControl_AddRef,
-    DirectDrawGammaControl_Release,
-    DirectDrawGammaControl_GetGammaRamp,
-    DirectDrawGammaControl_SetGammaRamp
-};
diff --git a/dlls/ddraw/surface_hal.c b/dlls/ddraw/surface_hal.c
deleted file mode 100644
index 1cd9455..0000000
--- a/dlls/ddraw/surface_hal.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*	DirectDrawSurface 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "wine/debug.h"
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static const IDirectDrawSurface7Vtbl HAL_IDirectDrawSurface7_VTable;
-
-static HRESULT HAL_DirectDrawSurface_create_surface(IDirectDrawSurfaceImpl* This,
-						    IDirectDrawImpl* pDD)
-{
-    HAL_PRIV_VAR(priv, This);
-    HAL_DDRAW_PRIV_VAR(ddpriv, pDD);
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
-    LPDDRAWI_DDRAWSURFACE_LCL local = &This->local;
-    DDHAL_CREATESURFACEDATA data;
-    HRESULT hr;
-
-    data.lpDD = dd_gbl;
-    data.lpDDSurfaceDesc = (LPDDSURFACEDESC)&This->surface_desc;
-    data.lplpSList = &local;
-    data.dwSCnt = 1;
-    data.ddRVal = 0;
-    data.CreateSurface = dd_gbl->lpDDCBtmp->HALDD.CreateSurface;
-    hr = data.CreateSurface(&data);
-
-    if (hr == DDHAL_DRIVER_HANDLED) {
-	if (This->global.fpVidMem < 4) {
-	    /* grab framebuffer data from current_mode */
-	    priv->hal.fb_pitch = dd_gbl->vmiData.lDisplayPitch;
-	    priv->hal.fb_vofs  = ddpriv->hal.next_vofs;
-	    priv->hal.fb_addr  = ((LPBYTE)dd_gbl->vmiData.fpPrimary) +
-				 dd_gbl->vmiData.lDisplayPitch * priv->hal.fb_vofs;
-	    TRACE("vofs=%ld, addr=%p\n", priv->hal.fb_vofs, priv->hal.fb_addr);
-	    ddpriv->hal.next_vofs += This->surface_desc.dwHeight;
-
-	    This->global.fpVidMem = (FLATPTR)priv->hal.fb_addr;
-	    This->global.u4.lPitch = priv->hal.fb_pitch;
-	}
-	This->surface_desc.lpSurface = (LPVOID)This->global.fpVidMem;
-	This->surface_desc.dwFlags |= DDSD_LPSURFACE;
-	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
-	    This->surface_desc.u1.dwLinearSize = This->global.u4.dwLinearSize;
-	    This->surface_desc.dwFlags |= DDSD_LINEARSIZE;
-	} else {
-	    This->surface_desc.u1.lPitch = This->global.u4.lPitch;
-	    This->surface_desc.dwFlags |= DDSD_PITCH;
-	}
-    }
-    else priv->hal.need_late = TRUE;
-
-    return data.ddRVal;
-}
-
-static inline BOOL HAL_IsUser(IDirectDrawSurfaceImpl* This)
-{
-    HAL_PRIV_VAR(priv, This);
-    if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_EXECUTEBUFFER))
-	return FALSE;
-    if (priv->hal.fb_addr)
-	return FALSE;
-    return TRUE;
-}
-
-HRESULT
-HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-				IDirectDrawImpl* pDD,
-				const DDSURFACEDESC2* pDDSD)
-{
-    HAL_PRIV_VAR(priv, This);
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
-    HRESULT hr;
-
-    TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);
-
-    /* copy surface_desc, we may want to modify it before DIB construction */
-    This->surface_desc = *pDDSD;
-
-    /* the driver may want to dereference these pointers */
-    This->local.lpSurfMore = &This->more;
-    This->local.lpGbl = &This->global;
-    This->gmore = &This->global_more;
-
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
-	hr = HAL_DirectDrawSurface_create_surface(This, pDD);
-	if (FAILED(hr)) return hr;
-
-	hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
-	if (FAILED(hr)) return hr;
-    }
-    else if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
-	FIXME("create execute buffer\n");
-	return DDERR_GENERIC;
-    }
-    else {
-	if (!(dd_gbl->dwFlags & DDRAWI_MODECHANGED)) {
-	    /* force a mode set (HALs like DGA may need it) */
-	    hr = HAL_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD, IDirectDraw7),
-					       pDD->width, pDD->height,
-					       pDD->pixelformat.u1.dwRGBBitCount,
-					       0, 0);
-	    if (FAILED(hr)) return hr;
-	}
-
-	if (dd_gbl->vmiData.fpPrimary) {
-	    hr = HAL_DirectDrawSurface_create_surface(This, pDD);
-	    if (FAILED(hr)) return hr;
-
-	    if (priv->hal.need_late) {
-		/* this doesn't make sense... driver error? */
-		ERR("driver failed to create framebuffer surface\n");
-		return DDERR_GENERIC;
-	    }
-
-	    hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
-	    if (FAILED(hr)) return hr;
-	} else {
-	    /* no framebuffer, construct User-based primary */
-	    hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD);
-	    if (FAILED(hr)) return hr;
-
-	    /* must notify HAL *after* creating User-based primary */
-	    /* (or use CreateSurfaceEx, which we don't yet) */
-	    hr = HAL_DirectDrawSurface_create_surface(This, pDD);
-	    if (FAILED(hr)) return hr;
-
-	    priv->hal.need_late = FALSE;
-	}
-    }
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
-			HAL_IDirectDrawSurface7_VTable);
-
-    This->final_release = HAL_DirectDrawSurface_final_release;
-    This->late_allocate = HAL_DirectDrawSurface_late_allocate;
-    This->duplicate_surface = HAL_DirectDrawSurface_duplicate_surface;
-
-    This->flip_data   = HAL_DirectDrawSurface_flip_data;
-    This->flip_update = HAL_DirectDrawSurface_flip_update;
-
-    This->set_palette    = HAL_DirectDrawSurface_set_palette;
-
-    This->get_display_window = HAL_DirectDrawSurface_get_display_window;
-
-    return DD_OK;
-}
-
-HRESULT
-HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-			     const DDSURFACEDESC2 *pDDSD,
-			     LPDIRECTDRAWSURFACE7 *ppSurf,
-			     IUnknown *pUnkOuter)
-{
-    IDirectDrawSurfaceImpl* This;
-    HRESULT hr;
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(*This) + sizeof(HAL_DirectDrawSurfaceImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    This->private = (HAL_DirectDrawSurfaceImpl*)(This+1);
-
-    hr = HAL_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
-
-    return hr;
-}
-
-void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
-    DDHAL_DESTROYSURFACEDATA data;
-
-    /* destroy HAL surface */
-    data.lpDD = dd_gbl;
-    data.lpDDSurface = &This->local;
-    data.ddRVal = 0;
-    data.DestroySurface = dd_gbl->lpDDCBtmp->HALDDSurface.DestroySurface;
-    data.DestroySurface(&data);
-
-    if (HAL_IsUser(This)) {
-	User_DirectDrawSurface_final_release(This);
-    } else {
-	DIB_DirectDrawSurface_final_release(This);
-    }
-}
-
-HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
-{
-    HAL_PRIV_VAR(priv, This);
-    if (priv->hal.need_late) {
-	priv->hal.need_late = FALSE;
-	return HAL_DirectDrawSurface_create_surface(This, This->ddraw_owner);
-    }
-    return DD_OK;
-}
-
-void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-				       IDirectDrawPaletteImpl* pal)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
-    DDHAL_SETPALETTEDATA data;
-
-    DIB_DirectDrawSurface_set_palette(This, pal);
-    data.lpDD = dd_gbl;
-    data.lpDDSurface = &This->local;
-    data.lpDDPalette = (pal != NULL ? &pal->global : NULL);
-    data.ddRVal = 0;
-    data.Attach = TRUE; /* what's this? */
-    data.SetPalette = dd_gbl->lpDDCBtmp->HALDDSurface.SetPalette;
-    if (data.SetPalette)
-	data.SetPalette(&data);
-}
-
-HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						LPDIRECTDRAWSURFACE7* ppDup)
-{
-    return HAL_DirectDrawSurface_Create(This->ddraw_owner,
-					     &This->surface_desc, ppDup, NULL);
-}
-
-void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
-				       LPCRECT pRect, DWORD dwFlags)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
-    DDHAL_LOCKDATA	data;
-
-    data.lpDD		= dd_gbl;
-    data.lpDDSurface	= &This->local;
-    data.ddRVal		= 0;
-    data.lpSurfData	= This->surface_desc.lpSurface; /* FIXME: correct? */
-    if (pRect) {
-	data.rArea.top	= pRect->top;
-	data.rArea.bottom	= pRect->bottom;
-	data.rArea.left	= pRect->left;
-	data.rArea.right	= pRect->right;
-	data.bHasRect 	= TRUE;
-    } else {
-	data.bHasRect 	= FALSE;
-    }
-    data.dwFlags	= dwFlags;
-
-    data.Lock		= dd_gbl->lpDDCBtmp->HALDDSurface.Lock;
-    if (data.Lock && (data.Lock(&data) == DDHAL_DRIVER_HANDLED))
-	return;
-
-    if (HAL_IsUser(This)) {
-	User_DirectDrawSurface_lock_update(This, pRect, dwFlags);
-    } else {
-	Main_DirectDrawSurface_lock_update(This, pRect, dwFlags);
-    }
-}
-
-void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-					 LPCRECT pRect)
-{
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
-    DDHAL_UNLOCKDATA	data;
-
-    data.lpDD		= dd_gbl;
-    data.lpDDSurface	= &This->local;
-    data.ddRVal		= 0;
-    data.Unlock		= dd_gbl->lpDDCBtmp->HALDDSurface.Unlock;
-    if (data.Unlock && (data.Unlock(&data) == DDHAL_DRIVER_HANDLED))
-	return;
-
-    if (HAL_IsUser(This)) {
-	User_DirectDrawSurface_unlock_update(This, pRect);
-    } else {
-	Main_DirectDrawSurface_unlock_update(This, pRect);
-    }
-}
-
-BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				     IDirectDrawSurfaceImpl* back,
-				     DWORD dwFlags)
-{
-    HAL_PRIV_VAR(front_priv, front);
-    HAL_PRIV_VAR(back_priv, back);
-    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = front->more.lpDD_lcl->lpGbl;
-    DDHAL_FLIPDATA data;
-    BOOL ret;
-
-    {
-	DWORD tmp;
-	tmp = front_priv->hal.fb_vofs;
-	front_priv->hal.fb_vofs = back_priv->hal.fb_vofs;
-	back_priv->hal.fb_vofs = tmp;
-    }
-    {
-	LPVOID tmp;
-	tmp = front_priv->hal.fb_addr;
-	front_priv->hal.fb_addr = back_priv->hal.fb_addr;
-	back_priv->hal.fb_addr = tmp;
-    }
-
-    if (HAL_IsUser(front)) {
-	ret = User_DirectDrawSurface_flip_data(front, back, dwFlags);
-    } else {
-	ret = DIB_DirectDrawSurface_flip_data(front, back, dwFlags);
-    }
-
-    TRACE("(%p,%p)\n",front,back);
-    data.lpDD = dd_gbl;
-    data.lpSurfCurr = &front->local;
-    data.lpSurfTarg = &back->local;
-    data.lpSurfCurrLeft = NULL;
-    data.lpSurfTargLeft = NULL;
-    data.dwFlags = dwFlags;
-    data.ddRVal = 0;
-    data.Flip = dd_gbl->lpDDCBtmp->HALDDSurface.Flip;
-    if (data.Flip)
-	if (data.Flip(&data) == DDHAL_DRIVER_HANDLED) ret = FALSE;
-
-    return ret;
-}
-
-void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags)
-{
-    if (HAL_IsUser(This)) {
-	User_DirectDrawSurface_flip_update(This, dwFlags);
-    }
-}
-
-HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
-{
-    return 0;
-}
-
-static const IDirectDrawSurface7Vtbl HAL_IDirectDrawSurface7_VTable =
-{
-    Main_DirectDrawSurface_QueryInterface,
-    Main_DirectDrawSurface_AddRef,
-    Main_DirectDrawSurface_Release,
-    Main_DirectDrawSurface_AddAttachedSurface,
-    Main_DirectDrawSurface_AddOverlayDirtyRect,
-    DIB_DirectDrawSurface_Blt,
-    Main_DirectDrawSurface_BltBatch,
-    DIB_DirectDrawSurface_BltFast,
-    Main_DirectDrawSurface_DeleteAttachedSurface,
-    Main_DirectDrawSurface_EnumAttachedSurfaces,
-    Main_DirectDrawSurface_EnumOverlayZOrders,
-    Main_DirectDrawSurface_Flip,
-    Main_DirectDrawSurface_GetAttachedSurface,
-    Main_DirectDrawSurface_GetBltStatus,
-    Main_DirectDrawSurface_GetCaps,
-    Main_DirectDrawSurface_GetClipper,
-    Main_DirectDrawSurface_GetColorKey,
-    Main_DirectDrawSurface_GetDC,
-    Main_DirectDrawSurface_GetFlipStatus,
-    Main_DirectDrawSurface_GetOverlayPosition,
-    Main_DirectDrawSurface_GetPalette,
-    Main_DirectDrawSurface_GetPixelFormat,
-    Main_DirectDrawSurface_GetSurfaceDesc,
-    Main_DirectDrawSurface_Initialize,
-    Main_DirectDrawSurface_IsLost,
-    Main_DirectDrawSurface_Lock,
-    Main_DirectDrawSurface_ReleaseDC,
-    DIB_DirectDrawSurface_Restore,
-    Main_DirectDrawSurface_SetClipper,
-    Main_DirectDrawSurface_SetColorKey,
-    Main_DirectDrawSurface_SetOverlayPosition,
-    Main_DirectDrawSurface_SetPalette,
-    Main_DirectDrawSurface_Unlock,
-    Main_DirectDrawSurface_UpdateOverlay,
-    Main_DirectDrawSurface_UpdateOverlayDisplay,
-    Main_DirectDrawSurface_UpdateOverlayZOrder,
-    Main_DirectDrawSurface_GetDDInterface,
-    Main_DirectDrawSurface_PageLock,
-    Main_DirectDrawSurface_PageUnlock,
-    DIB_DirectDrawSurface_SetSurfaceDesc,
-    Main_DirectDrawSurface_SetPrivateData,
-    Main_DirectDrawSurface_GetPrivateData,
-    Main_DirectDrawSurface_FreePrivateData,
-    Main_DirectDrawSurface_GetUniquenessValue,
-    Main_DirectDrawSurface_ChangeUniquenessValue,
-    Main_DirectDrawSurface_SetPriority,
-    Main_DirectDrawSurface_GetPriority,
-    Main_DirectDrawSurface_SetLOD,
-    Main_DirectDrawSurface_GetLOD
-};
diff --git a/dlls/ddraw/surface_main.c b/dlls/ddraw/surface_main.c
deleted file mode 100644
index 7045a99..0000000
--- a/dlls/ddraw/surface_main.c
+++ /dev/null
@@ -1,1516 +0,0 @@
-/*		DirectDrawSurface base implementation
- *
- * Copyright 1997-2000 Marcus Meissner
- * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
- * Copyright 2000-2001 TransGaming Technologies Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <string.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "wine/debug.h"
-#include "ddraw_private.h"
-#include "opengl_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps);
-
-/** Creation/Destruction functions */
-
-HRESULT
-Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
-				 IDirectDrawImpl *pDD,
-				 const DDSURFACEDESC2 *pDDSD)
-{
-    TRACE("(%p)->(%p,%p)\n", This, pDD, pDDSD);
-
-    if (pDDSD != &This->surface_desc) {
-	This->surface_desc.dwSize = sizeof(This->surface_desc);
-	DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD);
-    }
-    This->uniqueness_value = 1; /* unchecked */
-    This->ref = 1;
-
-    This->local.lpSurfMore = &This->more;
-    This->local.lpGbl = &This->global;
-    This->local.dwProcessId = GetCurrentProcessId();
-    This->local.dwFlags = 0; /* FIXME */
-    This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps;
-    /* FIXME: more local stuff */
-    This->more.lpDD_lcl = &pDD->local;
-    This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2;
-    This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3;
-    This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4;
-    /* FIXME: more more stuff */
-    This->gmore = &This->global_more;
-    This->global.u3.lpDD = pDD->local.lpGbl;
-    /* FIXME: more global stuff */
-
-    This->final_release = Main_DirectDrawSurface_final_release;
-    This->late_allocate = Main_DirectDrawSurface_late_allocate;
-    This->attach = Main_DirectDrawSurface_attach;
-    This->detach = Main_DirectDrawSurface_detach;
-    This->lock_update = Main_DirectDrawSurface_lock_update;
-    This->unlock_update = Main_DirectDrawSurface_unlock_update;
-    This->lose_surface = Main_DirectDrawSurface_lose_surface;
-    This->set_palette    = Main_DirectDrawSurface_set_palette;
-    This->update_palette = Main_DirectDrawSurface_update_palette;
-    This->get_display_window = Main_DirectDrawSurface_get_display_window;
-    This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp;
-    This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp;
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawSurface3,
-			DDRAW_IDDS3_Thunk_VTable);
-    ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
-			DDRAW_IDDGC_VTable);
-
-    /* There is no generic implementation of IDDS7 or texture */
-
-    Main_DirectDraw_AddSurface(pDD, This);
-    return DD_OK;
-}
-
-void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
-{
-    Main_DirectDraw_RemoveSurface(This->ddraw_owner, This);
-}
-
-HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
-{
-    return DD_OK;
-}
-
-static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
-{
-    if (This->palette) {
-        IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette));
-	This->palette = NULL;
-    }
-    This->final_release(This);
-    if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
-    HeapFree(GetProcessHeap(), 0, This->tex_private);
-    HeapFree(GetProcessHeap(), 0, This);
-}
-
-void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This)
-{
-    WARN("destroying surface %p with refcnt %lu\n", This, This->ref);
-    Main_DirectDrawSurface_Destroy(This);
-}
-
-ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->(): decreasing from %ld\n", This, ref + 1);
-    
-    if (ref == 0)
-    {
-	if (This->aux_release)
-	    This->aux_release(This->aux_ctx, This->aux_data);
-	Main_DirectDrawSurface_Destroy(This);
-
-	TRACE("released surface %p\n", This);
-	
-	return 0;
-    }
-
-    return ref;
-}
-
-ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->(): increasing from %ld\n", This, ref - 1);
-    
-    return ref;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
-				      LPVOID* ppObj)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
-
-    *ppObj = NULL;
-
-    if(!riid)
-        return DDERR_INVALIDPARAMS;
-
-    if (IsEqualGUID(&IID_IUnknown, riid)
-	|| IsEqualGUID(&IID_IDirectDrawSurface7, riid)
-	|| IsEqualGUID(&IID_IDirectDrawSurface4, riid))
-    {
-        InterlockedIncrement(&This->ref);
-	*ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7);
-	return S_OK;
-    }
-    else if (IsEqualGUID(&IID_IDirectDrawSurface, riid)
-	     || IsEqualGUID(&IID_IDirectDrawSurface2, riid)
-	     || IsEqualGUID(&IID_IDirectDrawSurface3, riid))
-    {
-        InterlockedIncrement(&This->ref);
-	*ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3);
-	return S_OK;
-    }
-    else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
-    {
-        InterlockedIncrement(&This->ref);
-	*ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl);
-	return S_OK;
-    }
-#ifdef HAVE_OPENGL
-    /* interfaces following here require OpenGL */
-    if( !opengl_initialized )
-        return E_NOINTERFACE;
-
-    if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) ||
-	  IsEqualGUID( &IID_IDirect3DHALDevice, riid) )
-    {
-        IDirect3DDeviceImpl *d3ddevimpl;
-	HRESULT ret_value;
-
-	ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, 1);
-	if (FAILED(ret_value)) return ret_value;
-
-	*ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);
-	TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj);
-	
-	InterlockedIncrement(&This->ref); /* No idea if this is correct.. Need to check using real Windows */
-	return ret_value;
-    }
-    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
-	     IsEqualGUID( &IID_IDirect3DTexture2, riid ))
-    {
-	HRESULT ret_value = S_OK;
-
-	/* Note: this is not exactly how Windows does it... But this seems not to hurt the only
-	         application I know creating a texture without this flag set and it will prevent
-		 bugs in other parts of Wine.
-	*/
-	This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
-
-	/* In case the texture surface was created before the D3D creation */
-	if (This->tex_private == NULL) {
-   	    if (This->ddraw_owner->d3d_private == NULL) {
-	        ERR("Texture created with no D3D object yet.. Not supported !\n");
-		return E_NOINTERFACE;
-	    }
-
-	    ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main);
-	    if (FAILED(ret_value)) return ret_value;
-	}
-	if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
-	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
-	    TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
-	} else {
-	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
-	    TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
-	}
-	InterlockedIncrement(&This->ref);
-	return ret_value;
-    }
-#endif
-
-    return E_NOINTERFACE;
-}
-
-/*** Callbacks */
-
-BOOL
-Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
-			      IDirectDrawSurfaceImpl *to)
-{
-    return TRUE;
-}
-
-BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
-{
-    return TRUE;
-}
-
-void
-Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
-	DWORD dwFlags)
-{
-}
-
-void
-Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-				     LPCRECT pRect)
-{
-}
-
-void
-Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This)
-{
-}
-
-void
-Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-				   IDirectDrawPaletteImpl* pal)
-{
-}
-
-void
-Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-				      IDirectDrawPaletteImpl* pal,
-				      DWORD dwStart, DWORD dwCount,
-				      LPPALETTEENTRY palent)
-{
-}
-
-HWND
-Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
-{
-    return 0;
-}
-
-HRESULT
-Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
-				      DWORD dwFlags,
-				      LPDDGAMMARAMP lpGammaRamp)
-{
-    HDC hDC;
-    HRESULT hr;
-    hr = This->get_dc(This, &hDC);
-    if (FAILED(hr)) return hr;
-    hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
-    This->release_dc(This, hDC);
-    return hr;
-}
-
-HRESULT
-Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
-				      DWORD dwFlags,
-				      LPDDGAMMARAMP lpGammaRamp)
-{
-    HDC hDC;
-    HRESULT hr;
-    hr = This->get_dc(This, &hDC);
-    if (FAILED(hr)) return hr;
-    hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
-    This->release_dc(This, hDC);
-    return hr;
-}
-
-
-/*** Interface functions */
-
-HRESULT WINAPI
-Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					  LPDIRECTDRAWSURFACE7 pAttach)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, pAttach);
-
-    TRACE("(%p)->(%p)\n",This,pAttach);
-
-    /* Does windows check this? */
-    if (surf == This)
-	return DDERR_CANNOTATTACHSURFACE; /* unchecked */
-
-    /* Does windows check this? */
-    if (surf->ddraw_owner != This->ddraw_owner)
-	return DDERR_CANNOTATTACHSURFACE; /* unchecked */
-
-    if (surf->surface_owner != NULL)
-	return DDERR_SURFACEALREADYATTACHED; /* unchecked */
-
-    /* TODO MSDN: "You can attach only z-buffer surfaces with this method."
-     * But apparently backbuffers and mipmaps can be attached too. */
-
-    /* Set MIPMAPSUBLEVEL if this seems to be one */
-    if (This->surface_desc.ddsCaps.dwCaps &
-	surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
-	surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
-	/* FIXME: we should probably also add to dwMipMapCount of this
-	 * and all parent surfaces (update create_texture if you do) */
-    }
-
-    /* Callback to allow the surface to do something special now that it is
-     * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */
-    if (!surf->attach(surf, This))
-	return DDERR_CANNOTATTACHSURFACE;
-
-    /* check: Where should it go in the chain? This puts it on the head. */
-    if (This->attached)
-	This->attached->prev_attached = surf;
-    surf->next_attached = This->attached;
-    surf->prev_attached = NULL;
-    This->attached = surf;
-    surf->surface_owner = This;
-
-    IDirectDrawSurface7_AddRef(pAttach);
-
-    return DD_OK;
-}
-
-/* MSDN: "not currently implemented." */
-HRESULT WINAPI
-Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface,
-					   LPRECT pRect)
-{
-    TRACE("(%p)->(%p)\n",iface,pRect);
-    return DDERR_UNSUPPORTED; /* unchecked */
-}
-
-/* MSDN: "not currently implemented." */
-HRESULT WINAPI
-Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface,
-				LPDDBLTBATCH pBatch, DWORD dwCount,
-				DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags);
-    return DDERR_UNSUPPORTED; /* unchecked */
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    volatile IDirectDrawSurfaceImpl* vThis = This;
-
-    TRACE("(%p)\n",This);
-    /* A uniquness value of 0 is apparently special.
-     * This needs to be checked. */
-    while (1)
-    {
-	DWORD old_uniqueness_value = vThis->uniqueness_value;
-	DWORD new_uniqueness_value = old_uniqueness_value+1;
-
-	if (old_uniqueness_value == 0) break;
-	if (new_uniqueness_value == 0) new_uniqueness_value = 1;
-
-	if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value,
-                                       old_uniqueness_value,
-                                       new_uniqueness_value)
-	    == old_uniqueness_value)
-	    break;
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					     DWORD dwFlags,
-					     LPDIRECTDRAWSURFACE7 pAttach)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, pAttach);
-
-    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);
-
-    if (!surf || (surf->surface_owner != This))
-	return DDERR_SURFACENOTATTACHED; /* unchecked */
-
-    surf->detach(surf);
-
-    /* Remove MIPMAPSUBLEVEL if this seemed to be one */
-    if (This->surface_desc.ddsCaps.dwCaps &
-	surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
-	surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
-	/* FIXME: we should probably also subtract from dwMipMapCount of this
-	 * and all parent surfaces */
-    }
-
-    if (surf->next_attached)
-	surf->next_attached->prev_attached = surf->prev_attached;
-    if (surf->prev_attached)
-	surf->prev_attached->next_attached = surf->next_attached;
-    if (This->attached == surf)
-	This->attached = surf->next_attached;
-
-    IDirectDrawSurface7_Release(pAttach);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface,
-					    LPVOID context,
-					    LPDDENUMSURFACESCALLBACK7 cb)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawSurfaceImpl* surf;
-    DDSURFACEDESC2 desc;
-    
-    TRACE("(%p)->(%p,%p)\n",This,context,cb);
-
-    for (surf = This->attached; surf != NULL; surf = surf->next_attached)
-    {
-	LPDIRECTDRAWSURFACE7 isurf = ICOM_INTERFACE(surf, IDirectDrawSurface7);
-
-	if (TRACE_ON(ddraw)) {
-	    TRACE("  => enumerating surface %p (priv. %p) with description:\n", isurf, surf);
-	    DDRAW_dump_surface_desc(&surf->surface_desc);
-	}
-
-	IDirectDrawSurface7_AddRef(isurf);
-	desc = surf->surface_desc;
-	/* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
-	if (cb(isurf, &desc, context) == DDENUMRET_CANCEL)
-	    break;
-    }
-
-    TRACE(" end of enumeration.\n");
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface,
-					  DWORD dwFlags, LPVOID context,
-					  LPDDENUMSURFACESCALLBACK7 cb)
-{
-    TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb);
-    return DD_OK;
-}
-
-BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				      IDirectDrawSurfaceImpl* back,
-				      DWORD dwFlags)
-{
-    /* uniqueness_value? */
-    /* This is necessary. But is it safe? */
-    {
-	HDC tmp = front->hDC;
-	front->hDC = back->hDC;
-	back->hDC = tmp;
-    }
-
-    {
-	BOOL tmp = front->dc_in_use;
-	front->dc_in_use = back->dc_in_use;
-	back->dc_in_use = tmp;
-    }
-
-    {
-	FLATPTR tmp = front->global.fpVidMem;
-	front->global.fpVidMem = back->global.fpVidMem;
-	back->global.fpVidMem = tmp;
-    }
-
-    {
-	ULONG_PTR tmp = front->global_more.hKernelSurface;
-	front->global_more.hKernelSurface = back->global_more.hKernelSurface;
-	back->global_more.hKernelSurface = tmp;
-    }
-
-    return TRUE;
-}
-
-/* This is unnecessarely complicated :-) */
-#define MEASUREMENT_WINDOW 5
-#define NUMBER_OF_WINDOWS 10
-
-static LONGLONG perf_freq;
-static LONGLONG perf_storage[NUMBER_OF_WINDOWS];
-static LONGLONG prev_time = 0;
-static unsigned int current_window;
-static unsigned int measurements_in_window;
-static unsigned int valid_windows;
-
-HRESULT WINAPI
-Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
-			    LPDIRECTDRAWSURFACE7 override, DWORD dwFlags)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawSurfaceImpl* target;
-    HRESULT hr;
-
-    TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags);
-
-    if (TRACE_ON(ddraw_fps)) {
-	LONGLONG current_time;
-	LONGLONG frame_duration;
-	QueryPerformanceCounter((LARGE_INTEGER *) &current_time);
-
-	if (prev_time != 0) {
-	    LONGLONG total_time = 0;
-	    int tot_meas;
-	    
-	    frame_duration = current_time - prev_time;
-	    prev_time = current_time;
-	    
-	    perf_storage[current_window] += frame_duration;
-	    measurements_in_window++;
-	    
-	    if (measurements_in_window >= MEASUREMENT_WINDOW) {
-		current_window++;
-		valid_windows++;
-
-		if (valid_windows < NUMBER_OF_WINDOWS) {
-		    unsigned int i;
-		    tot_meas = valid_windows * MEASUREMENT_WINDOW;
-		    for (i = 0; i < valid_windows; i++) {
-			total_time += perf_storage[i];
-		    }
-		} else {
-		    int i;
-		    tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW;
-		    for (i = 0; i < NUMBER_OF_WINDOWS; i++) {
-			total_time += perf_storage[i];
-		    }
-		}
-
-		TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time);
-		
-		if (current_window >= NUMBER_OF_WINDOWS) {
-		    current_window = 0;
-		}
-		perf_storage[current_window] = 0;
-		measurements_in_window = 0;
-	    }
-	} else {
-	    prev_time = current_time;
-	    memset(perf_storage, 0, sizeof(perf_storage));
-	    current_window = 0;
-	    valid_windows = 0;
-	    measurements_in_window = 0;
-	    QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq);
-	}
-    }
-    
-    /* MSDN: "This method can be called only for a surface that has the
-     * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */
-    if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	!= (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	return DDERR_NOTFLIPPABLE;
-
-    if (This->aux_flip)
-	if (This->aux_flip(This->aux_ctx, This->aux_data))
-	    return DD_OK;
-
-    /* 1. find the flip target */
-    /* XXX I don't think this algorithm works for more than 1 backbuffer. */
-    if (override == NULL)
-    {
-	static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER };
-	LPDIRECTDRAWSURFACE7 tgt;
-
-	hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
-	if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */
-
-	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-			     tgt);
-	IDirectDrawSurface7_Release(tgt);
-    }
-    else
-    {
-	BOOL on_chain = FALSE;
-	IDirectDrawSurfaceImpl* surf;
-
-	/* MSDN: "The method fails if the specified [override] surface is not
-	 * a member of the flipping chain." */
-
-	/* Verify that override is on this flip chain. We assume that
-	 * surf is the head of the flipping chain, because it's the front
-	 * buffer. */
-	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-			     override);
-
-	/* Either target is (indirectly) attached to This or This is
-	 * (indirectly) attached to target. */
-	for (surf = target; surf != NULL; surf = surf->surface_owner)
-	{
-	    if (surf == This)
-	    {
-		on_chain = TRUE;
-		break;
-	    }
-	}
-
-	if (!on_chain)
-	    return DDERR_INVALIDPARAMS; /* unchecked */
-    }
-
-    TRACE("flip to backbuffer: %p\n",target);
-    if (TRACE_ON(ddraw_flip)) {
-	static unsigned int flip_count = 0;
-	IDirectDrawPaletteImpl *palette;
-	char buf[32];
-	FILE *f;
-
-	/* Hack for paletted games... */
-	palette = target->palette;
-	target->palette = This->palette;
-	
-	sprintf(buf, "flip_%08d.ppm", flip_count++);
-	TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf);
-	f = fopen(buf, "wb");
-	DDRAW_dump_surface_to_disk(target, f, 8);
-	target->palette = palette;
-    }
-
-    if (This->flip_data(This, target, dwFlags))
-	This->flip_update(This, dwFlags);
-    
-    return DD_OK;
-}
-
-static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This,
-				      REFGUID tag)
-{
-    PrivateData* data;
-    for (data = This->private_data; data != NULL; data = data->next)
-    {
-	if (IsEqualGUID(&data->tag, tag)) break;
-    }
-
-    return data;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    PrivateData *data;
-
-    data = find_private_data(This, tag);
-    if (data == NULL) return DDERR_NOTFOUND;
-
-    if (data->prev)
-	data->prev->next = data->next;
-    if (data->next)
-	data->next->prev = data->prev;
-
-    if (data->flags & DDSPD_IUNKNOWNPTR)
-    {
-	if (data->ptr.object != NULL)
-	    IUnknown_Release(data->ptr.object);
-    }
-    else
-	HeapFree(GetProcessHeap(), 0, data->ptr.data);
-
-    HeapFree(GetProcessHeap(), 0, data);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface,
-					  LPDDSCAPS2 pCaps,
-					  LPDIRECTDRAWSURFACE7* ppSurface)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawSurfaceImpl* surf;
-    IDirectDrawSurfaceImpl* found = NULL;
-    DDSCAPS2 our_caps;
-    
-    if (TRACE_ON(ddraw)) {
-        TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2,
-	      pCaps->dwCaps3, pCaps->dwCaps4, ppSurface);
-	TRACE("   Caps are : "); DDRAW_dump_DDSCAPS2(pCaps); TRACE("\n");
-    }
-
-    our_caps = *pCaps;
-    if ((This->ddraw_owner->local.dwLocalFlags & DDRAWILCL_DIRECTDRAW7) == 0) {
-        /* As this is not a DirectDraw7 application, remove the garbage that some games
-	   put in the new fields of the DDSCAPS2 structure. */
-        our_caps.dwCaps2 = 0;
-	our_caps.dwCaps3 = 0;
-	our_caps.dwCaps4 = 0;
-	if (TRACE_ON(ddraw)) {
-	    TRACE("   Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps); TRACE("\n");
-	}
-    }
-    
-    for (surf = This->attached; surf != NULL; surf = surf->next_attached)
-    {
-        if (TRACE_ON(ddraw)) {
-	    TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf,
-		  surf->surface_desc.ddsCaps.dwCaps,
-		  surf->surface_desc.ddsCaps.dwCaps2,
-		  surf->surface_desc.ddsCaps.dwCaps3,
-		  surf->surface_desc.ddsCaps.dwCaps4);
-	    TRACE("   Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf->surface_desc.ddsCaps)); TRACE("\n");
-	}
-	if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
-	    ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2))
-	{
-	    /* MSDN: "This method fails if more than one surface is attached
-	     * that matches the capabilities requested." */
-	    if (found != NULL)
-            {
-                FIXME("More than one attached surface matches requested caps.  What should we do here?\n");
-                /* Previous code returned 'DDERR_NOTFOUND'.  That appears not
-                   to be correct, given what 3DMark expects from MipMapped surfaces.
-                   We shall just continue instead. */
-            }
-
-	    found = surf;
-	}
-    }
-
-    if (found == NULL) {
-        TRACE("Did not find any valid surface\n");
-	return DDERR_NOTFOUND;
-    }
-
-    *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE("Returning surface %p with description :\n", *ppSurface);
-	DDRAW_dump_surface_desc(&(found->surface_desc));
-    }
-    
-    /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */
-    IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7));
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
-{
-    TRACE("(%p)->(%08lx)\n",iface,dwFlags);
-
-    switch (dwFlags)
-    {
-    case DDGBS_CANBLT:
-    case DDGBS_ISBLTDONE:
-	return DD_OK;
-
-    default:
-	return DDERR_INVALIDPARAMS;
-    }
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pCaps);
-    *pCaps = This->surface_desc.ddsCaps;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWCLIPPER* ppClipper)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,ppClipper);
-    if (This->clipper == NULL)
-	return DDERR_NOCLIPPERATTACHED;
-
-    *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper);
-    IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper,
-					     IDirectDrawClipper));
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags,
-				   LPDDCOLORKEY pCKey)
-{
-    /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key
-     * isn't there? That's like saying that an int isn't there. (Which MS
-     * has done in other docs.) */
-
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - colorkey flags : ");
-	DDRAW_dump_colorkeyflag(dwFlags);
-    }
-
-    switch (dwFlags)
-    {
-    case DDCKEY_DESTBLT:
-	*pCKey = This->surface_desc.ddckCKDestBlt;
-	break;
-
-    case DDCKEY_DESTOVERLAY:
-	*pCKey = This->surface_desc.u3.ddckCKDestOverlay;
-	break;
-
-    case DDCKEY_SRCBLT:
-	*pCKey = This->surface_desc.ddckCKSrcBlt;
-	break;
-
-    case DDCKEY_SRCOVERLAY:
-	*pCKey = This->surface_desc.ddckCKSrcOverlay;
-	break;
-
-    default:
-	return DDERR_INVALIDPARAMS;
-    }
-
-    return DD_OK;
-}
-
-/* XXX We need to do something with the DC if the surface gets lost. */
-HRESULT WINAPI
-Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
-{
-    DDSURFACEDESC2 ddsd;
-    HRESULT hr;
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,phDC);
-    CHECK_LOST(This);
-
-    LOCK_OBJECT(This);
-
-    if (This->dc_in_use)
-    {
-	UNLOCK_OBJECT(This);
-	return DDERR_DCALREADYCREATED;
-    }
-
-    /* Lock as per MSDN.
-     * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
-     * thread has it locked, but GetDC does not. */
-    ddsd.dwSize = sizeof(ddsd);
-    hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0);
-    if (FAILED(hr))
-    {
-	UNLOCK_OBJECT(This);
-	return hr;
-    }
-
-    hr = This->get_dc(This, &This->hDC);
-
-    if ((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) &&
-	(This->palette == NULL)) {
-	IDirectDrawImpl *ddraw = This->ddraw_owner;
-	IDirectDrawSurfaceImpl *surf;
-	
-	for (surf = ddraw->surfaces; surf != NULL; surf = surf->next_ddraw) {
-	    if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) &&
-		(surf->palette != NULL)) {
-		RGBQUAD col[256];
-		IDirectDrawPaletteImpl *pal = surf->palette;
-		unsigned int n;
-		for (n=0; n<256; n++) {
-		    col[n].rgbRed   = pal->palents[n].peRed;
-		    col[n].rgbGreen = pal->palents[n].peGreen;
-		    col[n].rgbBlue  = pal->palents[n].peBlue;
-		    col[n].rgbReserved = 0;
-		}
-		SetDIBColorTable(This->hDC, 0, 256, col);
-		break;
-	    }
-	}
-
-    }
-    
-    if (SUCCEEDED(hr))
-    {
-	TRACE("returning %p\n",This->hDC);
-
-	*phDC = This->hDC;
-	This->dc_in_use = TRUE;
-    }
-    else WARN("No DC! Prepare for trouble\n");
-
-    UNLOCK_OBJECT(This);
-    return hr;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pDD);
-    *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7);
-    IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
-{
-    /* XXX: DDERR_INVALIDSURFACETYPE */
-
-    TRACE("(%p)->(%08lx)\n",iface,dwFlags);
-    switch (dwFlags)
-    {
-    case DDGFS_CANFLIP:
-    case DDGFS_ISFLIPDONE:
-	return DD_OK;
-
-    default:
-	return DDERR_INVALIDPARAMS;
-    }
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pdwMaxLOD);
-    CHECK_TEXTURE(This);
-
-    *pdwMaxLOD = This->max_lod;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
-					  LPLONG pX, LPLONG pY)
-{
-    return DDERR_NOTAOVERLAYSURFACE;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWPALETTE* ppPalette)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,ppPalette);
-    if (This->palette == NULL)
-	return DDERR_NOPALETTEATTACHED;
-
-    *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
-    IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette,
-					     IDirectDrawPalette));
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface,
-				      LPDDPIXELFORMAT pDDPixelFormat)
-{
-    /* What is DDERR_INVALIDSURFACETYPE for here? */
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pDDPixelFormat);
-    DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface,
-				   LPDWORD pdwPriority)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pdwPriority);
-    CHECK_TEXTURE(This);
-
-    *pdwPriority = This->priority;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface,
-				      REFGUID tag, LPVOID pBuffer,
-				      LPDWORD pcbBufferSize)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    PrivateData* data;
-
-    TRACE("(%p)->(%p), size = %ld\n", This, pBuffer, *pcbBufferSize);
-
-    data = find_private_data(This, tag);
-    if (data == NULL) return DDERR_NOTFOUND;
-
-    /* This may not be right. */
-    if ((data->flags & DDSPD_VOLATILE)
-	&& data->uniqueness_value != This->uniqueness_value)
-	return DDERR_EXPIRED;
-
-    if (*pcbBufferSize < data->size)
-    {
-	*pcbBufferSize = data->size;
-	return DDERR_MOREDATA;
-    }
-
-    if (data->flags & DDSPD_IUNKNOWNPTR)
-    {
-	*(LPUNKNOWN *)pBuffer = data->ptr.object;
-	IUnknown_AddRef(data->ptr.object);
-    }
-    else
-    {
-	memcpy(pBuffer, data->ptr.data, data->size);
-    }
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface,
-				      LPDDSURFACEDESC2 pDDSD)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pDDSD);
-    if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) ||
-    	(pDDSD->dwSize > sizeof(DDSURFACEDESC2))) {
-	ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize);
-	return DDERR_GENERIC;
-    }
-
-    DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc);
-    if (TRACE_ON(ddraw)) {
-      DDRAW_dump_surface_desc(pDDSD);
-    }
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface,
-					  LPDWORD pValue)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pValue);
-    *pValue = This->uniqueness_value;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD)
-{
-    TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD);
-    return DDERR_ALREADYINITIALIZED;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not"));
-    return This->lost ? DDERR_SURFACELOST : DD_OK;
-}
-
-
-/* XXX This doesn't actually do any locking or keep track of the locked
- * rectangles. The behaviour is poorly documented. */
-HRESULT WINAPI
-Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
-			    LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE("(%p)->Lock(%p,%p,%08lx,%p)\n",This,prect,pDDSD,flags,h);
-	TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags);
-    }
-    if (WARN_ON(ddraw)) {
-	if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) {
-	    WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY));
-	}
-    }
-    if (NULL != h) {
-        return DDERR_INVALIDPARAMS;
-    }
-    if (NULL == pDDSD) {
-        return DDERR_INVALIDPARAMS;
-    }
-
-    /* If the surface is already locked, return busy */
-    if (This->locked) {
-        WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
-        return DDERR_SURFACEBUSY;
-    }
-
-    /* First, copy the Surface description */
-    DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc));
-
-    /* Used to optimize the D3D Device locking */
-    This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY);
-    
-    /* If asked only for a part, change the surface pointer.
-     * (Not documented.) */
-    if (prect != NULL) {
-	TRACE("	lprect: %ldx%ld-%ldx%ld\n",
-		prect->left,prect->top,prect->right,prect->bottom);
-	/* First do some sanity checkings on the rectangle we receive.
-	   DungeonSiege seems to gives us once a very bad rectangle for example */
-	if ((prect->top < 0) ||
-	    (prect->left < 0) ||
-	    (prect->bottom < 0) ||
-	    (prect->right < 0) ||
-	    (prect->left >= prect->right) ||
-	    (prect->top >= prect->bottom) ||
-	    (prect->left >= This->surface_desc.dwWidth) ||
-	    (prect->right > This->surface_desc.dwWidth) ||
-	    (prect->top >= This->surface_desc.dwHeight) ||
-	    (prect->bottom > This->surface_desc.dwHeight)) {
-	    ERR(" Invalid values in LPRECT !!!\n");
-	    return DDERR_INVALIDPARAMS;
-	}
-
-	This->lock_update(This, prect, flags);
-
-	if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
-	    int blksize;
-	    switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) {
-		case MAKE_FOURCC('D','X','T','1') : blksize = 8; break;
-		case MAKE_FOURCC('D','X','T','3') : blksize = 16; break;
-		case MAKE_FOURCC('D','X','T','5') : blksize = 16; break;
-		default: return DDERR_INVALIDPIXELFORMAT;
-	    }
-	    pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
-		+ prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize
-	    	+ prect->left/4 * blksize;
-	} else
-	    pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
-		+ prect->top * This->surface_desc.u1.lPitch
-		+ prect->left * GET_BPP(This->surface_desc);
-    } else {
-	This->lock_update(This, NULL, flags);
-    }
-
-    This->locked = TRUE;
-
-    TRACE("locked surface returning description :\n");
-    if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
-{
-    /* Some surface types should return DDERR_CANTPAGELOCK. */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags)
-{
-    /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should
-     * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC)
-{
-    HRESULT hr;
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,hDC);
-
-    if (!This->dc_in_use || This->hDC != hDC)
-	return DDERR_INVALIDPARAMS;
-
-    This->release_dc(This, hDC);
-
-    hr = IDirectDrawSurface7_Unlock(iface, NULL);
-    if (FAILED(hr)) return hr;
-
-    This->dc_in_use = FALSE;
-    This->hDC = 0;
-
-    return DD_OK;
-}
-
-/* Restore */
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWCLIPPER pDDClipper)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p)\n",This,pDDClipper);
-    if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper))
-	return DD_OK;
-
-    if (This->clipper != NULL)
-	IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
-						  IDirectDrawClipper));
-
-    This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
-				pDDClipper);
-    if (pDDClipper != NULL)
-	IDirectDrawClipper_AddRef(pDDClipper);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface,
-				   DWORD dwFlags, LPDDCOLORKEY pCKey)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    
-    TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - colorkey flags : ");
-	DDRAW_dump_colorkeyflag(dwFlags);
-    }
-
-    if ((dwFlags & DDCKEY_COLORSPACE) != 0) {
-        FIXME(" colorkey value not supported (%08lx) !\n", dwFlags);
-	return DDERR_INVALIDPARAMS;
-    }
-    
-    /* TODO: investigate if this function can take multiple bits set at the same
-             time (ie setting multiple colorkey values at the same time with only
-	     one API call).
-    */
-    if (pCKey) {
-        switch (dwFlags & ~DDCKEY_COLORSPACE) {
-	    case DDCKEY_DESTBLT:
-	        This->surface_desc.ddckCKDestBlt = *pCKey;
-		This->surface_desc.dwFlags |= DDSD_CKDESTBLT;
-		break;
-
-	    case DDCKEY_DESTOVERLAY:
-	        This->surface_desc.u3.ddckCKDestOverlay = *pCKey;
-		This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
-		break;
-
-	    case DDCKEY_SRCOVERLAY:
-	        This->surface_desc.ddckCKSrcOverlay = *pCKey;
-		This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
-		break;
-
-	    case DDCKEY_SRCBLT:
-	        This->surface_desc.ddckCKSrcBlt = *pCKey;
-		This->surface_desc.dwFlags |= DDSD_CKSRCBLT;
-		break;
-
-	    default:
-	        return DDERR_INVALIDPARAMS;
-	}
-    } else {
-        switch (dwFlags & ~DDCKEY_COLORSPACE) {
-	    case DDCKEY_DESTBLT:
-		This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT;
-		break;
-
-	    case DDCKEY_DESTOVERLAY:
-		This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY;
-		break;
-
-	    case DDCKEY_SRCOVERLAY:
-		This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY;
-		break;
-
-	    case DDCKEY_SRCBLT:
-		This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT;
-		break;
-
-	    default:
-	        return DDERR_INVALIDPARAMS;
-	}
-    }
-
-    if (This->aux_setcolorkey_cb) This->aux_setcolorkey_cb(This, dwFlags, pCKey);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%08lx)\n",This,dwMaxLOD);
-    CHECK_TEXTURE(This);
-
-    This->max_lod = dwMaxLOD;
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface,
-					  LONG X, LONG Y)
-{
-    return DDERR_NOTAOVERLAYSURFACE;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface,
-				  LPDIRECTDRAWPALETTE pPalette)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-    IDirectDrawPalette *pal_to_rel = NULL;
-
-    TRACE("(%p)->(%p)\n",This,pPalette);
-    if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette))
-	return DD_OK;
-
-    if (This->palette != NULL) {
-	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-	    This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE;
-	pal_to_rel = ICOM_INTERFACE(This->palette, IDirectDrawPalette);
-    }
-
-    This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
-				pPalette);
-    if (pPalette != NULL) {
-	IDirectDrawPalette_AddRef(pPalette);
-	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-	    This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE;
-    }
-
-    This->set_palette(This, This->palette);
-
-    /* Do the palette release at the end to prevent doing some 'loop' when removing
-     * the surface maintaining the last reference on a palette.
-     */
-    if (pal_to_rel != NULL)
-	IDirectDrawPalette_Release(pal_to_rel);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface,
-				   DWORD dwPriority)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%08lx)\n",This,dwPriority);
-    CHECK_TEXTURE(This);
-
-    This->priority = dwPriority;
-    return DD_OK;
-}
-
-/* Be careful when locking this: it is risky to call the object's AddRef
- * or Release holding a lock. */
-HRESULT WINAPI
-Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface,
-				      REFGUID tag, LPVOID pData,
-				      DWORD cbSize, DWORD dwFlags)
-{
-    PrivateData* data;
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->(%p), size=%ld\n", This, pData, cbSize);
-
-    data = find_private_data(This, tag);
-    if (data == NULL)
-    {
-	data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
-	if (data == NULL) return DDERR_OUTOFMEMORY;
-
-	data->tag = *tag;
-	data->flags = dwFlags;
-	data->uniqueness_value = This->uniqueness_value;
-
-	if (dwFlags & DDSPD_IUNKNOWNPTR)
-	{
-	    data->ptr.object = (LPUNKNOWN)pData;
-	    data->size = sizeof(LPUNKNOWN);
-	    IUnknown_AddRef(data->ptr.object);
-	}
-	else
-	{
-	    data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize);
-	    if (data->ptr.data == NULL)
-	    {
-		HeapFree(GetProcessHeap(), 0, data);
-		return DDERR_OUTOFMEMORY;
-	    }
-
-            data->size = cbSize;
-            memcpy(data->ptr.data, pData, data->size);
-	}
-
-	/* link it in */
-	data->next = This->private_data;
-	data->prev = NULL;
-	if (This->private_data)
-	    This->private_data->prev = data;
-	This->private_data = data;
-
-	return DD_OK;
-    }
-    else
-    {
-	/* I don't actually know how windows handles this case. The only
-	 * reason I don't just call FreePrivateData is because I want to
-	 * guarantee SetPrivateData working when using LPUNKNOWN or data
-	 * that is no larger than the old data. */
-
-        FIXME("Replacing existing private data not implemented yet.\n");
-	return E_FAIL;
-    }
-}
-
-/* SetSurfaceDesc */
-
-HRESULT WINAPI
-Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
-
-    TRACE("(%p)->Unlock(%p)\n",This,pRect);
-
-    if (!This->locked) {
-        WARN("Surface not locked - returing DDERR_NOTLOCKED\n");
-        return DDERR_NOTLOCKED;
-    }
-
-    This->locked = FALSE;
-    This->unlock_update(This, pRect);
-    if (This->aux_unlock)
-	This->aux_unlock(This->aux_ctx, This->aux_data, pRect);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface,
-				     LPRECT pSrcRect,
-				     LPDIRECTDRAWSURFACE7 pDstSurface,
-				     LPRECT pDstRect, DWORD dwFlags,
-				     LPDDOVERLAYFX pFX)
-{
-    return DDERR_UNSUPPORTED;
-}
-
-/* MSDN: "not currently implemented." */
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface,
-					    DWORD dwFlags)
-{
-    return DDERR_UNSUPPORTED;
-}
-
-HRESULT WINAPI
-Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface,
-					   DWORD dwFlags,
-					   LPDIRECTDRAWSURFACE7 pDDSRef)
-{
-    return DDERR_NOTAOVERLAYSURFACE;
-}
diff --git a/dlls/ddraw/surface_thunks.c b/dlls/ddraw/surface_thunks.c
index 7a9861c..bba49bd 100644
--- a/dlls/ddraw/surface_thunks.c
+++ b/dlls/ddraw/surface_thunks.c
@@ -17,6 +17,8 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
 #include <stdarg.h>
 
 #include "windef.h"
@@ -38,6 +40,8 @@
 					     IDirectDrawSurface3,	\
 					     (pdds))
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
+
 static HRESULT WINAPI
 IDirectDrawSurface3Impl_QueryInterface(LPDIRECTDRAWSURFACE3 This, REFIID iid,
 				       LPVOID *ppObj)
@@ -52,9 +56,11 @@
 }
 
 static ULONG WINAPI
-IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 This)
+IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface)
 {
-    return IDirectDrawSurface7_Release(CONVERT(This));
+    ICOM_THIS_FROM( IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface);
+    TRACE("(%p)\n", This);
+    return IDirectDrawSurface7_Release(CONVERT(iface));
 }
 
 static HRESULT WINAPI
@@ -389,7 +395,7 @@
 					      dwFlags);
 }
 
-const IDirectDrawSurface3Vtbl DDRAW_IDDS3_Thunk_VTable =
+const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
 {
     IDirectDrawSurface3Impl_QueryInterface,
     IDirectDrawSurface3Impl_AddRef,
diff --git a/dlls/ddraw/surface_user.c b/dlls/ddraw/surface_user.c
deleted file mode 100644
index 86f6088..0000000
--- a/dlls/ddraw/surface_user.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*	User-based primary surface driver
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "winerror.h"
-#include "wine/debug.h"
-#include "ddraw_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-/* if you use OWN_WINDOW, don't use SYNC_UPDATE, or you may get trouble */
-/* #define SYNC_UPDATE */
-/*
- * FIXME: This does not work any more because the created window has its own
- *        thread queue that cannot be manipulated by application threads.
- * #define OWN_WINDOW
- */
-
-#ifdef OWN_WINDOW
-static void User_create_own_window(IDirectDrawSurfaceImpl* This);
-static void User_destroy_own_window(IDirectDrawSurfaceImpl* This);
-#endif
-#ifndef SYNC_UPDATE
-static DWORD CALLBACK User_update_thread(LPVOID);
-#endif
-static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc);
-
-static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt);
-
-static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable;
-
-HRESULT
-User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
-				 IDirectDrawImpl* pDD,
-				 const DDSURFACEDESC2* pDDSD)
-{
-    USER_PRIV_VAR(priv, This);
-    HRESULT hr;
-
-    TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);
-    hr = DIB_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr)) return hr;
-
-    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
-			User_IDirectDrawSurface7_VTable);
-
-    This->final_release = User_DirectDrawSurface_final_release;
-    This->duplicate_surface = User_DirectDrawSurface_duplicate_surface;
-
-    This->lock_update   = User_DirectDrawSurface_lock_update;
-    This->unlock_update = User_DirectDrawSurface_unlock_update;
-
-    This->flip_data   = User_DirectDrawSurface_flip_data;
-    This->flip_update = User_DirectDrawSurface_flip_update;
-
-    This->get_dc     = User_DirectDrawSurface_get_dc;
-    This->release_dc = User_DirectDrawSurface_release_dc;
-
-    This->set_palette    = User_DirectDrawSurface_set_palette;
-    This->update_palette = User_DirectDrawSurface_update_palette;
-
-    This->get_gamma_ramp = User_DirectDrawSurface_get_gamma_ramp;
-    This->set_gamma_ramp = User_DirectDrawSurface_set_gamma_ramp;
-
-    This->get_display_window = User_DirectDrawSurface_get_display_window;
-
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-#ifdef OWN_WINDOW
-	DirectDrawSurface_RegisterClass();
-#endif
-#ifndef SYNC_UPDATE
-	InitializeCriticalSection(&priv->user.crit);
-	priv->user.refresh_event = CreateEventW(NULL, TRUE, FALSE, NULL);
-	priv->user.update_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-	priv->user.update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL);
-#ifdef OWN_WINDOW
-	if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) {
-	    /* wait for window creation (or update thread destruction) */
-	    while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 100) == WAIT_TIMEOUT)
-		if (This->more.lpDDRAWReserved) break;
-	    if (!This->more.lpDDRAWReserved) {
-		ERR("window creation failed\n");
-	    }
-	}
-#endif
-#else
-#ifdef OWN_WINDOW
-	User_create_own_window(This);
-#endif
-#endif
-	if (!This->more.lpDDRAWReserved)
-	    This->more.lpDDRAWReserved = (LPVOID)pDD->window;
-    }
-
-    return DIB_DirectDrawSurface_alloc_dc(This, &priv->user.cached_dc);
-}
-
-HRESULT
-User_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
-			      const DDSURFACEDESC2 *pDDSD,
-			      LPDIRECTDRAWSURFACE7 *ppSurf,
-			      IUnknown *pUnkOuter)
-{
-    IDirectDrawSurfaceImpl* This;
-    HRESULT hr;
-    assert(pUnkOuter == NULL);
-
-    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		     sizeof(*This) + sizeof(User_DirectDrawSurfaceImpl));
-    if (This == NULL) return E_OUTOFMEMORY;
-
-    This->private = (User_DirectDrawSurfaceImpl*)(This+1);
-
-    hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD);
-    if (FAILED(hr))
-	HeapFree(GetProcessHeap(), 0, This);
-    else
-	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
-
-    return hr;
-}
-
-void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-#ifndef SYNC_UPDATE
-	HANDLE event = priv->user.update_event;
-	priv->user.update_event = 0;
-	SetEvent(event);
-	TRACE("waiting for update thread to terminate...\n");
-#ifdef OWN_WINDOW
-	/* dispatch any waiting sendmessages */
-	{
-	    MSG msg;
-	    PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE);
-	}
-	/* to avoid deadlocks, allow SendMessages from update thread
-	 * through while we wait for it */
-	while (MsgWaitForMultipleObjects(1, &priv->user.update_thread, FALSE,
-					 INFINITE, QS_SENDMESSAGE) == WAIT_OBJECT_0+1)
-	{
-	    MSG msg;
-	    PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE);
-	}
-#else
-	WaitForSingleObject(priv->user.update_thread,INFINITE);
-#endif
-	TRACE("update thread terminated\n");
-	CloseHandle(event);
-	CloseHandle(priv->user.update_thread);
-	CloseHandle(priv->user.refresh_event);
-	DeleteCriticalSection(&priv->user.crit);
-#else
-#ifdef OWN_WINDOW
-	User_destroy_own_window(This);
-#endif
-#endif
-	This->more.lpDDRAWReserved = 0;
-#ifdef OWN_WINDOW
-	DirectDrawSurface_UnregisterClass();
-#endif
-    }
-    DIB_DirectDrawSurface_free_dc(This, priv->user.cached_dc);
-    DIB_DirectDrawSurface_final_release(This);
-}
-
-static int User_DirectDrawSurface_init_wait(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-    int need_wait;
-    EnterCriticalSection(&priv->user.crit);
-    priv->user.wait_count++;
-    need_wait = priv->user.in_refresh;
-    LeaveCriticalSection(&priv->user.crit);
-    return need_wait;
-}
-
-static void User_DirectDrawSurface_end_wait(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-    EnterCriticalSection(&priv->user.crit);
-    if (!--priv->user.wait_count)
-	ResetEvent(priv->user.refresh_event);
-    LeaveCriticalSection(&priv->user.crit);
-}
-
-static void User_DirectDrawSurface_wait_update(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-    if (priv->user.in_refresh) {
-	if (User_DirectDrawSurface_init_wait(This))
-	    WaitForSingleObject(priv->user.refresh_event, 2);
-	User_DirectDrawSurface_end_wait(This);
-    }
-}
-
-void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
-					LPCRECT pRect, DWORD dwFlags)
-{
-#if 0
-    if (!(dwFlags & DDLOCK_WRITEONLY))
-	User_copy_from_screen(This, pRect);
-#endif
-    if (dwFlags & DDLOCK_WAIT) User_DirectDrawSurface_wait_update(This);
-
-    if (pRect) {
-	This->lastlockrect = *pRect;
-    } else {
-	This->lastlockrect.left = This->lastlockrect.right = 0;
-    }
-}
-
-void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
-					  LPCRECT pRect)
-{
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-#ifdef SYNC_UPDATE
-	User_copy_to_screen(This, pRect);
-#else
-	USER_PRIV_VAR(priv, This);
-	SetEvent(priv->user.update_event);
-#endif
-    }
-}
-
-void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
-					IDirectDrawPaletteImpl* pal)
-{
-    USER_PRIV_VAR(priv, This);
-
-    if (!pal) {
-	FIXME("selecting null palette\n");
-	/* I don't think selecting GDI object 0 will work, we should select
-	 * the original palette, returned by the first SelectPalette */
-	SelectPalette(priv->user.cached_dc, 0, FALSE);
-	return;
-    }
-
-    SelectPalette(priv->user.cached_dc, pal->hpal, FALSE);
-
-    DIB_DirectDrawSurface_set_palette(This, pal);
-}
-
-void User_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
-					   IDirectDrawPaletteImpl* pal,
-					   DWORD dwStart, DWORD dwCount,
-					   LPPALETTEENTRY palent)
-{
-#ifndef SYNC_UPDATE
-    USER_PRIV_VAR(priv, This);
-#endif
-
-    DIB_DirectDrawSurface_update_palette(This, pal, dwStart, dwCount, palent);
-    /* FIXME: realize palette on display window */
-
-#ifndef SYNC_UPDATE
-    /* with async updates, it's probably cool to force an update */
-    SetEvent(priv->user.update_event);
-#endif
-}
-
-HRESULT User_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
-						 LPDIRECTDRAWSURFACE7* ppDup)
-{
-    return User_DirectDrawSurface_Create(This->ddraw_owner,
-					 &This->surface_desc, ppDup, NULL);
-}
-
-BOOL User_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
-				      IDirectDrawSurfaceImpl* back,
-				      DWORD dwFlags)
-{
-    USER_PRIV_VAR(front_priv, front);
-    USER_PRIV_VAR(back_priv, back);
-
-    {
-	HDC tmp;
-	tmp = front_priv->user.cached_dc;
-	front_priv->user.cached_dc = back_priv->user.cached_dc;
-	back_priv->user.cached_dc = tmp;
-    }
-
-    return DIB_DirectDrawSurface_flip_data(front, back, dwFlags);
-}
-
-void User_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags)
-{
-#ifdef SYNC_UPDATE
-    This->lastlockrect.left = This->lastlockrect.right = 0;
-    assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
-    User_copy_to_screen(This,NULL);
-#else
-    USER_PRIV_VAR(priv, This);
-    assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
-    if (dwFlags & DDFLIP_WAIT) User_DirectDrawSurface_wait_update(This);
-    This->lastlockrect.left = This->lastlockrect.right = 0;
-    SetEvent(priv->user.update_event);
-#endif
-}
-
-HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC)
-{
-    USER_PRIV_VAR(priv, This);
-
-    *phDC = priv->user.cached_dc;
-    return S_OK;
-}
-
-HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This,
-					  HDC hDC)
-{
-    return S_OK;
-}
-
-HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp)
-{
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-	POINT offset;
-	HWND hDisplayWnd;
-	HDC hDisplayDC;
-	HRESULT hr;
-	hDisplayWnd = get_display_window(This, &offset);
-	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
-	hr = GetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
-	ReleaseDC(hDisplayWnd, hDisplayDC);
-	return hr;
-    }
-    return Main_DirectDrawSurface_get_gamma_ramp(This, dwFlags, lpGammaRamp);
-}
-
-HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
-					      DWORD dwFlags,
-					      LPDDGAMMARAMP lpGammaRamp)
-{
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-	POINT offset;
-	HWND hDisplayWnd;
-	HDC hDisplayDC;
-	HRESULT hr;
-	hDisplayWnd = get_display_window(This, &offset);
-	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
-	hr = SetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
-	ReleaseDC(hDisplayWnd, hDisplayDC);
-	return hr;
-    }
-    return Main_DirectDrawSurface_set_gamma_ramp(This, dwFlags, lpGammaRamp);
-}
-
-/* Returns the window that hosts the display.
- * *pt is set to the upper left position of the window relative to the
- * upper left corner of the surface. */
-static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt)
-{
-    memset(pt, 0, sizeof(*pt));
-
-    if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN)
-    {
-#ifdef OWN_WINDOW
-	USER_PRIV_VAR(priv, This);
-#if 1
-	SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0,
-		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|
-		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE);
-#endif
-	return priv->user.window;
-#else
-	return This->ddraw_owner->window;
-#endif
-    }
-    else
-    {
-	if (This->clipper != NULL)
-	{
-	    /* looks silly, but since we don't have the clipper locked */
-	    HWND hWnd = This->clipper->hWnd;
-
-	    if (hWnd != 0)
-	    {
-		ClientToScreen(hWnd, pt);
-		return hWnd;
-	    }
-	    else
-	    {
-		static BOOL warn = 0;
-		if (!warn++) FIXME("clipper clip lists not supported\n");
-
-		return GetDesktopWindow();
-	    }
-	}
-	else
-	{
-	    static BOOL warn = 0;
-	    if (!warn++) WARN("hosting on root\n");
-
-	    return GetDesktopWindow();
-	}
-    }
-}
-
-HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
-{
-    POINT offset;
-    return get_display_window(This, &offset);
-}
-
-#ifdef OWN_WINDOW
-static void User_create_own_window(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-
-    if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN)
-    {
-	priv->user.window = CreateWindowExA(WS_EX_TOPMOST |
-					    WS_EX_LAYERED |
-					    WS_EX_TRANSPARENT,
-					    "WINE_DDRAW", "DirectDraw",
-					    WS_POPUP,
-					    0, 0,
-					    This->surface_desc.dwWidth,
-					    This->surface_desc.dwHeight,
-					    GetDesktopWindow(),
-					    0, 0, This);
-	This->more.lpDDRAWReserved = (LPVOID)priv->user.window;
-	SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0,
-		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|
-		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW);
-	UpdateWindow(priv->user.window);
-    }
-}
-
-static void User_destroy_own_window(IDirectDrawSurfaceImpl* This)
-{
-    USER_PRIV_VAR(priv, This);
-
-    if (priv->user.window)
-    {
-	SetWindowPos(priv->user.window, 0, 0, 0, 0, 0,
-		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER|
-		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW);
-	This->more.lpDDRAWReserved = NULL;
-	DestroyWindow(priv->user.window);
-	priv->user.window = 0;
-    }
-}
-#endif
-
-#ifndef SYNC_UPDATE
-static DWORD CALLBACK User_update_thread(LPVOID arg)
-{
-    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)arg;
-    USER_PRIV_VAR(priv, This);
-    volatile HANDLE *pActive = (volatile HANDLE *)&priv->user.update_event;
-    HANDLE event = *pActive;
-
-#ifdef OWN_WINDOW
-    User_create_own_window(This);
-#endif
-
-    /* the point of this is that many games lock the primary surface
-     * multiple times per frame; this thread will then simply copy as
-     * often as it can without keeping the main thread waiting for
-     * each unlock, thus keeping the frame rate high */
-    do {
-#ifdef OWN_WINDOW
-	DWORD ret = MsgWaitForMultipleObjects(1, &event, FALSE, INFINITE, QS_ALLINPUT);
-	MSG msg;
-
-	while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
-	{
-	    switch (msg.message) {
-	    case WM_PAINT:
-		DispatchMessageA(&msg);
-		break;
-	    default:
-		/* since we risk getting keyboard messages posted to us,
-		 * repost posted messages to cooperative window */
-		PostMessageA(This->ddraw_owner->window, msg.message, msg.wParam, msg.lParam);
-	    }
-	}
-#else
-	DWORD ret = WaitForSingleObject(event, INFINITE);
-#endif
-	if (ret == WAIT_OBJECT_0)
-	{
-	    if (*pActive) {
-		priv->user.in_refresh = TRUE;
-		User_copy_to_screen(This, NULL);
-		EnterCriticalSection(&priv->user.crit);
-		priv->user.in_refresh = FALSE;
-		if (priv->user.wait_count)
-		    SetEvent(priv->user.refresh_event);
-		LeaveCriticalSection(&priv->user.crit);
-	    } else
-		break;
-	}
-	else if (ret != WAIT_OBJECT_0+1) break;
-    } while (TRUE);
-
-    SetEvent(priv->user.refresh_event);
-#ifdef OWN_WINDOW
-    User_destroy_own_window(This);
-#endif
-
-    return 0;
-}
-#endif
-
-static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
-{
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-	POINT offset;
-	HWND hDisplayWnd;
-	HDC hDisplayDC;
-	HDC hSurfaceDC;
-	RECT drawrect;
-
-	if (FAILED(This->get_dc(This, &hSurfaceDC)))
-	    return;
-
-	hDisplayWnd = get_display_window(This, &offset);
-	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
-#if 0
-	/* FIXME: this doesn't work... if users really want to run
-	 * X in 8bpp, then we need to call directly into display.drv
-	 * (or Wine's equivalent), and force a private colormap
-	 * without default entries. */
-	if (This->palette) {
-	    SelectPalette(hDisplayDC, This->palette->hpal, FALSE);
-	    RealizePalette(hDisplayDC); /* sends messages => deadlocks */
-	}
-#endif
-	drawrect.left	= 0;
-	drawrect.right	= This->surface_desc.dwWidth;
-	drawrect.top	= 0;
-	drawrect.bottom	= This->surface_desc.dwHeight;
-
-	if (This->clipper) {
-	    RECT xrc;
-	    HWND hwnd = This->clipper->hWnd;
-	    if (hwnd && GetClientRect(hwnd,&xrc)) {
-		OffsetRect(&xrc,offset.x,offset.y);
-		IntersectRect(&drawrect,&drawrect,&xrc);
-	    }
-	}
-	if (rc)
-	    IntersectRect(&drawrect,&drawrect,rc);
-	else {
-	    /* Only use this if the caller did not pass a rectangle, since
-	     * due to double locking this could be the wrong one ... */
-	    if (This->lastlockrect.left != This->lastlockrect.right)
-		IntersectRect(&drawrect,&drawrect,&This->lastlockrect);
-	}
-	BitBlt(hDisplayDC,
-		drawrect.left-offset.x, drawrect.top-offset.y,
-		drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
-		hSurfaceDC,
-		drawrect.left, drawrect.top,
-		SRCCOPY
-	);
-	ReleaseDC(hDisplayWnd, hDisplayDC);
-    }
-}
-
-#if 0
-static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
-{
-    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-    {
-	POINT offset;
-	HWND hDisplayWnd = get_display_window(This, &offset);
-	HDC hDisplayDC = GetDC(hDisplayWnd);
-	RECT drawrect;
-
-	drawrect.left	= 0;
-	drawrect.right	= This->surface_desc.dwWidth;
-	drawrect.top	= 0;
-	drawrect.bottom	= This->surface_desc.dwHeight;
-	if (rc)
-	    IntersectRect(&drawrect,&drawrect,rc);
-
-	BitBlt(This->hDC,
-	    drawrect.left, drawrect.top,
-	    drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
-	    hDisplayDC,
-	    drawrect.left+offset.x, drawrect.top+offset.y,
-	    SRCCOPY
-	);
-	ReleaseDC(hDisplayWnd, hDisplayDC);
-    }
-}
-#endif
-
-static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable =
-{
-    Main_DirectDrawSurface_QueryInterface,
-    Main_DirectDrawSurface_AddRef,
-    Main_DirectDrawSurface_Release,
-    Main_DirectDrawSurface_AddAttachedSurface,
-    Main_DirectDrawSurface_AddOverlayDirtyRect,
-    DIB_DirectDrawSurface_Blt,
-    Main_DirectDrawSurface_BltBatch,
-    DIB_DirectDrawSurface_BltFast,
-    Main_DirectDrawSurface_DeleteAttachedSurface,
-    Main_DirectDrawSurface_EnumAttachedSurfaces,
-    Main_DirectDrawSurface_EnumOverlayZOrders,
-    Main_DirectDrawSurface_Flip,
-    Main_DirectDrawSurface_GetAttachedSurface,
-    Main_DirectDrawSurface_GetBltStatus,
-    Main_DirectDrawSurface_GetCaps,
-    Main_DirectDrawSurface_GetClipper,
-    Main_DirectDrawSurface_GetColorKey,
-    Main_DirectDrawSurface_GetDC,
-    Main_DirectDrawSurface_GetFlipStatus,
-    Main_DirectDrawSurface_GetOverlayPosition,
-    Main_DirectDrawSurface_GetPalette,
-    Main_DirectDrawSurface_GetPixelFormat,
-    Main_DirectDrawSurface_GetSurfaceDesc,
-    Main_DirectDrawSurface_Initialize,
-    Main_DirectDrawSurface_IsLost,
-    Main_DirectDrawSurface_Lock,
-    Main_DirectDrawSurface_ReleaseDC,
-    DIB_DirectDrawSurface_Restore,
-    Main_DirectDrawSurface_SetClipper,
-    Main_DirectDrawSurface_SetColorKey,
-    Main_DirectDrawSurface_SetOverlayPosition,
-    Main_DirectDrawSurface_SetPalette,
-    Main_DirectDrawSurface_Unlock,
-    Main_DirectDrawSurface_UpdateOverlay,
-    Main_DirectDrawSurface_UpdateOverlayDisplay,
-    Main_DirectDrawSurface_UpdateOverlayZOrder,
-    Main_DirectDrawSurface_GetDDInterface,
-    Main_DirectDrawSurface_PageLock,
-    Main_DirectDrawSurface_PageUnlock,
-    DIB_DirectDrawSurface_SetSurfaceDesc,
-    Main_DirectDrawSurface_SetPrivateData,
-    Main_DirectDrawSurface_GetPrivateData,
-    Main_DirectDrawSurface_FreePrivateData,
-    Main_DirectDrawSurface_GetUniquenessValue,
-    Main_DirectDrawSurface_ChangeUniquenessValue,
-    Main_DirectDrawSurface_SetPriority,
-    Main_DirectDrawSurface_GetPriority,
-    Main_DirectDrawSurface_SetLOD,
-    Main_DirectDrawSurface_GetLOD
-};
diff --git a/dlls/ddraw/surface_wndproc.c b/dlls/ddraw/surface_wndproc.c
deleted file mode 100644
index cc36c48..0000000
--- a/dlls/ddraw/surface_wndproc.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*	User-based primary surface driver
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "winerror.h"
-
-#include "ddraw_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-
-static LRESULT WINAPI DirectDrawSurface_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-void DirectDrawSurface_RegisterClass(void)
-{
-    WNDCLASSA wc;
-    memset(&wc, 0, sizeof(wc));
-    wc.lpfnWndProc = DirectDrawSurface_WndProc;
-    wc.cbWndExtra  = sizeof(IDirectDrawSurfaceImpl*);
-    wc.hCursor     = (HCURSOR)IDC_ARROW;
-    wc.lpszClassName = "WINE_DDRAW";
-    RegisterClassA(&wc);
-}
-
-void DirectDrawSurface_UnregisterClass(void)
-{
-    UnregisterClassA("WINE_DDRAW", 0);
-}
-
-static LRESULT WINAPI DirectDrawSurface_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    IDirectDrawSurfaceImpl *This;
-    LRESULT ret;
-
-    This = (IDirectDrawSurfaceImpl *)GetWindowLongPtrA(hwnd, 0);
-    if (This) {
-	HWND window = This->ddraw_owner->window;
-
-	switch (msg) {
-	case WM_DESTROY:
-	case WM_NCDESTROY:
-	case WM_SHOWWINDOW:
-	case WM_WINDOWPOSCHANGING:
-	case WM_WINDOWPOSCHANGED:
-	case WM_SIZE:
-	case WM_MOVE:
-	case WM_ERASEBKGND:
-	case WM_SYNCPAINT:
-	    /* since we're pretending fullscreen,
-	     * let's not pass these on to the app */
-	    ret = DefWindowProcA(hwnd, msg, wParam, lParam);
-	    break;
-	case WM_NCHITTEST:
-	    ret = HTCLIENT;
-	    break;
-	case WM_MOUSEACTIVATE:
-	    ret = MA_NOACTIVATE;
-	    break;
-	case WM_PAINT:
-	    {
-		PAINTSTRUCT ps;
-		HDC dc;
-		dc = BeginPaint(hwnd, &ps);
-		/* call User_copy_to_screen? */
-		EndPaint(hwnd, &ps);
-		ret = 0;
-	    }
-	    break;
-	default:
-	    ret = window ? SendMessageA(window, msg, wParam, lParam)
-			 : DefWindowProcA(hwnd, msg, wParam, lParam);
-	}
-    } else {
-	if (msg == WM_CREATE) {
-	    CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
-	    This = (IDirectDrawSurfaceImpl *)cs->lpCreateParams;
-	    SetWindowLongPtrA(hwnd, 0, (LONG_PTR)This);
-	}
-	ret = DefWindowProcA(hwnd, msg, wParam, lParam);
-    }
-    return ret;
-}
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index def3fae..87f0231 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -320,53 +320,29 @@
     if(!out) goto out;
 
     /* Check the results */
-    if( !comparefloat(out[0].x, 128.0 ) ||
-        !comparefloat(out[0].y, 128.0 ) ||
-        !comparefloat(out[0].z, 0.0 ) ||
-        !comparefloat(out[0].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
+    ok( comparefloat(out[0].x, 128.0 ) &&
+        comparefloat(out[0].y, 128.0 ) &&
+        comparefloat(out[0].z, 0.0 ) &&
+        comparefloat(out[0].rhw, 1.0 ),
+        "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
 
-    if( !comparefloat(out[1].x, 256.0 ) ||
-        !comparefloat(out[1].y, 0.0 ) ||
-        !comparefloat(out[1].z, 1.0 ) ||
-        !comparefloat(out[1].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
+    ok( comparefloat(out[1].x, 256.0 ) &&
+        comparefloat(out[1].y, 0.0 ) &&
+        comparefloat(out[1].z, 1.0 ) &&
+        comparefloat(out[1].rhw, 1.0 ),
+        "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
 
-    if( !comparefloat(out[2].x, 0.0 ) ||
-        !comparefloat(out[2].y, 256.0 ) ||
-        !comparefloat(out[2].z, 0.5 ) ||
-        !comparefloat(out[2].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
-    }
+    ok( comparefloat(out[2].x, 0.0 ) &&
+        comparefloat(out[2].y, 256.0 ) &&
+        comparefloat(out[2].z, 0.5 ) &&
+        comparefloat(out[2].rhw, 1.0 ),
+        "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
 
-    if( !comparefloat(out[3].x, 192.0 ) ||
-        !comparefloat(out[3].y, 192.0 ) ||
-        !comparefloat(out[3].z, 0.25 ) ||
-        !comparefloat(out[3].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
+    ok( comparefloat(out[3].x, 192.0 ) &&
+        comparefloat(out[3].y, 192.0 ) &&
+        comparefloat(out[3].z, 0.25 ) &&
+        comparefloat(out[3].rhw, 1.0 ),
+        "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
 
     rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
     ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc);
@@ -379,16 +355,10 @@
      * so let's check for it: If the output vertex buffer has to RHW value,
      * The RHW value of the last vertex is written into the next vertex
      */
-    if( !comparefloat(out2[4].x, 1.0 ) ||
-        !comparefloat(out2[4].y, 0.0 ) ||
-        !comparefloat(out2[4].z, 0.0 ) )
-    {
-        todo_wine ok(FALSE, "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
-    }
+    ok( comparefloat(out2[4].x, 1.0 ) &&
+        comparefloat(out2[4].y, 0.0 ) &&
+        comparefloat(out2[4].z, 0.0 ),
+        "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
 
     rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
     ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc);
@@ -414,53 +384,29 @@
     if(!out) goto out;
 
     /* Check the results */
-    if( !comparefloat(out[0].x, 133.0 ) ||
-        !comparefloat(out[0].y, 70.0 ) ||
-        !comparefloat(out[0].z, -2.0 ) ||
-        !comparefloat(out[0].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
+    ok( comparefloat(out[0].x, 133.0 ) &&
+        comparefloat(out[0].y, 70.0 ) &&
+        comparefloat(out[0].z, -2.0 ) &&
+        comparefloat(out[0].rhw, 1.0 ),
+        "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
 
-    if( !comparefloat(out[1].x, 256.0 ) ||
-        !comparefloat(out[1].y, 5.0 ) ||
-        !comparefloat(out[1].z, 4.0 ) ||
-        !comparefloat(out[1].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
+    ok( comparefloat(out[1].x, 256.0 ) &&
+        comparefloat(out[1].y, 5.0 ) &&
+        comparefloat(out[1].z, 4.0 ) &&
+        comparefloat(out[1].rhw, 1.0 ),
+        "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
 
-    if( !comparefloat(out[2].x, 10.0 ) ||
-        !comparefloat(out[2].y, 135.0 ) ||
-        !comparefloat(out[2].z, 1.0 ) ||
-        !comparefloat(out[2].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
+    ok( comparefloat(out[2].x, 10.0 ) &&
+        comparefloat(out[2].y, 135.0 ) &&
+        comparefloat(out[2].z, 1.0 ) &&
+        comparefloat(out[2].rhw, 1.0 ),
+        "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
 
-    if( !comparefloat(out[3].x, 194.5 ) ||
-        !comparefloat(out[3].y, 102.5 ) ||
-        !comparefloat(out[3].z, -0.5 ) ||
-        !comparefloat(out[3].rhw, 1.0 ))
-    {
-        todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
+    ok( comparefloat(out[3].x, 194.5 ) &&
+        comparefloat(out[3].y, 102.5 ) &&
+        comparefloat(out[3].z, -0.5 ) &&
+        comparefloat(out[3].rhw, 1.0 ),
+        "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
 
     rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
     ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc);
@@ -495,53 +441,29 @@
     ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
 
     /* Check the results */
-    if( !comparefloat(out[0].x, 256.0 ) ||    /* X coordinate is cut at the surface edges */
-        !comparefloat(out[0].y, 70.0 ) ||
-        !comparefloat(out[0].z, -2.0 ) ||
-        !comparefloat(out[0].rhw, (1.0 / 3.0)))
-    {
-        todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
-    }
+    ok( comparefloat(out[0].x, 256.0 ) &&    /* X coordinate is cut at the surface edges */
+        comparefloat(out[0].y, 70.0 ) &&
+        comparefloat(out[0].z, -2.0 ) &&
+        comparefloat(out[0].rhw, (1.0 / 3.0)),
+        "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
 
-    if( !comparefloat(out[1].x, 256.0 ) ||
-        !comparefloat(out[1].y, 78.125000 ) ||
-        !comparefloat(out[1].z, -2.750000 ) ||
-        !comparefloat(out[1].rhw, 0.125000 ))
-    {
-        todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
-    }
+    ok( comparefloat(out[1].x, 256.0 ) &&
+        comparefloat(out[1].y, 78.125000 ) &&
+        comparefloat(out[1].z, -2.750000 ) &&
+        comparefloat(out[1].rhw, 0.125000 ),
+        "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
 
-    if( !comparefloat(out[2].x, 256.0 ) ||
-        !comparefloat(out[2].y, 44.000000 ) ||
-        !comparefloat(out[2].z, 0.400000 ) ||
-        !comparefloat(out[2].rhw, 0.400000 ))
-    {
-        todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
-    }
+    ok( comparefloat(out[2].x, 256.0 ) &&
+        comparefloat(out[2].y, 44.000000 ) &&
+        comparefloat(out[2].z, 0.400000 ) &&
+        comparefloat(out[2].rhw, 0.400000 ),
+        "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
 
-    if( !comparefloat(out[3].x, 256.0 ) ||
-        !comparefloat(out[3].y, 81.818184 ) ||
-        !comparefloat(out[3].z, -3.090909 ) ||
-        !comparefloat(out[3].rhw, 0.363636 ))
-    {
-        todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
-    else
-    {
-        todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
-    }
+    ok( comparefloat(out[3].x, 256.0 ) &&
+        comparefloat(out[3].y, 81.818184 ) &&
+        comparefloat(out[3].z, -3.090909 ) &&
+        comparefloat(out[3].rhw, 0.363636 ),
+        "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
 
     rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
     ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc);
diff --git a/dlls/ddraw/texture.c b/dlls/ddraw/texture.c
index 66c07f3..07b5edb 100644
--- a/dlls/ddraw/texture.c
+++ b/dlls/ddraw/texture.c
@@ -1,5 +1,6 @@
 /* Direct3D Texture
  * Copyright (c) 1998 Lionel ULMER
+ * Copyright (c) 2006 Stefan DÖSINGER
  *
  * This file contains the implementation of interface Direct3DTexture2.
  *
@@ -21,42 +22,238 @@
 #include "config.h"
 #include "wine/port.h"
 
+#include <assert.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stdlib.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
+
+#include "ddraw_private.h"
 #include "wine/debug.h"
 
-#include "opengl_private.h"
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
 
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_tex);
-
-#include <stdio.h>
-
-static void 
-snoop_texture(IDirectDrawSurfaceImpl *This) {
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-    char buf[128];
-    FILE *f;
-
-    TRACE_(ddraw_tex)("Dumping surface id (%5d) level (%2d) : \n", glThis->tex_name, This->mipmap_level);
-    DDRAW_dump_surface_desc(&(This->surface_desc));
-    
-    sprintf(buf, "tex_%05d_%02d.pnm", glThis->tex_name, This->mipmap_level);
-    f = fopen(buf, "wb");
-    DDRAW_dump_surface_to_disk(This, f, 1);
+/*****************************************************************************
+ * IUnknown interfaces. They are thunks to IDirectDrawSurface7
+ *****************************************************************************/
+static HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_2_QueryInterface(IDirect3DTexture2 *iface,
+                                            REFIID riid,
+                                            void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj);
+    return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7),
+                                              riid,
+                                              obj);
 }
 
+static HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture *iface,
+                                            REFIID riid,
+                                            void **obj)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj);
+
+    return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7),
+                                              riid,
+                                              obj);
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
+
+    return IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
+
+    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
+}
+
+static ULONG WINAPI
+Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2 *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
+
+    return IDirectDrawSurface7_Release(ICOM_INTERFACE(This, IDirectDrawSurface7));
+}
+
+
+static ULONG WINAPI
+Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
+
+    return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
+}
+
+/*****************************************************************************
+ * IDirect3DTexture interface
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DTexture1::Initialize
+ *
+ * The sdk says it's not implemented
+ *
+ * Params:
+ *  ?
+ *
+ * Returns
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DTextureImpl_1_Initialize(IDirect3DTexture *iface,
+                                  IDirect3DDevice *Direct3DDevice,
+                                  IDirectDrawSurface *DDSurface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, Direct3DDevice);
+    IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, DDSurface);
+    TRACE("(%p)->(%p,%p) Not implemented\n", This, d3d, surf);
+    return DDERR_UNSUPPORTED; /* Unchecked */
+}
+
+/*****************************************************************************
+ * IDirect3DTexture2::PaletteChanged
+ *
+ * Informs the texture about a palette change
+ *
+ * Params:
+ *  Start: Start index of the change
+ *  Count: The number of changed entries
+ *
+ * Returns
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2 *iface,
+                                         DWORD Start,
+                                         DWORD Count)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    FIXME("(%p)->(%08lx,%08lx): stub!\n", This, Start, Count);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture *iface,
+                                            DWORD Start,
+                                            DWORD Count)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", This, Start, Count);
+
+    return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+                                            Start,
+                                            Count);
+}
+
+
+/*****************************************************************************
+ * IDirect3DTexture::Unload
+ *
+ * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented
+ *
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DTextureImpl_1_Unload(IDirect3DTexture *iface)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->(): not implemented!\n", This);
+    return DDERR_UNSUPPORTED;
+}
+
+/*****************************************************************************
+ * IDirect3DTexture2::GetHandle
+ *
+ * Returns handle for the texture. At the moment, the interface
+ * to the IWineD3DTexture is used.
+ *
+ * Params:
+ *  Direct3DDevice2: Device this handle is assigned to
+ *  Handle: Address to store the handle at.
+ *
+ * Returns:
+ *  D3D_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface,
+                                    IDirect3DDevice2 *Direct3DDevice2,
+                                    D3DTEXTUREHANDLE *lpHandle)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, Direct3DDevice2);
+
+    TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle);
+
+    /* The handle is the WineD3DTexture interface. SetRenderState depends on this */
+    if(This->ddraw->wineD3DDevice)
+        *lpHandle = (D3DTEXTUREHANDLE) This->wineD3DTexture;
+    else
+    {
+        /* This is to fool applications which create a texture without a D3DDevice */
+        *lpHandle = (D3DTEXTUREHANDLE) This;
+    }
+
+    TRACE(" returning handle %08lx.\n", *lpHandle);
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface,
+                                       LPDIRECT3DDEVICE lpDirect3DDevice,
+                                       LPD3DTEXTUREHANDLE lpHandle)
+{
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, lpDirect3DDevice, lpHandle);
+
+    return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+                                       COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
+                                       lpHandle);
+}
+
+
+/*****************************************************************************
+ * get_sub_mimaplevel
+ *
+ * Helper function that returns the next mipmap level
+ *
+ * tex_ptr: Surface of which to return the next level
+ *
+ *****************************************************************************/
 static IDirectDrawSurfaceImpl *
 get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr)
 {
@@ -65,873 +262,245 @@
     LPDIRECTDRAWSURFACE7 next_level;
     IDirectDrawSurfaceImpl *surf_ptr;
     HRESULT hr;
-    
+
     hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7),
-						(DDSCAPS2 *) &mipmap_caps, &next_level);
+                                                (DDSCAPS2 *) &mipmap_caps, &next_level);
     if (FAILED(hr)) return NULL;
-    
+
     surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level);
     IDirectDrawSurface7_Release(next_level);
-    
+
     return surf_ptr;
 }
 
-/*******************************************************************************
- *			   IDirectSurface callback methods
- */
-
-HRESULT
-gltex_download_texture(IDirectDrawSurfaceImpl *surf_ptr) {
-    IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
-
-    FIXME("This is not supported yet... Expect some graphical glitches !!!\n");
-
-    /* GL and memory are in sync again ... 
-       No need to change the 'global' flag as it only handles the 'MEMORY_DIRTY' case.
-    */
-    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
-    
-    return DD_OK;
-}
-
-static GLenum
-convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwMinState, D3DTEXTUREMIPFILTER dwMipState)
-{
-    GLenum gl_state;
-
-    if (dwMipState == D3DTFP_NONE) {
-        switch (dwMinState) {
-            case D3DTFN_POINT:  gl_state = GL_NEAREST; break;
-	    case D3DTFN_LINEAR: gl_state = GL_LINEAR;  break;
-	    default:            gl_state = GL_LINEAR;  break;
-	}
-    } else if (dwMipState == D3DTFP_POINT) {
-        switch (dwMinState) {
-            case D3DTFN_POINT:  gl_state = GL_NEAREST_MIPMAP_NEAREST; break;
-	    case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_NEAREST;  break;
-	    default:            gl_state = GL_LINEAR_MIPMAP_NEAREST;  break;
-	}
-    } else {
-        switch (dwMinState) {
-            case D3DTFN_POINT:  gl_state = GL_NEAREST_MIPMAP_LINEAR; break;
-	    case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_LINEAR;  break;
-	    default:            gl_state = GL_LINEAR_MIPMAP_LINEAR;  break;
-	}
-    }
-    return gl_state;
-}
-
-static GLenum
-convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState)
-{
-    GLenum gl_state;
-
-    switch (dwState) {
-        case D3DTFG_POINT:
-	    gl_state = GL_NEAREST;
-	    break;
-        case D3DTFG_LINEAR:
-	    gl_state = GL_LINEAR;
-	    break;
-        default:
-	    gl_state = GL_LINEAR;
-	    break;
-    }
-    return gl_state;
-}
-
-static GLenum
-convert_tex_address_to_GL(D3DTEXTUREADDRESS dwState)
-{
-    GLenum gl_state;
-    switch (dwState) {
-        case D3DTADDRESS_WRAP:   gl_state = GL_REPEAT; break;
-	case D3DTADDRESS_CLAMP:  gl_state = GL_CLAMP; break;
-	case D3DTADDRESS_BORDER: gl_state = GL_CLAMP_TO_EDGE; break;
-	case D3DTADDRESS_MIRROR:
-	    if (GL_extensions.mirrored_repeat) {
-		gl_state = GL_MIRRORED_REPEAT_WINE;
-	    } else {
-		gl_state = GL_REPEAT;
-		/* This is a TRACE instead of a FIXME as the FIXME was already printed when the game
-		   actually set D3DTADDRESS_MIRROR.
-		*/
-		TRACE(" setting GL_REPEAT instead of GL_MIRRORED_REPEAT.\n");
-	    }
-	break;
-	default:                 gl_state = GL_REPEAT; break;
-    }
-    return gl_state;
-}
-
-HRESULT
-gltex_upload_texture(IDirectDrawSurfaceImpl *surf_ptr, IDirect3DDeviceImpl *d3ddev, DWORD stage) {
-    IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
-    IDirect3DDeviceGLImpl *gl_d3ddev = (IDirect3DDeviceGLImpl *) d3ddev;
-    BOOLEAN changed = FALSE;
-    GLenum unit = GL_TEXTURE0_WINE + stage;
-    
-    if (surf_ptr->mipmap_level != 0) {
-        WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", surf_ptr->mipmap_level);
-    }
-
-    /* Now check if the texture parameters for this texture are still in-line with what D3D expect
-       us to do..
-
-       NOTE: there is no check for the situation where the same texture is bound to multiple stage
-             but with different parameters per stage.
-    */
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_MAXMIPLEVEL - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1])) {
-	DWORD max_mip_level;
-	
-	if ((surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) == 0) {
-	    max_mip_level = 0;
-	} else {
-	    max_mip_level = surf_ptr->surface_desc.u2.dwMipMapCount - 1;
-	    if (d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1] != 0) {
-		if (max_mip_level >= d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1]) {
-		    max_mip_level = d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1] - 1;
-		}
-	    }
-	}
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_mip_level);
-	changed = TRUE;
-    }
-    
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_MAGFILTER - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAGFILTER - 1])) {
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
-			convert_mag_filter_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAGFILTER - 1]));
-	changed = TRUE;
-    }
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_MINFILTER - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_MINFILTER - 1]) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_MIPFILTER - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_MIPFILTER - 1])) {
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-			convert_min_filter_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_MINFILTER - 1],
-						 d3ddev->state_block.texture_stage_state[stage][D3DTSS_MIPFILTER - 1]));
-	changed = TRUE;
-    }
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_ADDRESSU - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1])) {
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-			convert_tex_address_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1]));
-	changed = TRUE;
-    }
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_ADDRESSV - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSV - 1])) {
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-			convert_tex_address_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSV - 1]));	
-	changed = TRUE;
-    }
-    if ((gl_surf_ptr->tex_parameters == NULL) ||
-	(gl_surf_ptr->tex_parameters[D3DTSS_BORDERCOLOR - D3DTSS_ADDRESSU] != 
-	 d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1])) {
-	GLfloat color[4];
-	
-	color[0] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 16) & 0xFF) / 255.0;
-	color[1] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >>  8) & 0xFF) / 255.0;
-	color[2] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >>  0) & 0xFF) / 255.0;
-	color[3] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 24) & 0xFF) / 255.0;
-	if (unit != gl_d3ddev->current_active_tex_unit) {
-	    GL_extensions.glActiveTexture(unit);
-	    gl_d3ddev->current_active_tex_unit = unit;
-	}
-	glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
-	changed = TRUE;
-    }
-
-    if (changed) {
-	if (gl_surf_ptr->tex_parameters == NULL) {
-	    gl_surf_ptr->tex_parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-						    sizeof(DWORD) * (D3DTSS_MAXMIPLEVEL + 1 - D3DTSS_ADDRESSU));
-	}
-	memcpy(gl_surf_ptr->tex_parameters, &(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1]),
-	       sizeof(DWORD) * (D3DTSS_MAXMIPLEVEL + 1 - D3DTSS_ADDRESSU));
-    }
-
-    if (*(gl_surf_ptr->global_dirty_flag) != SURFACE_MEMORY_DIRTY) {
-	TRACE(" nothing to do - memory copy and GL state in synch for all texture levels.\n");
-	return DD_OK;
-    }
-    
-    while (surf_ptr != NULL) {
-        IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
-	
-	if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) {
-            TRACE("   - level %d already uploaded.\n", surf_ptr->mipmap_level);
-	} else {
-	    TRACE("   - uploading texture level %d (initial done = %d).\n",
-		  surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
-
-	    /* Texture snooping for the curious :-) */
-	    if (TRACE_ON(ddraw_tex)) {
-		snoop_texture(surf_ptr);
-	    }
-
-	    if (unit != gl_d3ddev->current_active_tex_unit) {
-		GL_extensions.glActiveTexture(unit);
-		gl_d3ddev->current_active_tex_unit = unit;
-	    }
-	    
-	    if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
-						  gl_surf_ptr->initial_upload_done == FALSE, TRUE, 0, 0) == DD_OK) {
-	        upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr));
-		upload_surface_to_tex_memory_release();
-		gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
-		gl_surf_ptr->initial_upload_done = TRUE;
-	    } else {
-		ERR("Problem for upload of texture %d (level = %d / initial done = %d).\n",
-		    gl_surf_ptr->tex_name, surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
-	    }
-	}
-	
-	if (surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
-	    surf_ptr = get_sub_mimaplevel(surf_ptr);
-	} else {
-	    surf_ptr = NULL;
-	}
-    }
-    
-    *(gl_surf_ptr->global_dirty_flag) = SURFACE_MEMORY;
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
-                                       LPDIRECT3DDEVICE lpDirect3DDevice,
-                                       LPDIRECTDRAWSURFACE lpDDSurface)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
-    FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
-    return DD_OK;
-}
-
-static HRESULT
-gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY ckey )
-{
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-
-    if (glThis->dirty_flag == SURFACE_GL) {
-	GLint cur_tex;
-
-	TRACE(" flushing GL texture back to memory.\n");
-	
-	ENTER_GL();
-	glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
-	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-	gltex_download_texture(This);
-	glBindTexture(GL_TEXTURE_2D, cur_tex);
-	LEAVE_GL();
-    }
-
-    glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
-    *(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY;
-    /* TODO: check color-keying on mipmapped surfaces... */
-    
-    return DD_OK;
-}
-
-HRESULT
-gltex_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
-	  LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
-	  DWORD dwFlags, LPDDBLTFX lpbltfx)
-{
-    if (src != NULL) {
-	IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
-	if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) {
-	    FIXME("Blt from framebuffer to texture - unsupported now, please report !\n");
-	}
-    }
-    return DDERR_INVALIDPARAMS;
-}
-
-HRESULT
-gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx,
-	      DWORD dsty, LPDIRECTDRAWSURFACE7 src,
-	      LPRECT rsrc, DWORD trans)
-{
-    if (src != NULL) {
-	IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
-	
-	if ((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
-	    ((trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) == 0)) {
-	    /* This is a blt without color keying... We can use the direct copy. */
-	    RECT rsrc2;
-	    DWORD width, height;
-	    GLint cur_tex;
-	    IDirect3DTextureGLImpl *gl_surf_ptr = surf_ptr->tex_private;
-	    int y;
-	    
-	    if (rsrc == NULL) {
-		WARN("rsrc is NULL\n");
-		rsrc = &rsrc2;
-		
-		rsrc->left = 0;
-		rsrc->top = 0;
-		rsrc->right = src_ptr->surface_desc.dwWidth;
-		rsrc->bottom = src_ptr->surface_desc.dwHeight;
-	    }
-	    
-	    width = rsrc->right - rsrc->left;
-	    height = rsrc->bottom - rsrc->top;
-	    
-	    if (((dstx + width)  > surf_ptr->surface_desc.dwWidth) ||
-		((dsty + height) > surf_ptr->surface_desc.dwHeight)) {
-		FIXME("Does not handle clipping yet in FB => Texture blits !\n");
-		return DDERR_INVALIDPARAMS;
-	    }
-
-	    if ((width == 0) || (height == 0)) {
-		return DD_OK;
-	    }
-	    
-	    TRACE(" direct frame buffer => texture BltFast override.\n");
-	    
-	    ENTER_GL();
-	    
-	    glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
-	    /* This call is to create the actual texture name in GL (as we do 'late' ID creation) */
-	    gltex_get_tex_name(surf_ptr);
-	    glBindTexture(GL_TEXTURE_2D, gl_surf_ptr->tex_name);
-	    
-	    if ((gl_surf_ptr->dirty_flag == SURFACE_MEMORY_DIRTY) &&
-		!((dstx == 0) && (dsty == 0) &&
-		  (width == surf_ptr->surface_desc.dwWidth) && (height == surf_ptr->surface_desc.dwHeight))) {
-		/* If not 'full size' and the surface is dirty, first flush it to GL before doing the copy. */
-	        if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
-						      gl_surf_ptr->initial_upload_done == FALSE, TRUE, 0, 0) == DD_OK) {
-		    upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr));
-		    upload_surface_to_tex_memory_release();
-		    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
-		    gl_surf_ptr->initial_upload_done = TRUE;
-		} else {
-		    glBindTexture(GL_TEXTURE_2D, cur_tex);
-		    LEAVE_GL();
-		    ERR("Error at texture upload !\n");
-		    return DDERR_INVALIDPARAMS;
-		}
-	    }
-
-	    /* This is a hack and would need some clean-up :-) */
-	    if (gl_surf_ptr->initial_upload_done == FALSE) {
-		if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
-						      TRUE, TRUE, 0, 0) == DD_OK) {
-		    upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr));
-		    upload_surface_to_tex_memory_release();
-		    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
-		    gl_surf_ptr->initial_upload_done = TRUE;
-		} else {
-		    glBindTexture(GL_TEXTURE_2D, cur_tex);
-		    LEAVE_GL();
-		    ERR("Error at texture upload (initial case) !\n");
-		    return DDERR_INVALIDPARAMS;
-		}
-	    }
-	    
-	    if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0)
-		glReadBuffer(GL_FRONT);
-	    else if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER))
-		glReadBuffer(GL_BACK);
-	    else {
-		ERR("Wrong surface type for locking !\n");
-		glBindTexture(GL_TEXTURE_2D, cur_tex);
-		LEAVE_GL();
-		return DDERR_INVALIDPARAMS;
-	    }
-	    
-	    for (y = (src_ptr->surface_desc.dwHeight - rsrc->top - 1);
-		 y >= (src_ptr->surface_desc.dwHeight - (rsrc->top + height));
-		 y--) {
-		glCopyTexSubImage2D(GL_TEXTURE_2D, surf_ptr->mipmap_level,
-				    dstx, dsty,
-				    rsrc->left, y,
-				    width, 1);
-		dsty++;
-	    }
-	    
-	    glBindTexture(GL_TEXTURE_2D, cur_tex);
-	    LEAVE_GL();
-	    
-	    /* The SURFACE_GL case is not handled by the 'global' dirty flag */
-	    gl_surf_ptr->dirty_flag = SURFACE_GL;
-	    
-	    return DD_OK;
-	}
-    }
-    return DDERR_INVALIDPARAMS;
-}
-
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
-                                              DWORD dwStart,
-                                              DWORD dwCount)
+/*****************************************************************************
+ * IDirect3DTexture2::Load
+ *
+ * Loads a texture created with the DDSCAPS_ALLOCONLOAD
+ *
+ * This function isn't relayed to WineD3D because the whole interface is
+ * implemented in DDraw only. For speed improvements a implementation which
+ * takes OpenGL more into account could be placed into WineD3D.
+ *
+ * Params:
+ *  D3DTexture2: Address of the texture to load
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_TEXTURE_LOAD_FAILED.
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DTextureImpl_Load(IDirect3DTexture2 *iface,
+                          IDirect3DTexture2 *D3DTexture2)
 {
     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
-    FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
-    FIXME("(%p/%p)->(): stub!\n", This, iface);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
-					 LPDIRECT3DDEVICE2 lpDirect3DDevice2,
-					 LPD3DTEXTUREHANDLE lpHandle)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
-    IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
-    
-    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
-
-    /* The handle is simply the pointer to the implementation structure */
-    *lpHandle = (D3DTEXTUREHANDLE) This;
-
-    TRACE(" returning handle %08lx.\n", *lpHandle);
-    
-    /* Now set the device for this texture */
-    This->d3ddevice = lpDeviceImpl;
-
-    return D3D_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
-				    LPDIRECT3DTEXTURE2 lpD3DTexture2)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
-    return DD_OK;
-}
-
-static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal)
-{
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-
-    if (glThis->dirty_flag == SURFACE_GL) {
-	GLint cur_tex;
-	
-	TRACE(" flushing GL texture back to memory.\n");
-	
-	ENTER_GL();
-	glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
-	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-	gltex_download_texture(This);
-	glBindTexture(GL_TEXTURE_2D, cur_tex);
-	LEAVE_GL();
-    }
-    
-    /* First call the previous set_palette function */
-    glThis->set_palette(This, pal);
-    
-    /* And set the dirty flag */
-    glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
-    *(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY;
-    
-    /* TODO: check palette on mipmapped surfaces...
-       TODO: do we need to re-upload in case of usage of the paletted texture extension ? */
-}
-
-static void
-gltex_final_release(IDirectDrawSurfaceImpl *This)
-{
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-    DWORD mem_used;
-    int i;
-
-    TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
-
-    /* And delete texture handle */
-    ENTER_GL();
-    if (glThis->tex_name != 0)
-        glDeleteTextures(1, &(glThis->tex_name));
-    LEAVE_GL();	
-
-    HeapFree(GetProcessHeap(), 0, glThis->surface_ptr);
-
-    /* And if this texture was the current one, remove it at the device level */
-    if (This->d3ddevice != NULL)
-        for (i = 0; i < MAX_TEXTURES; i++)
-	    if (This->d3ddevice->current_texture[i] == This)
-	        This->d3ddevice->current_texture[i] = NULL;
-
-    /* All this should be part of main surface management not just a hack for texture.. */
-    if (glThis->loaded) {
-        mem_used = This->surface_desc.dwHeight *
-	           This->surface_desc.u1.lPitch;
-	This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
-    }
-
-    glThis->final_release(This);
-}
-
-static void
-gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
-{
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-    
-    glThis->lock_update(This, pRect, dwFlags);
-}
-
-static void
-gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
-{
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-
-    glThis->unlock_update(This, pRect);
-    
-    /* Set the dirty flag according to the lock type */
-    if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
-        glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
-	*(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY;
-    }
-}
-
-HRESULT WINAPI
-GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
-				  LPDIRECT3DTEXTURE2 lpD3DTexture2)
-{
-    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
-    IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
-    IDirectDrawSurfaceImpl *dst_ptr = This;
+    IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, D3DTexture2);
+    IWineD3DPalette *wine_pal, *wine_pal_src;
+    IDirectDrawPalette *pal = NULL, *pal_src = NULL;
+    IDirectDrawPaletteImpl *pal_impl, *pal_impl_src;
     HRESULT ret_value = D3D_OK;
-   
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
 
-    if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) ||
-	(src_ptr->surface_desc.u2.dwMipMapCount != dst_ptr->surface_desc.u2.dwMipMapCount)) {
+    TRACE("(%p)->(%p)\n", This, src_ptr);
+
+    if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) ||
+        (src_ptr->surface_desc.u2.dwMipMapCount != This->surface_desc.u2.dwMipMapCount))
+    {
         ERR("Trying to load surfaces with different mip-map counts !\n");
     }
 
-    /* Now loop through all mipmap levels and load all of them... */
-    while (1) {
-        IDirect3DTextureGLImpl *gl_dst_ptr = (IDirect3DTextureGLImpl *) dst_ptr->tex_private;
-	DDSURFACEDESC *src_d, *dst_d;
-	
-	if (gl_dst_ptr != NULL) {
-	    if (gl_dst_ptr->loaded == FALSE) {
-	        /* Only check memory for not already loaded texture... */
-	        DWORD mem_used;
-		if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
-                    mem_used = dst_ptr->surface_desc.u1.dwLinearSize;
-		else
-                    mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch;
-		if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
-		    TRACE(" out of virtual memory... Warning application.\n");
-		    return D3DERR_TEXTURE_LOAD_FAILED;
-		}
-	    }
-	    gl_dst_ptr->loaded = TRUE;
-	}
-    
-	TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, dst_ptr, src_ptr->mipmap_level);
+    while(1)
+    {
+        DDSURFACEDESC *src_d, *dst_d;
 
-	if ( dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
-	    /* If the surface is not allocated and its location is not yet specified,
-	       force it to video memory */ 
-	    if ( !(dst_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
-	        dst_ptr->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+        TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level);
 
-	/* Suppress the ALLOCONLOAD flag */
-	dst_ptr->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
-    
-	/* After seeing some logs, not sure at all about this... */
-	if (dst_ptr->palette == NULL) {
-	    dst_ptr->palette = src_ptr->palette;
-	    if (src_ptr->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette));
-	} else {
-	    if (src_ptr->palette != NULL) {
-	        PALETTEENTRY palent[256];
-		IDirectDrawPalette_GetEntries(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette),
-					      0, 0, 256, palent);
-		IDirectDrawPalette_SetEntries(ICOM_INTERFACE(dst_ptr->palette, IDirectDrawPalette),
-					      0, 0, 256, palent);
-	    }
-	}
-	
-	/* Copy one surface on the other */
-	dst_d = (DDSURFACEDESC *)&(dst_ptr->surface_desc);
-	src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc);
+        if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
+            /* If the surface is not allocated and its location is not yet specified,
+              force it to video memory */ 
+            if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
+                This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
 
-	if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
-	    /* Should also check for same pixel format, u1.lPitch, ... */
-	    ERR("Error in surface sizes\n");
-	    return D3DERR_TEXTURE_LOAD_FAILED;
-	} else {
-	    /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
-	    /* I should put a macro for the calculus of bpp */
-	  
-	    /* Copy also the ColorKeying stuff */
-	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-	        dst_d->dwFlags |= DDSD_CKSRCBLT;
-		dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
-		dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
-	    }
+        /* Suppress the ALLOCONLOAD flag */
+        This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
 
-	    /* Copy the main memory texture into the surface that corresponds to the OpenGL
-	       texture object. */
-	    if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
-	        memcpy(dst_d->lpSurface, src_d->lpSurface, src_ptr->surface_desc.u1.dwLinearSize);
-	    else
-	        memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
+        /* Get the palettes */
+        ret_value = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wine_pal);
+        if( ret_value != D3D_OK)
+        {
+            ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
+            return D3DERR_TEXTURE_LOAD_FAILED;
+        }
+        if(wine_pal)
+        {
+            ret_value = IWineD3DPalette_GetParent(wine_pal, (IUnknown **) &pal);
+            if(ret_value != D3D_OK)
+            {
+                ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
+                return D3DERR_TEXTURE_LOAD_FAILED;
+            }
+            pal_impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal);
+        }
+        else
+        {
+          pal_impl = NULL;
+        }
 
-	    if (gl_dst_ptr != NULL) {
-		/* Set this texture as dirty */
-		gl_dst_ptr->dirty_flag = SURFACE_MEMORY_DIRTY;
-		*(gl_dst_ptr->global_dirty_flag) = SURFACE_MEMORY_DIRTY;
-	    }
-	}
+        ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src);
+        if( ret_value != D3D_OK)
+        {
+            ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
+            return D3DERR_TEXTURE_LOAD_FAILED;
+        }
+        if(wine_pal_src)
+        {
+            ret_value = IWineD3DPalette_GetParent(wine_pal_src, (IUnknown **) &pal_src);
+            if(ret_value != D3D_OK)
+            {
+                ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
+                return D3DERR_TEXTURE_LOAD_FAILED;
+            }
+            pal_impl_src = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal_src);
+        }
+        else
+        {
+            pal_impl_src = NULL;
+        }
 
-	if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
-	    src_ptr = get_sub_mimaplevel(src_ptr);
-	} else {
-	    src_ptr = NULL;
-	}
-	if (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
-	    dst_ptr = get_sub_mimaplevel(dst_ptr);
-	} else {
-	    dst_ptr = NULL;
-	}
+        /* After seeing some logs, not sure at all about this... */
+        if (pal_impl == NULL)
+        {
+            IWineD3DSurface_SetPalette(This->WineD3DSurface, wine_pal);
+            if (pal_impl_src != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette));
+        }
+        else
+        {
+            if (pal_impl_src != NULL)
+            {
+                PALETTEENTRY palent[256];
+                IDirectDrawPalette_GetEntries(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette),
+                                              0, 0, 256, palent);
+                IDirectDrawPalette_SetEntries(ICOM_INTERFACE(pal_impl, IDirectDrawPalette),
+                                              0, 0, 256, palent);
+            }
+        }
 
-	if ((src_ptr == NULL) || (dst_ptr == NULL)) {
-	    if (src_ptr != dst_ptr) {
-	        ERR(" Loading surface with different mipmap structure !!!\n");
-	    }
-	    break;
-	}
+        /* Copy one surface on the other */
+        dst_d = (DDSURFACEDESC *)&(This->surface_desc);
+        src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc);
+
+        if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight))
+        {
+            /* Should also check for same pixel format, u1.lPitch, ... */
+            ERR("Error in surface sizes\n");
+            return D3DERR_TEXTURE_LOAD_FAILED;
+        }
+        else
+        {
+            WINED3DLOCKED_RECT pSrcRect, pDstRect;
+
+            /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
+            /* I should put a macro for the calculus of bpp */
+
+            /* Copy also the ColorKeying stuff */
+            if (src_d->dwFlags & DDSD_CKSRCBLT)
+            {
+                dst_d->dwFlags |= DDSD_CKSRCBLT;
+                dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
+                dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
+            }
+
+            /* Copy the main memory texture into the surface that corresponds to the OpenGL
+              texture object. */
+
+            ret_value = IWineD3DSurface_LockRect(src_ptr->WineD3DSurface, &pSrcRect, NULL, 0);
+            if(ret_value != D3D_OK)
+            {
+                ERR(" (%p) Locking the source surface failed\n", This);
+                return D3DERR_TEXTURE_LOAD_FAILED;
+            }
+
+            ret_value = IWineD3DSurface_LockRect(This->WineD3DSurface, &pDstRect, NULL, 0);
+            if(ret_value != D3D_OK)
+            {
+                ERR(" (%p) Locking the destination surface failed\n", This);
+                IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface);
+                return D3DERR_TEXTURE_LOAD_FAILED;
+            }
+
+            if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
+                memcpy(pDstRect.pBits, pSrcRect.pBits, src_ptr->surface_desc.u1.dwLinearSize);
+            else
+                memcpy(pDstRect.pBits, pSrcRect.pBits, pSrcRect.Pitch * src_d->dwHeight);
+
+            IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface);
+            IWineD3DSurface_UnlockRect(This->WineD3DSurface);
+        }
+
+        if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+        {
+            src_ptr = get_sub_mimaplevel(src_ptr);
+        }
+        else
+        {
+            src_ptr = NULL;
+        }
+        if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+        {
+            This = get_sub_mimaplevel(This);
+        }
+        else
+        {
+            This = NULL;
+        }
+
+        if ((src_ptr == NULL) || (This == NULL))
+        {
+            if (src_ptr != This)
+            {
+                ERR(" Loading surface with different mipmap structure !!!\n");
+            }
+            break;
+        }
     }
 
     return ret_value;
 }
 
-HRESULT WINAPI
-Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
-                                            REFIID riid,
-                                            LPVOID* obp)
+static HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface,
+                                  IDirect3DTexture *D3DTexture)
 {
-    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
-					      riid,
-					      obp);
-}
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
+    IDirectDrawSurfaceImpl *Texture = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTexture);
+    TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture);
 
-ULONG WINAPI
-Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
-    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
-{
-    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
-    return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
-                                            REFIID riid,
-                                            LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
-					      riid,
-					      obp);
-}
-
-ULONG WINAPI
-Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
-{
-    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
-    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
-}
-
-ULONG WINAPI
-Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
-{
-    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
-    return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
-                                            DWORD dwStart,
-                                            DWORD dwCount)
-{
-    TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
-    return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
-                                            dwStart,
-                                            dwCount);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
-				       LPDIRECT3DDEVICE lpDirect3DDevice,
-				       LPD3DTEXTUREHANDLE lpHandle)
-{
-    TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
-    return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
-				       COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
-				       lpHandle);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
-				  LPDIRECT3DTEXTURE lpD3DTexture)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
     return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
-				  COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
+                                  COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, D3DTexture));
 }
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture2.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DTexture2Vtbl VTABLE_IDirect3DTexture2 =
+/*****************************************************************************
+ * The VTables
+ *****************************************************************************/
+const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl =
 {
-    XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
-    XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
-    XCAST(GetHandle) Main_IDirect3DTextureImpl_2_1T_GetHandle,
-    XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
-    XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
+    Thunk_IDirect3DTextureImpl_2_QueryInterface,
+    Thunk_IDirect3DTextureImpl_2_AddRef,
+    Thunk_IDirect3DTextureImpl_2_Release,
+    IDirect3DTextureImpl_GetHandle,
+    IDirect3DTextureImpl_PaletteChanged,
+    IDirect3DTextureImpl_Load,
 };
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
 
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DTextureVtbl VTABLE_IDirect3DTexture =
+const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl =
 {
-    XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_1_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DTextureImpl_1_AddRef,
-    XCAST(Release) Thunk_IDirect3DTextureImpl_1_Release,
-    XCAST(Initialize) Main_IDirect3DTextureImpl_1_Initialize,
-    XCAST(GetHandle) Thunk_IDirect3DTextureImpl_1_GetHandle,
-    XCAST(PaletteChanged) Thunk_IDirect3DTextureImpl_1_PaletteChanged,
-    XCAST(Load) Thunk_IDirect3DTextureImpl_1_Load,
-    XCAST(Unload) Main_IDirect3DTextureImpl_1_Unload,
+    Thunk_IDirect3DTextureImpl_1_QueryInterface,
+    Thunk_IDirect3DTextureImpl_1_AddRef,
+    Thunk_IDirect3DTextureImpl_1_Release,
+    IDirect3DTextureImpl_1_Initialize,
+    Thunk_IDirect3DTextureImpl_1_GetHandle,
+    Thunk_IDirect3DTextureImpl_1_PaletteChanged,
+    Thunk_IDirect3DTextureImpl_1_Load,
+    IDirect3DTextureImpl_1_Unload,
 };
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, 
-			  IDirectDrawSurfaceImpl *main)
-{
-    /* First, initialize the texture vtables... */
-    ICOM_INIT_INTERFACE(surf, IDirect3DTexture,  VTABLE_IDirect3DTexture);
-    ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
-	
-    /* Only create all the private stuff if we actually have an OpenGL context.. */
-    if (d3d->current_device != NULL) {
-        IDirect3DTextureGLImpl *private;
-
-        private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
-	if (private == NULL) return DDERR_OUTOFMEMORY;
-
-	surf->tex_private = private;
-	
-	private->final_release = surf->final_release;
-	private->lock_update = surf->lock_update;
-	private->unlock_update = surf->unlock_update;
-	private->set_palette = surf->set_palette;
-	
-	/* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
-	   Otherwise, it will be uploaded here (and may be invalid). */
-	surf->final_release = gltex_final_release;
-	surf->lock_update = gltex_lock_update;
-	surf->unlock_update = gltex_unlock_update;
-	surf->aux_setcolorkey_cb = gltex_setcolorkey_cb;
-	surf->set_palette = gltex_set_palette;
-
-	/* We are the only one to use the aux_blt and aux_bltfast overrides, so no need
-	   to save those... */
-	surf->aux_blt = gltex_blt;
-	surf->aux_bltfast = gltex_bltfast;
-	
-	TRACE(" GL texture created for surface %p (private data at %p)\n", surf, private);
-
-	/* Do not create the OpenGL texture id here as some game generate textures from a different thread which
-	    cause problems.. */
-	private->tex_name = 0;
-	if (surf->mipmap_level == 0) {
-	    private->main = NULL;
-	    private->__global_dirty_flag = SURFACE_MEMORY_DIRTY;
-	    private->global_dirty_flag = &(private->__global_dirty_flag);
-	} else {
-	    private->main = main;
-	    private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (private->main->tex_private))->__global_dirty_flag);
-	}
-	private->initial_upload_done = FALSE;
-	private->dirty_flag = SURFACE_MEMORY_DIRTY;
-    }
-
-    return D3D_OK;
-}
-
-GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *surf)
-{
-    IDirect3DTextureGLImpl *private = (IDirect3DTextureGLImpl *) (surf->tex_private);
-    
-    if (private->tex_name == 0) {
-	/* The texture was not created yet... */	
-	ENTER_GL();
-	if (surf->mipmap_level == 0) {
-	    glGenTextures(1, &(private->tex_name));
-	    if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
-	    TRACE(" GL texture id is : %d.\n", private->tex_name);
-	} else {
-	    private->tex_name = gltex_get_tex_name(private->main);
-	    TRACE(" GL texture id reusing id %d from surface %p (private at %p)).\n", private->tex_name, private->main, private->main->tex_private);
-	}
-	LEAVE_GL();
-    }
-    return ((IDirect3DTextureGLImpl *) (surf->tex_private))->tex_name;
-}
diff --git a/dlls/ddraw/utils.c b/dlls/ddraw/utils.c
new file mode 100644
index 0000000..2ffd51b
--- /dev/null
+++ b/dlls/ddraw/utils.c
@@ -0,0 +1,1171 @@
+/*
+ * DirectDraw helper functions
+ *
+ * Copyright (c) 1997-2000 Marcus Meissner
+ * Copyright (c) 1998 Lionel Ulmer
+ * Copyright (c) 2000 TransGaming Technologies Inc.
+ * Copyright (c) 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#define NONAMELESSUNION
+
+#include "ddraw_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+void DDRAW_dump_flags_(DWORD flags, const flag_info* names, size_t num_names, int newline);
+
+/*****************************************************************************
+ * PixelFormat_WineD3DtoDD
+ *
+ * Converts an WINED3DFORMAT value into a DDPIXELFORMAT structure
+ *
+ * Params:
+ *  DDPixelFormat: Address of the structure to write the pixel format to
+ *  WineD3DFormat: Source format
+ *
+ *****************************************************************************/
+void
+PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat,
+                        WINED3DFORMAT WineD3DFormat)
+{
+    DWORD Size = DDPixelFormat->dwSize;
+    TRACE("Converting WINED3DFORMAT %d to DDRAW\n", WineD3DFormat);
+
+    if(Size==0) return;
+
+    memset(DDPixelFormat, 0x00, Size);
+    DDPixelFormat->dwSize = Size;
+    switch(WineD3DFormat)
+    {
+        case WINED3DFMT_R8G8B8:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 24;
+            DDPixelFormat->u2.dwRBitMask = 0x00ff0000;
+            DDPixelFormat->u3.dwGBitMask = 0x0000ff00;
+            DDPixelFormat->u4.dwBBitMask = 0x000000ff;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_A8R8G8B8:
+            DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 32;
+            DDPixelFormat->u2.dwRBitMask = 0x00ff0000;
+            DDPixelFormat->u3.dwGBitMask = 0x0000ff00;
+            DDPixelFormat->u4.dwBBitMask = 0x000000ff;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0xff000000;
+            break;
+
+        case WINED3DFMT_X8R8G8B8:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 32;
+            DDPixelFormat->u2.dwRBitMask = 0x00ff0000;
+            DDPixelFormat->u3.dwGBitMask = 0x0000ff00;
+            DDPixelFormat->u4.dwBBitMask = 0x000000ff;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_X8B8G8R8:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 32;
+            DDPixelFormat->u2.dwRBitMask = 0x000000ff;
+            DDPixelFormat->u3.dwGBitMask = 0x0000ff00;
+            DDPixelFormat->u4.dwBBitMask = 0x00ff0000;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_R5G6B5:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0xF800;
+            DDPixelFormat->u3.dwGBitMask = 0x07E0;
+            DDPixelFormat->u4.dwBBitMask = 0x001F;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_X1R5G5B5:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0x7C00;
+            DDPixelFormat->u3.dwGBitMask = 0x03E0;
+            DDPixelFormat->u4.dwBBitMask = 0x001F;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_A1R5G5B5:
+            DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0x7C00;
+            DDPixelFormat->u3.dwGBitMask = 0x03E0;
+            DDPixelFormat->u4.dwBBitMask = 0x001F;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x8000;
+            break;
+
+        case WINED3DFMT_A4R4G4B4:
+            DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0x0F00;
+            DDPixelFormat->u3.dwGBitMask = 0x00F0;
+            DDPixelFormat->u4.dwBBitMask = 0x000F;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000;
+            break;
+
+        case WINED3DFMT_R3G3B2:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 8;
+            DDPixelFormat->u2.dwRBitMask = 0xE0;
+            DDPixelFormat->u3.dwGBitMask = 0x1C;
+            DDPixelFormat->u4.dwBBitMask = 0x03;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_P8:
+            DDPixelFormat->dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 8;
+            DDPixelFormat->u2.dwRBitMask = 0x00;
+            DDPixelFormat->u3.dwGBitMask = 0x00;
+            DDPixelFormat->u4.dwBBitMask = 0x00;
+            break;
+
+        case WINED3DFMT_A8:
+            DDPixelFormat->dwFlags = DDPF_ALPHA;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwAlphaBitDepth = 8;
+            DDPixelFormat->u2.dwRBitMask = 0x0;
+            DDPixelFormat->u3.dwZBitMask = 0x0;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_A8R3G3B2:
+            DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0x00E0;
+            DDPixelFormat->u3.dwGBitMask = 0x001C;
+            DDPixelFormat->u4.dwBBitMask = 0x0003;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000;
+            break;
+
+        case WINED3DFMT_X4R4G4B4:
+            DDPixelFormat->dwFlags = DDPF_RGB;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwRGBBitCount = 16;
+            DDPixelFormat->u2.dwRBitMask = 0x0F00;
+            DDPixelFormat->u3.dwGBitMask = 0x00F0;
+            DDPixelFormat->u4.dwBBitMask = 0x000F;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            return;
+
+        /* How are Z buffer bit depth and Stencil buffer bit depth related?
+         */
+        case WINED3DFMT_D16:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwZBufferBitDepth = 16;
+            DDPixelFormat->u2.dwStencilBitDepth = 0;
+            DDPixelFormat->u3.dwZBitMask = 0x0000FFFF;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBZBitMask = 0x0000FFFF;
+            break;
+
+        case WINED3DFMT_D32:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwZBufferBitDepth = 32;
+            DDPixelFormat->u2.dwStencilBitDepth = 0;
+            DDPixelFormat->u3.dwZBitMask = 0xFFFFFFFF;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBZBitMask = 0xFFFFFFFF;
+            break;
+
+        case WINED3DFMT_D24X4S4:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            /* Should I set dwZBufferBitDepth to 32 here? */
+            DDPixelFormat->u1.dwZBufferBitDepth = 24;
+            DDPixelFormat->u2.dwStencilBitDepth = 4;
+            DDPixelFormat->u3.dwZBitMask = 0x0;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_D24S8:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            /* Should I set dwZBufferBitDepth to 32 here? */
+            DDPixelFormat->u1.dwZBufferBitDepth = 24;
+            DDPixelFormat->u2.dwStencilBitDepth = 8;
+            DDPixelFormat->u3.dwZBitMask = 0x0;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_D24X8:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwZBufferBitDepth = 24;
+            DDPixelFormat->u2.dwStencilBitDepth = 8;
+            DDPixelFormat->u3.dwZBitMask = 0x0;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+
+            break;
+        case WINED3DFMT_D15S1:
+            DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER;
+            DDPixelFormat->dwFourCC = 0;
+            /* Should I set dwZBufferBitDepth to 16 here? */
+            DDPixelFormat->u1.dwZBufferBitDepth = 15;
+            DDPixelFormat->u2.dwStencilBitDepth = 1;
+            DDPixelFormat->u3.dwZBitMask = 0x0;
+            DDPixelFormat->u4.dwStencilBitMask = 0x0;
+            DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_UYVY:
+        case WINED3DFMT_YUY2:
+        case WINED3DFMT_DXT1:
+        case WINED3DFMT_DXT2:
+        case WINED3DFMT_DXT3:
+        case WINED3DFMT_DXT4:
+        case WINED3DFMT_DXT5:
+        case WINED3DFMT_MULTI2_ARGB:
+        case WINED3DFMT_G8R8_G8B8:
+        case WINED3DFMT_R8G8_B8G8:
+            DDPixelFormat->dwFlags = DDPF_FOURCC;
+            DDPixelFormat->dwFourCC = WineD3DFormat;
+            break;
+
+        /* Luminance */
+        case WINED3DFMT_L8:
+            DDPixelFormat->dwFlags = DDPF_LUMINANCE;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwLuminanceBitCount = 8;
+            DDPixelFormat->u2.dwLuminanceBitMask = 0xff;
+            DDPixelFormat->u3.dwBumpDvBitMask = 0x0;
+            DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0;
+            break;
+
+        case WINED3DFMT_A4L4:
+            DDPixelFormat->dwFlags = DDPF_ALPHAPIXELS | DDPF_LUMINANCE;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwLuminanceBitCount = 4;
+            DDPixelFormat->u2.dwLuminanceBitMask = 0x0f;
+            DDPixelFormat->u3.dwBumpDvBitMask = 0x0;
+            DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0xf0;
+            break;
+
+        case WINED3DFMT_A8L8:
+            DDPixelFormat->dwFlags = DDPF_ALPHAPIXELS | DDPF_LUMINANCE;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwLuminanceBitCount = 16;
+            DDPixelFormat->u2.dwLuminanceBitMask = 0x00ff;
+            DDPixelFormat->u3.dwBumpDvBitMask = 0x0;
+            DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0xff00;
+            break;
+
+        /* Bump mapping */
+        case WINED3DFMT_V8U8:
+            DDPixelFormat->dwFlags = DDPF_BUMPDUDV;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwBumpBitCount = 16;
+            DDPixelFormat->u2.dwBumpDuBitMask =         0x000000ff;
+            DDPixelFormat->u3.dwBumpDvBitMask =         0x0000ff00;
+            DDPixelFormat->u4.dwBumpLuminanceBitMask =  0x00000000;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x00000000;
+            break;
+
+        case WINED3DFMT_L6V5U5:
+            DDPixelFormat->dwFlags = DDPF_BUMPDUDV;
+            DDPixelFormat->dwFourCC = 0;
+            DDPixelFormat->u1.dwBumpBitCount = 16;
+            DDPixelFormat->u2.dwBumpDuBitMask =         0x0000001f;
+            DDPixelFormat->u3.dwBumpDvBitMask =         0x000003e0;
+            DDPixelFormat->u4.dwBumpLuminanceBitMask =  0x0000fc00;
+            DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x00000000;
+            break;
+
+        default:
+            ERR("Can't translate this Pixelformat %d\n", WineD3DFormat);
+    }
+
+    if(TRACE_ON(ddraw)) {
+        TRACE("Returning: ");
+        DDRAW_dump_pixelformat(DDPixelFormat);
+        TRACE("\n");
+    }
+}
+/*****************************************************************************
+ * PixelFormat_DD2WineD3D
+ *
+ * Reads a DDPIXELFORMAT structure and returns the equal WINED3DFORMAT
+ *
+ * Params:
+ *  DDPixelFormat: The source format
+ *
+ * Returns:
+ *  The WINED3DFORMAT equal to the DDraw format
+ *  WINED3DFMT_UNKNOWN if a matching format wasn't found
+ *****************************************************************************/
+WINED3DFORMAT
+PixelFormat_DD2WineD3D(DDPIXELFORMAT *DDPixelFormat)
+{
+    TRACE("Convert a DirectDraw Pixelformat to a WineD3D Pixelformat\n");    
+    if(TRACE_ON(ddraw))
+    {
+        DDRAW_dump_pixelformat(DDPixelFormat);
+        TRACE("\n");
+    }
+
+    if(DDPixelFormat->dwFlags & DDPF_PALETTEINDEXED8)
+    {
+        return WINED3DFMT_P8;
+    }
+    else if(DDPixelFormat->dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4) )
+    {
+        FIXME("DDPF_PALETTEINDEXED1 to DDPF_PALETTEINDEXED4 are not supported by WineD3D (yet). Returning WINED3DFMT_P8\n");
+        return WINED3DFMT_P8;
+    }
+    else if(DDPixelFormat->dwFlags & DDPF_RGB)
+    {
+        switch(DDPixelFormat->u1.dwRGBBitCount)
+        {
+            case 8:
+                /* This is the only format that can match here */
+                return WINED3DFMT_R3G3B2;
+
+            case 16:
+                /* Read the Color masks */
+                if( (DDPixelFormat->u2.dwRBitMask == 0xF800) &&
+                    (DDPixelFormat->u3.dwGBitMask == 0x07E0) &&
+                    (DDPixelFormat->u4.dwBBitMask == 0x001F) )
+                {
+                    return WINED3DFMT_R5G6B5;
+                }
+
+                if( (DDPixelFormat->u2.dwRBitMask == 0x7C00) &&
+                    (DDPixelFormat->u3.dwGBitMask == 0x03E0) &&
+                    (DDPixelFormat->u4.dwBBitMask == 0x001F) )
+                {
+                    if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) &&
+                        (DDPixelFormat->u5.dwRGBAlphaBitMask == 0x8000))
+                        return WINED3DFMT_A1R5G5B5;
+                    else
+                        return WINED3DFMT_X1R5G5B5;
+                }
+
+                if( (DDPixelFormat->u2.dwRBitMask == 0x0F00) &&
+                    (DDPixelFormat->u3.dwGBitMask == 0x00F0) &&
+                    (DDPixelFormat->u4.dwBBitMask == 0x000F) )
+                {
+                    if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) &&
+                        (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xF000))
+                        return WINED3DFMT_A4R4G4B4;
+                    else
+                        return WINED3DFMT_X4R4G4B4;
+                }
+
+                if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) &&
+                    (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xFF00) &&
+                    (DDPixelFormat->u2.dwRBitMask == 0x00E0) &&
+                    (DDPixelFormat->u3.dwGBitMask == 0x001C) &&
+                    (DDPixelFormat->u4.dwBBitMask == 0x0003) )
+                {
+                    return WINED3DFMT_A8R3G3B2;
+                }
+                ERR("16 bit RGB Pixel format does not match\n");
+                return WINED3DFMT_UNKNOWN;
+
+            case 24:
+                return WINED3DFMT_R8G8B8;
+
+            case 32:
+                /* Read the Color masks */
+                if( (DDPixelFormat->u2.dwRBitMask == 0x00FF0000) &&
+                    (DDPixelFormat->u3.dwGBitMask == 0x0000FF00) &&
+                    (DDPixelFormat->u4.dwBBitMask == 0x000000FF) )
+                {
+                    if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) &&
+                        (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xFF000000))
+                        return WINED3DFMT_A8R8G8B8;
+                    else
+                        return WINED3DFMT_X8R8G8B8;
+
+                }
+                ERR("32 bit RGB pixel format does not match\n");
+
+            default:
+                ERR("Invalid dwRGBBitCount in Pixelformat structure\n");
+                return WINED3DFMT_UNKNOWN;
+        }
+    }
+    else if( (DDPixelFormat->dwFlags & DDPF_ALPHA) )
+    {
+        /* Alpha only Pixelformat */
+        switch(DDPixelFormat->u1.dwAlphaBitDepth)
+        {
+            case 1:
+            case 2:
+            case 4:
+                ERR("Unsupported Alpha-Only bit depth 0x%lx\n", DDPixelFormat->u1.dwAlphaBitDepth);
+            case 8:
+                return WINED3DFMT_A8;
+
+            default:
+                ERR("Invalid AlphaBitDepth in Alpha-Only Pixelformat\n");
+                return WINED3DFMT_UNKNOWN;
+        }
+    }
+    else if(DDPixelFormat->dwFlags & DDPF_LUMINANCE)
+    {
+        /* Luminance-only or luminance-alpha */
+        if(DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS)
+        {
+            /* Luminance with Alpha */
+            switch(DDPixelFormat->u1.dwLuminanceBitCount)
+            {
+                case 4:
+                    if(DDPixelFormat->u1.dwAlphaBitDepth == 4)
+                        return WINED3DFMT_A4L4;
+                    ERR("Unknown Alpha / Luminance bit depth combination\n");
+                    return WINED3DFMT_UNKNOWN;
+
+                case 6:
+                    ERR("A luminance Pixelformat shouldn't have 6 luminance bits. Returning D3DFMT_L6V5U5 for now!!\n");
+                    return WINED3DFMT_L6V5U5;
+
+                case 8:
+                    if(DDPixelFormat->u1.dwAlphaBitDepth == 8)
+                        return WINED3DFMT_A8L8;
+                    ERR("Unkown Alpha / Lumincase bit depth combination\n");
+                    return WINED3DFMT_UNKNOWN;
+            }
+        }
+        else
+        {
+            /* Luminance-only */
+            switch(DDPixelFormat->u1.dwLuminanceBitCount)
+            {
+                case 6:
+                    ERR("A luminance Pixelformat shouldn't have 6 luminance bits. Returning D3DFMT_L6V5U5 for now!!\n");
+                    return WINED3DFMT_L6V5U5;
+
+                case 8:
+                    return WINED3DFMT_L8;
+
+                default:
+                    ERR("Unkown luminance-only bit depth 0x%lx\n", DDPixelFormat->u1.dwLuminanceBitCount);
+                    return WINED3DFMT_UNKNOWN;
+             }
+        }
+    }
+    else if(DDPixelFormat->dwFlags & DDPF_ZBUFFER)
+    {
+        /* Z buffer */
+        if(DDPixelFormat->dwFlags & DDPF_STENCILBUFFER)
+        {
+            switch(DDPixelFormat->u1.dwZBufferBitDepth)
+            {
+                case 8:
+                    ERR("8 Bits Z+Stencil buffer pixelformat is not supported. Returning WINED3DFMT_UNKOWN\n");
+                    return WINED3DFMT_UNKNOWN;
+
+                case 15:
+                case 16:
+                    if(DDPixelFormat->u2.dwStencilBitDepth == 1)
+                        return WINED3DFMT_D15S1;
+
+                    ERR("Don't know how to handle a 16 bit Z buffer with %ld bit stencil buffer pixelformat\n", DDPixelFormat->u2.dwStencilBitDepth);
+                    return WINED3DFMT_UNKNOWN;
+
+                case 24:
+                    ERR("Don't know how to handle a 24 bit depth buffer with stencil bits\n");
+                    return WINED3DFMT_D24S8;
+
+                case 32:
+                    if(DDPixelFormat->u2.dwStencilBitDepth == 8)
+                        return WINED3DFMT_D24S8;
+                    else
+                        return WINED3DFMT_D24X4S4;
+
+                default:
+                    ERR("Unkown Z buffer depth %ld\n", DDPixelFormat->u1.dwZBufferBitDepth);
+                    return WINED3DFMT_UNKNOWN;
+            }
+        }
+        else
+        {
+            switch(DDPixelFormat->u1.dwZBufferBitDepth)
+            {
+                case 8:
+                    ERR("8 Bit Z buffers are not supported. Trying a 16 Bit one\n");
+                    return WINED3DFMT_D16;
+
+                case 16:
+                    return WINED3DFMT_D16;
+
+                case 24:
+                    return WINED3DFMT_D24X8;
+
+                case 32:
+                    return WINED3DFMT_D32;
+
+                default:
+                    ERR("Unsupported Z buffer depth %ld\n", DDPixelFormat->u1.dwZBufferBitDepth);
+                    return WINED3DFMT_UNKNOWN;
+            }
+        }
+    }
+    else if(DDPixelFormat->dwFlags & DDPF_FOURCC)
+    {
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('U', 'Y', 'V', 'Y'))
+        {
+            return WINED3DFMT_UYVY;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('Y', 'U', 'Y', '2'))
+        {
+            return WINED3DFMT_YUY2;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '1'))
+        {
+            return WINED3DFMT_DXT1;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '2'))
+        {
+            return WINED3DFMT_DXT2;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '3'))
+        {
+           return WINED3DFMT_DXT3;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '4'))
+        {
+            return WINED3DFMT_DXT4;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '5'))
+        {
+	    return WINED3DFMT_DXT5;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('G', 'R', 'G', 'B'))
+        {
+            return WINED3DFMT_G8R8_G8B8;
+        }
+        if(DDPixelFormat->dwFourCC == MAKEFOURCC('R', 'G', 'B', 'G'))
+        {
+            return WINED3DFMT_R8G8_B8G8;
+        }
+        return WINED3DFMT_UNKNOWN;  /* Abuse this as a error value */
+    }
+    else if(DDPixelFormat->dwFlags & DDPF_BUMPDUDV)
+    {
+        if( (DDPixelFormat->u1.dwBumpBitCount         == 16        ) &&
+            (DDPixelFormat->u2.dwBumpDuBitMask        == 0x000000ff) &&
+            (DDPixelFormat->u3.dwBumpDvBitMask        == 0x0000ff00) &&
+            (DDPixelFormat->u4.dwBumpLuminanceBitMask == 0x00000000) )
+        {
+            return WINED3DFMT_V8U8;
+        }
+        else if ( (DDPixelFormat->u1.dwBumpBitCount         == 16        ) &&
+                  (DDPixelFormat->u2.dwBumpDuBitMask        == 0x0000001f) &&
+                  (DDPixelFormat->u3.dwBumpDvBitMask        == 0x000003e0) &&
+                  (DDPixelFormat->u4.dwBumpLuminanceBitMask == 0x0000fc00) )
+        {
+            return WINED3DFMT_L6V5U5;
+        }
+    }
+
+    ERR("Unknown Pixelformat!\n");
+    return WINED3DFMT_UNKNOWN;
+}
+
+/*****************************************************************************
+ * Various dumping functions.
+ *
+ * They write the contents of a specific function to a DPRINTF.
+ *
+ *****************************************************************************/
+static void
+DDRAW_dump_DWORD(const void *in)
+{
+    DPRINTF("%ld", *((const DWORD *) in));
+}
+static void
+DDRAW_dump_PTR(const void *in)
+{
+    DPRINTF("%p", *((const void * const*) in));
+}
+void
+DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck)
+{
+    DPRINTF(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
+}
+void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
+{
+    static const flag_info flags[] = {
+        FE(DDSCAPS_RESERVED1),
+        FE(DDSCAPS_ALPHA),
+        FE(DDSCAPS_BACKBUFFER),
+        FE(DDSCAPS_COMPLEX),
+        FE(DDSCAPS_FLIP),
+        FE(DDSCAPS_FRONTBUFFER),
+        FE(DDSCAPS_OFFSCREENPLAIN),
+        FE(DDSCAPS_OVERLAY),
+        FE(DDSCAPS_PALETTE),
+        FE(DDSCAPS_PRIMARYSURFACE),
+        FE(DDSCAPS_PRIMARYSURFACELEFT),
+        FE(DDSCAPS_SYSTEMMEMORY),
+        FE(DDSCAPS_TEXTURE),
+        FE(DDSCAPS_3DDEVICE),
+        FE(DDSCAPS_VIDEOMEMORY),
+        FE(DDSCAPS_VISIBLE),
+        FE(DDSCAPS_WRITEONLY),
+        FE(DDSCAPS_ZBUFFER),
+        FE(DDSCAPS_OWNDC),
+        FE(DDSCAPS_LIVEVIDEO),
+        FE(DDSCAPS_HWCODEC),
+        FE(DDSCAPS_MODEX),
+        FE(DDSCAPS_MIPMAP),
+        FE(DDSCAPS_RESERVED2),
+        FE(DDSCAPS_ALLOCONLOAD),
+        FE(DDSCAPS_VIDEOPORT),
+        FE(DDSCAPS_LOCALVIDMEM),
+        FE(DDSCAPS_NONLOCALVIDMEM),
+        FE(DDSCAPS_STANDARDVGAMODE),
+        FE(DDSCAPS_OPTIMIZED)
+    };
+    static const flag_info flags2[] = {
+        FE(DDSCAPS2_HARDWAREDEINTERLACE),
+        FE(DDSCAPS2_HINTDYNAMIC),
+        FE(DDSCAPS2_HINTSTATIC),
+        FE(DDSCAPS2_TEXTUREMANAGE),
+        FE(DDSCAPS2_RESERVED1),
+        FE(DDSCAPS2_RESERVED2),
+        FE(DDSCAPS2_OPAQUE),
+        FE(DDSCAPS2_HINTANTIALIASING),
+        FE(DDSCAPS2_CUBEMAP),
+        FE(DDSCAPS2_CUBEMAP_POSITIVEX),
+        FE(DDSCAPS2_CUBEMAP_NEGATIVEX),
+        FE(DDSCAPS2_CUBEMAP_POSITIVEY),
+        FE(DDSCAPS2_CUBEMAP_NEGATIVEY),
+        FE(DDSCAPS2_CUBEMAP_POSITIVEZ),
+        FE(DDSCAPS2_CUBEMAP_NEGATIVEZ),
+        FE(DDSCAPS2_MIPMAPSUBLEVEL),
+        FE(DDSCAPS2_D3DTEXTUREMANAGE),
+        FE(DDSCAPS2_DONOTPERSIST),
+        FE(DDSCAPS2_STEREOSURFACELEFT)
+    };
+
+    DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0);
+    DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0);
+}
+
+void
+DDRAW_dump_DDSCAPS(const DDSCAPS *in)
+{
+    DDSCAPS2 in_bis;
+
+    in_bis.dwCaps = in->dwCaps;
+    in_bis.dwCaps2 = 0;
+    in_bis.dwCaps3 = 0;
+    in_bis.dwCaps4 = 0;
+
+    DDRAW_dump_DDSCAPS2(&in_bis);
+}
+
+void
+DDRAW_dump_flags_(DWORD flags,
+                  const flag_info* names,
+                  size_t num_names,
+                  int newline)
+{
+    unsigned int	i;
+
+    for (i=0; i < num_names; i++)
+        if ((flags & names[i].val) ||      /* standard flag value */
+            ((!flags) && (!names[i].val))) /* zero value only */
+            DPRINTF("%s ", names[i].name);
+
+    if (newline)
+        DPRINTF("\n");
+}
+
+void
+DDRAW_dump_pixelformat_flag(DWORD flagmask)
+{
+    static const flag_info flags[] =
+        {
+            FE(DDPF_ALPHAPIXELS),
+            FE(DDPF_ALPHA),
+            FE(DDPF_FOURCC),
+            FE(DDPF_PALETTEINDEXED4),
+            FE(DDPF_PALETTEINDEXEDTO8),
+            FE(DDPF_PALETTEINDEXED8),
+            FE(DDPF_RGB),
+            FE(DDPF_COMPRESSED),
+            FE(DDPF_RGBTOYUV),
+            FE(DDPF_YUV),
+            FE(DDPF_ZBUFFER),
+            FE(DDPF_PALETTEINDEXED1),
+            FE(DDPF_PALETTEINDEXED2),
+            FE(DDPF_ZPIXELS)
+    };
+
+    DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0);
+}
+
+void
+DDRAW_dump_members(DWORD flags,
+                   const void* data,
+                   const member_info* mems,
+                   size_t num_mems)
+{
+    unsigned int i;
+
+    for (i=0; i < num_mems; i++)
+    {
+        if (mems[i].val & flags)
+        {
+            DPRINTF(" - %s : ", mems[i].name);
+            mems[i].func((const char *)data + mems[i].offset);
+            DPRINTF("\n");
+        }
+    }
+}
+
+void
+DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf)
+{
+    DPRINTF("( ");
+    DDRAW_dump_pixelformat_flag(pf->dwFlags);
+    if (pf->dwFlags & DDPF_FOURCC)
+    {
+        DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
+                (unsigned char)( pf->dwFourCC     &0xff),
+                (unsigned char)((pf->dwFourCC>> 8)&0xff),
+                (unsigned char)((pf->dwFourCC>>16)&0xff),
+                (unsigned char)((pf->dwFourCC>>24)&0xff),
+                pf->dwFourCC,
+                pf->u1.dwYUVBitCount
+        );
+    }
+    if (pf->dwFlags & DDPF_RGB)
+    {
+        const char *cmd;
+        DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount);
+        switch (pf->u1.dwRGBBitCount)
+        {
+        case 4: cmd = "%1lx"; break;
+        case 8: cmd = "%02lx"; break;
+        case 16: cmd = "%04lx"; break;
+        case 24: cmd = "%06lx"; break;
+        case 32: cmd = "%08lx"; break;
+        default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
+        }
+        DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask);
+        DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask);
+        DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask);
+        if (pf->dwFlags & DDPF_ALPHAPIXELS)
+        {
+            DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask);
+        }
+        if (pf->dwFlags & DDPF_ZPIXELS)
+        {
+            DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask);
+        }
+    }
+    if (pf->dwFlags & DDPF_ZBUFFER)
+    {
+        DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth);
+    }
+    if (pf->dwFlags & DDPF_ALPHA)
+    {
+        DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth);
+    }
+    if (pf->dwFlags & DDPF_BUMPDUDV)
+    {
+        const char *cmd = "%08lx";
+        DPRINTF(", Bump bits: %ld, ", pf->u1.dwBumpBitCount);
+        DPRINTF(" U "); DPRINTF(cmd, pf->u2.dwBumpDuBitMask);
+        DPRINTF(" V "); DPRINTF(cmd, pf->u3.dwBumpDvBitMask);
+        DPRINTF(" L "); DPRINTF(cmd, pf->u4.dwBumpLuminanceBitMask);
+    }
+    DPRINTF(")");
+}
+
+void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
+{
+#define STRUCT DDSURFACEDESC2
+    static const member_info members[] =
+        {
+            ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight),
+            ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth),
+            ME(DDSD_PITCH, DDRAW_dump_DWORD, u1 /* lPitch */),
+            ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1 /* dwLinearSize */),
+            ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
+            ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2 /* dwMipMapCount */),
+            ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2 /* dwZBufferBitDepth */), /* This is for 'old-style' D3D */
+            ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2 /* dwRefreshRate */),
+            ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
+            ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),
+            ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3 /* ddckCKDestOverlay */),
+            ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt),
+            ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay),
+            ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt),
+            ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4 /* ddpfPixelFormat */)
+        };
+    static const member_info members_caps[] =
+        {
+            ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps)
+        };
+    static const member_info members_caps2[] =
+        {
+            ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps)
+        };
+#undef STRUCT
+
+    if (NULL == lpddsd)
+    {
+        DPRINTF("(null)\n");
+    }
+    else
+    {
+      if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2))
+      {
+          DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1);
+      }
+      else
+      {
+          DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
+      }
+      DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
+                          sizeof(members)/sizeof(members[0]));
+    }
+}
+
+void
+dump_D3DMATRIX(D3DMATRIX *mat)
+{
+    DPRINTF("  %f %f %f %f\n", mat->_11, mat->_12, mat->_13, mat->_14);
+    DPRINTF("  %f %f %f %f\n", mat->_21, mat->_22, mat->_23, mat->_24);
+    DPRINTF("  %f %f %f %f\n", mat->_31, mat->_32, mat->_33, mat->_34);
+    DPRINTF("  %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44);
+}
+
+DWORD
+get_flexible_vertex_size(DWORD d3dvtVertexType)
+{
+    DWORD size = 0;
+    int i;
+
+    if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
+    if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
+    if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
+    if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD);
+    switch (d3dvtVertexType & D3DFVF_POSITION_MASK)
+    {
+        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
+        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
+        default: TRACE(" matrix weighting not handled yet...\n");
+    }
+    for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++)
+    {
+        size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(D3DVALUE);
+    }
+
+    return size;
+}
+
+void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut)
+{
+    /* 2 adds three additional caps fields to the end. Both versions
+     * are unversioned. */
+    pOut->dwCaps = pIn->dwCaps;
+    pOut->dwCaps2 = 0;
+    pOut->dwCaps3 = 0;
+    pOut->dwCaps4 = 0;
+}
+
+void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn, DDDEVICEIDENTIFIER* pOut)
+{
+    /* 2 adds a dwWHQLLevel field to the end. Both structures are
+     * unversioned. */
+    memcpy(pOut, pIn, sizeof(*pOut));
+}
+
+void DDRAW_dump_cooperativelevel(DWORD cooplevel)
+{
+    static const flag_info flags[] =
+        {
+            FE(DDSCL_FULLSCREEN),
+            FE(DDSCL_ALLOWREBOOT),
+            FE(DDSCL_NOWINDOWCHANGES),
+            FE(DDSCL_NORMAL),
+            FE(DDSCL_ALLOWMODEX),
+            FE(DDSCL_EXCLUSIVE),
+            FE(DDSCL_SETFOCUSWINDOW),
+            FE(DDSCL_SETDEVICEWINDOW),
+            FE(DDSCL_CREATEDEVICEWINDOW)
+    };
+
+    if (TRACE_ON(ddraw))
+    {
+        DPRINTF(" - ");
+        DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
+    }
+}
+
+void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps)
+{
+    static const flag_info flags1[] =
+    {
+      FE(DDCAPS_3D),
+      FE(DDCAPS_ALIGNBOUNDARYDEST),
+      FE(DDCAPS_ALIGNSIZEDEST),
+      FE(DDCAPS_ALIGNBOUNDARYSRC),
+      FE(DDCAPS_ALIGNSIZESRC),
+      FE(DDCAPS_ALIGNSTRIDE),
+      FE(DDCAPS_BLT),
+      FE(DDCAPS_BLTQUEUE),
+      FE(DDCAPS_BLTFOURCC),
+      FE(DDCAPS_BLTSTRETCH),
+      FE(DDCAPS_GDI),
+      FE(DDCAPS_OVERLAY),
+      FE(DDCAPS_OVERLAYCANTCLIP),
+      FE(DDCAPS_OVERLAYFOURCC),
+      FE(DDCAPS_OVERLAYSTRETCH),
+      FE(DDCAPS_PALETTE),
+      FE(DDCAPS_PALETTEVSYNC),
+      FE(DDCAPS_READSCANLINE),
+      FE(DDCAPS_STEREOVIEW),
+      FE(DDCAPS_VBI),
+      FE(DDCAPS_ZBLTS),
+      FE(DDCAPS_ZOVERLAYS),
+      FE(DDCAPS_COLORKEY),
+      FE(DDCAPS_ALPHA),
+      FE(DDCAPS_COLORKEYHWASSIST),
+      FE(DDCAPS_NOHARDWARE),
+      FE(DDCAPS_BLTCOLORFILL),
+      FE(DDCAPS_BANKSWITCHED),
+      FE(DDCAPS_BLTDEPTHFILL),
+      FE(DDCAPS_CANCLIP),
+      FE(DDCAPS_CANCLIPSTRETCHED),
+      FE(DDCAPS_CANBLTSYSMEM)
+    };
+    static const flag_info flags2[] =
+    {
+      FE(DDCAPS2_CERTIFIED),
+      FE(DDCAPS2_NO2DDURING3DSCENE),
+      FE(DDCAPS2_VIDEOPORT),
+      FE(DDCAPS2_AUTOFLIPOVERLAY),
+      FE(DDCAPS2_CANBOBINTERLEAVED),
+      FE(DDCAPS2_CANBOBNONINTERLEAVED),
+      FE(DDCAPS2_COLORCONTROLOVERLAY),
+      FE(DDCAPS2_COLORCONTROLPRIMARY),
+      FE(DDCAPS2_CANDROPZ16BIT),
+      FE(DDCAPS2_NONLOCALVIDMEM),
+      FE(DDCAPS2_NONLOCALVIDMEMCAPS),
+      FE(DDCAPS2_NOPAGELOCKREQUIRED),
+      FE(DDCAPS2_WIDESURFACES),
+      FE(DDCAPS2_CANFLIPODDEVEN),
+      FE(DDCAPS2_CANBOBHARDWARE),
+      FE(DDCAPS2_COPYFOURCC),
+      FE(DDCAPS2_PRIMARYGAMMA),
+      FE(DDCAPS2_CANRENDERWINDOWED),
+      FE(DDCAPS2_CANCALIBRATEGAMMA),
+      FE(DDCAPS2_FLIPINTERVAL),
+      FE(DDCAPS2_FLIPNOVSYNC),
+      FE(DDCAPS2_CANMANAGETEXTURE),
+      FE(DDCAPS2_TEXMANINNONLOCALVIDMEM),
+      FE(DDCAPS2_STEREO),
+      FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL)
+    };
+    static const flag_info flags3[] =
+    {
+      FE(DDCKEYCAPS_DESTBLT),
+      FE(DDCKEYCAPS_DESTBLTCLRSPACE),
+      FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV),
+      FE(DDCKEYCAPS_DESTBLTYUV),
+      FE(DDCKEYCAPS_DESTOVERLAY),
+      FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE),
+      FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV),
+      FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE),
+      FE(DDCKEYCAPS_DESTOVERLAYYUV),
+      FE(DDCKEYCAPS_SRCBLT),
+      FE(DDCKEYCAPS_SRCBLTCLRSPACE),
+      FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV),
+      FE(DDCKEYCAPS_SRCBLTYUV),
+      FE(DDCKEYCAPS_SRCOVERLAY),
+      FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE),
+      FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV),
+      FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE),
+      FE(DDCKEYCAPS_SRCOVERLAYYUV),
+      FE(DDCKEYCAPS_NOCOSTOVERLAY)
+    };
+    static const flag_info flags4[] =
+    {
+      FE(DDFXCAPS_BLTALPHA),
+      FE(DDFXCAPS_OVERLAYALPHA),
+      FE(DDFXCAPS_BLTARITHSTRETCHYN),
+      FE(DDFXCAPS_BLTARITHSTRETCHY),
+      FE(DDFXCAPS_BLTMIRRORLEFTRIGHT),
+      FE(DDFXCAPS_BLTMIRRORUPDOWN),
+      FE(DDFXCAPS_BLTROTATION),
+      FE(DDFXCAPS_BLTROTATION90),
+      FE(DDFXCAPS_BLTSHRINKX),
+      FE(DDFXCAPS_BLTSHRINKXN),
+      FE(DDFXCAPS_BLTSHRINKY),
+      FE(DDFXCAPS_BLTSHRINKYN),
+      FE(DDFXCAPS_BLTSTRETCHX),
+      FE(DDFXCAPS_BLTSTRETCHXN),
+      FE(DDFXCAPS_BLTSTRETCHY),
+      FE(DDFXCAPS_BLTSTRETCHYN),
+      FE(DDFXCAPS_OVERLAYARITHSTRETCHY),
+      FE(DDFXCAPS_OVERLAYARITHSTRETCHYN),
+      FE(DDFXCAPS_OVERLAYSHRINKX),
+      FE(DDFXCAPS_OVERLAYSHRINKXN),
+      FE(DDFXCAPS_OVERLAYSHRINKY),
+      FE(DDFXCAPS_OVERLAYSHRINKYN),
+      FE(DDFXCAPS_OVERLAYSTRETCHX),
+      FE(DDFXCAPS_OVERLAYSTRETCHXN),
+      FE(DDFXCAPS_OVERLAYSTRETCHY),
+      FE(DDFXCAPS_OVERLAYSTRETCHYN),
+      FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT),
+      FE(DDFXCAPS_OVERLAYMIRRORUPDOWN)
+    };
+    static const flag_info flags5[] =
+    {
+      FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND),
+      FE(DDFXALPHACAPS_BLTALPHAPIXELS),
+      FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG),
+      FE(DDFXALPHACAPS_BLTALPHASURFACES),
+      FE(DDFXALPHACAPS_BLTALPHASURFACESNEG),
+      FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND),
+      FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS),
+      FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG),
+      FE(DDFXALPHACAPS_OVERLAYALPHASURFACES),
+      FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG)
+    };
+    static const flag_info flags6[] =
+    {
+      FE(DDPCAPS_4BIT),
+      FE(DDPCAPS_8BITENTRIES),
+      FE(DDPCAPS_8BIT),
+      FE(DDPCAPS_INITIALIZE),
+      FE(DDPCAPS_PRIMARYSURFACE),
+      FE(DDPCAPS_PRIMARYSURFACELEFT),
+      FE(DDPCAPS_ALLOW256),
+      FE(DDPCAPS_VSYNC),
+      FE(DDPCAPS_1BIT),
+      FE(DDPCAPS_2BIT),
+      FE(DDPCAPS_ALPHA),
+    };
+    static const flag_info flags7[] =
+    {
+      FE(DDSVCAPS_RESERVED1),
+      FE(DDSVCAPS_RESERVED2),
+      FE(DDSVCAPS_RESERVED3),
+      FE(DDSVCAPS_RESERVED4),
+      FE(DDSVCAPS_STEREOSEQUENTIAL),
+    };
+
+    DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize);
+    DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
+    DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
+    DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
+    DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
+    DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
+    DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
+    DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
+    DPRINTF("...\n");
+    DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes);
+    DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays);
+    DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch);
+    DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
+    DPRINTF("...\n");
+    DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
+}
+
+/*****************************************************************************
+ * multiply_matrix
+ *
+ * Multiplies 2 4x4 matrices src1 and src2, and stores the result in dest.
+ *
+ * Params:
+ *  dest: Pointer to the destination matrix
+ *  src1: Pointer to the first source matrix
+ *  src2: Pointer to the secound source matrix
+ *
+ *****************************************************************************/
+void
+multiply_matrix(D3DMATRIX *dest,
+                D3DMATRIX *src1,
+                D3DMATRIX *src2)
+{
+    D3DMATRIX temp;
+
+    /* Now do the multiplication 'by hand'.
+       I know that all this could be optimised, but this will be done later :-) */
+    temp._11 = (src1->_11 * src2->_11) + (src1->_21 * src2->_12) + (src1->_31 * src2->_13) + (src1->_41 * src2->_14);
+    temp._21 = (src1->_11 * src2->_21) + (src1->_21 * src2->_22) + (src1->_31 * src2->_23) + (src1->_41 * src2->_24);
+    temp._31 = (src1->_11 * src2->_31) + (src1->_21 * src2->_32) + (src1->_31 * src2->_33) + (src1->_41 * src2->_34);
+    temp._41 = (src1->_11 * src2->_41) + (src1->_21 * src2->_42) + (src1->_31 * src2->_43) + (src1->_41 * src2->_44);
+
+    temp._12 = (src1->_12 * src2->_11) + (src1->_22 * src2->_12) + (src1->_32 * src2->_13) + (src1->_42 * src2->_14);
+    temp._22 = (src1->_12 * src2->_21) + (src1->_22 * src2->_22) + (src1->_32 * src2->_23) + (src1->_42 * src2->_24);
+    temp._32 = (src1->_12 * src2->_31) + (src1->_22 * src2->_32) + (src1->_32 * src2->_33) + (src1->_42 * src2->_34);
+    temp._42 = (src1->_12 * src2->_41) + (src1->_22 * src2->_42) + (src1->_32 * src2->_43) + (src1->_42 * src2->_44);
+
+    temp._13 = (src1->_13 * src2->_11) + (src1->_23 * src2->_12) + (src1->_33 * src2->_13) + (src1->_43 * src2->_14);
+    temp._23 = (src1->_13 * src2->_21) + (src1->_23 * src2->_22) + (src1->_33 * src2->_23) + (src1->_43 * src2->_24);
+    temp._33 = (src1->_13 * src2->_31) + (src1->_23 * src2->_32) + (src1->_33 * src2->_33) + (src1->_43 * src2->_34);
+    temp._43 = (src1->_13 * src2->_41) + (src1->_23 * src2->_42) + (src1->_33 * src2->_43) + (src1->_43 * src2->_44);
+
+    temp._14 = (src1->_14 * src2->_11) + (src1->_24 * src2->_12) + (src1->_34 * src2->_13) + (src1->_44 * src2->_14);
+    temp._24 = (src1->_14 * src2->_21) + (src1->_24 * src2->_22) + (src1->_34 * src2->_23) + (src1->_44 * src2->_24);
+    temp._34 = (src1->_14 * src2->_31) + (src1->_24 * src2->_32) + (src1->_34 * src2->_33) + (src1->_44 * src2->_34);
+    temp._44 = (src1->_14 * src2->_41) + (src1->_24 * src2->_42) + (src1->_34 * src2->_43) + (src1->_44 * src2->_44);
+
+    /* And copy the new matrix in the good storage.. */
+    memcpy(dest, &temp, 16 * sizeof(D3DVALUE));
+}
+
+
+HRESULT
+hr_ddraw_from_wined3d(HRESULT hr)
+{
+    switch(hr)
+    {
+        case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS;
+        default: return hr;
+    }
+}
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c
index f4142c5..0514038 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -1,5 +1,6 @@
-/* Direct3D Viewport
+/* Direct3D Vertex Buffer
  * Copyright (c) 2002 Lionel ULMER
+ * Copyright (c) 2006 Stefan DÖSINGER
  *
  * This file contains the implementation of Direct3DVertexBuffer COM object
  *
@@ -19,58 +20,112 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <assert.h>
 #include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
-#include "wine/debug.h"
 
-#include "d3d_private.h"
-#include "opengl_private.h"
+#include "ddraw_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
+WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
 
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
-                                                   REFIID riid,
-                                                   LPVOID* obp)
+
+/*****************************************************************************
+ * IUnknown Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::QueryInterface
+ *
+ * The QueryInterface Method for Vertex Buffers
+ * For a link to QueryInterface rules, see IDirectDraw7::QueryInterface
+ *
+ * Params
+ *  riid: Queryied Interface id
+ *  obj: Address to return the interface pointer
+ *
+ * Returns:
+ *  S_OK on success
+ *  E_NOINTERFACE if the interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_QueryInterface(IDirect3DVertexBuffer7 *iface,
+                                         REFIID riid,
+                                         void  **obj)
 {
     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj);
 
     /* By default, set the object pointer to NULL */
-    *obp = NULL;
-      
-    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+    *obj = NULL;
+
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) )
+    {
         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
-	*obp = iface;
-	TRACE("  Creating IUnknown interface at %p.\n", *obp);
-	return S_OK;
+        *obj = iface;
+        TRACE("  Creating IUnknown interface at %p.\n", *obj);
+        return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
+    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) )
+    {
         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
-        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
-	TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obp);
-	return S_OK;
+        *obj = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
+        TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obj);
+        return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
+    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) )
+    {
         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
-        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
-	TRACE("  Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
-	return S_OK;
+        *obj = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
+        TRACE("  Creating IDirect3DVertexBuffer7 interface %p\n", *obj);
+        return S_OK;
     }
     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
+    return E_NOINTERFACE;
 }
 
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(IDirect3DVertexBuffer *iface,
+                                                 REFIID riid,
+                                                 void **obj)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, debugstr_guid(riid), obj);
+
+    return IDirect3DVertexBuffer7_QueryInterface(ICOM_INTERFACE(This, IDirect3DVertexBuffer7),
+                                                 riid,
+                                                 obj);
+}
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::AddRef
+ *
+ * AddRef for Vertex Buffers
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
 ULONG WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
+IDirect3DVertexBufferImpl_AddRef(IDirect3DVertexBuffer7 *iface)
 {
     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
@@ -81,477 +136,426 @@
 }
 
 ULONG WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
+Thunk_IDirect3DVertexBufferImpl_1_AddRef(IDirect3DVertexBuffer *iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This);
+
+    return IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This, IDirect3DVertexBuffer7));
+}
+
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::Release
+ *
+ * Release for Vertex Buffers
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+ULONG WINAPI
+IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface)
 {
     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
 
-    if (ref == 0) {
-        HeapFree(GetProcessHeap(), 0, This->vertices);
-	HeapFree(GetProcessHeap(), 0, This);
-	return 0;
+    if (ref == 0)
+    {
+        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        HeapFree(GetProcessHeap(), 0, This);
+        return 0;
     }
     return ref;
 }
 
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
-                                         DWORD dwFlags,
-                                         LPVOID* lplpData,
-                                         LPDWORD lpdwSize)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" lock flags : ");
-	DDRAW_dump_lockflag(dwFlags);
-    }
-    
-    if (This->processed) {
-        WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
-    }
-
-    if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
-
-    if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
-    *lplpData = This->vertices;
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    TRACE("(%p/%p)->()\n", This, iface);
-    /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
-						    DWORD dwVertexOp,
-						    DWORD dwDestIndex,
-						    DWORD dwCount,
-						    LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
-						    DWORD dwSrcIndex,
-						    LPDIRECT3DDEVICE7 lpD3DDevice,
-						    DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
-                                                        LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
-{
-    DWORD size;
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
-    
-    size = lpD3DVertexBufferDesc->dwSize;
-    memset(lpD3DVertexBufferDesc, 0, size);
-    memcpy(lpD3DVertexBufferDesc, &This->desc, 
-	   (size < This->desc.dwSize) ? size : This->desc.dwSize);
-    
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
-					     LPDIRECT3DDEVICE7 lpD3DDevice,
-					     DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
-
-    This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
-                                                        DWORD dwVertexOp,
-                                                        DWORD dwDestIndex,
-                                                        DWORD dwCount,
-                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
-                                                        DWORD dwVertexTypeDesc,
-                                                        LPDIRECT3DDEVICE7 lpD3DDevice,
-                                                        DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
-    return DD_OK;
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
-						  DWORD dwVertexOp,
-						  DWORD dwDestIndex,
-						  DWORD dwCount,
-						  LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
-						  DWORD dwSrcIndex,
-						  LPDIRECT3DDEVICE3 lpD3DDevice,
-						  DWORD dwFlags)
-{
-    TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
-	  dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
-    return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
-						  dwVertexOp,
-						  dwDestIndex,
-						  dwCount,
-						  COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
-						  dwSrcIndex,
-						  COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
-						  dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
-					   LPDIRECT3DDEVICE3 lpD3DDevice,
-					   DWORD dwFlags)
-{
-    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
-    return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
-					   COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
-					   dwFlags);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
-                                                 REFIID riid,
-                                                 LPVOID* obp)
-{
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
-                                                 riid,
-                                                 obp);
-}
-
 ULONG WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
+Thunk_IDirect3DVertexBufferImpl_1_Release(IDirect3DVertexBuffer *iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
-    return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This);
+
+    return IDirect3DVertexBuffer7_Release(ICOM_INTERFACE(This, IDirect3DVertexBuffer7));
 }
 
-ULONG WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
-    return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
-}
+/*****************************************************************************
+ * IDirect3DVertexBuffer Methods
+ *****************************************************************************/
 
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
-                                       DWORD dwFlags,
-                                       LPVOID* lplpData,
-                                       LPDWORD lpdwSize)
-{
-    TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
-    return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
-                                       dwFlags,
-                                       lplpData,
-                                       lpdwSize);
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
-{
-    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
-    return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
-}
-
-HRESULT WINAPI
-Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
-                                                      LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
-{
-    TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
-    return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
-                                                      lpD3DVertexBufferDesc);
-}
-
-#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
-
-static HRESULT
-process_vertices_strided(IDirect3DVertexBufferImpl *This,
-			 DWORD dwVertexOp,
-			 DWORD dwDestIndex,
-			 DWORD dwCount,
-			 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
-			 DWORD dwVertexTypeDesc,
-			 IDirect3DDeviceImpl *device_impl,
-			 DWORD dwFlags)
-{
-    IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
-    DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
-    char *dest_ptr;
-    unsigned int i;
-
-    This->processed = TRUE;
-
-    /* For the moment, the trick is to save the transform and lighting state at process
-       time to restore them at drawing time.
-       
-       The BIG problem with this method is nothing prevents D3D to do dirty tricks like
-       processing two different sets of vertices with two different rendering parameters
-       and then to display them using the same DrawPrimitive call.
-
-       It would be nice to check for such code here (but well, even this is not trivial
-       to do).
-
-       This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
-       in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
-       implementing this mostly useless (IMHO) API.
-    */
-    glThis->dwVertexTypeDesc = dwVertexTypeDesc;
-
-    if (dwVertexTypeDesc & D3DFVF_NORMAL) {
-        WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
-    }
-
-    if (glThis->vertices == NULL) {
-        glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
-    }
-    dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
-    
-    memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
-    memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
-    memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
-
-    for (i = 0; i < dwCount; i++) {
-        unsigned int tex_index;
-
-	if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-	    D3DVALUE *position =
-	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
-	    copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
-	} else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
-	    D3DVALUE *position =
-	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
-	    copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
-	}
-	if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
-	    dest_ptr += sizeof(DWORD);
-	}
-	if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
-	    D3DVALUE *normal = 
-	      (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
-	    copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
-	}
-	if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
-	    DWORD *color_d = 
-	      (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
-	    copy_and_next(dest_ptr, color_d, sizeof(DWORD));
-	}
-	if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
-	    DWORD *color_s = 
-	      (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
-	    copy_and_next(dest_ptr, color_s, sizeof(DWORD));
-	}
-	for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
-	    D3DVALUE *tex_coord =
-	      (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
-			    i * lpStrideData->textureCoords[tex_index].dwStride);
-	    copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index) * sizeof(D3DVALUE));
-	}
-
-	if (TRACE_ON(ddraw_geom)) {
-	    if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-	        D3DVALUE *position =
-		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
-		TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
-	    } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
-	        D3DVALUE *position =
-		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
-		TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
-	    }
-	    if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
-	        D3DVALUE *normal = 
-		  (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
-		TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
-	    }
-	    if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
-	        DWORD *color_d = 
-		  (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
-		TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
-				   (*color_d >> 16) & 0xFF,
-				   (*color_d >>  8) & 0xFF,
-				   (*color_d >>  0) & 0xFF,
-				   (*color_d >> 24) & 0xFF);
-	    }
-	    if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
-	        DWORD *color_s = 
-		  (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
-		TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
-				   (*color_s >> 16) & 0xFF,
-				   (*color_s >>  8) & 0xFF,
-				   (*color_s >>  0) & 0xFF,
-				   (*color_s >> 24) & 0xFF);
-	    }
-	    for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
-	        D3DVALUE *tex_coord =
-		  (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
-				i * lpStrideData->textureCoords[tex_index].dwStride);
-		switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) {
-		    case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break;
-		    case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break;
-		    case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break;
-		    case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break;
-		    default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break;
-		}
-	    }
-	    TRACE_(ddraw_geom)("\n");
-	}
-    }
-
-    return DD_OK;
-}
-
-#undef copy_and_next
-
-HRESULT WINAPI
-GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
-						  DWORD dwVertexOp,
-						  DWORD dwDestIndex,
-						  DWORD dwCount,
-						  LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
-						  DWORD dwSrcIndex,
-						  LPDIRECT3DDEVICE7 lpD3DDevice,
-						  DWORD dwFlags)
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::Lock
+ *
+ * Locks the vertex buffer and returns a pointer to the vertex data
+ * Locking vertex buffers is simmilar to locking surfaces, because Windows
+ * uses surfaces to store vertex data internally(According to the DX sdk)
+ *
+ * Params:
+ *  Flags: Locking flags. Relevant here are DDLOCK_READONLY, DDLOCK_WRITEONLY,
+ *         DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE.
+ *  Data:  Returns a pointer to the vertex data
+ *  Size:  Returns the size of the buffer if not NULL
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *  D3DERR_VERTEXBUFFEROPTIMIZED if called on an optimized buffer(WineD3D)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
+                               DWORD Flags,
+                               void **Data,
+                               DWORD *Size)
 {
     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
-    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
+    WINED3DVERTEXBUFFER_DESC Desc;
+    HRESULT hr;
+    TRACE("(%p)->(%08lx,%p,%p)\n", This, Flags, Data, Size);
+
+    /* Get the size, for returning it, and for locking */
+    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
+                                      &Desc);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr);
+        return hr;
+    }
+
+    if(Size) *Size = Desc.Size;
+
+    return IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer,
+                                     0 /* OffsetToLock */,
+                                     Desc.Size,
+                                     (BYTE **) Data,
+                                     Flags);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Lock(IDirect3DVertexBuffer *iface,
+                                       DWORD Flags,
+                                       void **Data,
+                                       DWORD *Size)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, Flags, Data, Size);
+
+    return IDirect3DVertexBuffer7_Lock(ICOM_INTERFACE(This, IDirect3DVertexBuffer7),
+                                       Flags,
+                                       Data,
+                                       Size);
+}
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::Unlock
+ *
+ * Unlocks a vertex Buffer
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_Unlock(IDirect3DVertexBuffer7 *iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    TRACE("(%p)->()\n", This);
+
+    /* This is easy :) */
+    return IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Unlock(IDirect3DVertexBuffer *iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This);
+
+    return IDirect3DVertexBuffer7_Unlock(ICOM_INTERFACE(This, IDirect3DVertexBuffer7));
+}
+
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::ProcessVertices
+ *
+ * Processes untransformed Vertices into a transformed or optimized vertex
+ * buffer. It can also perform other operations, such as lighting or clipping
+ *
+ * Params
+ *  VertexOp: Operation(s) to perform: D3DVOP_CLIP, _EXTENTS, _LIGHT, _TRANSFORM
+ *  DestIndex: Index in the destination buffer(This), where the vertices are
+ *             placed
+ *  Count: Number of Vertices in the Source buffer to process
+ *  SrcBuffer: Source vertex buffer
+ *  SrcIndex: Index of the first vertex in the src buffer to process
+ *  D3DDevice: Device to use for transformation
+ *  Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying
+ *         unchaned vertices
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS If D3DVOP_TRANSFORM wasn't passed
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
+                                          DWORD VertexOp,
+                                          DWORD DestIndex,
+                                          DWORD Count,
+                                          IDirect3DVertexBuffer7 *SrcBuffer,
+                                          DWORD SrcIndex,
+                                          IDirect3DDevice7 *D3DDevice,
+                                          DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, SrcBuffer);
+    IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice);
+    BOOL oldClip, doClip;
+    HRESULT hr;
+
+    TRACE("(%p)->(%08lx,%ld,%ld,%p,%ld,%p,%08lx)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags);
+
+    /* Vertex operations:
+     * D3DVOP_CLIP: Clips vertices outside the viewing frustrum. Needs clipping information
+     * in the vertex buffer (Buffer may not be created with D3DVBCAPS_DONOTCLIP)
+     * D3DVOP_EXTENTS: Causes the screen extents to be updated when rendering the vertices
+     * D3DVOP_LIGHT: Lights the vertices
+     * D3DVOP_TRANSFORM: Transform the vertices. This flag is necessary
+     *
+     * WineD3D only transforms and clips the vertices by now, so EXTENTS and LIGHT
+     * are not implemented. Clipping is disabled ATM, because of unsure conditions.
+     */
+    if( !(VertexOp & D3DVOP_TRANSFORM) ) return DDERR_INVALIDPARAMS;
+
+    /* WineD3D doesn't know d3d7 vertex operation, it uses
+     * render states instead. Set the render states according to
+     * the vertex ops
+     */
+    doClip = VertexOp & D3DVOP_CLIP ? TRUE : FALSE;
+    IWineD3DDevice_GetRenderState(D3D->wineD3DDevice,
+                                  WINED3DRS_CLIPPING,
+                                  (DWORD *) &oldClip);
+    if(doClip != oldClip)
+    {
+        IWineD3DDevice_SetRenderState(D3D->wineD3DDevice,
+                                      WINED3DRS_CLIPPING,
+                                      doClip);
+    }
+
+
+    hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice,
+                                        SrcIndex,
+                                        DestIndex,
+                                        Count,
+                                        This->wineD3DVertexBuffer,
+                                        Src->wineD3DVertexBuffer,
+                                        Flags);
+
+    /* Restore the states if needed */
+    if(doClip != oldClip)
+        IWineD3DDevice_SetRenderState(D3D->wineD3DDevice,
+                                      WINED3DRS_CLIPPING,
+                                      oldClip);
+    return hr;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(IDirect3DVertexBuffer *iface,
+                                                  DWORD VertexOp,
+                                                  DWORD DestIndex,
+                                                  DWORD Count,
+                                                  IDirect3DVertexBuffer *SrcBuffer,
+                                                  DWORD SrcIndex,
+                                                  IDirect3DDevice3 *D3DDevice,
+                                                  DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, SrcBuffer);
+    IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice);
+
+    TRACE_(ddraw_thunk)("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags);
+
+    return IDirect3DVertexBuffer7_ProcessVertices(ICOM_INTERFACE(This, IDirect3DVertexBuffer7),
+                                                  VertexOp,
+                                                  DestIndex,
+                                                  Count,
+                                                  ICOM_INTERFACE(Src, IDirect3DVertexBuffer7),
+                                                  SrcIndex,
+                                                  ICOM_INTERFACE(D3D, IDirect3DDevice7),
+                                                  Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::GetVertexBufferDesc
+ *
+ * Returns the description of a vertex buffer
+ *
+ * Params:
+ *  Desc: Address to write the description to
+ *
+ * Returns
+ *  DDERR_INVALIDPARAMS if Desc is NULL
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface,
+                                              D3DVERTEXBUFFERDESC *Desc)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    WINED3DVERTEXBUFFER_DESC WDesc;
+    HRESULT hr;
     DWORD size;
+    TRACE("(%p)->(%p)\n", This, Desc);
 
-    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);    
+    if(!Desc) return DDERR_INVALIDPARAMS;
 
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
-	TRACE(" - flags             : "); dump_D3DPV(dwFlags);
+    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
+                                      &WDesc);
+    if(hr != D3D_OK)
+    {
+        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr);
+        return hr;
     }
 
-    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
+    /* Clear the return value of garbage */
+    size = Desc->dwSize;
+    memset(Desc, 0, size);
 
-    size = get_flexible_vertex_size(src_impl->desc.dwFVF);
-    convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
+    /* Now fill the Desc structure */
+    Desc->dwSize = size;
+    Desc->dwCaps = This->Caps;
+    Desc->dwFVF = WDesc.FVF;
+    Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(WDesc.FVF);
 
-    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
-}
-
-HRESULT WINAPI
-GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
-						      DWORD dwVertexOp,
-						      DWORD dwDestIndex,
-						      DWORD dwCount,
-						      LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
-						      DWORD dwVertexTypeDesc,
-						      LPDIRECT3DDEVICE7 lpD3DDevice,
-						      DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
-    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
-
-    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
-    if (TRACE_ON(ddraw)) {
-        TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
-	TRACE(" - flags             : "); dump_D3DPV(dwFlags);
-	TRACE(" - vertex format     : "); dump_flexible_vertex(dwVertexTypeDesc);
-    }
-
-    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
-
-    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
-}
-
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
-{
-    XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
-    XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
-    XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
-    XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
-    XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
-    XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
-    XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
-    XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
-{
-    XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
-    XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
-    XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
-    XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
-    XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
-    XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
-    XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
-};
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
-{
-    IDirect3DVertexBufferImpl *object;
-    static const flag_info flags[] = {
-        FE(D3DVBCAPS_DONOTCLIP),
-        FE(D3DVBCAPS_OPTIMIZED),
-	FE(D3DVBCAPS_SYSTEMMEMORY),
-	FE(D3DVBCAPS_WRITEONLY)
-    };
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
-
-    object->ref = 1;
-    object->d3d = d3d;
-    object->desc = *lpD3DVertBufDesc;
-    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
-    object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
-    
-    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);
-    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
-
-    *obj = object;
-
-    if (TRACE_ON(ddraw)) {
-        TRACE(" creating implementation at %p with description :\n", *obj);
-	TRACE("  flags        : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
-	TRACE("  vertex type  : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
-	TRACE("  num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
-    }
-    
-    
     return D3D_OK;
 }
+
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(IDirect3DVertexBuffer *iface,
+                                                      D3DVERTEXBUFFERDESC *Desc)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, Desc);
+
+    return IDirect3DVertexBuffer7_GetVertexBufferDesc(ICOM_INTERFACE(This, IDirect3DVertexBuffer7),
+                                                      Desc);
+}
+
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::Optimize
+ *
+ * Converts an unoptimized vertex buffer into an optimized buffer
+ *
+ * Params:
+ *  D3DDevice: Device for which this buffer is optimized
+ *  Flags: Not used, should be set to 0
+ *
+ * Returns
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_Optimize(IDirect3DVertexBuffer7 *iface,
+                                   IDirect3DDevice7 *D3DDevice,
+                                   DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice);
+    FIXME("(%p)->(%p,%08lx): stub!\n", This, D3D, Flags);
+
+    /* We could forward this call to WineD3D and take advantage
+     * of it once we use OpenGL vertex buffers
+     */
+    This->Caps |= D3DVBCAPS_OPTIMIZED;
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Optimize(IDirect3DVertexBuffer *iface,
+                                           IDirect3DDevice3 *D3DDevice,
+                                           DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice);
+    TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", This, D3D, Flags);
+
+    return IDirect3DVertexBuffer7_Optimize(ICOM_INTERFACE(This, IDirect3DVertexBuffer7),
+                                           ICOM_INTERFACE(D3D, IDirect3DDevice7),
+                                           Flags);
+}
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7::ProcessVerticesStrided
+ *
+ * This method processes untransformed strided vertices into a processed
+ * or optimized vertex buffer.
+ *
+ * For more details on the parameters, see
+ * IDirect3DVertexBuffer7::ProcessVertices
+ *
+ * Params:
+ *  VertexOp: Operations to perform
+ *  DestIndex: Destination index to write the vertices to
+ *  Count: Number of input vertices
+ *  StrideData: Array containing the input vertices
+ *  VertexTypeDesc: Vertex Description or source index?????????
+ *  D3DDevice: IDirect3DDevice7 to use for processing
+ *  Flags: Can be D3DPV_DONOTCOPYDATA to avoid copying unmodified vertices
+ *
+ * Returns
+ *  D3D_OK on success, or DDERR_*
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DVertexBufferImpl_ProcessVerticesStrided(IDirect3DVertexBuffer7 *iface,
+                                                 DWORD VertexOp,
+                                                 DWORD DestIndex,
+                                                 DWORD Count,
+                                                 D3DDRAWPRIMITIVESTRIDEDDATA *StrideData,
+                                                 DWORD VertexTypeDesc,
+                                                 IDirect3DDevice7 *D3DDevice,
+                                                 DWORD Flags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice);
+    FIXME("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, VertexOp, DestIndex, Count, StrideData, VertexTypeDesc, D3D, Flags);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * The VTables
+ *****************************************************************************/
+
+const IDirect3DVertexBuffer7Vtbl IDirect3DVertexBuffer7_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    IDirect3DVertexBufferImpl_QueryInterface,
+    IDirect3DVertexBufferImpl_AddRef,
+    IDirect3DVertexBufferImpl_Release,
+    /*** IDirect3DVertexBuffer Methods ***/
+    IDirect3DVertexBufferImpl_Lock,
+    IDirect3DVertexBufferImpl_Unlock,
+    IDirect3DVertexBufferImpl_ProcessVertices,
+    IDirect3DVertexBufferImpl_GetVertexBufferDesc,
+    IDirect3DVertexBufferImpl_Optimize,
+    /*** IDirect3DVertexBuffer7 Methods ***/
+    IDirect3DVertexBufferImpl_ProcessVerticesStrided
+};
+
+const IDirect3DVertexBufferVtbl IDirect3DVertexBuffer1_Vtbl =
+{
+    /*** IUnknown Methods ***/
+    Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
+    Thunk_IDirect3DVertexBufferImpl_1_AddRef,
+    Thunk_IDirect3DVertexBufferImpl_1_Release,
+    /*** IDirect3DVertexBuffer Methods ***/
+    Thunk_IDirect3DVertexBufferImpl_1_Lock,
+    Thunk_IDirect3DVertexBufferImpl_1_Unlock,
+    Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
+    Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    Thunk_IDirect3DVertexBufferImpl_1_Optimize
+};
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 4b83f59..ab06ece 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -1,5 +1,6 @@
 /* Direct3D Viewport
  * Copyright (c) 1998 Lionel ULMER
+ * Copyright (c) 2006 Stefan DÖSINGER
  *
  * This file contains the implementation of Direct3DViewport2.
  *
@@ -19,26 +20,43 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
+#include <assert.h>
 #include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
-#include "objbase.h"
 #include "wingdi.h"
+#include "wine/exception.h"
+#include "excpt.h"
+
 #include "ddraw.h"
 #include "d3d.h"
+
+#include "ddraw_private.h"
 #include "wine/debug.h"
 
-#include "d3d_private.h"
+WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
 
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+/*****************************************************************************
+ * Helper functions
+ *****************************************************************************/
 
-static void activate(IDirect3DViewportImpl* This) {
+/*****************************************************************************
+ * viewport_activate
+ *
+ * activates the viewport using IDirect3DDevice7::SetViewport
+ *
+ *****************************************************************************/
+void viewport_activate(IDirect3DViewportImpl* This) {
     IDirect3DLightImpl* light;
     D3DVIEWPORT7 vp;
     
@@ -71,7 +89,12 @@
     IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
 }
 
-
+/*****************************************************************************
+ * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2
+ *
+ * Writes viewport information to TRACE
+ *
+ *****************************************************************************/
 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
 {
     TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
@@ -100,13 +123,33 @@
 	  lpvp->dvMinZ, lpvp->dvMaxZ);
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
-                                                REFIID riid,
-                                                LPVOID* obp)
+/*****************************************************************************
+ * IUnknown Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DViewport3::QueryInterface
+ *
+ * A normal QueryInterface. Can query all interface versions and the
+ * IUnknown interface. The VTables of the different versions
+ * are equal
+ *
+ * Params:
+ *  refiid: Interface id queried for
+ *  obj: Address to write the interface pointer to
+ *
+ * Returns:
+ *  S_OK on success.
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_QueryInterface(IDirect3DViewport3 *iface,
+                                     REFIID riid,
+                                     void **obp)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obp);
 
     *obp = NULL;
 
@@ -120,27 +163,45 @@
 	return S_OK;
     }
     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
+    return E_NOINTERFACE;
 }
 
-ULONG WINAPI
-Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
+/*****************************************************************************
+ * IDirect3DViewport3::AddRef
+ *
+ * Increases the refcount.
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DViewportImpl_AddRef(IDirect3DViewport3 *iface)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
-    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
+    TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
 
     return ref;
 }
 
-ULONG WINAPI
-Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
+/*****************************************************************************
+ * IDirect3DViewport3::Release
+ *
+ * Reduces the refcount. If it falls to 0, the interface is released
+ *
+ * Returns:
+ *  The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirect3DViewportImpl_Release(IDirect3DViewport3 *iface)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
+    TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
 
     if (!ref) {
         HeapFree(GetProcessHeap(), 0, This);
@@ -149,19 +210,46 @@
     return ref;
 }
 
+/*****************************************************************************
+ * IDirect3DViewport Methods.
+ *****************************************************************************/
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
-                                            LPDIRECT3D lpDirect3D)
+/*****************************************************************************
+ * IDirect3DViewport3::Initialize
+ *
+ * No-op initialization.
+ *
+ * Params:
+ *  Direct3D: The direct3D device this viewport is assigned to
+ *
+ * Returns:
+ *  DDERR_ALREADYINITIALIZED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_Initialize(IDirect3DViewport3 *iface,
+                                 IDirect3D *Direct3D)
 {
-    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
-    return DD_OK;
+    TRACE("(%p)->(%p) no-op...\n", iface, Direct3D);
+    return DDERR_ALREADYINITIALIZED;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
-                                             LPD3DVIEWPORT lpData)
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport
+ *
+ * Returns the viewport data assigned to this viewport interface
+ *
+ * Params:
+ *  Data: Address to store the data
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_GetViewport(IDirect3DViewport3 *iface,
+                                  D3DVIEWPORT *lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     DWORD dwSize;
@@ -174,7 +262,7 @@
     memset(lpData, 0, dwSize);
     memcpy(lpData, &(This->viewports.vp1), dwSize);
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  returning D3DVIEWPORT :\n");
 	_dump_D3DVIEWPORT(lpData);
     }
@@ -182,15 +270,28 @@
     return DD_OK;
 }
 
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport
+ *
+ * Sets the viewport information for this interface
+ *
+ * Params:
+ *  lpData: Viewport to set
+ *
+ * Returns:
+ *  D3D_OK on succes
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
 HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
-                                             LPD3DVIEWPORT lpData)
+IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface,
+                                  D3DVIEWPORT *lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     LPDIRECT3DVIEWPORT3 current_viewport;
     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  getting D3DVIEWPORT :\n");
 	_dump_D3DVIEWPORT(lpData);
     }
@@ -215,36 +316,75 @@
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
-                                                   DWORD dwVertexCount,
-                                                   LPD3DTRANSFORMDATA lpData,
-                                                   DWORD dwFlags,
-                                                   LPDWORD lpOffScreen)
+/*****************************************************************************
+ * IDirect3DViewport3::TransformVertices
+ *
+ * Transforms vertices by the transformation matrix.
+ *
+ * Params:
+ *  dwVertexCount: The number of vertices to be transformed
+ *  lpData: Pointer to the vertex data
+ *  dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
+ *  lpOffScreen: Is set to nonzero if all vertices are off-screen
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_TransformVertices(IDirect3DViewport3 *iface,
+                                        DWORD dwVertexCount,
+                                        D3DTRANSFORMDATA *lpData,
+                                        DWORD dwFlags,
+                                        DWORD *lpOffScreen)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
+    FIXME("(%p)->(%08lx,%p,%08lx,%p): stub!\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen);
     if (lpOffScreen)
 	*lpOffScreen = 0;
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
-                                               DWORD dwElementCount,
-                                               LPD3DLIGHTDATA lpData)
+/*****************************************************************************
+ * IDirect3DViewport3::LightElements
+ *
+ * The DirectX 5.0 sdk says that it's not implemented
+ *
+ * Params:
+ *  ?
+ *
+ * Returns:
+ *  DDERR_UNSUPPORTED
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_LightElements(IDirect3DViewport3 *iface,
+                                    DWORD dwElementCount,
+                                    LPD3DLIGHTDATA lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
-    return DD_OK;
+    TRACE("(%p)->(%08lx,%p): Unimplemented!\n", This, dwElementCount, lpData);
+    return DDERR_UNSUPPORTED;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
-                                               D3DMATERIALHANDLE hMat)
+/*****************************************************************************
+ * IDirect3DViewport3::SetBackground
+ *
+ * Sets tje background material
+ *
+ * Params:
+ *  hMat: Handle from a IDirect3DMaterial interface
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface,
+                                    D3DMATERIALHANDLE hMat)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
+    TRACE("(%p)->(%08lx)\n", This, (DWORD) hMat);
     
     This->background = (IDirect3DMaterialImpl *) hMat;
     TRACE(" setting background color : %f %f %f %f\n",
@@ -253,43 +393,100 @@
 	  This->background->mat.u.diffuse.u3.b,
 	  This->background->mat.u.diffuse.u4.a);
 
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
-                                               LPD3DMATERIALHANDLE lphMat,
-                                               LPBOOL lpValid)
+/*****************************************************************************
+ * IDirect3DViewport3::GetBackground
+ *
+ * Returns the material handle assigned to the background of the viewport
+ *
+ * Params:
+ *  lphMat: Address to store the handle
+ *  lpValid: is set to FALSE if no background is set, TRUE if one is set
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *  (DDERR_INVALIDPARAMS if Mat or Valid is NULL)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_GetBackground(IDirect3DViewport3 *iface,
+                                    D3DMATERIALHANDLE *lphMat,
+                                    BOOL *lpValid)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
-    return DD_OK;
+    FIXME("(%p)->(%p,%p): stub!\n", This, lphMat, lpValid);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
-                                                    LPDIRECTDRAWSURFACE lpDDSurface)
+/*****************************************************************************
+ * IDirect3DViewport3::SetBackgroundDepth
+ *
+ * Sets a surface that represents the background depth. It's contents are
+ * used to set the depth buffer in IDirect3DViewport3::Clear
+ *
+ * Params:
+ *  lpDDSurface: Surface to set
+ *
+ * Returns: D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_SetBackgroundDepth(IDirect3DViewport3 *iface,
+                                         IDirectDrawSurface *lpDDSurface)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
-    return DD_OK;
+    FIXME("(%p)->(%p): stub!\n", This, lpDDSurface);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
-                                                    LPDIRECTDRAWSURFACE* lplpDDSurface,
-                                                    LPBOOL lpValid)
+/*****************************************************************************
+ * IDirect3DViewport3::GetBackgroundDepth
+ *
+ * Returns the surface that represents the depth field
+ *
+ * Params:
+ *  lplpDDSurface: Address to store the interface pointer
+ *  lpValid: Set to TRUE if a depth is asigned, FALSE otherwise
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *  (DDERR_INVALIDPARAMS if DDSurface of Valid is NULL)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_GetBackgroundDepth(IDirect3DViewport3 *iface,
+                                         IDirectDrawSurface **lplpDDSurface,
+                                         LPBOOL lpValid)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
+    FIXME("(%p)->(%p,%p): stub!\n", This, lplpDDSurface, lpValid);
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
-                                       DWORD dwCount,
-                                       LPD3DRECT lpRects,
-                                       DWORD dwFlags)
+/*****************************************************************************
+ * IDirect3DViewport3::Clear
+ *
+ * Clears the render target and / or the z buffer
+ *
+ * Params:
+ *  dwCount: The amount of rectangles to clear. If 0, the whole buffer is
+ *           cleared
+ *  lpRects: Pointer to the array of rectangles. If NULL, Count must be 0
+ *  dwFlags: D3DCLEAR_ZBUFFER and / or D3DCLEAR_TARGET
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  D3DERR_VIEWPORTHASNODEVICE if there's no active device
+ *  The return value of IDirect3DDevice7::Clear
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
+                            DWORD dwCount, 
+                            D3DRECT *lpRects,
+                            DWORD dwFlags)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     DWORD color = 0x00000000;
@@ -310,21 +507,40 @@
 	      ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
 	}
     }
-    return This->active_device->clear(This->active_device, dwCount, lpRects, 
-				      dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
-				      color, 1.0, 0x00000000);
+
+    return IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
+                                  dwCount,
+                                  lpRects,
+                                  dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
+                                  color,
+                                  1.0,
+                                  0x00000000);
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
-                                          LPDIRECT3DLIGHT lpDirect3DLight)
+/*****************************************************************************
+ * IDirect3DViewport3::AddLight
+ *
+ * Adds an light to the viewport
+ *
+ * Params:
+ *  lpDirect3DLight: Interface of the light to add
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Direct3DLight is NULL
+ *  DDERR_INVALIDPARAMS if there are 8 lights or more
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
+                               IDirect3DLight *lpDirect3DLight)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
     DWORD i = 0;
     DWORD map = This->map_lights;
     
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
+    TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
     
     if (This->num_lights >= 8)
         return DDERR_INVALIDPARAMS;
@@ -350,18 +566,31 @@
         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
     }
     
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
-                                             LPDIRECT3DLIGHT lpDirect3DLight)
+/*****************************************************************************
+ * IDirect3DViewport3::DeleteLight
+ *
+ * Deletes a light from the viewports' light list
+ *
+ * Params:
+ *  lpDirect3DLight: Light to delete
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the light wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface,
+                                  IDirect3DLight *lpDirect3DLight)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
     IDirect3DLightImpl *cur_light, *prev_light = NULL;
     
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
+    TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
     cur_light = This->lights;
     while (cur_light != NULL) {
         if (cur_light == lpDirect3DLightImpl) {
@@ -372,7 +601,7 @@
 	    cur_light->active_viewport = NULL;
 	    This->num_lights--;
 	    This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
-	    return DD_OK;
+	    return D3D_OK;
 	}
 	prev_light = cur_light;
 	cur_light = cur_light->next;
@@ -380,24 +609,57 @@
     return DDERR_INVALIDPARAMS;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
-                                           LPDIRECT3DLIGHT lpDirect3DLight,
-                                           LPDIRECT3DLIGHT* lplpDirect3DLight,
-                                           DWORD dwFlags)
+/*****************************************************************************
+ * IDirect3DViewport::NextLight
+ *
+ * Enumerates the lights associated with the viewport
+ *
+ * Params:
+ *  lpDirect3DLight: Light to start with
+ *  lplpDirect3DLight: Address to store the successor to
+ *
+ * Returns:
+ *  D3D_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface,
+                                IDirect3DLight *lpDirect3DLight,
+                                IDirect3DLight **lplpDirect3DLight,
+                                DWORD dwFlags)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
-    return DD_OK;
+    FIXME("(%p)->(%p,%p,%08lx): stub!\n", This, lpDirect3DLight, lplpDirect3DLight, dwFlags);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
-                                            LPD3DVIEWPORT2 lpData)
+/*****************************************************************************
+ * IDirect3DViewport2 Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport2
+ *
+ * Returns the currently set viewport in a D3DVIEWPORT2 structure.
+ * Simmilar to IDirect3DViewport3::GetViewport
+ *
+ * Params:
+ *  lpData: Pointer to the structure to fill
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the viewport was set with
+ *                      IDirect3DViewport3::SetViewport
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_GetViewport2(IDirect3DViewport3 *iface,
+                                   D3DVIEWPORT2 *lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     DWORD dwSize;
-    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+    TRACE("(%p)->(%p)\n", This, lpData);
     if (This->use_vp2 != 1) {
         ERR("  Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
 	return DDERR_INVALIDPARAMS;
@@ -406,23 +668,35 @@
     memset(lpData, 0, dwSize);
     memcpy(lpData, &(This->viewports.vp2), dwSize);
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  returning D3DVIEWPORT2 :\n");
 	_dump_D3DVIEWPORT2(lpData);
     }
     
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
-                                            LPD3DVIEWPORT2 lpData)
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport2
+ *
+ * Sets the viewport from a D3DVIEWPORT2 structure
+ *
+ * Params:
+ *  lpData: Viewport to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_SetViewport2(IDirect3DViewport3 *iface,
+                                   D3DVIEWPORT2 *lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     LPDIRECT3DVIEWPORT3 current_viewport;
     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
-    if (TRACE_ON(ddraw)) {
+    if (TRACE_ON(d3d7)) {
         TRACE("  getting D3DVIEWPORT2 :\n");
 	_dump_D3DVIEWPORT2(lpData);
     }
@@ -438,105 +712,126 @@
       IDirect3DViewport3_Release(current_viewport);
     }
 
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
-                                                 LPDIRECTDRAWSURFACE4 lpDDS)
+/*****************************************************************************
+ * IDirect3DViewport3 Methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirect3DViewport3::SetBackgroundDepth2
+ *
+ * Sets a IDirectDrawSurface4 surface as the background depth surface
+ *
+ * Params:
+ *  lpDDS: Surface to set
+ *
+ * Returns:
+ *  D3D_OK, because it's stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_SetBackgroundDepth2(IDirect3DViewport3 *iface,
+                                          IDirectDrawSurface4 *lpDDS)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
-    return DD_OK;
+    FIXME("(%p)->(%p): stub!\n", This, lpDDS);
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
-                                                 LPDIRECTDRAWSURFACE4* lplpDDS,
-                                                 LPBOOL lpValid)
+/*****************************************************************************
+ * IDirect3DViewport3::GetBackgroundDepth2
+ *
+ * Returns the IDirect3DSurface4 interface to the background depth surface
+ *
+ * Params:
+ *  lplpDDS: Address to store the interface pointer at
+ *  lpValid: Set to true if a surface is assigned
+ *
+ * Returns:
+ *  D3D_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_GetBackgroundDepth2(IDirect3DViewport3 *iface,
+                                          IDirectDrawSurface4 **lplpDDS,
+                                          BOOL *lpValid)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
-    return DD_OK;
+    return D3D_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
-                                    DWORD dwCount,
-                                    LPD3DRECT lpRects,
-                                    DWORD dwFlags,
-                                    DWORD dwColor,
-                                    D3DVALUE dvZ,
-                                    DWORD dwStencil)
+/*****************************************************************************
+ * IDirect3DViewport3::Clear2
+ *
+ * Another clearing method
+ *
+ * Params:
+ *  Count: Number of rectangles to clear
+ *  Rects: Rectangle array to clear
+ *  Flags: Some flags :)
+ *  Color: Color to fill the render target with
+ *  Z: Value to fill the depth buffer with
+ *  Stencil: Value to fill the stencil bits with
+ *
+ * Returns:
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirect3DViewportImpl_Clear2(IDirect3DViewport3 *iface,
+                             DWORD dwCount,
+                             LPD3DRECT lpRects,
+                             DWORD dwFlags,
+                             DWORD dwColor,
+                             D3DVALUE dvZ,
+                             DWORD dwStencil)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
+    TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
     if (This->active_device == NULL) {
         ERR(" Trying to clear a viewport not attached to a device !\n");
 	return D3DERR_VIEWPORTHASNODEVICE;
     }
-    return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
+    return IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
+                                  dwCount,
+                                  lpRects,
+                                  dwFlags,
+                                  dwColor,
+                                  dvZ,
+                                  dwStencil);
 }
 
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
+/*****************************************************************************
+ * The VTable
+ *****************************************************************************/
 
-static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3 =
+const IDirect3DViewport3Vtbl IDirect3DViewport3_Vtbl =
 {
-    XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
-    XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
-    XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
-    XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
-    XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
-    XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
-    XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
-    XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
-    XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
-    XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
-    XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
-    XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear,
-    XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
-    XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
-    XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
-    XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
-    XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
-    XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
-    XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
-    XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
+    /*** IUnknown Methods ***/
+    IDirect3DViewportImpl_QueryInterface,
+    IDirect3DViewportImpl_AddRef,
+    IDirect3DViewportImpl_Release,
+    /*** IDirect3DViewport Methods */
+    IDirect3DViewportImpl_Initialize,
+    IDirect3DViewportImpl_GetViewport,
+    IDirect3DViewportImpl_SetViewport,
+    IDirect3DViewportImpl_TransformVertices,
+    IDirect3DViewportImpl_LightElements,
+    IDirect3DViewportImpl_SetBackground,
+    IDirect3DViewportImpl_GetBackground,
+    IDirect3DViewportImpl_SetBackgroundDepth,
+    IDirect3DViewportImpl_GetBackgroundDepth,
+    IDirect3DViewportImpl_Clear,
+    IDirect3DViewportImpl_AddLight,
+    IDirect3DViewportImpl_DeleteLight,
+    IDirect3DViewportImpl_NextLight,
+    /*** IDirect3DViewport2 Methods ***/
+    IDirect3DViewportImpl_GetViewport2,
+    IDirect3DViewportImpl_SetViewport2,
+    /*** IDirect3DViewport3 Methods ***/
+    IDirect3DViewportImpl_SetBackgroundDepth2,
+    IDirect3DViewportImpl_GetBackgroundDepth2,
+    IDirect3DViewportImpl_Clear2,
 };
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-#undef XCAST
-#endif
-
-
-
-
-HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
-{
-    IDirect3DViewportImpl *object;
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
-
-    object->ref = 1;
-    object->d3d = d3d;
-    object->activate = activate;
-    object->use_vp2 = 0xFF;
-    object->next = NULL;
-    object->lights = NULL;
-    object->num_lights = 0;
-    object->map_lights = 0;
-    
-    ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
-
-    *obj = object;
-
-    TRACE(" creating implementation at %p.\n", *obj);
-    
-    return D3D_OK;
-}