diff --git a/configure.ac b/configure.ac
index 6dd03d4..24c9fc2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -524,6 +524,7 @@ then
                       X11/extensions/Xinerama.h \
                       X11/extensions/Xrandr.h \
                       X11/extensions/Xrender.h \
+                      X11/extensions/Xcomposite.h \
                       X11/extensions/xf86vmode.h],,,
 [#ifdef HAVE_X11_XLIB_H
 # include <X11/Xlib.h>
@@ -617,6 +618,16 @@ Wine will be built without XRandr support. (winex11.drv)])
         WINE_NOTICE_IF([test "x$ac_cv_lib_soname_Xinerama" = "x"],[Xinerama development files not found.
 Wine will be built without Xinerama support. (winex11.drv)])
 
+        dnl *** Check for X Composite extension
+        if test "$ac_cv_header_X11_extensions_Xcomposite_h" = "yes"
+        then
+                AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>]], [[static typeof(XCompositeRedirectWindow) * func;]])],
+                  [WINE_CHECK_SONAME(Xcomposite,XCompositeRedirectWindow,,,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])])
+        fi
+        WINE_NOTICE_IF([test "x$ac_cv_lib_soname_Xcomposite" = "x"],[XComposite development files not found.
+Wine will be built without XComposite support. (winex11.drv)])
+
     dnl *** End of X11/Xlib.h check
 
     dnl Check for the presence of OpenGL
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index a623868..254dec2 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -150,6 +150,25 @@ DC *DC_GetDCPtr( HDC hdc )
 }
 
 /***********************************************************************
+ *           DC_GetDCPtrNoLock
+ *
+ * Retrieve a DC ptr without acquiring the GDI lock.
+ */
+DC *DC_GetDCPtrNoLock( HDC hdc )
+{
+    GDIOBJHDR *ptr = GDI_GetObjPtrNoLock( hdc, MAGIC_DONTCARE );
+    if (!ptr) return NULL;
+    if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
+        (GDIMAGIC(ptr->wMagic) == MEMORY_DC_MAGIC) ||
+        (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
+        (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
+        return (DC *)ptr;
+    GDI_ReleaseObjNoLock( hdc );
+    SetLastError( ERROR_INVALID_HANDLE );
+    return NULL;
+}
+
+/***********************************************************************
  *           DC_GetDCUpdate
  *
  * Retrieve a DC ptr while making sure the visRgn is updated.
@@ -185,6 +204,14 @@ void DC_ReleaseDCPtr( DC *dc )
     GDI_ReleaseObj( dc->hSelf );
 }
 
+/***********************************************************************
+ *           DC_ReleaseDCPtrNoLock
+ */
+void DC_ReleaseDCPtrNoLock( DC *dc )
+{
+    GDI_ReleaseObjNoLock( dc->hSelf );
+}
+
 
 /***********************************************************************
  *           DC_FreeDCPtr
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 4476424..46e2943 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -394,8 +394,10 @@ extern void CLIPPING_UpdateGCRegion( DC * dc );
 /* dc.c */
 extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic );
 extern DC * DC_GetDCUpdate( HDC hdc );
+extern DC * DC_GetDCPtrNoLock( HDC hdc );
 extern DC * DC_GetDCPtr( HDC hdc );
 extern void DC_ReleaseDCPtr( DC *dc );
+extern void DC_ReleaseDCPtrNoLock( DC *dc );
 extern BOOL DC_FreeDCPtr( DC *dc );
 extern void DC_InitDC( DC * dc );
 extern void DC_UpdateXforms( DC * dc );
@@ -448,7 +450,9 @@ extern void *GDI_AllocObject( WORD, WORD, HGDIOBJ *, const struct gdi_obj_funcs
 extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj );
 extern BOOL GDI_FreeObject( HGDIOBJ, void *obj );
 extern void *GDI_GetObjPtr( HGDIOBJ, WORD );
+extern void *GDI_GetObjPtrNoLock( HGDIOBJ, WORD );
 extern void GDI_ReleaseObj( HGDIOBJ );
+extern void GDI_ReleaseObjNoLock( HGDIOBJ );
 extern void GDI_CheckNotLock(void);
 extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc);
 extern BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc);
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index 075058e..539ef24 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -767,6 +767,35 @@ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
     return ptr;
 }
 
+/***********************************************************************
+ *           GDI_GetObjPtrNoLock
+ *
+ * Return a pointer to the GDI object associated to the handle, without holding
+ * the GDI lock.
+ */
+void *GDI_GetObjPtrNoLock( HGDIOBJ handle, WORD magic )
+{
+    GDIOBJHDR *ptr = NULL;
+    int i;
+
+    _EnterSysLevel( &GDI_level );
+
+    i = ((UINT_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
+    if (i >= 0 && i < MAX_LARGE_HANDLES)
+    {
+        ptr = large_handles[i];
+        if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
+    }
+
+    _LeaveSysLevel( &GDI_level );
+
+    if (!ptr)
+        WARN( "Invalid handle %p\n", handle );
+    else
+        TRACE("(%p): handle acquired\n", handle);
+
+    return ptr;
+}
 
 /***********************************************************************
  *           GDI_ReleaseObj
@@ -778,6 +807,15 @@ void GDI_ReleaseObj( HGDIOBJ handle )
     _LeaveSysLevel( &GDI_level );
 }
 
+/***********************************************************************
+ *           GDI_ReleaseObjNoLock
+ *
+ */
+void GDI_ReleaseObjNoLock( HGDIOBJ handle )
+{
+    TRACE("(%p): released\n", handle);
+}
+
 
 /***********************************************************************
  *           GDI_CheckNotLock
diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c
index 473f628..1d8068f 100644
--- a/dlls/gdi32/painting.c
+++ b/dlls/gdi32/painting.c
@@ -351,7 +351,7 @@ BOOL WINAPI SetPixelFormat( HDC hdc, INT iPixelFormat,
                             const PIXELFORMATDESCRIPTOR *ppfd)
 {
     INT bRet = FALSE;
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCPtrNoLock( hdc );
 
     TRACE("(%p,%d,%p)\n",hdc,iPixelFormat,ppfd);
 
@@ -360,7 +360,7 @@ BOOL WINAPI SetPixelFormat( HDC hdc, INT iPixelFormat,
     if (!dc->funcs->pSetPixelFormat) FIXME(" :stub\n");
     else bRet = dc->funcs->pSetPixelFormat(dc->physDev,iPixelFormat,ppfd);
 
-    DC_ReleaseDCPtr( dc );
+    DC_ReleaseDCPtrNoLock( dc );
     return bRet;
 }
 
@@ -445,7 +445,7 @@ INT WINAPI DescribePixelFormat( HDC hdc, INT iPixelFormat, UINT nBytes,
 BOOL WINAPI SwapBuffers( HDC hdc )
 {
     INT bRet = FALSE;
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCUpdate( hdc );
 
     TRACE("(%p)\n",hdc);
 
diff --git a/dlls/openal32/libopenal32.def b/dlls/openal32/libopenal32.def
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl
index 381b1a9..75755d2 100755
--- a/dlls/opengl32/make_opengl
+++ b/dlls/opengl32/make_opengl
@@ -214,12 +214,8 @@ sub GenerateThunk($$$$$)
     my $trace_arg = "";
 
     return "" if $func_ref->[0] eq "glGetString";
-    return "" if $func_ref->[0] eq "glGetIntegerv";
-    return "" if $func_ref->[0] eq "glEnable";
-    return "" if $func_ref->[0] eq "glIsEnabled";
-    return "" if $func_ref->[0] eq "glDisable";
-    return "" if $func_ref->[0] eq "glScissor";
-    return "" if $func_ref->[0] eq "glViewport";
+    return "" if $func_ref->[0] eq "glFlush";
+    return "" if $func_ref->[0] eq "glFinish";
 
     # If for opengl_norm.c, generate a nice heading otherwise Patrik won't be happy :-)
     # Patrik says: Well I would be even happier if a (OPENGL32.@) was added as well. Done. :-)
diff --git a/dlls/opengl32/opengl32.spec b/dlls/opengl32/opengl32.spec
index 8b7b28a..4812082 100644
--- a/dlls/opengl32/opengl32.spec
+++ b/dlls/opengl32/opengl32.spec
@@ -130,8 +130,6 @@
 @  stdcall glGetHistogramParameterfv( long long ptr ) wine_glGetHistogramParameterfv
 @  stdcall glGetHistogramParameteriv( long long ptr ) wine_glGetHistogramParameteriv
 @  stdcall glGetIntegerv( long ptr ) wine_glGetIntegerv
-@  stub    glGetLevelParameterfv
-@  stub    glGetLevelParameteriv
 @  stdcall glGetLightfv( long long ptr ) wine_glGetLightfv
 @  stdcall glGetLightiv( long long ptr ) wine_glGetLightiv
 @  stdcall glGetMapdv( long long ptr ) wine_glGetMapdv
@@ -374,6 +372,8 @@
 @  stdcall glVertex4sv( ptr ) wine_glVertex4sv
 @  stdcall glVertexPointer( long long long ptr ) wine_glVertexPointer
 @  stdcall glViewport( long long long long ) wine_glViewport
+@  stub    glGetLevelParameterfv
+@  stub    glGetLevelParameteriv
 @  stdcall wglChoosePixelFormat(long ptr) gdi32.ChoosePixelFormat
 @  stdcall wglCopyContext(long long long)
 @  stdcall wglCreateContext(long) gdi32.wglCreateContext
diff --git a/dlls/opengl32/opengl_norm.c b/dlls/opengl32/opengl_norm.c
index 6534301..be6c5f2 100644
--- a/dlls/opengl32/opengl_norm.c
+++ b/dlls/opengl32/opengl_norm.c
@@ -810,6 +810,16 @@ void WINAPI wine_glDepthRange( GLclampd nearParam, GLclampd farParam ) {
 }
 
 /***********************************************************************
+ *              glDisable (OPENGL32.@)
+ */
+void WINAPI wine_glDisable( GLenum cap ) {
+  TRACE("(%d)\n", cap );
+  ENTER_GL();
+  glDisable( cap );
+  LEAVE_GL();
+}
+
+/***********************************************************************
  *              glDisableClientState (OPENGL32.@)
  */
 void WINAPI wine_glDisableClientState( GLenum array ) {
@@ -900,6 +910,16 @@ void WINAPI wine_glEdgeFlagv( GLboolean* flag ) {
 }
 
 /***********************************************************************
+ *              glEnable (OPENGL32.@)
+ */
+void WINAPI wine_glEnable( GLenum cap ) {
+  TRACE("(%d)\n", cap );
+  ENTER_GL();
+  glEnable( cap );
+  LEAVE_GL();
+}
+
+/***********************************************************************
  *              glEnableClientState (OPENGL32.@)
  */
 void WINAPI wine_glEnableClientState( GLenum array ) {
@@ -1060,26 +1080,6 @@ void WINAPI wine_glFeedbackBuffer( GLsizei size, GLenum type, GLfloat* buffer )
 }
 
 /***********************************************************************
- *              glFinish (OPENGL32.@)
- */
-void WINAPI wine_glFinish( void ) {
-  TRACE("()\n");
-  ENTER_GL();
-  glFinish( );
-  LEAVE_GL();
-}
-
-/***********************************************************************
- *              glFlush (OPENGL32.@)
- */
-void WINAPI wine_glFlush( void ) {
-  TRACE("()\n");
-  ENTER_GL();
-  glFlush( );
-  LEAVE_GL();
-}
-
-/***********************************************************************
  *              glFogf (OPENGL32.@)
  */
 void WINAPI wine_glFogf( GLenum pname, GLfloat param ) {
@@ -1304,6 +1304,16 @@ void WINAPI wine_glGetHistogramParameteriv( GLenum target, GLenum pname, GLint*
 }
 
 /***********************************************************************
+ *              glGetIntegerv (OPENGL32.@)
+ */
+void WINAPI wine_glGetIntegerv( GLenum pname, GLint* params ) {
+  TRACE("(%d, %p)\n", pname, params );
+  ENTER_GL();
+  glGetIntegerv( pname, params );
+  LEAVE_GL();
+}
+
+/***********************************************************************
  *              glGetLightfv (OPENGL32.@)
  */
 void WINAPI wine_glGetLightfv( GLenum light, GLenum pname, GLfloat* params ) {
@@ -1724,6 +1734,18 @@ void WINAPI wine_glInterleavedArrays( GLenum format, GLsizei stride, GLvoid* poi
 }
 
 /***********************************************************************
+ *              glIsEnabled (OPENGL32.@)
+ */
+GLboolean WINAPI wine_glIsEnabled( GLenum cap ) {
+  GLboolean ret_value;
+  TRACE("(%d)\n", cap );
+  ENTER_GL();
+  ret_value = glIsEnabled( cap );
+  LEAVE_GL();
+  return ret_value;
+}
+
+/***********************************************************************
  *              glIsList (OPENGL32.@)
  */
 GLboolean WINAPI wine_glIsList( GLuint list ) {
@@ -2830,6 +2852,16 @@ void WINAPI wine_glScalef( GLfloat x, GLfloat y, GLfloat z ) {
 }
 
 /***********************************************************************
+ *              glScissor (OPENGL32.@)
+ */
+void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) {
+  TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
+  ENTER_GL();
+  glScissor( x, y, width, height );
+  LEAVE_GL();
+}
+
+/***********************************************************************
  *              glSelectBuffer (OPENGL32.@)
  */
 void WINAPI wine_glSelectBuffer( GLsizei size, GLuint* buffer ) {
@@ -3688,3 +3720,13 @@ void WINAPI wine_glVertexPointer( GLint size, GLenum type, GLsizei stride, GLvoi
   glVertexPointer( size, type, stride, pointer );
   LEAVE_GL();
 }
+
+/***********************************************************************
+ *              glViewport (OPENGL32.@)
+ */
+void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) {
+  TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
+  ENTER_GL();
+  glViewport( x, y, width, height );
+  LEAVE_GL();
+}
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 029f361..505bb82 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -48,12 +48,8 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl);
 typedef struct wine_wgl_s {
     PROC WINAPI  (*p_wglGetProcAddress)(LPCSTR  lpszProc);
 
-    void WINAPI  (*p_wglDisable)(GLenum cap);
-    void WINAPI  (*p_wglEnable)(GLenum cap);
-    void WINAPI  (*p_wglGetIntegerv)(GLenum pname, GLint* params);
-    GLboolean WINAPI (*p_wglIsEnabled)(GLenum cap);
-    void WINAPI  (*p_wglScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
-    void WINAPI  (*p_wglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+    void WINAPI  (*p_wglFlush)();
+    void WINAPI  (*p_wglFinish)();
 } wine_wgl_t;
 
 /** global wgl object */
@@ -569,48 +565,21 @@ BOOL WINAPI wglUseFontOutlinesW(HDC hdc,
 }
 
 /***********************************************************************
- *              glEnable (OPENGL32.@)
+ *              glFlush (OPENGL32.@)
  */
-void WINAPI wine_glEnable( GLenum cap )
+void WINAPI wine_glFlush()
 {
-    TRACE("(%d)\n", cap );
-    wine_wgl.p_wglEnable(cap);
+    TRACE("()\n");
+    wine_wgl.p_wglFlush();
 }
 
 /***********************************************************************
- *              glIsEnabled (OPENGL32.@)
+ *              glFinish (OPENGL32.@)
  */
-GLboolean WINAPI wine_glIsEnabled( GLenum cap )
+void WINAPI wine_glFinish()
 {
-    TRACE("(%d)\n", cap );
-    return wine_wgl.p_wglIsEnabled(cap);
-}
-
-/***********************************************************************
- *              glDisable (OPENGL32.@)
- */
-void WINAPI wine_glDisable( GLenum cap )
-{
-    TRACE("(%d)\n", cap );
-    wine_wgl.p_wglDisable(cap);
-}
-
-/***********************************************************************
- *              glScissor (OPENGL32.@)
- */
-void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height )
-{
-    TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
-    wine_wgl.p_wglScissor(x, y, width, height);
-}
-
-/***********************************************************************
- *              glViewport (OPENGL32.@)
- */
-void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height )
-{
-    TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
-    wine_wgl.p_wglViewport(x, y, width, height);
+    TRACE("()\n");
+    wine_wgl.p_wglFinish();
 }
 
 /***********************************************************************
@@ -666,14 +635,6 @@ const GLubyte * WINAPI wine_glGetString( GLenum name )
   return (const GLubyte *) internal_gl_extensions;
 }
 
-/***********************************************************************
- *              glGetIntegerv (OPENGL32.@)
- */
-void WINAPI wine_glGetIntegerv( GLenum pname, GLint* params )
-{
-    wine_wgl.p_wglGetIntegerv(pname, params);
-}
-
 
 /* This is for brain-dead applications that use OpenGL functions before even
    creating a rendering context.... */
@@ -699,12 +660,8 @@ static BOOL process_attach(void)
   wine_wgl.p_wglGetProcAddress = (void *)GetProcAddress(mod_gdi32, "wglGetProcAddress");
 
   /* Interal WGL function */
-  wine_wgl.p_wglDisable = (void *)wine_wgl.p_wglGetProcAddress("wglDisable");
-  wine_wgl.p_wglEnable = (void *)wine_wgl.p_wglGetProcAddress("wglEnable");
-  wine_wgl.p_wglGetIntegerv = (void *)wine_wgl.p_wglGetProcAddress("wglGetIntegerv");
-  wine_wgl.p_wglIsEnabled = (void *)wine_wgl.p_wglGetProcAddress("wglIsEnabled");
-  wine_wgl.p_wglScissor = (void *)wine_wgl.p_wglGetProcAddress("wglScissor");
-  wine_wgl.p_wglViewport = (void *)wine_wgl.p_wglGetProcAddress("wglViewport");
+  wine_wgl.p_wglFlush = (void *)wine_wgl.p_wglGetProcAddress("wglFlush");
+  wine_wgl.p_wglFinish = (void *)wine_wgl.p_wglGetProcAddress("wglFinish");
 
   internal_gl_disabled_extensions[0] = 0;
   if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey)) {
diff --git a/dlls/winex11.drv/dce.c b/dlls/winex11.drv/dce.c
index 3b80308..e6b8fc2 100644
--- a/dlls/winex11.drv/dce.c
+++ b/dlls/winex11.drv/dce.c
@@ -147,10 +147,18 @@ static void update_visible_region( struct dce *dce )
                                    (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
 
     if (top == dce->hwnd && ((data = X11DRV_get_win_data( dce->hwnd )) != NULL) &&
-         IsIconic( dce->hwnd ) && data->icon_window)
+         IsIconic( dce->hwnd ) && data->icon_window) {
         escape.drawable = data->icon_window;
-    else
+        escape.wgl_info.iPixelFormat = X11DRV_get_pixel_format( dce->hwnd );
+        escape.wgl_info.gl_surface = X11DRV_get_gl_surface( dce->hwnd );
+        escape.wgl_info.pixmap = X11DRV_get_gl_pixmap( dce->hwnd );
+    }
+    else {
         escape.drawable = X11DRV_get_whole_window( top );
+        escape.wgl_info.iPixelFormat = X11DRV_get_pixel_format( dce->hwnd );
+        escape.wgl_info.gl_surface = X11DRV_get_gl_surface( dce->hwnd );
+        escape.wgl_info.pixmap = X11DRV_get_gl_pixmap( dce->hwnd );
+    }
 
     escape.code = X11DRV_SET_DRAWABLE;
     escape.mode = IncludeInferiors;
@@ -185,6 +193,9 @@ static void release_dce( struct dce *dce )
     escape.drawable_rect = virtual_screen_rect;
     SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
              virtual_screen_rect.bottom - virtual_screen_rect.top );
+    escape.wgl_info.iPixelFormat = 0;
+    escape.wgl_info.gl_surface = 0;
+    escape.wgl_info.pixmap = 0;
     ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
 }
 
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index f3010de..b45fc8e 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -958,6 +958,8 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
         return X11DRV_AcquireClipboard( hwnd );
     case WM_X11DRV_DELETE_WINDOW:
         return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+    case WM_X11DRV_CREATE_GL_SURFACE:
+        return X11DRV_create_gl_surface( hwnd, lp );
     default:
         FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
         return 0;
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 4bb44f2..d0f1bbb 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -340,6 +340,7 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID
                     physDev->dc_rect = data->dc_rect;
                     physDev->drawable = data->drawable;
                     physDev->drawable_rect = data->drawable_rect;
+                    physDev->wgl_info = data->wgl_info;
                     wine_tsx11_lock();
                     XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
                     wine_tsx11_unlock();
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 98ecedb..be2e6ec 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -34,6 +34,10 @@
 #include "wine/library.h"
 #include "wine/debug.h"
 
+#ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
+#include <X11/extensions/Xcomposite.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
 WINE_DECLARE_DEBUG_CHANNEL(opengl);
 
@@ -108,11 +112,9 @@ typedef struct wine_glcontext {
     XVisualInfo *vis;
     WineGLPixelFormat *fmt;
     GLXContext ctx;
+    Drawable new_drawable;
     BOOL do_escape;
     X11DRV_PDEVICE *physDev;
-    RECT viewport;
-    RECT scissor;
-    BOOL scissor_enabled;
     struct wine_glcontext *next;
     struct wine_glcontext *prev;
 } Wine_GLContext;
@@ -136,6 +138,15 @@ typedef struct wine_glpbuffer {
     int        texture_level;
 } Wine_GLPBuffer;
 
+/* Duplicated from window.c */
+static const char pixel_format_prop[] = "__wine_x11_pixel_format";
+static const char gl_surface_prop[]   = "__wine_x11_gl_surface";
+static const char gl_pixmap_prop[]    = "__wine_x11_gl_pixmap";
+
+static void *xcomposite_handle;
+static int xcomp_event_base;
+static int xcomp_error_base;
+
 static Wine_GLContext *context_list;
 static struct WineGLInfo WineGLInfo = { 0 };
 static int use_render_texture_emulation = 1;
@@ -209,6 +220,13 @@ static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
 #define PUSH2(attribs,att,value)  do { attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); } while(0)
 
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
+
+#ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
+/* XComposite */
+MAKE_FUNCPTR(XCompositeQueryExtension)
+MAKE_FUNCPTR(XCompositeRedirectWindow)
+#endif
+
 /* GLX 1.0 */
 MAKE_FUNCPTR(glXChooseVisual)
 MAKE_FUNCPTR(glXCreateContext)
@@ -245,6 +263,7 @@ MAKE_FUNCPTR(glXGetCurrentReadDrawable)
 /* GLX Extensions */
 static void* (*pglXGetProcAddressARB)(const GLubyte *);
 static int   (*pglXSwapIntervalSGI)(int);
+static void  (*pglXCopySubBufferMESA)(Display *, GLXDrawable, int, int, int, int);
 
 /* ATI GLX Extensions */
 static BOOL  (*pglXBindTexImageATI)(Display *dpy, GLXPbuffer pbuffer, int buffer);
@@ -261,20 +280,17 @@ MAKE_FUNCPTR(glBitmap)
 MAKE_FUNCPTR(glCopyTexSubImage1D)
 MAKE_FUNCPTR(glCopyTexImage2D)
 MAKE_FUNCPTR(glCopyTexSubImage2D)
-MAKE_FUNCPTR(glDisable)
 MAKE_FUNCPTR(glDrawBuffer)
-MAKE_FUNCPTR(glEnable)
 MAKE_FUNCPTR(glEndList)
 MAKE_FUNCPTR(glGetError)
 MAKE_FUNCPTR(glGetIntegerv)
 MAKE_FUNCPTR(glGetString)
-MAKE_FUNCPTR(glIsEnabled)
 MAKE_FUNCPTR(glNewList)
 MAKE_FUNCPTR(glPixelStorei)
 MAKE_FUNCPTR(glReadPixels)
-MAKE_FUNCPTR(glScissor)
 MAKE_FUNCPTR(glTexImage2D)
-MAKE_FUNCPTR(glViewport)
+MAKE_FUNCPTR(glFlush)
+MAKE_FUNCPTR(glFinish)
 #undef MAKE_FUNCPTR
 
 static BOOL X11DRV_WineGL_InitOpenglInfo(void)
@@ -365,6 +381,38 @@ static BOOL has_opengl(void)
     if (init_done) return (opengl_handle != NULL);
     init_done = 1;
 
+    if (composite_gl) {
+#if defined(SONAME_LIBXCOMPOSITE) && defined(HAVE_X11_EXTENSIONS_XCOMPOSITE_H)
+        xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
+        if (xcomposite_handle) {
+            pXCompositeQueryExtension = wine_dlsym(xcomposite_handle, "XCompositeQueryExtension", NULL, 0);
+            pXCompositeRedirectWindow = wine_dlsym(xcomposite_handle, "XCompositeRedirectWindow", NULL, 0);
+            if (!pXCompositeQueryExtension || !pXCompositeRedirectWindow) {
+                ERR("Functions were missing from %s, GLXPixmaps will be used for compositing\n"
+                    "\tIf this is not accelerated, you may wish to disable compositing\n", SONAME_LIBXCOMPOSITE);
+                wine_dlclose(xcomposite_handle, NULL, 0);
+                xcomposite_handle = NULL;
+            }
+
+            if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
+                                          &xcomp_error_base)) {
+                ERR("XComposite extension not enabled, GLXPixmaps will be used for compositing\n"
+                    "\tIf this is not accelerated, you may wish to disable compositing\n");
+                wine_dlclose(xcomposite_handle, NULL, 0);
+                xcomposite_handle = NULL;
+            }
+            else
+                TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
+        }
+        else
+            WARN("%s not found, GLXPixmaps will be used for compositing\n"
+                 "\tIf this is not accelerated, you may wish to disable compositing\n", SONAME_LIBXCOMPOSITE);
+#else
+        WARN("Xcomposite support not compiled in, GLXPixmaps will be used for compositing\n"
+             "\tIf this is not accelerated, you may wish to disable compositing\n");
+#endif
+    }
+
     /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient
        and include all dependencies */
     opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
@@ -412,20 +460,17 @@ LOAD_FUNCPTR(glBitmap)
 LOAD_FUNCPTR(glCopyTexSubImage1D)
 LOAD_FUNCPTR(glCopyTexImage2D)
 LOAD_FUNCPTR(glCopyTexSubImage2D)
-LOAD_FUNCPTR(glDisable)
 LOAD_FUNCPTR(glDrawBuffer)
-LOAD_FUNCPTR(glEnable)
 LOAD_FUNCPTR(glEndList)
 LOAD_FUNCPTR(glGetError)
 LOAD_FUNCPTR(glGetIntegerv)
 LOAD_FUNCPTR(glGetString)
-LOAD_FUNCPTR(glIsEnabled)
 LOAD_FUNCPTR(glNewList)
 LOAD_FUNCPTR(glPixelStorei)
 LOAD_FUNCPTR(glReadPixels)
-LOAD_FUNCPTR(glScissor)
 LOAD_FUNCPTR(glTexImage2D)
-LOAD_FUNCPTR(glViewport)
+LOAD_FUNCPTR(glFlush)
+LOAD_FUNCPTR(glFinish)
 #undef LOAD_FUNCPTR
 
 /* It doesn't matter if these fail. They'll only be used if the driver reports
@@ -513,6 +558,15 @@ LOAD_FUNCPTR(glXFreeMemoryNV)
         pglXDrawableAttribATI = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribATI");
     }
 
+    if(glxRequireExtension("GLX_MESA_copy_sub_buffer")) {
+        pglXCopySubBufferMESA = (void*)pglXGetProcAddressARB((const GLubyte *) "glXCopySubBufferMESA");
+    }
+    else {
+        if (!xcomposite_handle && composite_gl)
+            ERR("GLX_MESA_copy_sub_buffer is required for compositing using GLXPixmaps!\n"
+                "\tYou may experience graphical glitches or no GL display!\n");
+    }
+
     X11DRV_WineGL_LoadExtensions();
 
     wine_tsx11_unlock();
@@ -554,6 +608,26 @@ static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx)
     return ret;
 }
 
+/* Mark any allocated context using the glx drawable 'old' to use 'new' */
+static inline void mark_drawable_dirty(Drawable old, Drawable new)
+{
+    Wine_GLContext *ctx;
+    for (ctx = context_list; ctx; ctx = ctx->next) {
+        if (old == get_glxdrawable(ctx->physDev)) {
+            ctx->new_drawable = new;
+        }
+    }
+}
+
+/* Given the current context, make sure its drawable is sync'd */
+static inline void sync_context(Wine_GLContext *context)
+{
+    if(!context || !context->new_drawable)
+        return;
+    pglXMakeCurrent(gdi_display, context->new_drawable, context->ctx);
+    context->new_drawable = 0;
+}
+
 /**
  * get_hdc_from_Drawable (internal)
  *
@@ -957,6 +1031,132 @@ static WineGLPixelFormat* ConvertPixelFormatGLXtoWGL(Display *display, int fmt_i
     return NULL;
 }
 
+struct wgl_surface_data {
+    int w, h;
+    Drawable drawable;
+    int iPixelFormat;
+};
+
+LRESULT X11DRV_create_gl_surface(HWND hwnd, LPARAM lp)
+{
+    struct x11drv_win_data *data;
+    struct x11drv_wgl_data *wgl_info;
+    struct wgl_surface_data *surf_info = (struct wgl_surface_data*)lp;
+    WineGLPixelFormat *fmt;
+    XVisualInfo *vis;
+    Drawable gl_surface;
+    Pixmap pixmap;
+    int value;
+
+    if(!(data = X11DRV_get_win_data(hwnd)) ) {
+        ERR("No win data for hwnd (%p)!\n", hwnd);
+        return 0;
+    }
+    wgl_info = &data->wgl_info;
+
+    fmt = ConvertPixelFormatWGLtoGLX(gdi_display, surf_info->iPixelFormat,
+                                     FALSE /* Offscreen */, &value);
+    if(!fmt) {
+        ERR("Invalid iPixelFormat: %d\n", surf_info->iPixelFormat);
+        return 0;
+    }
+
+    wine_tsx11_lock();
+
+    vis = pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig);
+    if(!vis) {
+        wine_tsx11_unlock();
+        ERR("No visual for fbconfig %#x!\n", (unsigned int)fmt->fbconfig);
+        return 0;
+    }
+
+    /* HACK: enable when not testing offscreen rendering */
+    if(0 && data->whole_window && XVisualIDFromVisual(visual) == vis->visualid) {
+        TRACE("Requested visual and window match, using window directly\n");
+        goto done;
+    }
+
+    gl_surface = wgl_info->gl_surface;
+    pixmap = wgl_info->pixmap;
+
+    wgl_info->gl_surface = 0;
+    wgl_info->pixmap = 0;
+
+#ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
+    if (!wgl_info->gl_surface && xcomposite_handle) {
+        XSetWindowAttributes attrib;
+
+        attrib.override_redirect = True;
+        if ((vis->class == PseudoColor) || (vis->class == GrayScale) ||
+            (vis->class == DirectColor))
+            attrib.colormap = XCreateColormap(gdi_display, surf_info->drawable,
+                                              vis->visual, AllocAll);
+        else
+            attrib.colormap = XCreateColormap(gdi_display, surf_info->drawable,
+                                              vis->visual, AllocNone);
+        XInstallColormap(gdi_display, attrib.colormap);
+
+        wgl_info->gl_surface = XCreateWindow(gdi_display, surf_info->drawable,
+                                             -surf_info->w, 0, surf_info->w,
+                                             surf_info->h, 0, vis->depth,
+                                             InputOutput, vis->visual,
+                                             CWColormap | CWOverrideRedirect,
+                                             &attrib);
+        if(wgl_info->gl_surface) {
+            pXCompositeRedirectWindow(gdi_display, wgl_info->gl_surface,
+                                      CompositeRedirectManual);
+            XMapWindow(gdi_display, wgl_info->gl_surface);
+        }
+        else
+            WARN("Failed to create window for offscreen rendering\n");
+    }
+#endif
+
+    if(!wgl_info->gl_surface && composite_gl) {
+        wgl_info->pixmap = XCreatePixmap(gdi_display, surf_info->drawable,
+                                         surf_info->w, surf_info->h,
+                                         vis->depth);
+        if(!wgl_info->pixmap) {
+            wgl_info->gl_surface = gl_surface;
+            wgl_info->pixmap = pixmap;
+            XFree(vis);
+            wine_tsx11_unlock();
+            ERR("Failed to create surface for offscreen rendering\n");
+            return 0;
+        }
+
+        wgl_info->gl_surface = pglXCreateGLXPixmap(gdi_display, vis,
+                                                   wgl_info->pixmap);
+        if(!wgl_info->gl_surface) {
+            XFreePixmap(gdi_display, wgl_info->pixmap);
+            wgl_info->gl_surface = gl_surface;
+            wgl_info->pixmap = pixmap;
+            XFree(vis);
+            wine_tsx11_unlock();
+            ERR("Failed to create glxpixmap for offscreen rendering\n");
+            return 0;
+        }
+    }
+
+done:
+    XFree(vis);
+
+    XFlush(gdi_display);
+    wine_tsx11_unlock();
+
+    if(wgl_info->gl_surface)
+        TRACE("Created offscreen rendering surface %p (%p), parent %p\n",
+              (void*)wgl_info->gl_surface, (void*)wgl_info->pixmap,
+              (void*)surf_info->drawable);
+
+    wgl_info->iPixelFormat = surf_info->iPixelFormat;
+    SetPropA(hwnd, pixel_format_prop, (HANDLE)wgl_info->iPixelFormat);
+    SetPropA(hwnd, gl_surface_prop, (HANDLE)wgl_info->gl_surface);
+    SetPropA(hwnd, gl_pixmap_prop, (HANDLE)wgl_info->pixmap);
+
+    return 1;
+}
+
 /**
  * X11DRV_ChoosePixelFormat
  *
@@ -1338,11 +1538,11 @@ int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
   int tmp;
   TRACE("(%p)\n", physDev);
 
-  fmt = ConvertPixelFormatWGLtoGLX(gdi_display, physDev->current_pf, TRUE, &tmp);
+  fmt = ConvertPixelFormatWGLtoGLX(gdi_display, physDev->wgl_info.iPixelFormat, TRUE, &tmp);
   if(!fmt)
   {
     /* This happens on HDCs on which SetPixelFormat wasn't called yet */
-    ERR("Unable to find a WineGLPixelFormat for iPixelFormat=%d\n", physDev->current_pf);
+    ERR("Unable to find a WineGLPixelFormat for iPixelFormat=%d\n", physDev->wgl_info.iPixelFormat);
     return 0;
   }
   else if(fmt->offscreenOnly)
@@ -1353,8 +1553,8 @@ int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
     return 1;
   }
 
-  TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
-  return physDev->current_pf;
+  TRACE("(%p): returns %d\n", physDev, physDev->wgl_info.iPixelFormat);
+  return physDev->wgl_info.iPixelFormat;
 }
 
 /**
@@ -1365,8 +1565,11 @@ int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
 			   int iPixelFormat,
 			   const PIXELFORMATDESCRIPTOR *ppfd) {
+  struct x11drv_wgl_data *wgl_info = &physDev->wgl_info;
+  struct wgl_surface_data surf_info;
   WineGLPixelFormat *fmt;
   int value;
+  HWND hwnd;
 
   TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
 
@@ -1389,7 +1592,31 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
     return 0;
   }
 
-  physDev->current_pf = iPixelFormat;
+    if(wgl_info->iPixelFormat) {
+        if(wgl_info->iPixelFormat == iPixelFormat)
+            return TRUE;
+        return 0;
+    }
+
+    hwnd = WindowFromDC(physDev->hdc);
+    surf_info.w = physDev->dc_rect.right - physDev->dc_rect.left;
+    surf_info.h = physDev->dc_rect.bottom - physDev->dc_rect.top;
+    surf_info.drawable = physDev->drawable;
+    surf_info.iPixelFormat = iPixelFormat;
+
+    /* Make sure we have a sane surface size */
+    if(surf_info.w <= 0) surf_info.w = 32;
+    if(surf_info.h <= 0) surf_info.h = 32;
+
+    if(!SendMessageW(hwnd, WM_X11DRV_CREATE_GL_SURFACE, 0, (LPARAM)&surf_info)) {
+        ERR("Couldn't create GL surface, returning failure\n");
+        return 0;
+    }
+
+    /* Make sure the physdev is up to date */
+    physDev->wgl_info.iPixelFormat = X11DRV_get_pixel_format(hwnd);
+    physDev->wgl_info.gl_surface = X11DRV_get_gl_surface(hwnd);
+    physDev->wgl_info.pixmap = X11DRV_get_gl_pixmap(hwnd);
 
   if (TRACE_ON(opengl)) {
     int gl_test = 0;
@@ -1422,6 +1649,8 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
       TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
     }
   }
+
+  TRACE("Set pixel format %d for physdev (%p)\n", wgl_info->iPixelFormat, physDev);
   return TRUE;
 }
 
@@ -1434,7 +1663,7 @@ HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev)
 {
     Wine_GLContext *ret;
     WineGLPixelFormat *fmt;
-    int hdcPF = physDev->current_pf;
+    int hdcPF = physDev->wgl_info.iPixelFormat;
     int fmt_count = 0;
     int value = 0;
     int gl_test = 0;
@@ -1586,53 +1815,6 @@ PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc)
     return NULL;
 }
 
-/***********************************************************************
- *		sync_current_drawable
- *
- * Adjust the current viewport and scissor in order to position
- * and size the current drawable correctly on the parent window.
- */
-static void sync_current_drawable(BOOL updatedc)
-{
-    int dy;
-    int width;
-    int height;
-    RECT rc;
-    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
-
-    TRACE("\n");
-
-    if (ctx && ctx->physDev)
-    {
-        if (updatedc)
-            GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */
-
-        dy = ctx->physDev->drawable_rect.bottom - ctx->physDev->drawable_rect.top -
-            ctx->physDev->dc_rect.bottom;
-        width = ctx->physDev->dc_rect.right - ctx->physDev->dc_rect.left;
-        height = ctx->physDev->dc_rect.bottom - ctx->physDev->dc_rect.top;
-
-        wine_tsx11_lock();
-
-        pglViewport(ctx->physDev->dc_rect.left + ctx->viewport.left,
-            dy + ctx->viewport.top,
-            ctx->viewport.right ? (ctx->viewport.right - ctx->viewport.left) : width,
-            ctx->viewport.bottom ? (ctx->viewport.bottom - ctx->viewport.top) : height);
-
-        pglEnable(GL_SCISSOR_TEST);
-
-        if (ctx->scissor_enabled)
-            pglScissor(ctx->physDev->dc_rect.left + min(width, max(0, ctx->scissor.left)),
-                dy + min(height, max(0, ctx->scissor.top)),
-                min(width, max(0, ctx->scissor.right - ctx->scissor.left)),
-                min(height, max(0, ctx->scissor.bottom - ctx->scissor.top)));
-        else
-            pglScissor(ctx->physDev->dc_rect.left, dy, width, height);
-
-        wine_tsx11_unlock();
-    }
-}
-
 /**
  * X11DRV_wglMakeCurrent
  *
@@ -1681,16 +1863,13 @@ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
         if(ret)
         {
             ctx->physDev = physDev;
+            ctx->new_drawable = 0;
 
             if (type == OBJ_MEMDC)
             {
                 ctx->do_escape = TRUE;
                 pglDrawBuffer(GL_FRONT_LEFT);
             }
-            else
-            {
-                sync_current_drawable(FALSE);
-            }
         }
     }
     wine_tsx11_unlock();
@@ -1728,6 +1907,7 @@ BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* hDrawDev, X11DRV_PDEVICE* h
             if (ctx->ctx == NULL) {
                 ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, GetObjectType(hDrawDev->hdc) == OBJ_MEMDC ? False : True);
                 TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
+                ctx->new_drawable = 0;
             }
             ret = pglXMakeContextCurrent(gdi_display, d_draw, d_read, ctx->ctx);
             NtCurrentTeb()->glContext = ctx;
@@ -1950,127 +2130,59 @@ BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count
      return TRUE;
 }
 
-static void WINAPI X11DRV_wglDisable(GLenum cap)
+static inline void update_drawable(X11DRV_PDEVICE *physDev)
 {
-    if (cap == GL_SCISSOR_TEST)
-    {
-       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+    Drawable src = physDev->wgl_info.pixmap ? physDev->wgl_info.pixmap :
+                                              physDev->wgl_info.gl_surface;
+    int w, h;
 
-       if (ctx)
-          ctx->scissor_enabled = FALSE;
-    }
-    else
-    {
-        wine_tsx11_lock();
-        pglDisable(cap);
-        wine_tsx11_unlock();
-    }
-}
+    if(!src)
+        return;
 
-static void WINAPI X11DRV_wglEnable(GLenum cap)
-{
-    if (cap == GL_SCISSOR_TEST)
-    {
-       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+    w = physDev->dc_rect.right - physDev->dc_rect.left;
+    h = physDev->dc_rect.bottom - physDev->dc_rect.top;
 
-       if (ctx)
-           ctx->scissor_enabled = TRUE;
-    }
-    else
-    {
-        wine_tsx11_lock();
-        pglEnable(cap);
-        wine_tsx11_unlock();
+    if(w > 0 && h > 0) {
+        XFlush(gdi_display);
+        XCopyArea(gdi_display, src, physDev->drawable, physDev->gc, 0, 0, w, h,
+                  physDev->dc_rect.left, physDev->dc_rect.top);
     }
 }
 
-/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
-static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
+static void WINAPI X11DRV_wglFlush()
 {
-    wine_tsx11_lock();
-    switch(pname)
-    {
-    case GL_DEPTH_BITS:
-        {
-            GLXContext gl_ctx = pglXGetCurrentContext();
-            Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
-
-            pglGetIntegerv(pname, params);
-            /**
-             * if we cannot find a Wine Context
-             * we only have the default wine desktop context,
-             * so if we have only a 24 depth say we have 32
-             */
-            if (NULL == ret && 24 == *params) {
-                *params = 32;
-            }
-            TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
-            break;
-        }
-    case GL_ALPHA_BITS:
-        {
-            GLXContext gl_ctx = pglXGetCurrentContext();
-            Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
+    Wine_GLContext *ctx = NtCurrentTeb()->glContext;
+    X11DRV_PDEVICE *physDev = ctx->physDev;
+    RECT rc;
 
-            pglXGetFBConfigAttrib(gdi_display, ret->fmt->fbconfig, GLX_ALPHA_SIZE, params);
-            TRACE("returns GL_ALPHA_BITS as '%d'\n", *params);
-            break;
-        }
-    default:
-        pglGetIntegerv(pname, params);
-        break;
-    }
-    wine_tsx11_unlock();
-}
+    TRACE("()\n");
 
-static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap)
-{
-    GLboolean enabled = False;
+    GetClipBox(physDev->hdc, &rc);
 
-    if (cap == GL_SCISSOR_TEST)
-    {
-       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+    wine_tsx11_lock();
+    sync_context(ctx);
+    pglFlush();
 
-       if (ctx)
-           enabled = ctx->scissor_enabled;
-    }
-    else
-    {
-        wine_tsx11_lock();
-        enabled = pglIsEnabled(cap);
-        wine_tsx11_unlock();
-    }
-    return enabled;
+    update_drawable(physDev);
+    wine_tsx11_unlock();
 }
 
-static void WINAPI X11DRV_wglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+static void WINAPI X11DRV_wglFinish()
 {
-    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+    Wine_GLContext *ctx = NtCurrentTeb()->glContext;
+    X11DRV_PDEVICE *physDev = ctx->physDev;
+    RECT rc;
 
-    if (ctx)
-    {
-        ctx->scissor.left = x;
-        ctx->scissor.top = y;
-        ctx->scissor.right = x + width;
-        ctx->scissor.bottom = y + height;
+    TRACE("()\n");
 
-        sync_current_drawable(TRUE);
-    }
-}
+    GetClipBox(physDev->hdc, &rc);
 
-static void WINAPI X11DRV_wglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
-
-    if (ctx)
-    {
-        ctx->viewport.left = x;
-        ctx->viewport.top = y;
-        ctx->viewport.right = x + width;
-        ctx->viewport.bottom = y + height;
+    wine_tsx11_lock();
+    sync_context(ctx);
+    pglFinish();
 
-        sync_current_drawable(TRUE);
-    }
+    update_drawable(physDev);
+    wine_tsx11_unlock();
 }
 
 /**
@@ -2342,7 +2454,7 @@ HDC X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *physDev, HPBUFFERARB hPbuffer)
 
     /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
      * All formats in our pixelformat list are compatible with each other and the main drawable. */
-    physDev->current_pf = object->fmt->iPixelFormat;
+    physDev->wgl_info.iPixelFormat = object->fmt->iPixelFormat;
     physDev->drawable = object->drawable;
     SetRect( &physDev->drawable_rect, 0, 0, object->width, object->height );
     physDev->dc_rect = physDev->drawable_rect;
@@ -3106,12 +3218,8 @@ static const WineGLExtension WGL_internal_functions =
 {
   "",
   {
-    { "wglDisable", X11DRV_wglDisable },
-    { "wglEnable", X11DRV_wglEnable },
-    { "wglGetIntegerv", X11DRV_wglGetIntegerv },
-    { "wglIsEnabled", X11DRV_wglIsEnabled },
-    { "wglScissor", X11DRV_wglScissor },
-    { "wglViewport", X11DRV_wglViewport },
+    { "wglFlush", X11DRV_wglFlush },
+    { "wglFinish", X11DRV_wglFinish },
   }
 };
 
@@ -3303,8 +3411,11 @@ Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
             ret = physDev->bitmap->glxpixmap;
         }
     }
+    else if(physDev->wgl_info.gl_surface)
+        ret = physDev->wgl_info.gl_surface;
     else
         ret = physDev->drawable;
+
     return ret;
 }
 
@@ -3316,6 +3427,87 @@ BOOL destroy_glxpixmap(XID glxpixmap)
     return TRUE;
 }
 
+BOOL update_gl_surface(struct x11drv_win_data *data)
+{
+    struct x11drv_wgl_data *wgl_info = &data->wgl_info;
+    int w, h, value;
+
+    if(!wgl_info->iPixelFormat || !wgl_info->gl_surface)
+        return TRUE;
+
+    wine_tsx11_lock();
+    pglXQueryDrawable(gdi_display, wgl_info->gl_surface, GLX_WIDTH, (unsigned int*)&w);
+    pglXQueryDrawable(gdi_display, wgl_info->gl_surface, GLX_HEIGHT, (unsigned int*)&h);
+
+    if(w != data->client_rect.right - data->client_rect.left ||
+       h != data->client_rect.bottom - data->client_rect.top)
+    {
+        WineGLPixelFormat *fmt;
+        XVisualInfo *vis;
+
+        w = data->client_rect.right - data->client_rect.left;
+        h = data->client_rect.bottom - data->client_rect.top;
+
+        if(w <= 0 || h <= 0) {
+            wine_tsx11_unlock();
+            TRACE("New surface size has negative or zero size; nothing to do\n");
+            return TRUE;
+        }
+
+        TRACE("Resizing GL surface to %dx%d\n", w, h);
+
+        fmt = ConvertPixelFormatWGLtoGLX(gdi_display, wgl_info->iPixelFormat,
+                                         FALSE /* Offscreen */, &value);
+        if(!fmt) {
+            wine_tsx11_unlock();
+            ERR("Invalid pixel format %d!\n", wgl_info->iPixelFormat);
+            return FALSE;
+        }
+
+        vis = pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig);
+        if(!vis) {
+            wine_tsx11_unlock();
+            ERR("No visual for fbconfig %#x!\n", (unsigned int)fmt->fbconfig);
+            return 0;
+        }
+
+        if(wgl_info->pixmap) {
+            GLXPixmap glxpixmap = wgl_info->gl_surface;
+            Pixmap pixmap = wgl_info->pixmap;
+            struct wgl_surface_data surf_info;
+            HWND hwnd;
+
+            hwnd = data->hwnd;
+            surf_info.w = data->client_rect.right - data->client_rect.left;
+            surf_info.h = data->client_rect.bottom - data->client_rect.top;
+            surf_info.drawable = root_window; /* should be alright? */
+            surf_info.iPixelFormat = wgl_info->iPixelFormat;
+
+            wine_tsx11_unlock();
+            if(!X11DRV_create_gl_surface(hwnd, (LPARAM)&surf_info)) {
+                wine_tsx11_lock();
+                XFree(vis);
+                wine_tsx11_unlock();
+                ERR("Couldn't create GL surface, returning failure\n");
+                return 0;
+            }
+            wine_tsx11_lock();
+
+            pglXDestroyGLXPixmap(gdi_display, glxpixmap);
+            XFreePixmap(gdi_display, pixmap);
+
+            mark_drawable_dirty(glxpixmap, wgl_info->gl_surface);
+        }
+        else
+            XMoveResizeWindow(gdi_display, wgl_info->gl_surface, -w, 0, w, h);
+
+        XFree(vis);
+        XFlush(gdi_display);
+    }
+    wine_tsx11_unlock();
+    return TRUE;
+}
+
 /**
  * X11DRV_SwapBuffers
  *
@@ -3331,10 +3523,36 @@ BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev)
   
   TRACE_(opengl)("(%p)\n", physDev);
 
-  drawable = get_glxdrawable(physDev);
-  wine_tsx11_lock();
-  pglXSwapBuffers(gdi_display, drawable);
-  wine_tsx11_unlock();
+  sync_context(NtCurrentTeb()->glContext);
+
+  if(physDev->wgl_info.gl_surface)
+  {
+      int w, h;
+
+      w = physDev->dc_rect.right - physDev->dc_rect.left;
+      h = physDev->dc_rect.bottom - physDev->dc_rect.top;
+
+      wine_tsx11_lock();
+
+      if(physDev->wgl_info.pixmap && pglXCopySubBufferMESA) {
+          pglFlush();
+          pglXCopySubBufferMESA(gdi_display, physDev->wgl_info.gl_surface,
+                                0, 0, w, h);
+      }
+      else
+          pglXSwapBuffers(gdi_display, physDev->wgl_info.gl_surface);
+
+      update_drawable(physDev);
+
+      wine_tsx11_unlock();
+  }
+  else
+  {
+      drawable = get_glxdrawable(physDev);
+      wine_tsx11_lock();
+      pglXSwapBuffers(gdi_display, drawable);
+      wine_tsx11_unlock();
+  }
 
   /* FPS support */
   if (TRACE_ON(fps))
@@ -3397,6 +3615,20 @@ XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
 
 #else  /* no OpenGL includes */
 
+LRESULT X11DRV_create_gl_surface(HWND hwnd, LPARAM lp)
+{
+  ERR("No OpenGL support compiled in.\n");
+
+  return 0;
+}
+
+BOOL update_gl_surface(struct x11drv_win_data *data)
+{
+  ERR("No OpenGL support compiled in.\n");
+
+  return TRUE;
+}
+
 /***********************************************************************
  *		ChoosePixelFormat (X11DRV.@)
  */
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 030989b..b29d038 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -55,6 +55,9 @@ static XContext win_data_context;
 
 static const char whole_window_prop[] = "__wine_x11_whole_window";
 static const char icon_window_prop[]  = "__wine_x11_icon_window";
+static const char pixel_format_prop[] = "__wine_x11_pixel_format";
+static const char gl_surface_prop[]   = "__wine_x11_gl_surface";
+static const char gl_pixmap_prop[]    = "__wine_x11_gl_pixmap";
 static const char managed_prop[]      = "__wine_x11_managed";
 static const char visual_id_prop[]    = "__wine_x11_visual_id";
 
@@ -702,6 +705,7 @@ void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data
     data->client_rect = *new_client_rect;
     OffsetRect( &data->client_rect, -data->whole_rect.left, -data->whole_rect.top );
 
+    update_gl_surface(data);
     if (!data->whole_window || data->lock_changes) return;
 
     mask = get_window_changes( &changes, &old_whole_rect, &data->whole_rect );
@@ -901,6 +905,35 @@ void X11DRV_DestroyWindow( HWND hwnd )
     if (!(data = X11DRV_get_win_data( hwnd ))) return;
 
     free_window_dce( data );
+
+    if (data->wgl_info.pixmap)
+    {
+        if (data->wgl_info.gl_surface)
+            destroy_glxpixmap(data->wgl_info.gl_surface);
+        data->wgl_info.gl_surface = 0;
+
+        wine_tsx11_lock();
+        XFreePixmap(gdi_display, data->wgl_info.pixmap);
+        data->wgl_info.pixmap = 0;
+    }
+    else
+    {
+        wine_tsx11_lock();
+        if (data->wgl_info.gl_surface)
+            XDestroyWindow(gdi_display, data->wgl_info.gl_surface);
+        data->wgl_info.gl_surface = 0;
+    }
+    XFlush(gdi_display);
+
+    XDeleteContext( display, (XID)data->wgl_info.iPixelFormat, winContext );
+    XDeleteContext( display, (XID)data->wgl_info.gl_surface, winContext );
+    XDeleteContext( display, (XID)data->wgl_info.pixmap, winContext );
+    wine_tsx11_unlock();
+
+    RemovePropA( data->hwnd, pixel_format_prop );
+    RemovePropA( data->hwnd, gl_surface_prop );
+    RemovePropA( data->hwnd, gl_pixmap_prop );
+
     destroy_whole_window( display, data );
     destroy_icon_window( display, data );
 
@@ -930,6 +963,9 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
         data->lock_changes  = 0;
         data->hWMIconBitmap = 0;
         data->hWMIconMask   = 0;
+        data->wgl_info.iPixelFormat = 0;
+        data->wgl_info.pixmap = 0;
+        data->wgl_info.gl_surface = 0;
 
         wine_tsx11_lock();
         if (!winContext) winContext = XUniqueContext();
@@ -1051,6 +1087,15 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
         get_desktop_xwin( display, data );
     }
 
+    wine_tsx11_lock();
+    XSaveContext( display, (XID)data->wgl_info.iPixelFormat, winContext, (char *)hwnd );
+    XSaveContext( display, (XID)data->wgl_info.gl_surface, winContext, (char *)hwnd );
+    XSaveContext( display, (XID)data->wgl_info.pixmap, winContext, (char *)hwnd );
+    wine_tsx11_unlock();
+    SetPropA( hwnd, pixel_format_prop, (HANDLE)data->wgl_info.iPixelFormat );
+    SetPropA( hwnd, gl_surface_prop, (HANDLE)data->wgl_info.gl_surface );
+    SetPropA( hwnd, gl_pixmap_prop, (HANDLE)data->wgl_info.pixmap );
+
     /* get class or window DC if needed */
     alloc_window_dce( data );
 
@@ -1214,6 +1259,30 @@ Window X11DRV_get_whole_window( HWND hwnd )
 }
 
 
+int X11DRV_get_pixel_format( HWND hwnd )
+{
+    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+
+    if (!data) return (int)GetPropA( hwnd, pixel_format_prop );
+    return data->wgl_info.iPixelFormat;
+}
+
+Drawable X11DRV_get_gl_surface( HWND hwnd )
+{
+    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+
+    if (!data) return (Drawable)GetPropA( hwnd, gl_surface_prop );
+    return data->wgl_info.gl_surface;
+}
+
+Pixmap X11DRV_get_gl_pixmap( HWND hwnd )
+{
+    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+
+    if (!data) return (Pixmap)GetPropA( hwnd, gl_pixmap_prop );
+    return data->wgl_info.pixmap;
+}
+
 /***********************************************************************
  *		X11DRV_get_ic
  *
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 8594e20..6741aeb 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -66,6 +66,7 @@ typedef int Status;
 
 struct tagCURSORICONINFO;
 struct dce;
+struct x11drv_win_data;
 
 extern void wine_tsx11_lock(void);
 extern void wine_tsx11_unlock(void);
@@ -119,6 +120,14 @@ typedef UINT	 X_PHYSFONT;
 
 typedef struct tagXRENDERINFO *XRENDERINFO;
 
+struct x11drv_wgl_data {
+    /* This is needed for rendering GL to an offscreen surface, which can
+     * be composited to a drawable */
+    int      iPixelFormat;
+    Drawable gl_surface;
+    Pixmap   pixmap;
+};
+
   /* X physical device */
 typedef struct
 {
@@ -138,7 +147,7 @@ typedef struct
     int           depth;       /* bit depth of the DC */
     int           exposures;   /* count of graphics exposures operations */
     struct dce   *dce;         /* opaque pointer to DCE */
-    int           current_pf;
+    struct x11drv_wgl_data wgl_info;
     XRENDERINFO   xrender;
 } X11DRV_PDEVICE;
 
@@ -273,6 +282,7 @@ extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
 extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display);
 extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev);
 extern BOOL destroy_glxpixmap(XID glxpixmap);
+extern BOOL update_gl_surface(struct x11drv_win_data *data);
 
 /* XIM support */
 extern XIC X11DRV_CreateIC(XIM xim, Display *display, Window win);
@@ -485,6 +495,7 @@ struct x11drv_escape_set_drawable
     int                      mode;         /* ClipByChildren or IncludeInferiors */
     RECT                     dc_rect;      /* DC rectangle relative to drawable */
     RECT                     drawable_rect;/* Drawable rectangle relative to screen */
+    struct x11drv_wgl_data   wgl_info;
 };
 
 struct x11drv_escape_set_dce
@@ -537,6 +548,7 @@ extern int private_color_map;
 extern int primary_monitor;
 extern int copy_default_colors;
 extern int alloc_system_colors;
+extern int composite_gl;
 extern int xrender_error_base;
 
 extern BYTE key_state_table[256];
@@ -633,7 +645,8 @@ extern DWORD EVENT_x11_time_to_win32_time(Time time);
 enum x11drv_window_messages
 {
     WM_X11DRV_ACQUIRE_SELECTION = 0x80001000,
-    WM_X11DRV_DELETE_WINDOW
+    WM_X11DRV_DELETE_WINDOW,
+    WM_X11DRV_CREATE_GL_SURFACE
 };
 
 /* x11drv private window data */
@@ -645,6 +658,7 @@ struct x11drv_win_data
     RECT        window_rect;    /* USER window rectangle relative to parent */
     RECT        whole_rect;     /* X window rectangle for the whole window relative to parent */
     RECT        client_rect;    /* client area relative to whole window */
+    struct x11drv_wgl_data wgl_info;
     XIC         xic;            /* X input context */
     XWMHints   *wm_hints;       /* window manager hints */
     BOOL        managed;        /* is window managed? */
@@ -656,8 +670,12 @@ struct x11drv_win_data
 
 extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
 extern Window X11DRV_get_whole_window( HWND hwnd );
+extern int X11DRV_get_pixel_format( HWND hwnd );
+extern Drawable X11DRV_get_gl_surface( HWND hwnd );
+extern Pixmap X11DRV_get_gl_pixmap( HWND hwnd );
 extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
 extern XIC X11DRV_get_ic( HWND hwnd );
+extern LRESULT X11DRV_create_gl_surface( HWND hwnd, LPARAM lp );
 
 extern void alloc_window_dce( struct x11drv_win_data *data );
 extern void free_window_dce( struct x11drv_win_data *data );
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index ac3bb24..ae271d0 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -86,6 +86,7 @@ int client_side_antialias_with_core = 1;
 int client_side_antialias_with_render = 1;
 int copy_default_colors = 128;
 int alloc_system_colors = 256;
+int composite_gl = 1;
 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
 int xrender_error_base = 0;
 
@@ -365,6 +366,9 @@ static void setup_options(void)
     if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
         alloc_system_colors = atoi(buffer);
 
+    if (!get_config_key( hkey, appkey, "CompositeGL", buffer, sizeof(buffer) ))
+        composite_gl = IS_OPTION_TRUE( buffer[0] );
+
     get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
 
     if (appkey) RegCloseKey( appkey );
diff --git a/include/config.h.in b/include/config.h.in
index a1c7b29..5b74673 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -909,6 +909,9 @@
 /* Define to 1 if you have the <X11/extensions/Xrender.h> header file. */
 #undef HAVE_X11_EXTENSIONS_XRENDER_H
 
+/* Define to 1 if you have the <X11/extensions/Xcomposite.h> header file. */
+#undef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
+
 /* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
 #undef HAVE_X11_EXTENSIONS_XSHM_H
 
@@ -1038,6 +1041,9 @@
 /* Define to the soname of the libXrender library. */
 #undef SONAME_LIBXRENDER
 
+/* Define to the soname of the libXcomposite library. */
+#undef SONAME_LIBXCOMPOSITE
+
 /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
 #undef STAT_MACROS_BROKEN
 
