Implement swapchains.

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index fa65f21..c1ec0bb 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -655,6 +655,9 @@
     /* OpenGL/GLX related */
     GLXContext              swap_ctx;
     Drawable                swap_drawable;
+
+    /* ready for when we move over to wined3d */
+    IWineD3DSwapChain      *wineD3DSwapChain;
 };
 
 /* IUnknown: */
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index ae3996a..ecf2ca4 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -579,6 +579,61 @@
     return res;
 }
 
+/* Callback for creating the inplicite swapchain when the device is created */
+HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device,
+                                                WINED3DPRESENT_PARAMETERS* pPresentationParameters,
+                                                IWineD3DSwapChain ** ppSwapChain){
+    HRESULT res = D3D_OK;
+    IDirect3DSwapChain8Impl *d3dSwapChain = NULL;
+    /* We have to pass the presentation parameters back and forth */
+    D3DPRESENT_PARAMETERS localParameters;
+    localParameters.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
+    localParameters.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);
+    localParameters.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);
+    localParameters.BackBufferCount                = *(pPresentationParameters->BackBufferCount);
+    localParameters.MultiSampleType                = *(pPresentationParameters->MultiSampleType);
+  /* d3d9 only */
+  /* localParameters.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality); */
+    localParameters.SwapEffect                     = *(pPresentationParameters->SwapEffect);
+    localParameters.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);
+    localParameters.Windowed                       = *(pPresentationParameters->Windowed);
+    localParameters.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);
+    localParameters.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);
+    localParameters.Flags                          = *(pPresentationParameters->Flags);
+    localParameters.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+/* not in d3d8 */
+/*    localParameters.PresentationInterval           = *(pPresentationParameters->PresentationInterval); */
+
+    TRACE("(%p) rellaying\n", device);
+    /*copy the presentation parameters*/
+    res = IDirect3DDevice8_CreateAdditionalSwapChain((IDirect3DDevice8 *)device, &localParameters, (IDirect3DSwapChain8 **)&d3dSwapChain);
+
+    if (res == D3D_OK){
+        *ppSwapChain = d3dSwapChain->wineD3DSwapChain;
+    } else {
+        FIXME("failed to create additional swap chain\n");
+        *ppSwapChain = NULL;
+    }
+    /* Copy back the presentation parameters */
+    TRACE("(%p) setting up return parameters\n", device);
+   *pPresentationParameters->BackBufferWidth               = localParameters.BackBufferWidth;
+   *pPresentationParameters->BackBufferHeight              = localParameters.BackBufferHeight;
+   *pPresentationParameters->BackBufferFormat              = localParameters.BackBufferFormat;
+   *pPresentationParameters->BackBufferCount               = localParameters.BackBufferCount;
+   *pPresentationParameters->MultiSampleType               = localParameters.MultiSampleType;
+/*   *pPresentationParameters->MultiSampleQuality            leave alone incase wineD3D set something internally */
+   *pPresentationParameters->SwapEffect                    = localParameters.SwapEffect;
+   *pPresentationParameters->hDeviceWindow                 = localParameters.hDeviceWindow;
+   *pPresentationParameters->Windowed                      = localParameters.Windowed;
+   *pPresentationParameters->EnableAutoDepthStencil        = localParameters.EnableAutoDepthStencil;
+   *pPresentationParameters->AutoDepthStencilFormat        = localParameters.AutoDepthStencilFormat;
+   *pPresentationParameters->Flags                         = localParameters.Flags;
+   *pPresentationParameters->FullScreen_RefreshRateInHz    = localParameters.FullScreen_RefreshRateInHz;
+/*   *pPresentationParameters->PresentationInterval          leave alone incase wineD3D set something internally */
+
+   return res;
+}
+
 HRESULT  WINAPI  IDirect3D8Impl_CreateDevice               (LPDIRECT3D8 iface,
                                                             UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
                                                             DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
@@ -624,7 +679,7 @@
     localParameters.Flags                          = &pPresentationParameters->Flags;                      
     localParameters.FullScreen_RefreshRateInHz     = &pPresentationParameters->FullScreen_RefreshRateInHz; 
     localParameters.PresentationInterval           = &pPresentationParameters->FullScreen_PresentationInterval;    /* Renamed in dx9 */
-    IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateRenderTarget);
+    IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateAdditionalSwapChain);
 
     /** use StateBlock Factory here, for creating the startup stateBlock */
     object->StateBlock = NULL;
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index b0aedf5..4c96a63 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -184,7 +184,6 @@
 typedef struct IDirect3DVertexBuffer9Impl      IDirect3DVertexBuffer9Impl;
 typedef struct IDirect3DIndexBuffer9Impl       IDirect3DIndexBuffer9Impl;
 typedef struct IDirect3DSurface9Impl           IDirect3DSurface9Impl;
-typedef struct IDirect3DSwapChain9Impl         IDirect3DSwapChain9Impl;
 typedef struct IDirect3DResource9Impl          IDirect3DResource9Impl;
 typedef struct IDirect3DVolume9Impl            IDirect3DVolume9Impl;
 typedef struct IDirect3DStateBlock9Impl        IDirect3DStateBlock9Impl;
@@ -560,34 +559,15 @@
 /*****************************************************************************
  * IDirect3DSwapChain9 implementation structure
  */
-struct IDirect3DSwapChain9Impl
+typedef struct IDirect3DSwapChain9Impl
 {
     /* IUnknown fields */
     const IDirect3DSwapChain9Vtbl *lpVtbl;
     DWORD                   ref;
 
     /* IDirect3DSwapChain9 fields */
-    IDirect3DDevice9Impl   *Device;
-    IDirect3DSurface9Impl  *frontBuffer;
-    IDirect3DSurface9Impl  *backBuffer;
-    IDirect3DSurface9Impl  *depthStencilBuffer;
-    D3DPRESENT_PARAMETERS   PresentParms;        
-};
-
-/* IUnknown: */
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID refiid, LPVOID* obj);
-extern ULONG WINAPI   IDirect3DSwapChain9Impl_AddRef(LPDIRECT3DSWAPCHAIN9 iface);
-extern ULONG WINAPI   IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface);
-
-/* IDirect3DSwapChain9: */
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters);
-
+    IWineD3DSwapChain      *wineD3DSwapChain;
+} IDirect3DSwapChain9Impl;
 
 /* ------------------ */
 /* IDirect3DResource9 */
@@ -1210,4 +1190,14 @@
                                           IWineD3DVolume **ppVolume, 
                                           HANDLE   * pSharedHandle);
 
+extern HRESULT WINAPI D3D9CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height,
+                                         WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+                                         DWORD MultisampleQuality, BOOL Discard,
+                                         IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
+
+extern HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
+                                         WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+                                         DWORD MultisampleQuality, BOOL Lockable, 
+                                         IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
+
 #endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 2d99208..8a08a5d 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -57,7 +57,6 @@
     TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
 
     if (ref == 0) {
-      IDirect3D9_Release((LPDIRECT3D9) This->direct3d);
       IWineD3DDevice_Release(This->WineD3DDevice);
       HeapFree(GetProcessHeap(), 0, This);
     }
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 5ce74f6..4c7aa85 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -175,38 +175,103 @@
 }
 
 /* Internal function called back during the CreateDevice to create a render target */
-HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height, 
-                                         WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, 
-                                         DWORD MultisampleQuality, BOOL Lockable, 
+HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
+                                         WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+                                         DWORD MultisampleQuality, BOOL Lockable,
                                          IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
     HRESULT res = D3D_OK;
     IDirect3DSurface9Impl *d3dSurface = NULL;
-    IDirect3DDevice9Impl* pDeviceImpl = (IDirect3DDevice9Impl*) device;
-
+    TRACE("(%p) call back\n", device);
     res = IDirect3DDevice9_CreateRenderTarget((IDirect3DDevice9 *)device, Width, Height, 
-                                         (D3DFORMAT) Format, MultiSample, MultisampleQuality, Lockable, 
+                                         (D3DFORMAT)Format, MultiSample, MultisampleQuality, Lockable,
                                          (IDirect3DSurface9 **)&d3dSurface, pSharedHandle);
 
     if (SUCCEEDED(res)) {
         *ppSurface = d3dSurface->wineD3DSurface;
-	if (NULL == pDeviceImpl->backBuffer) {
-	  pDeviceImpl->backBuffer = d3dSurface;
-	  pDeviceImpl->renderTarget = d3dSurface;
-	  IDirect3DSurface9Impl_AddRef((LPDIRECT3DSURFACE9) pDeviceImpl->renderTarget);
-	}
     } else {
         *ppSurface = NULL;
     }
     return res;
 }
 
+HRESULT WINAPI D3D9CB_CreateAdditionalSwapChain(IUnknown *device,
+                                                WINED3DPRESENT_PARAMETERS* pPresentationParameters,
+                                                IWineD3DSwapChain ** ppSwapChain) {
+    HRESULT res = D3D_OK;
+    IDirect3DSwapChain9Impl *d3dSwapChain = NULL;
+    D3DPRESENT_PARAMETERS localParameters;
+    TRACE("(%p) call back\n", device);
+
+    localParameters.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
+    localParameters.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);
+    localParameters.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);
+    localParameters.BackBufferCount                = *(pPresentationParameters->BackBufferCount);
+    localParameters.MultiSampleType                = *(pPresentationParameters->MultiSampleType);
+    localParameters.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality);
+    localParameters.SwapEffect                     = *(pPresentationParameters->SwapEffect);
+    localParameters.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);
+    localParameters.Windowed                       = *(pPresentationParameters->Windowed);
+    localParameters.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);
+    localParameters.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);
+    localParameters.Flags                          = *(pPresentationParameters->Flags);
+    localParameters.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+    localParameters.PresentationInterval           = *(pPresentationParameters->PresentationInterval);
+
+    /*copy the presentation parameters*/
+    res = IDirect3DDevice9_CreateAdditionalSwapChain((IDirect3DDevice9 *)device, &localParameters, (IDirect3DSwapChain9 **)&d3dSwapChain);
+
+    if (res == D3D_OK && d3dSwapChain != NULL) {
+        *ppSwapChain = d3dSwapChain->wineD3DSwapChain;
+    } else {
+        *ppSwapChain = NULL;
+    }
+    /*Copy back the presentation parameters*/
+   *pPresentationParameters->BackBufferWidth               = localParameters.BackBufferWidth;
+   *pPresentationParameters->BackBufferHeight              = localParameters.BackBufferHeight;
+   *pPresentationParameters->BackBufferFormat              = localParameters.BackBufferFormat;
+   *pPresentationParameters->BackBufferCount               = localParameters.BackBufferCount;
+   *pPresentationParameters->MultiSampleType               = localParameters.MultiSampleType;
+   *pPresentationParameters->MultiSampleQuality            = localParameters.MultiSampleQuality;
+   *pPresentationParameters->SwapEffect                    = localParameters.SwapEffect;
+   *pPresentationParameters->hDeviceWindow                 = localParameters.hDeviceWindow;
+   *pPresentationParameters->Windowed                      = localParameters.Windowed;
+   *pPresentationParameters->EnableAutoDepthStencil        = localParameters.EnableAutoDepthStencil;
+   *pPresentationParameters->AutoDepthStencilFormat        = localParameters.AutoDepthStencilFormat;
+   *pPresentationParameters->Flags                         = localParameters.Flags;
+   *pPresentationParameters->FullScreen_RefreshRateInHz    = localParameters.FullScreen_RefreshRateInHz;
+   *pPresentationParameters->PresentationInterval          = localParameters.PresentationInterval;
+
+   return res;
+}
+
+/* Internal function called back during the CreateDevice to create a render target */
+HRESULT WINAPI D3D9CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height, 
+                                         WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+                                         DWORD MultisampleQuality, BOOL Discard,
+                                         IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
+    HRESULT res = D3D_OK;
+    IDirect3DSurface9Impl *d3dSurface = NULL;
+    TRACE("(%p) call back\n", device);
+
+    res = IDirect3DDevice9_CreateDepthStencilSurface((IDirect3DDevice9 *)device, Width, Height, 
+                                         (D3DFORMAT)Format, MultiSample, MultisampleQuality, Discard, 
+                                         (IDirect3DSurface9 **)&d3dSurface, pSharedHandle);
+    if (res == D3D_OK) {
+        *ppSurface = d3dSurface->wineD3DSurface;
+    }
+    return res;
+}
+
+
 HRESULT  WINAPI  IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
-					     DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
-					     IDirect3DDevice9** ppReturnedDeviceInterface) {
+                                            DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
+                                            IDirect3DDevice9** ppReturnedDeviceInterface) {
 
     IDirect3D9Impl       *This   = (IDirect3D9Impl *)iface;
     IDirect3DDevice9Impl *object = NULL;
     WINED3DPRESENT_PARAMETERS localParameters;
+    HRESULT hr;
+    TRACE("(%p) Relay \n", This);
 
     /* Check the validity range of the adapter parameter */
     if (Adapter >= IDirect3D9Impl_GetAdapterCount(iface)) {
@@ -224,28 +289,38 @@
 
     object->lpVtbl = &Direct3DDevice9_Vtbl;
     object->ref = 1;
-    object->direct3d = This;
-    IDirect3D9_AddRef((LPDIRECT3D9) object->direct3d);
     *ppReturnedDeviceInterface = (IDirect3DDevice9 *)object;
-    
+
     /* Allocate an associated WineD3DDevice object */
     localParameters.BackBufferWidth                = &pPresentationParameters->BackBufferWidth;
-    localParameters.BackBufferHeight               = &pPresentationParameters->BackBufferHeight;           
-    localParameters.BackBufferFormat               = &pPresentationParameters->BackBufferFormat;           
-    localParameters.BackBufferCount                = &pPresentationParameters->BackBufferCount;            
-    localParameters.MultiSampleType                = &pPresentationParameters->MultiSampleType;            
-    localParameters.MultiSampleQuality             = &pPresentationParameters->MultiSampleQuality;         
-    localParameters.SwapEffect                     = &pPresentationParameters->SwapEffect;                 
-    localParameters.hDeviceWindow                  = &pPresentationParameters->hDeviceWindow;              
-    localParameters.Windowed                       = &pPresentationParameters->Windowed;                   
-    localParameters.EnableAutoDepthStencil         = &pPresentationParameters->EnableAutoDepthStencil;     
-    localParameters.AutoDepthStencilFormat         = &pPresentationParameters->AutoDepthStencilFormat;     
-    localParameters.Flags                          = &pPresentationParameters->Flags;                      
+    localParameters.BackBufferHeight               = &pPresentationParameters->BackBufferHeight;
+    localParameters.BackBufferFormat               = &pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferCount                = &pPresentationParameters->BackBufferCount;
+    localParameters.MultiSampleType                = &pPresentationParameters->MultiSampleType;
+    localParameters.MultiSampleQuality             = &pPresentationParameters->MultiSampleQuality;
+    localParameters.SwapEffect                     = &pPresentationParameters->SwapEffect;
+    localParameters.hDeviceWindow                  = &pPresentationParameters->hDeviceWindow;
+    localParameters.Windowed                       = &pPresentationParameters->Windowed;
+    localParameters.EnableAutoDepthStencil         = &pPresentationParameters->EnableAutoDepthStencil;
+    localParameters.AutoDepthStencilFormat         = &pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.Flags                          = &pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz     = &pPresentationParameters->FullScreen_RefreshRateInHz; 
-    localParameters.PresentationInterval           = &pPresentationParameters->PresentationInterval;       
-    return IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D9CB_CreateRenderTarget);
+    localParameters.PresentationInterval           = &pPresentationParameters->PresentationInterval;
+
+    hr =IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D9CB_CreateAdditionalSwapChain);
+
+    if (hr == D3D_OK) {
+
+        TRACE("(%p) : Created Device %p\n", This, object);
+    } else {
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppReturnedDeviceInterface = NULL;
+    }
+    return hr;
 }
 
+
+
 const IDirect3D9Vtbl Direct3D9_Vtbl =
 {
     IDirect3D9Impl_QueryInterface,
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index 93ce291..dbe23d1 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -3,6 +3,7 @@
  *
  * Copyright 2002-2003 Jason Edmeades
  *                     Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,7 +23,7 @@
 #include "config.h"
 #include "d3d9_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
 /* IDirect3DSwapChain IUnknown parts follow: */
 HRESULT WINAPI IDirect3DSwapChain9Impl_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID riid, LPVOID* ppobj)
@@ -31,8 +32,8 @@
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDirect3DSwapChain9)) {
-        IDirect3DSwapChain9Impl_AddRef(iface);
-	*ppobj = This;
+        IUnknown_AddRef(iface);
+        *ppobj = This;
         return D3D_OK;
     }
 
@@ -64,50 +65,62 @@
 /* IDirect3DSwapChain9 parts follow: */
 HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain,  ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    HRESULT hrc = D3D_OK;
+    IWineD3DSurface *mySurface = NULL;
+
+    TRACE("(%p) Relay\n", This);
+
+    hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, Type, &mySurface);
+    if (hrc == D3D_OK && NULL != mySurface) {
+       IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
+       IWineD3DSurface_Release(mySurface);
+    }
+    return hrc;
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, pRasterStatus);
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, pMode);
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice) {
-    IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;  
-    TRACE("(%p) : returning %p\n", This, This->Device);
-    *ppDevice = (LPDIRECT3DDEVICE9) This->Device;
+    IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
+    HRESULT hrc = D3D_OK;
+    IWineD3DDevice *device = NULL;
 
-    /* Note  Calling this method will increase the internal reference count 
-       on the IDirect3DDevice9 interface. */
-    IDirect3DDevice9Impl_AddRef(*ppDevice);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+
+    hrc = IWineD3DSwapChain_GetDevice(This->wineD3DSwapChain, &device);
+    if (hrc == D3D_OK && NULL != device) {
+       IWineD3DDevice_GetParent(device, (IUnknown **)ppDevice);
+       IWineD3DDevice_Release(device);
+    }
+    return hrc;
 }
 
 HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
-    FIXME("(%p) : copy\n", This); 
-    memcpy(pPresentationParameters, &This->PresentParms, sizeof(D3DPRESENT_PARAMETERS));
-    return D3D_OK;
+    FIXME("(%p) : inplement using WINED3DPRESENT_PARAMERS\n", This);
+    return IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, pPresentationParameters);
 }
 
 
@@ -129,18 +142,67 @@
 /* IDirect3DDevice9 IDirect3DSwapChain9 Methods follow: */
 HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
+    IDirect3DSwapChain9Impl* object;
+    HRESULT hrc = D3D_OK;
+    WINED3DPRESENT_PARAMETERS localParameters;
+
+    TRACE("(%p) Relay\n", This);
+
+    object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object));
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *pSwapChain = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
+    }
+    object->ref = 1;
+    object->lpVtbl = &Direct3DSwapChain9_Vtbl;
+
+    /* Allocate an associated WineD3DDevice object */
+    localParameters.BackBufferWidth                = &pPresentationParameters->BackBufferWidth;
+    localParameters.BackBufferHeight               = &pPresentationParameters->BackBufferHeight;
+    localParameters.BackBufferFormat               = &pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferCount                = &pPresentationParameters->BackBufferCount;
+    localParameters.MultiSampleType                = &pPresentationParameters->MultiSampleType;
+    localParameters.MultiSampleQuality             = &pPresentationParameters->MultiSampleQuality;
+    localParameters.SwapEffect                     = &pPresentationParameters->SwapEffect;
+    localParameters.hDeviceWindow                  = &pPresentationParameters->hDeviceWindow;
+    localParameters.Windowed                       = &pPresentationParameters->Windowed;
+    localParameters.EnableAutoDepthStencil         = &pPresentationParameters->EnableAutoDepthStencil;
+    localParameters.AutoDepthStencilFormat         = &pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.Flags                          = &pPresentationParameters->Flags;
+    localParameters.FullScreen_RefreshRateInHz     = &pPresentationParameters->FullScreen_RefreshRateInHz;
+    localParameters.PresentationInterval           = &pPresentationParameters->PresentationInterval;
+
+
+    hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface);
+    if (hrc != D3D_OK) {
+        FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This);
+        HeapFree(GetProcessHeap(), 0 , object);
+        *pSwapChain = NULL;
+    }else{
+        *pSwapChain = (IDirect3DSwapChain9 *)object;
+    }
+    TRACE("(%p) returning %p\n", This, *pSwapChain);
     return D3D_OK;
 }
 
 HRESULT  WINAPI  IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    HRESULT hrc = D3D_OK;
+    IWineD3DSwapChain *swapchain = NULL;
+
+    TRACE("(%p) Relay\n", This);
+
+    hrc = IWineD3DDevice_GetSwapChain(This->WineD3DDevice, iSwapChain, &swapchain);
+    if (hrc == D3D_OK && NULL != swapchain) {
+       IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)pSwapChain);
+       IWineD3DSwapChain_Release(swapchain);
+    }
+    return hrc;
 }
 
 UINT     WINAPI  IDirect3DDevice9Impl_GetNumberOfSwapChains(LPDIRECT3DDEVICE9 iface) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    FIXME("(%p) : stub\n", This);
-    return 1;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
 }
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 6c8e2e7..51bb669 100644
--- a/dlls/wined3d/Makefile.in
+++ b/dlls/wined3d/Makefile.in
@@ -19,6 +19,7 @@
 	resource.c \
 	stateblock.c \
 	surface.c \
+	swapchain.c \
 	texture.c \
 	utils.c \
 	vertexbuffer.c \
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7e59670..da38662 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -30,6 +30,26 @@
 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
 
+/* 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 */
+};
+
+/* 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;
+}
+
 /* helper macros */
 #define D3DMEMCHECK(object, ppResult) if(NULL == object){ *ppResult = NULL; WARN("Out of memory\n"); return D3DERR_OUTOFVIDEOMEMORY;}
 
@@ -275,7 +295,29 @@
         if (((IWineD3DImpl *)This->wineD3D)->dxVersion > 8) { /*We don't create a state block in d3d8 yet*/
             /* NOTE: You must release the parent if the objects was created via a callback
             ** ***************************/
-            IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
+            int i;
+            IUnknown* swapChainParent;
+
+            /* Release all of the swapchains, except the implicite swapchain (#0) */
+            for(i = 1; i < This->numberOfSwapChains; i++){
+                /*  TODO: don't access swapchains[x] directly! */
+                IWineD3DSwapChain_Release(This->swapchains[i]);
+            }
+
+            if (This->stateBlock != NULL) {
+                IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
+            }
+
+            if (This->swapchains[0] != NULL) {
+                /* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release it's parent now */
+                /*  TODO: don't access swapchains[x] directly!, check that there are no-more swapchains left for this device! */
+                IWineD3DSwapChain_GetParent(This->swapchains[0], &swapChainParent);
+                IUnknown_Release(swapChainParent);           /* once for the get parent */
+                if (IUnknown_Release(swapChainParent)  > 0){  /* the second time for when it was created */
+                    FIXME("(%p) Something's still holding the implicite swapchain\n",This);
+                }
+            }
+
         }
         IWineD3D_Release(This->wineD3D);
         HeapFree(GetProcessHeap(), 0, This);
@@ -412,11 +454,11 @@
     while (pow2Width < Width) pow2Width <<= 1;
     while (pow2Height < Height) pow2Height <<= 1;
 
-    if(pow2Width > Width || pow2Height > Height){
-        FIXME("non-power-two textures unsupported\n"); /* OpenGL provides support for these gratis */
+    if((pow2Width > Width || pow2Height > Height) && !Usage & D3DUSAGE_RENDERTARGET) {
+        /** TODO: add support for non power two  textures (OpenGL 2 provices support for * non-power-two textures gratis) **/
+        FIXME("non-power-two textures unsupported\n");
         return D3DERR_NOTAVAILABLE;
     }
-
         
     /** TODO: Check against the maximum texture sizes supported by the video card **/
     
@@ -779,28 +821,418 @@
 }
 
 /* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
-HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS*  pPresentationParameters,                                                                   void** ppSwapChain,
+HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS*  pPresentationParameters,                                                                   IWineD3DSwapChain** ppSwapChain,
                                                             IUnknown* parent,
                                                             D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget,
                                                             D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil){
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
-    *ppSwapChain = NULL;
-    FIXME("(%p) : Stub\n",This);
-    return D3D_OK;
+
+    HDC                     hDc;
+    IWineD3DSwapChainImpl  *object; /** NOTE: impl ref allowed since this is a create function **/
+    int                     num;
+    XVisualInfo             template;
+    GLXContext              oldContext;
+    Drawable                oldDrawable;
+    HRESULT                 hr = D3D_OK;
+
+    TRACE("(%p) : Created Aditional Swap Chain\n", This);
+
+   /** FIXME: Test under windows to find out what the life cycle of a swap chain is,
+   * does a device hold a reference to a swap chain giving them a lifetime of the device
+   * or does the swap chain notify the device of it'd destruction.
+    *******************************/
+
+    D3DCREATEOBJECTINSTANCE(object, SwapChain)
+
+    /* Initialize other useful values */
+    object->presentParms.BackBufferCount = 1; /* TODO:? support for gl_aux buffers */
+
+    /*********************
+    * Lookup the window Handle and the relating X window handle
+    ********************/
+
+    /* Setup hwnd we are using, plus which display this equates to */
+    object->win_handle = *(pPresentationParameters->hDeviceWindow);
+    if (!object->win_handle) {
+        object->win_handle = This->createParms.hFocusWindow;
+    }
+
+    object->win        = (Window)GetPropA(object->win_handle, "__wine_x11_whole_window" );
+    hDc                = GetDC(object->win_handle);
+    object->display    = get_display(hDc);
+    ReleaseDC(object->win_handle, hDc);
+    TRACE("Using a display of %p %p  \n", object->display, hDc);
+
+    if (NULL == object->display || NULL == hDc) {
+        WARN("Failed to get a display and HDc for Window %p\n", object->win_handle);
+        return D3DERR_NOTAVAILABLE;
+    }
+
+    if (object->win == 0) {
+        WARN("Failed to get a valid XVisuial ID for the window %p\n", object->win_handle);
+        return D3DERR_NOTAVAILABLE;
+    }
+    /**
+    * Create an opengl context for the display visual
+    *  NOTE: the visual is chosen as the window is created and the glcontext cannot
+    *     use different properties after that point in time. FIXME: How to handle when requested format
+    *     doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
+    *     it chooses is identical to the one already being used!
+     **********************************/
+
+    /** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
+    ENTER_GL();
+
+    /* Create a new context for this swapchain */
+    template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
+    /* TODO: change this to find a similar visual, but one with a stencil/zbuffer buffer that matches the request
+    (or the best possible if none is requested) */
+    TRACE("Found x visual ID  : %ld\n", template.visualid);
+
+    object->visInfo   = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
+    if (NULL == object->visInfo) {
+        ERR("cannot really get XVisual\n");
+        LEAVE_GL();
+        return D3DERR_NOTAVAILABLE;
+    } else {
+        int n, value;
+        /* Write out some debug info about the visual/s */
+        TRACE("Using x visual ID  : %ld\n", template.visualid);
+        TRACE("        visual info: %p\n", object->visInfo);
+        TRACE("        num items  : %d\n", num);
+        for(n = 0;n < num; n++){
+            TRACE("=====item=====: %d\n", n + 1);
+            TRACE("   visualid      : %ld\n", object->visInfo[n].visualid);
+            TRACE("   screen        : %d\n",  object->visInfo[n].screen);
+            TRACE("   depth         : %u\n",  object->visInfo[n].depth);
+            TRACE("   class         : %d\n",  object->visInfo[n].class);
+            TRACE("   red_mask      : %ld\n", object->visInfo[n].red_mask);
+            TRACE("   green_mask    : %ld\n", object->visInfo[n].green_mask);
+            TRACE("   blue_mask     : %ld\n", object->visInfo[n].blue_mask);
+            TRACE("   colormap_size : %d\n",  object->visInfo[n].colormap_size);
+            TRACE("   bits_per_rgb  : %d\n",  object->visInfo[n].bits_per_rgb);
+            /* log some extra glx info */
+            glXGetConfig(object->display, object->visInfo, GLX_AUX_BUFFERS, &value);
+            TRACE("   gl_aux_buffers  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_BUFFER_SIZE ,&value);
+            TRACE("   gl_buffer_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_RED_SIZE, &value);
+            TRACE("   gl_red_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_GREEN_SIZE, &value);
+            TRACE("   gl_green_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_BLUE_SIZE, &value);
+            TRACE("   gl_blue_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_ALPHA_SIZE, &value);
+            TRACE("   gl_alpha_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_DEPTH_SIZE ,&value);
+            TRACE("   gl_depth_size  : %d\n",  value);
+            glXGetConfig(object->display, object->visInfo, GLX_STENCIL_SIZE, &value);
+            TRACE("   gl_stencil_size : %d\n",  value);
+        }
+        /* Now choose a simila visual ID*/
+    }
+#ifdef USE_CONTEXT_MANAGER
+
+    /** TODO: use a context mamager **/
+#endif
+
+    {
+        IWineD3DSwapChain *implSwapChain;
+        if (D3D_OK != IWineD3DDevice_GetSwapChain(iface, 0, &implSwapChain)) {
+            /* The first time around we create the context that is shared with all other swapchians and render targets */
+            object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
+            TRACE("Creating implicite context for vis %p, hwnd %p\n", object->display, object->visInfo);
+        } else {
+
+            TRACE("Creating context for vis %p, hwnd %p\n", object->display, object->visInfo);
+            /* TODO: don't use Impl structures outside of create functions! (a context manager will replace the ->glCtx) */
+            /* and create a new context with the implicit swapchains context as the shared context */
+            object->glCtx = glXCreateContext(object->display, object->visInfo, ((IWineD3DSwapChainImpl *)implSwapChain)->glCtx, GL_TRUE);
+            IWineD3DSwapChain_Release(implSwapChain);
+        }
+    }
+
+    /* Cleanup */
+    XFree(object->visInfo);
+    object->visInfo = NULL;
+
+    if (NULL == object->glCtx) {
+        ERR("cannot create glxContext\n");
+        LEAVE_GL();
+        return D3DERR_NOTAVAILABLE;
+    }
+
+    LEAVE_GL();
+    if (object->glCtx == NULL) {
+        ERR("Error in context creation !\n");
+        return D3DERR_INVALIDCALL;
+    } else {
+        TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
+                object->win_handle, object->glCtx, object->win, object->visInfo);
+    }
+
+   /*********************
+   * Windowed / Fullscreen
+   *******************/
+
+   /**
+   * TODO: MSDNsays that we are only allowed one fullscreen swapchain per device,
+   * so we should really check to see if their is a fullscreen swapchain already
+   * I think Windows and X have differnt ideas about fullscreen, does a single head count as full screen?
+    **************************************/
+
+   if (!*(pPresentationParameters->Windowed)) {
+
+        DEVMODEW devmode;
+        HDC      hdc;
+        int      bpp = 0;
+
+        /* Get info on the current display setup */
+        hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
+        bpp = GetDeviceCaps(hdc, BITSPIXEL);
+        DeleteDC(hdc);
+
+        /* Change the display settings */
+        memset(&devmode, 0, sizeof(DEVMODEW));
+        devmode.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+        devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp; /* Stupid XVidMode cannot change bpp */
+        devmode.dmPelsWidth  = *(pPresentationParameters->BackBufferWidth);
+        devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
+        MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
+        ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
+
+        /* Make popup window */
+        SetWindowLongA(object->win_handle, GWL_STYLE, WS_POPUP);
+        SetWindowPos(object->win_handle, HWND_TOP, 0, 0,
+                     *(pPresentationParameters->BackBufferWidth),
+                     *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
+
+
+    }
+
+
+    /** MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
+     *  then the corresponding dimension of the client area of the hDeviceWindow
+     *  (or the focus window, if hDeviceWindow is NULL) is taken.
+      **********************/
+
+    if (*(pPresentationParameters->Windowed) &&
+        ((*(pPresentationParameters->BackBufferWidth)  == 0) ||
+         (*(pPresentationParameters->BackBufferHeight) == 0))) {
+
+        RECT Rect;
+        GetClientRect(object->win_handle, &Rect);
+
+        if (*(pPresentationParameters->BackBufferWidth) == 0) {
+           *(pPresentationParameters->BackBufferWidth) = Rect.right;
+           TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
+        }
+        if (*(pPresentationParameters->BackBufferHeight) == 0) {
+           *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
+           TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
+        }
+    }
+
+   /*********************
+   * finish off parameter initialization
+   *******************/
+
+    /* Put the correct figures in the presentation parameters */
+    TRACE("Coppying accross presentaion paraneters\n");
+    object->presentParms.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
+    object->presentParms.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);
+    object->presentParms.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);
+    object->presentParms.BackBufferCount                = *(pPresentationParameters->BackBufferCount);
+    object->presentParms.MultiSampleType                = *(pPresentationParameters->MultiSampleType);
+    object->presentParms.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality);
+    object->presentParms.SwapEffect                     = *(pPresentationParameters->SwapEffect);
+    object->presentParms.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);
+    object->presentParms.Windowed                       = *(pPresentationParameters->Windowed);
+    object->presentParms.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);
+    object->presentParms.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);
+    object->presentParms.Flags                          = *(pPresentationParameters->Flags);
+    object->presentParms.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+    object->presentParms.PresentationInterval           = *(pPresentationParameters->PresentationInterval);
+
+
+   /* FIXME: check for any failures */
+   /*********************
+   * Create the back, front and stencil buffers
+   *******************/
+    TRACE("calling rendertarget CB\n");
+    hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
+                             object->presentParms.BackBufferWidth,
+                             object->presentParms.BackBufferHeight,
+                             object->presentParms.BackBufferFormat,
+                             object->presentParms.MultiSampleType,
+                             object->presentParms.MultiSampleQuality,
+                             TRUE /* Lockable */,
+                             &object->frontBuffer,
+                             NULL /* pShared (always null)*/);
+    if (object->frontBuffer != NULL)
+        IWineD3DSurface_SetContainer(object->frontBuffer, (IUnknown *)object);
+    TRACE("calling rendertarget CB\n");
+    hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
+                             object->presentParms.BackBufferWidth,
+                             object->presentParms.BackBufferHeight,
+                             object->presentParms.BackBufferFormat,
+                             object->presentParms.MultiSampleType,
+                             object->presentParms.MultiSampleQuality,
+                             TRUE /* Lockable */,
+                             &object->backBuffer,
+                             NULL /* pShared (always null)*/);
+    if (object->backBuffer != NULL)
+       IWineD3DSurface_SetContainer(object->backBuffer, (IUnknown *)object);
+
+    /* Under directX swapchains share the depth stencil, so only create one depth-stencil */
+    if (pPresentationParameters->EnableAutoDepthStencil) {
+        TRACE("Creating depth stencil buffer\n");
+        if (This->depthStencilBuffer == NULL ) {
+            hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent,
+                                    object->presentParms.BackBufferWidth,
+                                    object->presentParms.BackBufferHeight,
+                                    object->presentParms.AutoDepthStencilFormat,
+                                    object->presentParms.MultiSampleType,
+                                    object->presentParms.MultiSampleQuality,
+                                    FALSE /* FIXME: Discard */,
+                                    &This->depthStencilBuffer,
+                                    NULL /* pShared (always null)*/  );
+            if (This->depthStencilBuffer != NULL)
+                IWineD3DSurface_SetContainer(This->depthStencilBuffer, (IUnknown *)iface);
+        }
+
+        /** TODO: A check on width, height and multisample types
+        *(since the zbuffer must be at least as large as the render target and have the same multisample parameters)
+         ****************************/
+        object->wantsDepthStencilBuffer = TRUE;
+    } else {
+        object->wantsDepthStencilBuffer = FALSE;
+    }
+
+    TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer, object->wantsDepthStencilBuffer);
+
+
+   /*********************
+   * init the default renderTarget management
+   *******************/
+    object->drawable     = object->win;
+    object->render_ctx   = object->glCtx;
+
+    if(hr == D3D_OK){
+        /*********************
+         * Setup some defaults and clear down the buffers
+         *******************/
+        ENTER_GL();
+        /** save current context and drawable **/
+        oldContext   =   glXGetCurrentContext();
+        oldDrawable  =   glXGetCurrentDrawable();
+
+        TRACE("Activating context (display %p context %p drawable %ld)!\n", object->display, object->glCtx, object->win);
+        if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
+            ERR("Error in setting current context (display %p context %p drawable %ld)!\n", object->display, object->glCtx, object->win);
+        }
+        checkGLcall("glXMakeCurrent");
+
+        TRACE("Setting up the screen\n");
+        /* Clear the screen */
+        glClearColor(0.0, 0.0, 0.0, 0.0);
+        checkGLcall("glClearColor");
+        glClearIndex(0);
+        glClearDepth(1);
+        glClearStencil(0xffff);
+
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+        checkGLcall("glClear");
+
+        glColor3f(1.0, 1.0, 1.0);
+        checkGLcall("glColor3f");
+
+        glEnable(GL_LIGHTING);
+        checkGLcall("glEnable");
+
+        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+        checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
+
+        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+        checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
+
+        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+        checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
+
+        /* switch back to the original context (unless it was zero)*/
+        if (This->numberOfSwapChains != 0) {
+            /** TODO: restore the context and drawable **/
+            glXMakeCurrent(object->display, oldDrawable, oldContext);
+        }
+
+        LEAVE_GL();
+
+        /* TODO: move this off into a linked list implementation! (add swapchain, remove swapchain or something along those lines) */
+#if 0
+            IListOperator *listOperator;
+            IListStore_CreateListOperator(This->swapchainStore, &listOperator);
+            IListOperator_Append(listOperator, (void *)object);
+            IListOperator_Release(listOperator);
+#endif
+
+        This->swapchains[This->numberOfSwapChains++] = (IWineD3DSwapChain *)object;
+        TRACE("Set swapchain to %p\n", object);
+    } else { /* something went wrong so clean up */
+        IUnknown* bufferParent;
+        if (object->frontBuffer) {
+            IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
+            IUnknown_Release(bufferParent); /* once for the get parent */
+            if(IUnknown_Release(bufferParent) > 0){
+                FIXME("(%p) Something's still holding the front buffer\n",This);
+            }
+        }
+        if (object->backBuffer) {
+            IWineD3DSurface_GetParent(object->backBuffer, &bufferParent);
+            IUnknown_Release(bufferParent); /* once for the get parent */
+            if(IUnknown_Release(bufferParent) > 0){
+                FIXME("(%p) Something's still holding the back buffer\n",This);
+            }
+        }
+        /* NOTE: don't clean up the depthstencil buffer because it belongs to the device */
+        /* Clean up the context */
+        /* check that we are the current context first (we shouldn't be though!) */
+        if (object->glCtx != 0) {
+            if(glXGetCurrentContext() == object->glCtx){
+                glXMakeCurrent(object->display, None, NULL);
+            }
+            glXDestroyContext(object->display, object->glCtx);
+        }
+        HeapFree(GetProcessHeap(), 0, object);
+
+    }
+    return hr;
 }
 
 /** NOTE: These are ahead of the other getters and setters to save using a forward declartion **/
 UINT     WINAPI  IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    
-    FIXME("(%p) : Stub\n",This);
-    return 1;
+
+    /* TODO: move over to using a linked list. */
+    TRACE("(%p) returning %d\n", This, This->numberOfSwapChains);
+    return This->numberOfSwapChains;
 }
 
-HRESULT  WINAPI  IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, void** pSwapChain) {
+HRESULT  WINAPI  IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, IWineD3DSwapChain **pSwapChain) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    
-    FIXME("(%p) : Stub\n",This);
+    TRACE("(%p) : swapchain %d \n", This, iSwapChain);
+
+    if(iSwapChain >= IWineD3DDeviceImpl_GetNumberOfSwapChains(iface) || iSwapChain < 0){
+        *pSwapChain = NULL;
+        return D3DERR_INVALIDCALL;
+    }else{
+        /** TODO: move off to a linked list implementation **/
+        *pSwapChain = This->swapchains[iSwapChain];
+    }
+
+    /* TODO: move over to using stores and linked lists. */
+
+    IWineD3DSwapChain_AddRef(*pSwapChain);
+    TRACE("(%p) returning %p\n", This, *pSwapChain);
     return D3D_OK;
 }
 
@@ -3611,19 +4043,19 @@
 HRESULT WINAPI IWineD3DDeviceImpl_GetBackBuffer(IWineD3DDevice *iface, UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, 
                                                 IWineD3DSurface** ppBackBuffer) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    
-    *ppBackBuffer = (IWineD3DSurface *) This->backBuffer;
+    IWineD3DSwapChain *swapChain;
+    HRESULT hr;
+
     TRACE("(%p) : BackBuf %d Type %d SwapChain %d returning %p\n", This, BackBuffer, Type, iSwapChain, *ppBackBuffer);
 
-    if (BackBuffer > This->presentParms.BackBufferCount - 1) {
-        FIXME("Only one backBuffer currently supported\n");
-        return D3DERR_INVALIDCALL;
+    hr = IWineD3DDeviceImpl_GetSwapChain(iface,  iSwapChain, &swapChain);
+    if(hr == D3D_OK){
+        hr = IWineD3DSwapChain_GetBackBuffer(swapChain, BackBuffer, Type, ppBackBuffer);
+            IWineD3DSwapChain_Release(swapChain);
+    }else{
+        *ppBackBuffer = NULL;
     }
-
-    /* Note inc ref on returned surface */
-    IWineD3DSurface_AddRef(*ppBackBuffer);
-
-    return D3D_OK;
+    return hr;
 }
 
 HRESULT WINAPI IWineD3DDeviceImpl_GetDeviceCaps(IWineD3DDevice *iface, WINED3DCAPS* pCaps) {
@@ -3632,33 +4064,19 @@
     return IWineD3D_GetDeviceCaps(This->wineD3D, This->adapterNo, This->devType, pCaps);
 }
 
-/** TODO: move to swapchains **/
 HRESULT WINAPI IWineD3DDeviceImpl_GetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, D3DDISPLAYMODE* pMode) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    HDC                 hdc;
-    int                 bpp = 0;
+    IWineD3DSwapChain *swapChain;
+    HRESULT hr;
 
-    pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
-    pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
-    pMode->RefreshRate  = 85; /*FIXME: How to identify? */
-
-    hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-    bpp = GetDeviceCaps(hdc, BITSPIXEL);
-    DeleteDC(hdc);
-
-    switch (bpp) {
-    case  8: pMode->Format       = WINED3DFMT_R8G8B8; break;
-    case 16: pMode->Format       = WINED3DFMT_R5G6B5; break;
-    case 24: /*pMode->Format       = WINED3DFMT_R8G8B8; break; */
-    case 32: pMode->Format       = WINED3DFMT_A8R8G8B8; break;
-    default: 
-       FIXME("Unrecognized display mode format\n");
-       pMode->Format       = WINED3DFMT_UNKNOWN;
+    hr = IWineD3DDeviceImpl_GetSwapChain(iface,  iSwapChain, (IWineD3DSwapChain **)&swapChain);
+    if (hr == D3D_OK) {
+        hr = IWineD3DSwapChain_GetDisplayMode(swapChain, pMode);
+        IWineD3DSwapChain_Release(swapChain);
+    }else{
+        FIXME("(%p) Error getting display mode\n", This);
     }
-
-    FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, 
-          pMode->Format, debug_d3dformat(pMode->Format));
-    return D3D_OK;
+    return hr;
 }
 /*****
  * Stateblock related functions
@@ -3753,76 +4171,19 @@
 HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface, 
                                           CONST RECT* pSourceRect, CONST RECT* pDestRect, 
                                           HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+   IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DSwapChain *swapChain = NULL;
+    int i;
+    int swapchains = IWineD3DDeviceImpl_GetNumberOfSwapChains(iface);
+
     TRACE("(%p) Presenting the frame\n", This);
 
-    ENTER_GL();
+    for(i = 0 ; i < swapchains ; i ++){
 
-    if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
-
-    glXSwapBuffers(This->display, This->drawable);
-    /* Don't call checkGLcall, as glGetError is not applicable here */
-    
-    TRACE("glXSwapBuffers called, Starting new frame\n");
-
-    /* FPS support */
-    if (TRACE_ON(d3d_fps))
-    {
-        static long prev_time, frames;
-
-        DWORD time = GetTickCount();
-        frames++;
-        /* every 1.5 seconds */
-        if (time - prev_time > 1500) {
-            TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
-            prev_time = time;
-            frames = 0;
-        }
-    }
-
-#if defined(FRAME_DEBUGGING)
-{
-    if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
-        if (!isOn) {
-            isOn = TRUE;
-            FIXME("Enabling D3D Trace\n");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Starting\n");
-            isDumpingFrames = TRUE;
-            glClear(GL_COLOR_BUFFER_BIT);
-#endif
-
-#if defined(SINGLE_FRAME_DEBUGGING)
-        } else {
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Finishing\n");
-            isDumpingFrames = FALSE;
-#endif
-            FIXME("Singe Frame trace complete\n");
-            DeleteFileA("C:\\D3DTRACE");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
-#endif
-        }
-    } else {
-        if (isOn) {
-            isOn = FALSE;
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Finishing\n");
-            isDumpingFrames = FALSE;
-#endif
-            FIXME("Disabling D3D Trace\n");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
-        }
-    }
-}
-#endif
-
-    LEAVE_GL();
-    /* Although this is not strictly required, a simple demo showed this does occur
-       on (at least non-debug) d3d                                                  */
-    if (This->presentParms.SwapEffect == D3DSWAPEFFECT_DISCARD) {
-       IWineD3DDevice_Clear(iface, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+        IWineD3DDeviceImpl_GetSwapChain(iface, i , (IWineD3DSwapChain **)&swapChain);
+        TRACE("presentinng chain %d, %p\n", i, swapChain);
+        IWineD3DSwapChain_Present(swapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
+        IWineD3DSwapChain_Release(swapChain);
     }
 
     return D3D_OK;
@@ -4076,10 +4437,14 @@
 }
 
 HRESULT  WINAPI  IWineD3DDeviceImpl_GetFrontBufferData(IWineD3DDevice *iface,UINT iSwapChain, IWineD3DSurface *pDestSurface){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    
-    TRACE("(%p) : stub\n", This);
-    return D3D_OK;
+    IWineD3DSwapChain *swapChain;
+    HRESULT hr;
+    hr = IWineD3DDeviceImpl_GetSwapChain(iface,  iSwapChain, (IWineD3DSwapChain **)&swapChain);
+    if(hr == D3D_OK){
+        hr = IWineD3DSwapChain_GetFrontBufferData(swapChain, pDestSurface);
+                IWineD3DSwapChain_Release(swapChain);
+    }
+    return hr;
 }
 
 HRESULT  WINAPI  IWineD3DDeviceImpl_ValidateDevice(IWineD3DDevice *iface, DWORD* pNumPasses) {
@@ -4344,24 +4709,28 @@
 }
 
 void WINAPI IWineD3DDeviceImpl_SetGammaRamp(IWineD3DDevice * iface, UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
-    HDC hDC;
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    
-    FIXME("(%p) : pRamp@%p\n", This, pRamp);
-    hDC = GetDC(This->win_handle);
-    SetDeviceGammaRamp(hDC, (LPVOID) pRamp);
-    ReleaseDC(This->win_handle, hDC);
+    IWineD3DSwapChain *swapchain;
+    HRESULT hrc = D3D_OK;
+
+    TRACE("Relaying  to swapchain\n");
+
+    if ((hrc = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapchain)) == D3D_OK){
+        IWineD3DSwapChain_SetGammaRamp(swapchain, Flags, (D3DGAMMARAMP *)pRamp);
+        IWineD3DSwapChain_Release(swapchain);
+    }
     return;
 }
 
 void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
-    HDC hDC;
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    IWineD3DSwapChain *swapchain;
+    HRESULT hrc = D3D_OK;
 
-    FIXME("(%p) : pRamp@%p\n", This, pRamp);
-    hDC = GetDC(This->win_handle);
-    GetDeviceGammaRamp(hDC, pRamp);
-    ReleaseDC(This->win_handle, hDC);
+    TRACE("Relaying  to swapchain\n");
+
+    if ((hrc = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapchain)) == D3D_OK){
+        hrc =IWineD3DSwapChain_GetGammaRamp(swapchain, pRamp);
+        IWineD3DSwapChain_Release(swapchain);
+    }
     return;
 }
 
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index deb5e19..e0caaf0 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4,6 +4,7 @@
  * Copyright 2002-2004 Jason Edmeades
  * Copyright 2003-2004 Raphael Junqueira
  * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1526,15 +1527,12 @@
    and fields being inserted in the middle, a new structure is used in place    */
 HRESULT  WINAPI  IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
                                            DWORD BehaviourFlags, WINED3DPRESENT_PARAMETERS* pPresentationParameters,
-                                           IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget) {
+                                           IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent,
+                                           D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) {
 
-    HWND                whichHWND;
-    HDC                 hDc;
     IWineD3DDeviceImpl *object  = NULL;
     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
-    int                 num;
-    XVisualInfo         template;
-    HRESULT             res;
+    IWineD3DSwapChainImpl *swapchain;
 
     /* Validate the adapter number */
     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
@@ -1573,241 +1571,85 @@
     object->adapterNo                    = Adapter;
     object->devType                      = DeviceType;
 
-    /* Setup hwnd we are using, plus which display this equates to */
-    whichHWND = *(pPresentationParameters->hDeviceWindow);
-    if (!whichHWND) {
-        whichHWND = hFocusWindow;
-    }
-    object->win_handle = whichHWND;
-    object->win        = (Window)GetPropA( whichHWND, "__wine_x11_whole_window" );
-    hDc                = GetDC(whichHWND);
-    object->display    = get_display(hDc);
-    ReleaseDC(whichHWND, hDc);
-
     /* FIXME: Use for dx8 code eventually too! */
     /* Deliberately no indentation here, as this if will be removed when dx8 support merged in */
-    if (This->dxVersion > 8) {   
+    if (This->dxVersion > 8) {
 
-    /* Create a context based off the properties of the existing visual */
-    /*   Note the visual is chosen as the window is created and the glcontext cannot
-         use different properties after that point in time. FIXME: How to handle when requested format 
-         doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
-         it chooses is identical to the one already being used!                                        */
-    /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
-    ENTER_GL();
-    template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
-    object->visInfo   = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
-    if (NULL == object->visInfo) {
-        ERR("cannot really get XVisual\n"); 
-        LEAVE_GL();
-        return D3DERR_NOTAVAILABLE;
-    }
-    object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
-    if (NULL == object->glCtx) {
-        ERR("cannot create glxContext\n"); 
-        LEAVE_GL();
-        return D3DERR_NOTAVAILABLE;
-    }
-    LEAVE_GL();
+        /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
+        IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object,
+                                        (D3DSTATEBLOCKTYPE) 0,
+                                        (IWineD3DStateBlock **)&object->stateBlock,
+                                        NULL);   /* Note: No parent needed for initial internal stateblock */
+        object->updateStateBlock = object->stateBlock;
+        IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)object->updateStateBlock);
+        /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
 
-    if (object->glCtx == NULL) {
-        ERR("Error in context creation !\n");
-        return D3DERR_INVALIDCALL;
-    } else {
-        TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
-                whichHWND, object->glCtx, object->win, object->visInfo);
-    }
+        /* Setup the  implicite swapchain */
+        TRACE("Creating implicite swapchain\n");
 
-    /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate  */
-    /*        dimensions                                                               */
-    if (!*(pPresentationParameters->Windowed)) {
+        if (D3D_OK == D3DCB_CreateAdditionalSwapChain((IUnknown *) object->parent, pPresentationParameters, (IWineD3DSwapChain **)&swapchain) && swapchain != NULL) {
 
-        DEVMODEW devmode;
-        HDC      hdc;
-        int      bpp = 0;
-
-        /* Get info on the current display setup */
-        hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-        bpp = GetDeviceCaps(hdc, BITSPIXEL);
-        DeleteDC(hdc);
-
-        /* Change the display settings */
-        memset(&devmode, 0, sizeof(DEVMODEW));
-        devmode.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 
-        devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;   /*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
-        devmode.dmPelsWidth  = *(pPresentationParameters->BackBufferWidth);
-        devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
-        MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
-        ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
-
-        /* Make popup window */
-        SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
-        SetWindowPos(object->win_handle, HWND_TOP, 0, 0, 
-                     *(pPresentationParameters->BackBufferWidth),
-                     *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
-    }
-
-    /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
-       then the corresponding dimension of the client area of the hDeviceWindow
-       (or the focus window, if hDeviceWindow is NULL) is taken. */
-    if (*(pPresentationParameters->Windowed) && 
-        ((*(pPresentationParameters->BackBufferWidth)  == 0) ||
-         (*(pPresentationParameters->BackBufferHeight) == 0))) {
-
-        RECT Rect;
-        GetClientRect(whichHWND, &Rect);
-
-        if (*(pPresentationParameters->BackBufferWidth) == 0) {
-           *(pPresentationParameters->BackBufferWidth) = Rect.right;
-           TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
-        }
-        if (*(pPresentationParameters->BackBufferHeight) == 0) {
-           *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
-           TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
-        }
-    }
-
-    /* Save the presentation parms now filled in correctly */
-    object->presentParms.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
-    object->presentParms.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);           
-    object->presentParms.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);           
-    object->presentParms.BackBufferCount                = *(pPresentationParameters->BackBufferCount);            
-    object->presentParms.MultiSampleType                = *(pPresentationParameters->MultiSampleType);            
-    object->presentParms.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality);         
-    object->presentParms.SwapEffect                     = *(pPresentationParameters->SwapEffect);                 
-    object->presentParms.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);              
-    object->presentParms.Windowed                       = *(pPresentationParameters->Windowed);                   
-    object->presentParms.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);     
-    object->presentParms.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);     
-    object->presentParms.Flags                          = *(pPresentationParameters->Flags);                      
-    object->presentParms.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz); 
-    object->presentParms.PresentationInterval           = *(pPresentationParameters->PresentationInterval);       
-
-    /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
-    IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object, 
-                                    (D3DSTATEBLOCKTYPE) 0, 
-                                    (IWineD3DStateBlock **)&object->stateBlock,
-                                    NULL);   /* Note: No parent needed for initial internal stateblock */
-    object->updateStateBlock = object->stateBlock;
-
-    /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
-    TRACE("Creating initial device surfaces\n");
-
-    /* We need to 'magic' either d3d8 or d3d9 surfaces for the front and backbuuffer 
-       but the respective CreateRenderTarget functions take a differing number of
-       parms. Fix this by passing in a function to call which takes identical parms
-       and handles the differences at the d3dx layer, and returns the IWineD3DSurface
-       pointer rather than the created D3D8/9 one                                      */
-    if ((res = D3DCB_CreateRenderTarget((IUnknown *) parent,
-                                        *(pPresentationParameters->BackBufferWidth),
-                                        *(pPresentationParameters->BackBufferHeight),
-                                        *(pPresentationParameters->BackBufferFormat),
-                                        *(pPresentationParameters->MultiSampleType),
-                                        *(pPresentationParameters->MultiSampleQuality),
-                                        TRUE,
-                                        (IWineD3DSurface **) &object->frontBuffer,
-                                        NULL) != D3D_OK) ||
-        (res = D3DCB_CreateRenderTarget((IUnknown *) parent,
-                                        *(pPresentationParameters->BackBufferWidth),
-                                        *(pPresentationParameters->BackBufferHeight),
-                                        *(pPresentationParameters->BackBufferFormat),
-                                        *(pPresentationParameters->MultiSampleType),
-                                        *(pPresentationParameters->MultiSampleQuality),
-                                        TRUE,
-                                        (IWineD3DSurface **) &object->backBuffer,
-                                       NULL) != D3D_OK))
-    {
-        ERR("D3DCB_CreateRenderTarget() failed\n");
-        return res;
-    }
-
-/* TODO: 
-    if (*(pPresentationParameters->EnableAutoDepthStencil)) {
-       IWineD3DDevice_CreateDepthStencilSurface((IWineD3DDevice *) object,
-                                                *(pPresentationParameters->BackBufferWidth),
-                                                *(pPresentationParameters->BackBufferHeight),
-                                                *(pPresentationParameters->AutoDepthStencilFormat,
-                                                D3DMULTISAMPLE_NONE,
-                                                (IWineD3DSurface *) &object->depthStencilBuffer);
-    } else {
-      object->depthStencilBuffer = NULL;
-    }
-    TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
-*/    
-
-    /* init the default renderTarget management */
-    object->drawable     = object->win;
-    object->render_ctx   = object->glCtx;
-    object->renderTarget = object->backBuffer;
+            object->renderTarget = swapchain->backBuffer;
+            IWineD3DSurface_AddRef(object->renderTarget);
+            /* Depth Stencil support */
+            object->stencilBufferTarget = object->depthStencilBuffer;
+            if (NULL != object->stencilBufferTarget) {
+                IWineD3DSurface_AddRef(object->stencilBufferTarget);
+            }
     
-    IWineD3DSurface_AddRef((IWineD3DSurface *) object->renderTarget);
-/* TODO: Depth Stencil support
-    object->stencilBufferTarget = object->depthStencilBuffer;
-    if (NULL != object->stencilBufferTarget) {
-      IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
+            /* Set up some starting GL setup */
+    
+            ENTER_GL();
+            /*
+            * Initialize openGL extension related variables
+            *  with Default values 
+            */
+    
+            This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, swapchain->display);
+            /* Setup all the devices defaults */
+            IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock);
+#if 0
+            IWineD3DImpl_CheckGraphicsMemory();
+#endif
+            LEAVE_GL();
+    
+            { /* Set a default viewport */
+                D3DVIEWPORT9 vp;
+                vp.X      = 0;
+                vp.Y      = 0;
+                vp.Width  = *(pPresentationParameters->BackBufferWidth);
+                vp.Height = *(pPresentationParameters->BackBufferHeight);
+                vp.MinZ   = 0.0f;
+                vp.MaxZ   = 1.0f;
+                IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
+            }
+    
+    
+            /* Initialize the current view state */
+            object->modelview_valid = 1;
+            object->proj_valid = 0;
+            object->view_ident = 1;
+            object->last_was_rhw = 0;
+            glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
+            TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
+    
+            /* Clear the screen */
+            IWineD3DDevice_Clear((IWineD3DDevice *) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+        } else { /* couldn't create swapchain */
+            IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->updateStateBlock);
+            object->updateStateBlock = NULL;
+            IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->stateBlock);
+            object->stateBlock = NULL;
+            HeapFree(GetProcessHeap(), 0, object);
+            *ppReturnedDeviceInterface = NULL;
+            return D3DERR_INVALIDCALL;
+        }
+
+    } else { /* End of FIXME: remove when dx8 merged in */
+
+     FIXME("(%p) Incomplete stub for d3d8\n", This);
+
     }
-*/    
-
-    /* Set up some starting GL setup */
-    ENTER_GL();
-
-    if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
-      ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
-    }
-    checkGLcall("glXMakeCurrent");
-
-    /* Clear the screen */
-    glClearColor(1.0, 0.0, 0.0, 0.0);
-    checkGLcall("glClearColor");
-    glColor3f(1.0, 1.0, 1.0);
-    checkGLcall("glColor3f");
-
-    glEnable(GL_LIGHTING);
-    checkGLcall("glEnable");
-
-    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
-    checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
-
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
-    checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
-
-    glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
-    checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
-
-    /* 
-     * Initialize openGL extension related variables
-     *  with Default values 
-     */
-    This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, object->display);
-
-    /* Setup all the devices defaults */
-    IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock); 
-
-    LEAVE_GL();
-
-    { /* Set a default viewport */
-       D3DVIEWPORT9 vp;
-       vp.X      = 0;
-       vp.Y      = 0;
-       vp.Width  = *(pPresentationParameters->BackBufferWidth);
-       vp.Height = *(pPresentationParameters->BackBufferHeight);
-       vp.MinZ   = 0.0f;
-       vp.MaxZ   = 1.0f;
-       IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
-    }
-
-    /* Initialize the current view state */
-    object->modelview_valid = 1;
-    object->proj_valid = 0;
-    object->view_ident = 1;
-    object->last_was_rhw = 0;
-    glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
-    TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
-
-    /* Clear the screen */
-    IWineD3DDevice_Clear((IWineD3DDevice *) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
-
-    } /* End of FIXME: remove when dx8 merged in */
 
     return D3D_OK;
 }
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
new file mode 100644
index 0000000..4dae6d2
--- /dev/null
+++ b/dlls/wined3d/swapchain.c
@@ -0,0 +1,458 @@
+/*
+ *IDirect3DSwapChain9 implementation
+ *
+ *Copyright 2002-2003 Jason Edmeades
+ *Copyright 2002-2003 Raphael Junqueira
+ *Copyright 2005 Oliver Stieber
+ *
+ *This library is free software; you can redistribute it and/or
+ *modify it under the terms of the GNU Lesser General Public
+ *License as published by the Free Software Foundation; either
+ *version 2.1 of the License, or (at your option) any later version.
+ *
+ *This library is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *Lesser General Public License for more details.
+ *
+ *You should have received a copy of the GNU Lesser General Public
+ *License along with this library; if not, write to the Free Software
+ *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wined3d_private.h"
+
+
+/* TODO: move to shared header (or context manager )*/
+/* 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 */
+};
+
+/* 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;
+}
+
+/*TODO: some of the additional parameters may be required to 
+    set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
+    but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/
+    
+    
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_fps);
+
+
+/* IDirect3DSwapChain IUnknown parts follow: */
+ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    DWORD refCount = InterlockedIncrement(&This->ref);
+    TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
+    return refCount;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj)
+{
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    TRACE("(%p)->(%s,%p) \n",This,debugstr_guid(riid),ppobj);
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
+        IWineD3DSwapChainImpl_AddRef(iface);
+        if(ppobj == NULL){
+            ERR("Query interface called but now data allocated\n");
+            return E_NOINTERFACE;
+        }
+        *ppobj = This;
+        return D3D_OK;
+    }    
+    return E_NOINTERFACE;
+}
+
+
+ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    DWORD refCount;    
+    refCount = InterlockedDecrement(&This->ref);
+    TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
+    if (refCount == 0) {
+        IUnknown* bufferParent;
+        IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
+        IUnknown_Release(bufferParent); /* once for the get parent */
+        if(IUnknown_Release(bufferParent) > 0){
+            FIXME("(%p) Something's still holding the front buffer\n",This);
+        }
+
+        IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
+        IUnknown_Release(bufferParent); /* once for the get parent */
+        if(IUnknown_Release(bufferParent) > 0){
+            FIXME("(%p) Something's still holding the back buffer\n",This);
+        }
+        /* Clean up the context */
+        /* check that we are the current context first */
+        if(glXGetCurrentContext() == This->glCtx){
+            glXMakeCurrent(This->display, None, NULL);
+        }
+        glXDestroyContext(This->display, This->glCtx);
+        /* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
+         all others are crated by the caller, so releasing the parent should cause
+         the child to be released, not the other way around!
+         */
+         /* TODO: notify the device that this swapchain doesn't exist any more */
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return refCount;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    *ppParent = This->parent;
+    IUnknown_AddRef(*ppParent);
+    TRACE("(%p) returning %p\n", This , *ppParent);
+    return D3D_OK;
+}
+
+/*IWineD3DSwapChain parts follow: */
+HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    
+    ENTER_GL();
+
+    if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
+    /* TODO: If only source rect or dest rect are supplied then clip the window to match */
+    TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
+    
+    /* Don't call checkGLcall, as glGetError is not applicable here */
+    if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
+        /* Set this swapchain up to point to the new destination.. */
+#ifdef USE_CONTEXT_MANAGER
+            /* TODO: use a context mamager */
+#endif
+            
+            /* FIXME: Never access */
+            IWineD3DSwapChainImpl *swapChainImpl;
+            IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
+            FIXME("Unable to render to a destination window %d\n", (int)hDestWindowOverride );
+            if(This == swapChainImpl){
+                /* FIXME: this will be fixed by moving to a context management system */
+                FIXME("Cannot change the target of the implicite swapchain\n");
+            }else{
+                HDC               hDc;
+                XVisualInfo       template;
+                int               num;
+                Display          *oldDisplay = This->display;
+                GLXContext        oldContext = This->glCtx;
+                IUnknown*         tmp;           
+                GLXContext        currentContext;
+                Drawable          currentDrawable;
+                hDc                          = GetDC(hDestWindowOverride);
+                This->win_handle             = hDestWindowOverride;            
+                This->win                    = (Window)GetPropA( hDestWindowOverride, "__wine_x11_whole_window" );
+
+                TRACE("Creating a new context for the window %p \n", hDestWindowOverride);
+                ENTER_GL();
+                TRACE("Desctroying context %p %p\n", This->display, This->render_ctx);
+
+
+
+                LEAVE_GL();
+                ENTER_GL();
+
+                This->display    = get_display(hDc);
+                TRACE("Got display%p  for  %p %p\n",  This->display, hDc, hDestWindowOverride);
+                ReleaseDC(hDestWindowOverride, hDc);
+                template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
+                This->visInfo   = XGetVisualInfo(This->display, VisualIDMask, &template, &num);
+                if (NULL == This->visInfo) {
+                    ERR("cannot really get XVisual\n"); 
+                    LEAVE_GL();
+                    return D3DERR_NOTAVAILABLE;
+                }
+                /* Now we have problems? well not really we just need to know what the implicite context is */
+                /* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
+                /* destroy the active context?*/
+                TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
+                This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);
+
+                if (NULL == This->glCtx) {
+                    ERR("cannot create glxContext\n"); 
+                }
+                This->drawable     = This->win;
+                This->render_ctx   = This->glCtx;
+                /* SEtup some default states TODO: apply the stateblock to the new context */
+                /** save current context and drawable **/
+                currentContext  =   glXGetCurrentContext();
+                currentDrawable =   glXGetCurrentDrawable();
+
+                if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
+                    ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
+                }
+
+                checkGLcall("glXMakeCurrent");
+
+                /* Clear the screen */
+                glClearColor(0.0, 0.0, 0.0, 0.0);
+                checkGLcall("glClearColor");
+                glClearIndex(0);
+                glClearDepth(1);
+                glClearStencil(0);
+                
+                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+                checkGLcall("glClear");
+                
+                glColor3f(1.0, 1.0, 1.0);
+                checkGLcall("glColor3f");
+                
+                glEnable(GL_LIGHTING);
+                checkGLcall("glEnable");
+                
+                glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+                checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
+                
+                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+                checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
+                
+                glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+                checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
+                
+                /* If this swapchain is currently the active context then make this swapchain active */
+                if(IWineD3DSurface_GetContainer((IWineD3DSurface *)This->wineD3DDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmp) == D3D_OK){
+                    if(tmp != (IUnknown *)This){
+                        glXMakeCurrent(This->display, currentDrawable, currentContext);
+                        checkGLcall("glXMakeCurrent");
+                    }
+                    IUnknown_Release(tmp);
+                }else{
+                    /* reset the context */
+                    glXMakeCurrent(This->display, currentDrawable, currentContext);
+                    checkGLcall("glXMakeCurrent");                    
+                }
+                /* delete the old contxt*/
+                glXDestroyContext(oldDisplay, oldContext); /* Should this happen on an active context? seems a bad idea */
+                LEAVE_GL();
+            }
+            IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapChainImpl);
+                
+        }
+            
+            
+        /* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */
+    
+    glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */
+    
+    TRACE("glXSwapBuffers called, Starting new frame\n");
+    /* FPS support */
+    if (TRACE_ON(d3d_fps))
+    {
+        static long prev_time, frames;
+
+        DWORD time = GetTickCount();
+        frames++;
+        /* every 1.5 seconds */
+        if (time - prev_time > 1500) {
+            TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
+            prev_time = time;
+            frames = 0;
+        }
+    }
+
+#if defined(FRAME_DEBUGGING)
+{
+    if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
+        if (!isOn) {
+            isOn = TRUE;
+            FIXME("Enabling D3D Trace\n");
+            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
+#if defined(SHOW_FRAME_MAKEUP)
+            FIXME("Singe Frame snapshots Starting\n");
+            isDumpingFrames = TRUE;
+            glClear(GL_COLOR_BUFFER_BIT);
+#endif
+
+#if defined(SINGLE_FRAME_DEBUGGING)
+        } else {
+#if defined(SHOW_FRAME_MAKEUP)
+            FIXME("Singe Frame snapshots Finishing\n");
+            isDumpingFrames = FALSE;
+#endif
+            FIXME("Singe Frame trace complete\n");
+            DeleteFileA("C:\\D3DTRACE");
+            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+#endif
+        }
+    } else {
+        if (isOn) {
+            isOn = FALSE;
+#if defined(SHOW_FRAME_MAKEUP)
+            FIXME("Single Frame snapshots Finishing\n");
+            isDumpingFrames = FALSE;
+#endif
+            FIXME("Disabling D3D Trace\n");
+            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+        }
+    }
+}
+#endif
+
+    LEAVE_GL();
+    /* Although this is not strictly required, a simple demo showed this does occur
+       on (at least non-debug) d3d                                                  */
+    if (This->presentParms.SwapEffect & D3DSWAPEFFECT_DISCARD) {
+    
+        TRACE("Clearing\n");     
+
+       IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+
+    }
+        TRACE("returning\n");
+    return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)pDestSurface;
+    GLenum format;
+    GLenum type;
+    
+    TRACE("(%p) : iface(%p) pDestSurface(%p) \n", This, iface, pDestSurface);
+    ENTER_GL();
+
+    /* check to see if it's the backbuffer or the frontbuffer being requested (to make sureteh data is upto date) */
+    format = D3DFmt2GLFmt(This->wineD3DDevice, surface->resource.format);
+    type   = D3DFmt2GLType(This->wineD3DDevice, surface->resource.format);
+    glReadBuffer(GL_FRONT);
+    glReadPixels(0, 
+                0, 
+                surface->currentDesc.Width, 
+                surface->currentDesc.Height,
+                format, 
+                type, 
+                surface->resource.allocatedMemory);            
+    LEAVE_GL();
+    return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
+
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;        
+    
+    *ppBackBuffer = (IWineD3DSurface *) This->backBuffer;
+    TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
+
+    if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
+        FIXME("Only one backBuffer currently supported\n");
+        return D3DERR_INVALIDCALL;
+    }
+
+    /* Note inc ref on returned surface */
+    IWineD3DSurface_AddRef(*ppBackBuffer);    
+    return D3D_OK;
+    
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, D3DRASTER_STATUS*pRasterStatus) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;    
+    pRasterStatus->InVBlank = TRUE;
+    pRasterStatus->ScanLine = 0;
+    FIXME("(%p) : stub\n", This);
+    return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, D3DDISPLAYMODE*pMode) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;        
+    HDC                 hdc;
+    int                 bpp = 0;
+
+    pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
+    pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
+    pMode->RefreshRate  = 85; /* FIXME: How to identify? */
+
+    hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
+    bpp = GetDeviceCaps(hdc, BITSPIXEL);
+    DeleteDC(hdc);
+
+    switch (bpp) {
+    case  8: pMode->Format       = D3DFMT_R8G8B8; break;
+    case 16: pMode->Format       = D3DFMT_R5G6B5; break;
+    case 24: /*pMode->Format       = D3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
+    case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
+    default: 
+       FIXME("Unrecognized display mode format\n");
+       pMode->Format       = D3DFMT_UNKNOWN;
+    }
+
+    TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
+    pMode->Format, debug_d3dformat(pMode->Format));
+    return D3D_OK;        
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;  
+
+    *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
+
+    /* Note  Calling this method will increase the internal reference count 
+       on the IDirect3DDevice9 interface. */
+    IWineD3DDevice_AddRef(*ppDevice);
+    TRACE("(%p) : returning %p\n", This, *ppDevice);
+    return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, D3DPRESENT_PARAMETERS *pPresentationParameters) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    FIXME("(%p) : copy\n", This); 
+    memcpy(pPresentationParameters, &This->presentParms, sizeof(D3DPRESENT_PARAMETERS));
+    return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST D3DGAMMARAMP *pRamp){
+
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    HDC hDC;
+    TRACE("(%p) : pRamp@%p flags(%ld) \n", This, pRamp, Flags);
+    hDC = GetDC(This->win_handle);
+    SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
+    ReleaseDC(This->win_handle, hDC);
+    return D3D_OK;
+    
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, D3DGAMMARAMP *pRamp){
+
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    HDC hDC;
+    TRACE("(%p) : pRamp@%p\n", This, pRamp);
+    hDC = GetDC(This->win_handle);
+    GetDeviceGammaRamp(hDC, pRamp);
+    ReleaseDC(This->win_handle, hDC);
+    return D3D_OK;
+    
+}
+
+
+IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
+{
+    IWineD3DSwapChainImpl_QueryInterface,
+    IWineD3DSwapChainImpl_AddRef,
+    IWineD3DSwapChainImpl_Release,
+    IWineD3DSwapChainImpl_GetParent,
+    IWineD3DSwapChainImpl_GetDevice,
+    IWineD3DSwapChainImpl_Present,
+    IWineD3DSwapChainImpl_GetFrontBufferData,
+    IWineD3DSwapChainImpl_GetBackBuffer,
+    IWineD3DSwapChainImpl_GetRasterStatus,
+    IWineD3DSwapChainImpl_GetDisplayMode,
+    IWineD3DSwapChainImpl_GetPresentParameters,
+    IWineD3DSwapChainImpl_SetGammaRamp,
+    IWineD3DSwapChainImpl_GetGammaRamp 
+};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b5a8cc9..d2baf75 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3,7 +3,8 @@
  *
  * Copyright 2002-2003 The wine-d3d team
  * Copyright 2002-2003 Raphael Junqueira
- * Copyright 2004      Jason Edmeades   
+ * Copyright 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -41,6 +42,9 @@
 #include "wine/wined3d_interface.h"
 #include "wine/wined3d_gl.h"
 
+/* Swap chains */
+#define MAX_SWAPCHAINS 256
+
 extern int vs_mode;
 #define VS_NONE 0
 #define VS_HW   1
@@ -339,13 +343,6 @@
     IWineD3D               *wineD3D;
 
     /* X and GL Information */
-    HWND                    win_handle;
-    Window                  win;
-    Display                *display;
-    GLXContext              glCtx;
-    XVisualInfo            *visInfo;
-    GLXContext              render_ctx;
-    Drawable                drawable;
     GLint                   maxConcurrentLights;
 
     /* Optimization */
@@ -376,6 +373,10 @@
     UINT                            adapterNo;
     D3DDEVTYPE                      devType;
 
+    /* TODO: Replace with a linked list */
+    IWineD3DSwapChain      *swapchains[MAX_SWAPCHAINS]; /* no-one wil ever need more that MAX_SWAPCHAINS swapchains */
+    int                     numberOfSwapChains;
+
     /* Render Target Support */
     IWineD3DSurface        *frontBuffer;
     IWineD3DSurface        *backBuffer;
@@ -754,6 +755,43 @@
 extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
 
 /*****************************************************************************
+ * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
+ */
+
+typedef struct IWineD3DSwapChainImpl
+{
+    /*IUnknown part*/
+    IWineD3DSwapChainVtbl    *lpVtbl;
+    DWORD                     ref;     /* Note: Ref counting not required */
+
+    IUnknown                 *parent;
+    IWineD3DDeviceImpl       *wineD3DDevice;
+
+    /* IWineD3DSwapChain fields */
+    IWineD3DSurface          *backBuffer;
+    IWineD3DSurface          *frontBuffer;
+    BOOL                      wantsDepthStencilBuffer;
+    D3DPRESENT_PARAMETERS     presentParms;
+
+    /* TODO: move everything upto drawable off into a context manager
+      and store the 'data' in the contextManagerData interface.
+    IUnknown                  *contextManagerData;
+    */
+
+    HWND                    win_handle;
+    Window                  win;
+    Display                *display;
+
+    GLXContext              glCtx;
+    XVisualInfo            *visInfo;
+    GLXContext              render_ctx;
+    /* This has been left in device for now, but needs moving off into a rendertarget mamangement class and seperated out from swapchains and devices. */
+    Drawable                drawable;
+} IWineD3DSwapChainImpl;
+
+extern IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl;
+
+/*****************************************************************************
  * Utility function prototypes 
  */