[PATCH] WineD3D: Use a swapchain for GDI surfaces=0A=

Stefan Doesinger stefan at codeweavers.com
Tue Aug 5 14:23:00 CDT 2008


=0A=
This is a long-needed cleanup aimed at removing the=0A=
ddraw_primary, ddraw_window, ddraw_width and ddraw_height members=0A=
from IWineD3DDeviceImpl, which just do not belong there.=0A=
Destination window and screen handling is supposed to be done by=0A=
swapchains.=0A=
=0A=
This patch only installs the swapchain itself, but it still reads=0A=
the dest window etc from the device. This will be fixed by the=0A=
next patches.=0A=
---=0A=
 dlls/d3d8/device.c               |    2 +-=0A=
 dlls/d3d9/swapchain.c            |    2 +-=0A=
 dlls/ddraw/ddraw.c               |   94 +++++++++++++-=0A=
 dlls/ddraw/ddraw_private.h       |    1 +=0A=
 dlls/ddraw/surface.c             |   64 +++++----=0A=
 dlls/wined3d/Makefile.in         |    1 +=0A=
 dlls/wined3d/device.c            |  110 +++++++++++++----=0A=
 dlls/wined3d/surface.c           |    7 +-=0A=
 dlls/wined3d/surface_gdi.c       |  222 ++++----------------------------=0A=
 dlls/wined3d/swapchain_gdi.c     |  264 =
++++++++++++++++++++++++++++++++++++++=0A=
 dlls/wined3d/wined3d_private.h   |    3 +-=0A=
 include/wine/wined3d_interface.h |    8 +-=0A=
 12 files changed, 517 insertions(+), 261 deletions(-)=0A=
 create mode 100644 dlls/wined3d/swapchain_gdi.c=0A=
=0A=
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c=0A=
index 476abe9..d1ae476 100644=0A=
--- a/dlls/d3d8/device.c=0A=
+++ b/dlls/d3d8/device.c=0A=
@@ -307,7 +307,7 @@ static HRESULT WINAPI =
IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD=0A=
     localParameters.PresentationInterval                        =3D =
pPresentationParameters->FullScreen_PresentationInterval;=0A=
 =0A=
     EnterCriticalSection(&d3d8_cs);=0A=
-    hrc =3D =
IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, =
&localParameters, &object->wineD3DSwapChain, (IUnknown*)object, =
D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface);=0A=
+    hrc =3D =
IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, =
&localParameters, &object->wineD3DSwapChain, (IUnknown*)object, =
D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface, =
SURFACE_OPENGL);=0A=
     LeaveCriticalSection(&d3d8_cs);=0A=
 =0A=
     pPresentationParameters->BackBufferWidth                    =3D =
localParameters.BackBufferWidth;=0A=
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c=0A=
index 421230f..0dd9b8f 100644=0A=
--- a/dlls/d3d9/swapchain.c=0A=
+++ b/dlls/d3d9/swapchain.c=0A=
@@ -229,7 +229,7 @@ HRESULT  WINAPI  =
IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE=0A=
     localParameters.PresentationInterval                =3D =
pPresentationParameters->PresentationInterval;=0A=
 =0A=
     EnterCriticalSection(&d3d9_cs);=0A=
-    hrc =3D =
IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, =
&localParameters, &object->wineD3DSwapChain, (IUnknown*)object, =
D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface);=0A=
+    hrc =3D =
IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, =
&localParameters, &object->wineD3DSwapChain, (IUnknown*)object, =
D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface, =
SURFACE_OPENGL);=0A=
     LeaveCriticalSection(&d3d9_cs);=0A=
 =0A=
     pPresentationParameters->BackBufferWidth            =3D =
localParameters.BackBufferWidth;=0A=
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c=0A=
index 5a8ea0e..d037769 100644=0A=
--- a/dlls/ddraw/ddraw.c=0A=
+++ b/dlls/ddraw/ddraw.c=0A=
@@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw);=0A=
 static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, =
const DDSURFACEDESC2* provided);=0A=
 static HRESULT WINAPI IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl =
*This, IDirectDrawSurfaceImpl *primary);=0A=
 static HRESULT WINAPI IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl =
*This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT =
level);=0A=
+static HRESULT WINAPI =
IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *This, =
IDirectDrawSurfaceImpl *primary);=0A=
 =0A=
 /* Device identifier. Don't relay it to WineD3D */=0A=
 static const DDDEVICEIDENTIFIER2 deviceidentifier =3D=0A=
@@ -1626,6 +1627,7 @@ =
IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,=0A=
     IUnknown *Parent;=0A=
     IParentImpl *parImpl =3D NULL;=0A=
     IWineD3DSurface *wineD3DSurface;=0A=
+    IWineD3DSwapChain *swapchain;=0A=
     HRESULT hr;=0A=
     void *tmp;=0A=
     IWineD3DClipper *clipper =3D NULL;=0A=
@@ -1650,6 +1652,8 @@ =
IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,=0A=
     if(surfImpl->ImplType =3D=3D This->ImplType) return DDENUMRET_OK; =
/* Continue */=0A=
 =0A=
     /* Get the objects */=0A=
+    swapchain =3D surfImpl->wineD3DSwapChain;=0A=
+    surfImpl->wineD3DSwapChain =3D NULL;=0A=
     wineD3DSurface =3D surfImpl->WineD3DSurface;=0A=
     IWineD3DSurface_GetParent(wineD3DSurface, &Parent);=0A=
     IUnknown_Release(Parent); /* For the getParent */=0A=
@@ -1681,6 +1685,17 @@ =
IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,=0A=
     hr =3D IWineD3DSurface_GetDesc(wineD3DSurface, &Desc);=0A=
     if(hr !=3D D3D_OK) return hr;=0A=
 =0A=
+    if(swapchain) {=0A=
+        /* If there's a swapchain, it owns the IParent interface. =
Create a new one for the=0A=
+         * new surface=0A=
+         */=0A=
+        parImpl =3D HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, =
sizeof(*parImpl));=0A=
+        ICOM_INIT_INTERFACE(parImpl, IParent, IParent_Vtbl);=0A=
+        parImpl->ref =3D 1;=0A=
+=0A=
+        Parent =3D (IUnknown *) parImpl;=0A=
+    }=0A=
+=0A=
     /* Create the new surface */=0A=
     hr =3D IWineD3DDevice_CreateSurface(This->wineD3DDevice,=0A=
                                       Width, Height, Format,=0A=
@@ -1711,10 +1726,23 @@ =
IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,=0A=
     }=0A=
     /* TODO: Copy the surface content, except for render targets */=0A=
 =0A=
-    if(IWineD3DSurface_Release(wineD3DSurface) =3D=3D 0)=0A=
-        TRACE("Surface released successful, next surface\n");=0A=
-    else=0A=
-        ERR("Something's still holding the old WineD3DSurface\n");=0A=
+    /* If there's a swapchain, it owns the wined3d surfaces. So Destroy=0A=
+     * the swapchain=0A=
+     */=0A=
+    if(swapchain) {=0A=
+        /* The backbuffers have the swapchain set as well, but the =
primary=0A=
+         * owns it and destroys it=0A=
+         */=0A=
+        if(surfImpl->surface_desc.ddsCaps.dwCaps & =
DDSCAPS_PRIMARYSURFACE) {=0A=
+            IWineD3DDevice_UninitGDI(This->wineD3DDevice, =
D3D7CB_DestroySwapChain);=0A=
+        }=0A=
+        surfImpl->isRenderTarget =3D FALSE;=0A=
+    } else {=0A=
+        if(IWineD3DSurface_Release(wineD3DSurface) =3D=3D 0)=0A=
+            TRACE("Surface released successful, next surface\n");=0A=
+        else=0A=
+            ERR("Something's still holding the old WineD3DSurface\n");=0A=
+    }=0A=
 =0A=
     surfImpl->ImplType =3D This->ImplType;=0A=
 =0A=
@@ -2711,6 +2739,8 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,=0A=
             LeaveCriticalSection(&ddraw_cs);=0A=
             return hr;=0A=
         }=0A=
+    } else if(!(This->d3d_initialized) && desc2.ddsCaps.dwCaps & =
DDSCAPS_PRIMARYSURFACE) {=0A=
+        IDirectDrawImpl_CreateGDISwapChain(This, object);=0A=
     }=0A=
 =0A=
     /* Addref the ddraw interface to keep an reference for each surface =
*/=0A=
@@ -3117,6 +3147,7 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown *device,=0A=
     IParentImpl *object =3D NULL;=0A=
     HRESULT res =3D D3D_OK;=0A=
     IWineD3DSwapChain *swapchain;=0A=
+    IDirectDrawSurfaceImpl *iterator;=0A=
     TRACE("(%p) call back\n", device);=0A=
 =0A=
     object =3D HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, =
sizeof(IParentImpl));=0A=
@@ -3135,7 +3166,8 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown *device,=0A=
                                                    &swapchain, =0A=
                                                    (IUnknown*) =
ICOM_INTERFACE(object, IParent),=0A=
                                                    =
D3D7CB_CreateRenderTarget,=0A=
-                                                   =
D3D7CB_CreateDepthStencilSurface);=0A=
+                                                   =
D3D7CB_CreateDepthStencilSurface,=0A=
+                                                   This->ImplType);=0A=
     if (res !=3D D3D_OK)=0A=
     {=0A=
         FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain =
failed\n", This);=0A=
@@ -3146,11 +3178,63 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown =
*device,=0A=
     {=0A=
         *ppSwapChain =3D swapchain;=0A=
         object->child =3D (IUnknown *) swapchain;=0A=
+        This->d3d_target->wineD3DSwapChain =3D swapchain;=0A=
+        iterator =3D This->d3d_target->complex_array[0];=0A=
+        while(iterator) {=0A=
+            iterator->wineD3DSwapChain =3D swapchain;=0A=
+            iterator =3D iterator->complex_array[0];=0A=
+        }=0A=
     }=0A=
 =0A=
     return res;=0A=
 }=0A=
 =0A=
+static HRESULT WINAPI =
IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *This,=0A=
+                                                         =
IDirectDrawSurfaceImpl *primary) {=0A=
+    HRESULT hr;=0A=
+    WINED3DPRESENT_PARAMETERS presentation_parameters;=0A=
+    HWND window;=0A=
+=0A=
+    hr =3D IWineD3DDevice_GetHWND(This->wineD3DDevice,=0A=
+                                &window);=0A=
+    if(FAILED(hr)) {=0A=
+        return hr;=0A=
+    }=0A=
+=0A=
+    memset(&presentation_parameters, 0, =
sizeof(presentation_parameters));=0A=
+=0A=
+    /* Use the surface description for the device parameters, not the=0A=
+     * Device settings. The app might render to an offscreen surface=0A=
+     */=0A=
+    presentation_parameters.BackBufferWidth                 =3D =
primary->surface_desc.dwWidth;=0A=
+    presentation_parameters.BackBufferHeight                =3D =
primary->surface_desc.dwHeight;=0A=
+    presentation_parameters.BackBufferFormat                =3D =
PixelFormat_DD2WineD3D(&primary->surface_desc.u4.ddpfPixelFormat);=0A=
+    presentation_parameters.BackBufferCount                 =3D =
(primary->surface_desc.dwFlags & DDSD_BACKBUFFERCOUNT) ? =
primary->surface_desc.dwBackBufferCount : 0;=0A=
+    presentation_parameters.MultiSampleType                 =3D =
WINED3DMULTISAMPLE_NONE;=0A=
+    presentation_parameters.MultiSampleQuality              =3D 0;=0A=
+    presentation_parameters.SwapEffect                      =3D =
WINED3DSWAPEFFECT_FLIP;=0A=
+    presentation_parameters.hDeviceWindow                   =3D window;=0A=
+    presentation_parameters.Windowed                        =3D =
!(This->cooperative_level & DDSCL_FULLSCREEN);=0A=
+    presentation_parameters.EnableAutoDepthStencil          =3D FALSE; =
/* Not on GDI swapchains */=0A=
+    presentation_parameters.AutoDepthStencilFormat          =3D 0;=0A=
+    presentation_parameters.Flags                           =3D 0;=0A=
+    presentation_parameters.FullScreen_RefreshRateInHz      =3D =
WINED3DPRESENT_RATE_DEFAULT; /* Default rate: It's already set */=0A=
+    presentation_parameters.PresentationInterval            =3D =
WINED3DPRESENT_INTERVAL_DEFAULT;=0A=
+=0A=
+    This->d3d_target =3D primary;=0A=
+    hr =3D IWineD3DDevice_InitGDI(This->wineD3DDevice,=0A=
+                                &presentation_parameters,=0A=
+                                D3D7CB_CreateAdditionalSwapChain);=0A=
+    This->d3d_target =3D NULL;=0A=
+=0A=
+    if (hr !=3D D3D_OK)=0A=
+    {=0A=
+        FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain =
failed\n", This);=0A=
+        primary->wineD3DSwapChain =3D NULL;=0A=
+    }=0A=
+    return hr;=0A=
+}=0A=
+=0A=
 =
/************************************************************************=
*****=0A=
  * IDirectDrawImpl_AttachD3DDevice=0A=
  *=0A=
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h=0A=
index 56908cb..b7816d7 100644=0A=
--- a/dlls/ddraw/ddraw_private.h=0A=
+++ b/dlls/ddraw/ddraw_private.h=0A=
@@ -228,6 +228,7 @@ struct IDirectDrawSurfaceImpl=0A=
     IDirectDrawImpl         *ddraw;=0A=
     IWineD3DSurface         *WineD3DSurface;=0A=
     IWineD3DBaseTexture     *wineD3DTexture;=0A=
+    IWineD3DSwapChain       *wineD3DSwapChain;=0A=
 =0A=
     /* This implementation handles attaching surfaces to other surfaces =
*/=0A=
     IDirectDrawSurfaceImpl  *next_attached;=0A=
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c=0A=
index 1cf4d57..b4129b3 100644=0A=
--- a/dlls/ddraw/surface.c=0A=
+++ b/dlls/ddraw/surface.c=0A=
@@ -307,40 +307,46 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 =
*iface)=0A=
             IWineD3DBaseTexture_Release(This->wineD3DTexture);=0A=
         }=0A=
         /* If it's the RenderTarget, destroy the d3ddevice */=0A=
-        else if( (ddraw->d3d_initialized) && (This =3D=3D =
ddraw->d3d_target))=0A=
+        else if(This->wineD3DSwapChain)=0A=
         {=0A=
-            TRACE("(%p) Destroying the render target, uninitializing =
D3D\n", This);=0A=
-=0A=
-            /* Unset any index buffer, just to be sure */=0A=
-            IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL);=0A=
-            IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, =
NULL);=0A=
-            IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, =
NULL);=0A=
-            for(i =3D 0; i < ddraw->numConvertedDecls; i++)=0A=
-            {=0A=
-                IWineD3DVertexDeclaration_Release(ddraw->decls[i].decl);=0A=
-            }=0A=
-            HeapFree(GetProcessHeap(), 0, ddraw->decls);=0A=
-            ddraw->numConvertedDecls =3D 0;=0A=
+            if((ddraw->d3d_initialized) && (This =3D=3D =
ddraw->d3d_target)) {=0A=
+                TRACE("(%p) Destroying the render target, =
uninitializing D3D\n", This);=0A=
+=0A=
+                /* Unset any index buffer, just to be sure */=0A=
+                IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL);=0A=
+                =
IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL);=0A=
+                =
IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL);=0A=
+                for(i =3D 0; i < ddraw->numConvertedDecls; i++)=0A=
+                {=0A=
+                    =
IWineD3DVertexDeclaration_Release(ddraw->decls[i].decl);=0A=
+                }=0A=
+                HeapFree(GetProcessHeap(), 0, ddraw->decls);=0A=
+                ddraw->numConvertedDecls =3D 0;=0A=
 =0A=
-            if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, =
D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) !=3D D3D_OK)=0A=
-            {=0A=
-                /* Not good */=0A=
-                ERR("(%p) Failed to uninit 3D\n", This);=0A=
-            }=0A=
-            else=0A=
-            {=0A=
-                /* Free the d3d window if one was created */=0A=
-                if(ddraw->d3d_window !=3D 0)=0A=
+                if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, =
D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) !=3D D3D_OK)=0A=
                 {=0A=
-                    TRACE(" (%p) Destroying the hidden render window =
%p\n", This, ddraw->d3d_window);=0A=
-                    DestroyWindow(ddraw->d3d_window);=0A=
-                    ddraw->d3d_window =3D 0;=0A=
+                    /* Not good */=0A=
+                    ERR("(%p) Failed to uninit 3D\n", This);=0A=
+                }=0A=
+                else=0A=
+                {=0A=
+                    /* Free the d3d window if one was created */=0A=
+                    if(ddraw->d3d_window !=3D 0)=0A=
+                    {=0A=
+                        TRACE(" (%p) Destroying the hidden render =
window %p\n", This, ddraw->d3d_window);=0A=
+                        DestroyWindow(ddraw->d3d_window);=0A=
+                        ddraw->d3d_window =3D 0;=0A=
+                    }=0A=
+                    /* Unset the pointers */=0A=
                 }=0A=
-                /* Unset the pointers */=0A=
-            }=0A=
 =0A=
-            ddraw->d3d_initialized =3D FALSE;=0A=
-            ddraw->d3d_target =3D NULL;=0A=
+                This->wineD3DSwapChain =3D NULL; /* Uninit3D releases =
the swapchain */=0A=
+                ddraw->d3d_initialized =3D FALSE;=0A=
+                ddraw->d3d_target =3D NULL;=0A=
+            } else {=0A=
+                IWineD3DDevice_UninitGDI(ddraw->wineD3DDevice, =
D3D7CB_DestroySwapChain);=0A=
+                This->wineD3DSwapChain =3D NULL;=0A=
+            }=0A=
 =0A=
             /* Reset to the default surface implementation type. This =
is needed if apps use=0A=
              * non render target surfaces and expect blits to work =
after destroying the render=0A=
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in=0A=
index 7591b4d..dd0984e 100644=0A=
--- a/dlls/wined3d/Makefile.in=0A=
+++ b/dlls/wined3d/Makefile.in=0A=
@@ -30,6 +30,7 @@ C_SRCS =3D \=0A=
 	surface.c \=0A=
 	surface_gdi.c \=0A=
 	swapchain.c \=0A=
+	swapchain_gdi.c \=0A=
 	swapchain_base.c \=0A=
 	texture.c \=0A=
 	utils.c \=0A=
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c=0A=
index 49a72eb..836b318 100644=0A=
--- a/dlls/wined3d/device.c=0A=
+++ b/dlls/wined3d/device.c=0A=
@@ -718,10 +718,6 @@ static HRESULT  WINAPI =
IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U=0A=
            This, Width, Height, Format, debug_d3dformat(Format),=0A=
            (WINED3DFMT_D16_LOCKABLE =3D=3D Format), *ppSurface, =
object->resource.allocatedMemory, object->resource.size);=0A=
 =0A=
-    /* Store the DirectDraw primary surface. This is the first =
rendertarget surface created */=0A=
-    if( (Usage & WINED3DUSAGE_RENDERTARGET) && (!This->ddraw_primary) )=0A=
-        This->ddraw_primary =3D (IWineD3DSurface *) object;=0A=
-=0A=
     /* Look at the implementation and set the correct Vtable */=0A=
     switch(Impl) {=0A=
         case SURFACE_OPENGL:=0A=
@@ -1387,7 +1383,8 @@ static void WINAPI =
IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND=0A=
 static HRESULT WINAPI =
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, =
WINED3DPRESENT_PARAMETERS*  pPresentationParameters,                     =
                                              IWineD3DSwapChain** =
ppSwapChain,=0A=
                                                             IUnknown* =
parent,=0A=
                                                             =
D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget,=0A=
-                                                            =
D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil) {=0A=
+                                                            =
D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil,=0A=
+                                                            =
WINED3DSURFTYPE surface_type) {=0A=
     IWineD3DDeviceImpl      *This =3D (IWineD3DDeviceImpl *)iface;=0A=
 =0A=
     HDC                     hDc;=0A=
@@ -1414,6 +1411,17 @@ static HRESULT WINAPI =
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic=0A=
     }=0A=
 =0A=
     D3DCREATEOBJECTINSTANCE(object, SwapChain)=0A=
+    switch(surface_type) {=0A=
+        case SURFACE_GDI:=0A=
+            object->lpVtbl =3D &IWineGDISwapChain_Vtbl;=0A=
+            break;=0A=
+        case SURFACE_OPENGL:=0A=
+            object->lpVtbl =3D &IWineD3DSwapChain_Vtbl;=0A=
+            break;=0A=
+        case SURFACE_UNKNOWN:=0A=
+            FIXME("Caller tried to create a SURFACE_UNKNOWN =
swapchain\n");=0A=
+            return WINED3DERR_INVALIDCALL;=0A=
+    }=0A=
 =0A=
     /*********************=0A=
     * Lookup the window Handle and the relating X window handle=0A=
@@ -1485,7 +1493,9 @@ static HRESULT WINAPI =
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic=0A=
                              NULL /* pShared (always null)*/);=0A=
     if (object->frontBuffer !=3D NULL) {=0A=
         IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase =
*)object);=0A=
-        IWineD3DSurface_ModifyLocation(object->frontBuffer, =
SFLAG_INDRAWABLE, TRUE);=0A=
+        if(surface_type =3D=3D SURFACE_OPENGL) {=0A=
+            IWineD3DSurface_ModifyLocation(object->frontBuffer, =
SFLAG_INDRAWABLE, TRUE);=0A=
+        }=0A=
     } else {=0A=
         ERR("Failed to create the front buffer\n");=0A=
         goto error;=0A=
@@ -1530,14 +1540,16 @@ static HRESULT WINAPI =
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic=0A=
         return E_OUTOFMEMORY;=0A=
     object->num_contexts =3D 1;=0A=
 =0A=
-    object->context[0] =3D CreateContext(This, (IWineD3DSurfaceImpl *) =
object->frontBuffer, object->win_handle, FALSE /* pbuffer */, =
pPresentationParameters);=0A=
-    if (!object->context[0]) {=0A=
-        ERR("Failed to create a new context\n");=0A=
-        hr =3D WINED3DERR_NOTAVAILABLE;=0A=
-        goto error;=0A=
-    } else {=0A=
-        TRACE("Context created (HWND=3D%p, glContext=3D%p)\n",=0A=
-              object->win_handle, object->context[0]->glCtx);=0A=
+    if(surface_type =3D=3D SURFACE_OPENGL) {=0A=
+        object->context[0] =3D CreateContext(This, (IWineD3DSurfaceImpl =
*) object->frontBuffer, object->win_handle, FALSE /* pbuffer */, =
pPresentationParameters);=0A=
+        if (!object->context[0]) {=0A=
+            ERR("Failed to create a new context\n");=0A=
+            hr =3D WINED3DERR_NOTAVAILABLE;=0A=
+            goto error;=0A=
+        } else {=0A=
+            TRACE("Context created (HWND=3D%p, glContext=3D%p)\n",=0A=
+                object->win_handle, object->context[0]->glCtx);=0A=
+        }=0A=
     }=0A=
 =0A=
    /*********************=0A=
@@ -1571,23 +1583,27 @@ static HRESULT WINAPI =
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic=0A=
                 ERR("Cannot create new back buffer\n");=0A=
                 goto error;=0A=
             }=0A=
-            ENTER_GL();=0A=
-            glDrawBuffer(GL_BACK);=0A=
-            checkGLcall("glDrawBuffer(GL_BACK)");=0A=
-            LEAVE_GL();=0A=
+            if(surface_type =3D=3D SURFACE_OPENGL) {=0A=
+                ENTER_GL();=0A=
+                glDrawBuffer(GL_BACK);=0A=
+                checkGLcall("glDrawBuffer(GL_BACK)");=0A=
+                LEAVE_GL();=0A=
+            }=0A=
         }=0A=
     } else {=0A=
         object->backBuffer =3D NULL;=0A=
 =0A=
         /* Single buffering - draw to front buffer */=0A=
-        ENTER_GL();=0A=
-        glDrawBuffer(GL_FRONT);=0A=
-        checkGLcall("glDrawBuffer(GL_FRONT)");=0A=
-        LEAVE_GL();=0A=
+        if(surface_type =3D=3D SURFACE_OPENGL) {=0A=
+            ENTER_GL();=0A=
+            glDrawBuffer(GL_FRONT);=0A=
+            checkGLcall("glDrawBuffer(GL_FRONT)");=0A=
+            LEAVE_GL();=0A=
+        }=0A=
     }=0A=
 =0A=
     /* Under directX swapchains share the depth stencil, so only create =
one depth-stencil */=0A=
-    if (pPresentationParameters->EnableAutoDepthStencil && hr =3D=3D =
WINED3D_OK) {=0A=
+    if (pPresentationParameters->EnableAutoDepthStencil && hr =3D=3D =
WINED3D_OK && surface_type =3D=3D SURFACE_OPENGL) {=0A=
         TRACE("Creating depth stencil buffer\n");=0A=
         if (This->auto_depth_stencil_buffer =3D=3D NULL ) {=0A=
             hr =3D D3DCB_CreateDepthStencil(This->parent,=0A=
@@ -2240,6 +2256,33 @@ err_out:=0A=
     return hr;=0A=
 }=0A=
 =0A=
+static HRESULT WINAPI IWineD3DDeviceImpl_InitGDI(IWineD3DDevice *iface, =
WINED3DPRESENT_PARAMETERS* pPresentationParameters, =
D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) {=0A=
+    IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *) iface;=0A=
+    IWineD3DSwapChainImpl *swapchain =3D NULL;=0A=
+    HRESULT hr;=0A=
+=0A=
+    /* Setup the implicit swapchain */=0A=
+    TRACE("Creating implicit swapchain\n");=0A=
+    hr=3DD3DCB_CreateAdditionalSwapChain(This->parent, =
pPresentationParameters, (IWineD3DSwapChain **)&swapchain);=0A=
+    if (FAILED(hr) || !swapchain) {=0A=
+        WARN("Failed to create implicit swapchain\n");=0A=
+        goto err_out;=0A=
+    }=0A=
+=0A=
+    This->NumberOfSwapChains =3D 1;=0A=
+    This->swapchains =3D HeapAlloc(GetProcessHeap(), 0, =
This->NumberOfSwapChains * sizeof(IWineD3DSwapChain *));=0A=
+    if(!This->swapchains) {=0A=
+        ERR("Out of memory!\n");=0A=
+        goto err_out;=0A=
+    }=0A=
+    This->swapchains[0] =3D (IWineD3DSwapChain *) swapchain;=0A=
+    return WINED3D_OK;=0A=
+=0A=
+err_out:=0A=
+    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);=0A=
+    return hr;=0A=
+}=0A=
+=0A=
 static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice =
*iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyDepthStencilSurface, =
D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) {=0A=
     IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *) iface;=0A=
     int sampler;=0A=
@@ -2377,6 +2420,23 @@ static HRESULT WINAPI =
IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D=0A=
     return WINED3D_OK;=0A=
 }=0A=
 =0A=
+static HRESULT WINAPI IWineD3DDeviceImpl_UninitGDI(IWineD3DDevice =
*iface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) {=0A=
+    IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *) iface;=0A=
+    unsigned int i;=0A=
+=0A=
+    for(i=3D0; i < This->NumberOfSwapChains; i++) {=0A=
+        TRACE("Releasing the implicit swapchain %d\n", i);=0A=
+        if (D3DCB_DestroySwapChain(This->swapchains[i])  > 0) {=0A=
+            FIXME("(%p) Something's still holding the implicit =
swapchain\n", This);=0A=
+        }=0A=
+    }=0A=
+=0A=
+    HeapFree(GetProcessHeap(), 0, This->swapchains);=0A=
+    This->swapchains =3D NULL;=0A=
+    This->NumberOfSwapChains =3D 0;=0A=
+    return WINED3D_OK;=0A=
+}=0A=
+=0A=
 static void WINAPI IWineD3DDeviceImpl_SetFullscreen(IWineD3DDevice =
*iface, BOOL fullscreen) {=0A=
     IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *) iface;=0A=
     TRACE("(%p) Setting DDraw fullscreen mode to %s\n", This, =
fullscreen ? "true" : "false");=0A=
@@ -7644,7 +7704,9 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =3D=0A=
     IWineD3DDeviceImpl_CreatePalette,=0A=
     /*** Odd functions **/=0A=
     IWineD3DDeviceImpl_Init3D,=0A=
+    IWineD3DDeviceImpl_InitGDI,=0A=
     IWineD3DDeviceImpl_Uninit3D,=0A=
+    IWineD3DDeviceImpl_UninitGDI,=0A=
     IWineD3DDeviceImpl_SetFullscreen,=0A=
     IWineD3DDeviceImpl_SetMultithreaded,=0A=
     IWineD3DDeviceImpl_EvictManagedResources,=0A=
@@ -7790,7 +7852,9 @@ const IWineD3DDeviceVtbl =
IWineD3DDevice_DirtyConst_Vtbl =3D=0A=
     IWineD3DDeviceImpl_CreatePalette,=0A=
     /*** Odd functions **/=0A=
     IWineD3DDeviceImpl_Init3D,=0A=
+    IWineD3DDeviceImpl_InitGDI,=0A=
     IWineD3DDeviceImpl_Uninit3D,=0A=
+    IWineD3DDeviceImpl_UninitGDI,=0A=
     IWineD3DDeviceImpl_SetFullscreen,=0A=
     IWineD3DDeviceImpl_SetMultithreaded,=0A=
     IWineD3DDeviceImpl_EvictManagedResources,=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index 07c7076..dff833e 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -471,8 +471,6 @@ ULONG WINAPI =
IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {=0A=
         HeapFree(GetProcessHeap(), 0, This->palette9);=0A=
 =0A=
         IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);=0A=
-        if(iface =3D=3D device->ddraw_primary)=0A=
-            device->ddraw_primary =3D NULL;=0A=
 =0A=
         if(This->overlay_dest) {=0A=
             list_remove(&This->overlay_entry);=0A=
@@ -1460,7 +1458,10 @@ HRESULT WINAPI =
IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {=0A=
         if(This->palette) {=0A=
             pal =3D This->palette->palents;=0A=
         } else {=0A=
-            IWineD3DSurfaceImpl *dds_primary =3D (IWineD3DSurfaceImpl =
*)This->resource.wineD3DDevice->ddraw_primary;=0A=
+            IWineD3DSurfaceImpl *dds_primary;=0A=
+            IWineD3DSwapChainImpl *swapchain;=0A=
+            swapchain =3D (IWineD3DSwapChainImpl =
*)This->resource.wineD3DDevice->swapchains[0];=0A=
+            dds_primary =3D (IWineD3DSurfaceImpl =
*)swapchain->frontBuffer;=0A=
             if (dds_primary && dds_primary->palette)=0A=
                 pal =3D dds_primary->palette->palents;=0A=
         }=0A=
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c=0A=
index 1b1e5db..7874f92 100644=0A=
--- a/dlls/wined3d/surface_gdi.c=0A=
+++ b/dlls/wined3d/surface_gdi.c=0A=
@@ -34,99 +34,6 @@=0A=
 =0A=
 /* Use the d3d_surface debug channel to have one channel for all =
surfaces */=0A=
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);=0A=
-WINE_DECLARE_DEBUG_CHANNEL(fps);=0A=
-=0A=
-/***********************************************************************=
******=0A=
- * x11_copy_to_screen=0A=
- *=0A=
- * Helper function that blts the front buffer contents to the target =
window=0A=
- *=0A=
- * Params:=0A=
- *  This: Surface to copy from=0A=
- *  rc: Rectangle to copy=0A=
- *=0A=
- =
*************************************************************************=
****/=0A=
-static void=0A=
-x11_copy_to_screen(IWineD3DSurfaceImpl *This,=0A=
-                   LPRECT rc)=0A=
-{=0A=
-    if(This->resource.usage & WINED3DUSAGE_RENDERTARGET)=0A=
-    {=0A=
-        POINT offset =3D {0,0};=0A=
-        HWND hDisplayWnd;=0A=
-        HDC hDisplayDC;=0A=
-        HDC hSurfaceDC =3D 0;=0A=
-        RECT drawrect;=0A=
-        TRACE("(%p)->(%p): Copying to screen\n", This, rc);=0A=
-=0A=
-        hSurfaceDC =3D This->hDC;=0A=
-=0A=
-        hDisplayWnd =3D This->resource.wineD3DDevice->ddraw_window;=0A=
-        hDisplayDC =3D GetDCEx(hDisplayWnd, 0, =
DCX_CLIPSIBLINGS|DCX_CACHE);=0A=
-        if(rc)=0A=
-        {=0A=
-            TRACE(" copying rect (%d,%d)->(%d,%d), offset (%d,%d)\n",=0A=
-            rc->left, rc->top, rc->right, rc->bottom, offset.x, =
offset.y);=0A=
-        }=0A=
-=0A=
-        /* Front buffer coordinates are screen coordinates. Map them to =
the destination=0A=
-         * window if not fullscreened=0A=
-         */=0A=
-        if(!This->resource.wineD3DDevice->ddraw_fullscreen) {=0A=
-            ClientToScreen(hDisplayWnd, &offset);=0A=
-        }=0A=
-#if 0=0A=
-        /* FIXME: this doesn't work... if users really want to run=0A=
-        * X in 8bpp, then we need to call directly into display.drv=0A=
-        * (or Wine's equivalent), and force a private colormap=0A=
-        * without default entries. */=0A=
-        if (This->palette) {=0A=
-            SelectPalette(hDisplayDC, This->palette->hpal, FALSE);=0A=
-            RealizePalette(hDisplayDC); /* sends messages =3D> =
deadlocks */=0A=
-        }=0A=
-#endif=0A=
-        drawrect.left	=3D 0;=0A=
-        drawrect.right	=3D This->currentDesc.Width;=0A=
-        drawrect.top	=3D 0;=0A=
-        drawrect.bottom	=3D This->currentDesc.Height;=0A=
-=0A=
-#if 0=0A=
-        /* TODO: Support clippers */=0A=
-        if (This->clipper)=0A=
-        {=0A=
-            RECT xrc;=0A=
-            HWND hwnd =3D ((IWineD3DClipperImpl *) This->clipper)->hWnd;=0A=
-            if (hwnd && GetClientRect(hwnd,&xrc))=0A=
-            {=0A=
-                OffsetRect(&xrc,offset.x,offset.y);=0A=
-                IntersectRect(&drawrect,&drawrect,&xrc);=0A=
-            }=0A=
-        }=0A=
-#endif=0A=
-        if (rc)=0A=
-        {=0A=
-            IntersectRect(&drawrect,&drawrect,rc);=0A=
-        }=0A=
-        else=0A=
-        {=0A=
-            /* Only use this if the caller did not pass a rectangle, =
since=0A=
-             * due to double locking this could be the wrong one ...=0A=
-             */=0A=
-            if (This->lockedRect.left !=3D This->lockedRect.right)=0A=
-            {=0A=
-                IntersectRect(&drawrect,&drawrect,&This->lockedRect);=0A=
-            }=0A=
-        }=0A=
-=0A=
-        BitBlt(hDisplayDC,=0A=
-               drawrect.left-offset.x, drawrect.top-offset.y,=0A=
-               drawrect.right-drawrect.left, =
drawrect.bottom-drawrect.top,=0A=
-               hSurfaceDC,=0A=
-               drawrect.left, drawrect.top,=0A=
-               SRCCOPY);=0A=
-        ReleaseDC(hDisplayWnd, hDisplayDC);=0A=
-    }=0A=
-}=0A=
 =0A=
 =
/************************************************************************=
*****=0A=
  * IWineD3DSurface::Release, GDI version=0A=
@@ -140,7 +47,6 @@ ULONG WINAPI =
IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) {=0A=
     ULONG ref =3D InterlockedDecrement(&This->resource.ref);=0A=
     TRACE("(%p) : Releasing from %d\n", This, ref + 1);=0A=
     if (ref =3D=3D 0) {=0A=
-        IWineD3DDeviceImpl *device =3D This->resource.wineD3DDevice;=0A=
         TRACE("(%p) : cleaning up\n", This);=0A=
 =0A=
         if(This->Flags & SFLAG_DIBSECTION) {=0A=
@@ -157,8 +63,6 @@ ULONG WINAPI =
IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) {=0A=
         HeapFree(GetProcessHeap(), 0, This->palette9);=0A=
 =0A=
         IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);=0A=
-        if(iface =3D=3D device->ddraw_primary)=0A=
-            device->ddraw_primary =3D NULL;=0A=
 =0A=
         if(This->overlay_dest) {=0A=
             list_remove(&This->overlay_entry);=0A=
@@ -258,7 +162,7 @@ static HRESULT WINAPI=0A=
 IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)=0A=
 {=0A=
     IWineD3DSurfaceImpl *This =3D (IWineD3DSurfaceImpl *)iface;=0A=
-    IWineD3DDeviceImpl *dev =3D This->resource.wineD3DDevice;=0A=
+    IWineD3DSwapChainImpl *swapchain =3D NULL;=0A=
     TRACE("(%p)\n", This);=0A=
 =0A=
     if (!(This->Flags & SFLAG_LOCKED))=0A=
@@ -287,10 +191,11 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface =
*iface)=0A=
         }=0A=
 #endif=0A=
 =0A=
-    /* Update the screen */=0A=
-    if(This =3D=3D (IWineD3DSurfaceImpl *) dev->ddraw_primary)=0A=
-    {=0A=
-        x11_copy_to_screen(This, &This->lockedRect);=0A=
+    /* Tell the swapchain to update the screen */=0A=
+    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void =
**) &swapchain);=0A=
+    if(swapchain) {=0A=
+        x11_copy_to_screen(swapchain, &This->lockedRect);=0A=
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);=0A=
     }=0A=
 =0A=
     This->Flags &=3D ~SFLAG_LOCKED;=0A=
@@ -317,101 +222,18 @@ IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface,=0A=
                          IWineD3DSurface *override,=0A=
                          DWORD Flags)=0A=
 {=0A=
-    IWineD3DSurfaceImpl *This =3D (IWineD3DSurfaceImpl *) iface;=0A=
-    IWineD3DSurfaceImpl *Target =3D (IWineD3DSurfaceImpl *) override;=0A=
-    TRACE("(%p)->(%p,%x)\n", This, override, Flags);=0A=
-=0A=
-    TRACE("(%p) Flipping to surface %p\n", This, Target);=0A=
-=0A=
-    if(Target =3D=3D NULL)=0A=
-    {=0A=
-        ERR("(%p): Can't flip without a target\n", This);=0A=
-        return WINED3DERR_INVALIDCALL;=0A=
-    }=0A=
-=0A=
-    /* Flip the DC */=0A=
-    {=0A=
-        HDC tmp;=0A=
-        tmp =3D This->hDC;=0A=
-        This->hDC =3D Target->hDC;=0A=
-        Target->hDC =3D tmp;=0A=
-    }=0A=
-=0A=
-    /* Flip the DIBsection */=0A=
-    {=0A=
-        HBITMAP tmp;=0A=
-        tmp =3D This->dib.DIBsection;=0A=
-        This->dib.DIBsection =3D Target->dib.DIBsection;=0A=
-        Target->dib.DIBsection =3D tmp;=0A=
-    }=0A=
-=0A=
-    /* Flip the surface data */=0A=
-    {=0A=
-        void* tmp;=0A=
-=0A=
-        tmp =3D This->dib.bitmap_data;=0A=
-        This->dib.bitmap_data =3D Target->dib.bitmap_data;=0A=
-        Target->dib.bitmap_data =3D tmp;=0A=
-=0A=
-        tmp =3D This->resource.allocatedMemory;=0A=
-        This->resource.allocatedMemory =3D =
Target->resource.allocatedMemory;=0A=
-        Target->resource.allocatedMemory =3D tmp;=0A=
-=0A=
-        if(This->resource.heapMemory) {=0A=
-            ERR("GDI Surface %p has heap memory allocated\n", This);=0A=
-        }=0A=
-        if(Target->resource.heapMemory) {=0A=
-            ERR("GDI Surface %p has heap memory allocated\n", Target);=0A=
-        }=0A=
-    }=0A=
-=0A=
-    /* client_memory should not be different, but just in case */=0A=
-    {=0A=
-        BOOL tmp;=0A=
-        tmp =3D This->dib.client_memory;=0A=
-        This->dib.client_memory =3D Target->dib.client_memory;=0A=
-        Target->dib.client_memory =3D tmp;=0A=
-    }=0A=
-=0A=
-    /* Useful for debugging */=0A=
-#if 0=0A=
-        {=0A=
-            static unsigned int gen =3D 0;=0A=
-            char buffer[4096];=0A=
-            ++gen;=0A=
-            if ((gen % 10) =3D=3D 0) {=0A=
-                snprintf(buffer, sizeof(buffer), =
"/tmp/surface%p_type%u_level%u_%u.ppm", This, =
This->glDescription.target, This->glDescription.level, gen);=0A=
-                IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);=0A=
-            }=0A=
-            /*=0A=
-             * debugging crash code=0A=
-            if (gen =3D=3D 250) {=0A=
-              void** test =3D NULL;=0A=
-              *test =3D 0;=0A=
-            }=0A=
-            */=0A=
-        }=0A=
-#endif=0A=
-=0A=
-    /* Update the screen */=0A=
-    x11_copy_to_screen(This, NULL);=0A=
+    IWineD3DSwapChainImpl *swapchain =3D NULL;=0A=
+    HRESULT hr;=0A=
 =0A=
-    /* FPS support */=0A=
-    if (TRACE_ON(fps))=0A=
-    {=0A=
-        static long prev_time, frames;=0A=
-=0A=
-        DWORD time =3D GetTickCount();=0A=
-        frames++;=0A=
-        /* every 1.5 seconds */=0A=
-        if (time - prev_time > 1500) {=0A=
-            TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - =
prev_time));=0A=
-            prev_time =3D time;=0A=
-            frames =3D 0;=0A=
-        }=0A=
+    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void =
**) &swapchain);=0A=
+    if(!swapchain) {=0A=
+        ERR("Flipped surface is not on a swapchain\n");=0A=
+        return WINEDDERR_NOTFLIPPABLE;=0A=
     }=0A=
 =0A=
-    return WINED3D_OK;=0A=
+    hr =3D IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, =
NULL, NULL, 0, NULL, 0);=0A=
+    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);=0A=
+    return hr;=0A=
 }=0A=
 =0A=
 =
/************************************************************************=
*****=0A=
@@ -588,7 +410,10 @@ HRESULT WINAPI =
IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {=0A=
         if(This->palette) {=0A=
             pal =3D This->palette->palents;=0A=
         } else {=0A=
-            IWineD3DSurfaceImpl *dds_primary =3D (IWineD3DSurfaceImpl =
*)This->resource.wineD3DDevice->ddraw_primary;=0A=
+            IWineD3DSurfaceImpl *dds_primary;=0A=
+            IWineD3DSwapChainImpl *swapchain;=0A=
+            swapchain =3D (IWineD3DSwapChainImpl =
*)This->resource.wineD3DDevice->swapchains[0];=0A=
+            dds_primary =3D (IWineD3DSurfaceImpl =
*)swapchain->frontBuffer;=0A=
             if (dds_primary && dds_primary->palette)=0A=
                 pal =3D dds_primary->palette->palents;=0A=
         }=0A=
@@ -637,6 +462,7 @@ HRESULT WINAPI =
IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) {=0A=
     RGBQUAD col[256];=0A=
     IWineD3DPaletteImpl *pal =3D This->palette;=0A=
     unsigned int n;=0A=
+    IWineD3DSwapChainImpl *swapchain;=0A=
     TRACE("(%p)\n", This);=0A=
 =0A=
     if (!pal) return WINED3D_OK;=0A=
@@ -654,8 +480,12 @@ HRESULT WINAPI =
IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) {=0A=
 =0A=
     /* Update the image because of the palette change. Some games like =
e.g Red Alert=0A=
        call SetEntries a lot to implement fading. */=0A=
-    if(This =3D=3D (IWineD3DSurfaceImpl *) =
This->resource.wineD3DDevice->ddraw_primary)=0A=
-        x11_copy_to_screen(This, NULL);=0A=
+    /* Tell the swapchain to update the screen */=0A=
+    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void =
**) &swapchain);=0A=
+    if(swapchain) {=0A=
+        x11_copy_to_screen(swapchain, &This->lockedRect);=0A=
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);=0A=
+    }=0A=
 =0A=
     return WINED3D_OK;=0A=
 }=0A=
diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c=0A=
new file mode 100644=0A=
index 0000000..658ea2f=0A=
--- /dev/null=0A=
+++ b/dlls/wined3d/swapchain_gdi.c=0A=
@@ -0,0 +1,264 @@=0A=
+/*=0A=
+ *IDirect3DSwapChain9 implementation=0A=
+ *=0A=
+ *Copyright 2002-2003 Jason Edmeades=0A=
+ *Copyright 2002-2003 Raphael Junqueira=0A=
+ *Copyright 2005 Oliver Stieber=0A=
+ *Copyright 2007-2008 Stefan D=F6singer for CodeWeavers=0A=
+ *=0A=
+ *This library is free software; you can redistribute it and/or=0A=
+ *modify it under the terms of the GNU Lesser General Public=0A=
+ *License as published by the Free Software Foundation; either=0A=
+ *version 2.1 of the License, or (at your option) any later version.=0A=
+ *=0A=
+ *This library is distributed in the hope that it will be useful,=0A=
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU=0A=
+ *Lesser General Public License for more details.=0A=
+ *=0A=
+ *You should have received a copy of the GNU Lesser General Public=0A=
+ *License along with this library; if not, write to the Free Software=0A=
+ *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, =
USA=0A=
+ */=0A=
+=0A=
+#include "config.h"=0A=
+#include "wined3d_private.h"=0A=
+=0A=
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);=0A=
+WINE_DECLARE_DEBUG_CHANNEL(fps);=0A=
+=0A=
+static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain =
*iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderback) {=0A=
+    IWineD3DSwapChainImpl *This =3D (IWineD3DSwapChainImpl *)iface;=0A=
+    WINED3DDISPLAYMODE mode;=0A=
+=0A=
+    TRACE("Destroying swapchain %p\n", iface);=0A=
+=0A=
+    IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);=0A=
+=0A=
+    /* release the ref to the front and back buffer parents */=0A=
+    if(This->frontBuffer) {=0A=
+        IWineD3DSurface_SetContainer(This->frontBuffer, 0);=0A=
+        if(D3DCB_DestroyRenderback(This->frontBuffer) > 0) {=0A=
+            FIXME("(%p) Something's still holding the front =
buffer\n",This);=0A=
+        }=0A=
+    }=0A=
+=0A=
+    if(This->backBuffer) {=0A=
+        int i;=0A=
+        for(i =3D 0; i < This->presentParms.BackBufferCount; i++) {=0A=
+            IWineD3DSurface_SetContainer(This->backBuffer[i], 0);=0A=
+            if(D3DCB_DestroyRenderback(This->backBuffer[i]) > 0) {=0A=
+                FIXME("(%p) Something's still holding the back =
buffer\n",This);=0A=
+            }=0A=
+        }=0A=
+        HeapFree(GetProcessHeap(), 0, This->backBuffer);=0A=
+    }=0A=
+=0A=
+    /* Restore the screen resolution if we rendered in fullscreen=0A=
+     * This will restore the screen resolution to what it was before =
creating the swapchain. In case of d3d8 and d3d9=0A=
+     * this will be the original desktop resolution. In case of d3d7 =
this will be a NOP because ddraw sets the resolution=0A=
+     * before starting up Direct3D, thus orig_width and orig_height =
will be equal to the modes in the presentation params=0A=
+     */=0A=
+    if(This->presentParms.Windowed =3D=3D FALSE) {=0A=
+        mode.Width =3D This->orig_width;=0A=
+        mode.Height =3D This->orig_height;=0A=
+        mode.RefreshRate =3D 0;=0A=
+        mode.Format =3D This->orig_fmt;=0A=
+        IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) =
This->wineD3DDevice, 0, &mode);=0A=
+    }=0A=
+=0A=
+    HeapFree(GetProcessHeap(), 0, This);=0A=
+}=0A=
+=0A=
+/***********************************************************************=
******=0A=
+ * x11_copy_to_screen=0A=
+ *=0A=
+ * Helper function that blts the front buffer contents to the target =
window=0A=
+ *=0A=
+ * Params:=0A=
+ *  This: Surface to copy from=0A=
+ *  rc: Rectangle to copy=0A=
+ *=0A=
+ =
*************************************************************************=
****/=0A=
+void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc) {=0A=
+    IWineD3DSurfaceImpl *front =3D (IWineD3DSurfaceImpl *) =
This->frontBuffer;=0A=
+=0A=
+    if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) {=0A=
+        POINT offset =3D {0,0};=0A=
+        HWND hDisplayWnd;=0A=
+        HDC hDisplayDC;=0A=
+        HDC hSurfaceDC =3D 0;=0A=
+        RECT drawrect;=0A=
+        TRACE("(%p)->(%p): Copying to screen\n", front, rc);=0A=
+=0A=
+        hSurfaceDC =3D front->hDC;=0A=
+=0A=
+        hDisplayWnd =3D front->resource.wineD3DDevice->ddraw_window;=0A=
+        hDisplayDC =3D GetDCEx(hDisplayWnd, 0, =
DCX_CLIPSIBLINGS|DCX_CACHE);=0A=
+        if(rc) {=0A=
+            TRACE(" copying rect (%d,%d)->(%d,%d), offset (%d,%d)\n",=0A=
+                  rc->left, rc->top, rc->right, rc->bottom, offset.x, =
offset.y);=0A=
+        }=0A=
+=0A=
+        /* Front buffer coordinates are screen coordinates. Map them to =
the destination=0A=
+        * window if not fullscreened=0A=
+        */=0A=
+        if(!front->resource.wineD3DDevice->ddraw_fullscreen) {=0A=
+            ClientToScreen(hDisplayWnd, &offset);=0A=
+        }=0A=
+#if 0=0A=
+        /* FIXME: This doesn't work... if users really want to run=0A=
+        * X in 8bpp, then we need to call directly into display.drv=0A=
+        * (or Wine's equivalent), and force a private colormap=0A=
+        * without default entries. */=0A=
+        if (front->palette) {=0A=
+        SelectPalette(hDisplayDC, front->palette->hpal, FALSE);=0A=
+        RealizePalette(hDisplayDC); /* sends messages =3D> deadlocks */=0A=
+    }=0A=
+#endif=0A=
+        drawrect.left   =3D 0;=0A=
+        drawrect.right  =3D front->currentDesc.Width;=0A=
+        drawrect.top    =3D 0;=0A=
+        drawrect.bottom =3D front->currentDesc.Height;=0A=
+=0A=
+#if 0=0A=
+        /* TODO: Support clippers */=0A=
+        if (front->clipper)=0A=
+        {=0A=
+        RECT xrc;=0A=
+        HWND hwnd =3D ((IWineD3DClipperImpl *) front->clipper)->hWnd;=0A=
+        if (hwnd && GetClientRect(hwnd,&xrc))=0A=
+        {=0A=
+        OffsetRect(&xrc,offset.x,offset.y);=0A=
+        IntersectRect(&drawrect,&drawrect,&xrc);=0A=
+    }=0A=
+    }=0A=
+#endif=0A=
+        if (rc) {=0A=
+            IntersectRect(&drawrect,&drawrect,rc);=0A=
+        }=0A=
+        else {=0A=
+            /* Only use this if the caller did not pass a rectangle, =
since=0A=
+            * due to double locking this could be the wrong one ...=0A=
+            */=0A=
+            if (front->lockedRect.left !=3D front->lockedRect.right) {=0A=
+                IntersectRect(&drawrect,&drawrect,&front->lockedRect);=0A=
+            }=0A=
+        }=0A=
+=0A=
+        BitBlt(hDisplayDC,=0A=
+               drawrect.left-offset.x, drawrect.top-offset.y,=0A=
+               drawrect.right-drawrect.left, =
drawrect.bottom-drawrect.top,=0A=
+               hSurfaceDC,=0A=
+               drawrect.left, drawrect.top,=0A=
+               SRCCOPY);=0A=
+        ReleaseDC(hDisplayWnd, hDisplayDC);=0A=
+    }=0A=
+}=0A=
+=0A=
+static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain =
*iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND =
hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {=0A=
+    IWineD3DSwapChainImpl *This =3D (IWineD3DSwapChainImpl *) iface;=0A=
+    IWineD3DSurfaceImpl *front, *back;=0A=
+=0A=
+    if(!This->backBuffer) {=0A=
+        WARN("Swapchain doesn't have a backbuffer, returning =
WINED3DERR_INVALIDCALL\n");=0A=
+        return WINED3DERR_INVALIDCALL;=0A=
+    }=0A=
+    front =3D (IWineD3DSurfaceImpl *) This->frontBuffer;=0A=
+    back =3D (IWineD3DSurfaceImpl *) This->backBuffer[0];=0A=
+=0A=
+    /* Flip the DC */=0A=
+    {=0A=
+        HDC tmp;=0A=
+        tmp =3D front->hDC;=0A=
+        front->hDC =3D back->hDC;=0A=
+        back->hDC =3D tmp;=0A=
+    }=0A=
+=0A=
+    /* Flip the DIBsection */=0A=
+    {=0A=
+        HBITMAP tmp;=0A=
+        tmp =3D front->dib.DIBsection;=0A=
+        front->dib.DIBsection =3D back->dib.DIBsection;=0A=
+        back->dib.DIBsection =3D tmp;=0A=
+    }=0A=
+=0A=
+    /* Flip the surface data */=0A=
+    {=0A=
+        void* tmp;=0A=
+=0A=
+        tmp =3D front->dib.bitmap_data;=0A=
+        front->dib.bitmap_data =3D back->dib.bitmap_data;=0A=
+        back->dib.bitmap_data =3D tmp;=0A=
+=0A=
+        tmp =3D front->resource.allocatedMemory;=0A=
+        front->resource.allocatedMemory =3D =
back->resource.allocatedMemory;=0A=
+        back->resource.allocatedMemory =3D tmp;=0A=
+=0A=
+        if(front->resource.heapMemory) {=0A=
+            ERR("GDI Surface %p has heap memory allocated\n", front);=0A=
+        }=0A=
+        if(back->resource.heapMemory) {=0A=
+            ERR("GDI Surface %p has heap memory allocated\n", back);=0A=
+        }=0A=
+    }=0A=
+=0A=
+    /* client_memory should not be different, but just in case */=0A=
+    {=0A=
+        BOOL tmp;=0A=
+        tmp =3D front->dib.client_memory;=0A=
+        front->dib.client_memory =3D back->dib.client_memory;=0A=
+        back->dib.client_memory =3D tmp;=0A=
+    }=0A=
+=0A=
+    /* FPS support */=0A=
+    if (TRACE_ON(fps))=0A=
+    {=0A=
+        static long prev_time, frames;=0A=
+=0A=
+        DWORD time =3D GetTickCount();=0A=
+        frames++;=0A=
+        /* every 1.5 seconds */=0A=
+        if (time - prev_time > 1500) {=0A=
+            TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - =
prev_time));=0A=
+            prev_time =3D time;=0A=
+            frames =3D 0;=0A=
+        }=0A=
+    }=0A=
+=0A=
+    x11_copy_to_screen(This, NULL);=0A=
+=0A=
+    return WINED3D_OK;=0A=
+}=0A=
+=0A=
+/* FIXME: This should not be needed, the base version is OK */=0A=
+HRESULT WINAPI =
IWineGDIBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, =
WINED3DDISPLAYMODE*pMode) {=0A=
+    IWineD3DSwapChainImpl *This =3D (IWineD3DSwapChainImpl *)iface;=0A=
+    IWineD3DDeviceImpl *device =3D This->wineD3DDevice;=0A=
+=0A=
+    pMode->Width =3D device->ddraw_width;=0A=
+    pMode->Height =3D device->ddraw_height;=0A=
+    pMode->Format =3D device->ddraw_format;=0A=
+    pMode->RefreshRate =3D 0;=0A=
+    return WINED3D_OK;=0A=
+}=0A=
+=0A=
+const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =3D=0A=
+{=0A=
+    /* IUnknown */=0A=
+    IWineD3DBaseSwapChainImpl_QueryInterface,=0A=
+    IWineD3DBaseSwapChainImpl_AddRef,=0A=
+    IWineD3DBaseSwapChainImpl_Release,=0A=
+    /* IWineD3DSwapChain */=0A=
+    IWineD3DBaseSwapChainImpl_GetParent,=0A=
+    IWineGDISwapChainImpl_Destroy,=0A=
+    IWineD3DBaseSwapChainImpl_GetDevice,=0A=
+    IWineGDISwapChainImpl_Present,=0A=
+    IWineD3DBaseSwapChainImpl_GetFrontBufferData,=0A=
+    IWineD3DBaseSwapChainImpl_GetBackBuffer,=0A=
+    IWineD3DBaseSwapChainImpl_GetRasterStatus,=0A=
+    IWineD3DBaseSwapChainImpl_GetDisplayMode,=0A=
+    IWineD3DBaseSwapChainImpl_GetPresentParameters,=0A=
+    IWineD3DBaseSwapChainImpl_SetGammaRamp,=0A=
+    IWineD3DBaseSwapChainImpl_GetGammaRamp=0A=
+};=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 0629dd2..0c163f4 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -918,7 +918,6 @@ struct IWineD3DDeviceImpl=0A=
 =0A=
     /* DirectDraw stuff */=0A=
     HWND ddraw_window;=0A=
-    IWineD3DSurface *ddraw_primary;=0A=
     DWORD ddraw_width, ddraw_height;=0A=
     WINED3DFORMAT ddraw_format;=0A=
     BOOL ddraw_fullscreen;=0A=
@@ -1745,6 +1744,8 @@ typedef struct IWineD3DSwapChainImpl=0A=
 } IWineD3DSwapChainImpl;=0A=
 =0A=
 extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl;=0A=
+const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl;=0A=
+void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc);=0A=
 =0A=
 HRESULT WINAPI =
IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, =
REFIID riid, LPVOID *ppobj);=0A=
 ULONG WINAPI IWineD3DBaseSwapChainImpl_AddRef(IWineD3DSwapChain *iface);=0A=
diff --git a/include/wine/wined3d_interface.h =
b/include/wine/wined3d_interface.h=0A=
index b478cda..e8b4d94 100644=0A=
--- a/include/wine/wined3d_interface.h=0A=
+++ b/include/wine/wined3d_interface.h=0A=
@@ -367,14 +367,16 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)=0A=
     STDMETHOD(CreateVolume)(THIS_ UINT Width, UINT Height, UINT Depth, =
DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct =
IWineD3DVolume** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown =
*parent) PURE;=0A=
     STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, =
DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct =
IWineD3DCubeTexture** ppCubeTexture, HANDLE* pSharedHandle, IUnknown =
*parent, D3DCB_CREATESURFACEFN pFn) PURE;=0A=
     STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, struct =
IWineD3DQuery **ppQuery, IUnknown *pParent);=0A=
-    STDMETHOD(CreateAdditionalSwapChain)(THIS_ =
WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct =
IWineD3DSwapChain **pSwapChain, IUnknown *pParent, =
D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2);=0A=
+    STDMETHOD(CreateAdditionalSwapChain)(THIS_ =
WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct =
IWineD3DSwapChain **pSwapChain, IUnknown *pParent, =
D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2, =
WINED3DSURFTYPE surface_type);=0A=
     STDMETHOD(CreateVertexDeclaration)(THIS_ struct =
IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent, const =
WINED3DVERTEXELEMENT *elements, UINT element_count) PURE;=0A=
     STDMETHOD(CreateVertexDeclarationFromFVF)(THIS_ struct =
IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent, DWORD Fvf) PURE;=0A=
     STDMETHOD(CreateVertexShader)(THIS_ struct =
IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD* pFunction, =
struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;=0A=
     STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct =
IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE;=0A=
     STDMETHOD_(HRESULT,CreatePalette)(THIS_ DWORD Flags, PALETTEENTRY =
*PalEnt, struct IWineD3DPalette **Palette, IUnknown *Parent);=0A=
     STDMETHOD(Init3D)(THIS_ WINED3DPRESENT_PARAMETERS* =
pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN =
D3DCB_CreateAdditionalSwapChain);=0A=
+    STDMETHOD(InitGDI)(THIS_ WINED3DPRESENT_PARAMETERS* =
pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN =
D3DCB_CreateAdditionalSwapChain);=0A=
     STDMETHOD(Uninit3D)(THIS, D3DCB_DESTROYSURFACEFN pFn, =
D3DCB_DESTROYSWAPCHAINFN pFn2);=0A=
+    STDMETHOD(UninitGDI)(THIS, D3DCB_DESTROYSWAPCHAINFN pFn2);=0A=
     STDMETHOD_(void, SetFullscreen)(THIS_ BOOL fullscreen);=0A=
     STDMETHOD_(void, SetMultithreaded)(THIS);=0A=
     STDMETHOD(EvictManagedResources)(THIS) PURE;=0A=
@@ -508,14 +510,16 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)=0A=
 #define IWineD3DDevice_CreateVolume(p,a,b,c,d,e,f,g,h,i)        =
(p)->lpVtbl->CreateVolume(p,a,b,c,d,e,f,g,h,i)=0A=
 #define IWineD3DDevice_CreateCubeTexture(p,a,b,c,d,e,f,g,h,i)   =
(p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g,h,i)=0A=
 #define IWineD3DDevice_CreateQuery(p,a,b,c)                     =
(p)->lpVtbl->CreateQuery(p,a,b,c)=0A=
-#define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e)   =
(p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e)=0A=
+#define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e,f) =
(p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e,f)=0A=
 #define IWineD3DDevice_CreateVertexDeclaration(p,a,b,c,d)       =
(p)->lpVtbl->CreateVertexDeclaration(p,a,b,c,d)=0A=
 #define IWineD3DDevice_CreateVertexDeclarationFromFVF(p,a,b,c)  =
(p)->lpVtbl->CreateVertexDeclarationFromFVF(p,a,b,c)=0A=
 #define IWineD3DDevice_CreateVertexShader(p,a,b,c,d)            =
(p)->lpVtbl->CreateVertexShader(p,a,b,c,d)=0A=
 #define IWineD3DDevice_CreatePixelShader(p,a,b,c)               =
(p)->lpVtbl->CreatePixelShader(p,a,b,c)=0A=
 #define IWineD3DDevice_CreatePalette(p, a, b, c, d)             =
(p)->lpVtbl->CreatePalette(p, a, b, c, d)=0A=
 #define IWineD3DDevice_Init3D(p, a, b)                          =
(p)->lpVtbl->Init3D(p, a, b)=0A=
+#define IWineD3DDevice_InitGDI(p, a, b)                         =
(p)->lpVtbl->InitGDI(p, a, b)=0A=
 #define IWineD3DDevice_Uninit3D(p, a, b)                        =
(p)->lpVtbl->Uninit3D(p, a, b)=0A=
+#define IWineD3DDevice_UninitGDI(p, a)                          =
(p)->lpVtbl->UninitGDI(p, a)=0A=
 #define IWineD3DDevice_SetFullscreen(p, a)                      =
(p)->lpVtbl->SetFullscreen(p, a)=0A=
 #define IWineD3DDevice_SetMultithreaded(p)                      =
(p)->lpVtbl->SetMultithreaded(p)=0A=
 #define IWineD3DDevice_EvictManagedResources(p)                 =
(p)->lpVtbl->EvictManagedResources(p)=0A=
-- =0A=
1.5.4.5=0A=
=0A=

------=_NextPart_000_001D_01C90123.E9F21790--




More information about the wine-patches mailing list