winex11.drv: Correctly position and clip opengl child windows.
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl
index 657617a..1f4de68 100755
--- a/dlls/opengl32/make_opengl
+++ b/dlls/opengl32/make_opengl
@@ -266,6 +266,21 @@
     if ( $func_ref->[0] eq "glGetIntegerv" ) {
 	$wine_func_ref_name = "internal_glGetIntegerv";
     }
+    if ( $func_ref->[0] eq "glEnable" ) {
+	$wine_func_ref_name = "internal_glEnable";
+    }
+    if ( $func_ref->[0] eq "glIsEnabled" ) {
+	$wine_func_ref_name = "internal_glIsEnabled";
+    }
+    if ( $func_ref->[0] eq "glDisable" ) {
+	$wine_func_ref_name = "internal_glDisable";
+    }
+    if ( $func_ref->[0] eq "glScissor" ) {
+	$wine_func_ref_name = "internal_glScissor";
+    }
+    if ( $func_ref->[0] eq "glViewport" ) {
+	$wine_func_ref_name = "internal_glViewport";
+    }
     $ret = "$ret$prefix$wine_func_ref_name( $call_arg);\n";
     if ($thread_safe) {
 	$ret = "$ret  LEAVE_GL();\n";
diff --git a/dlls/opengl32/opengl_ext.h b/dlls/opengl32/opengl_ext.h
index 580df22..d700187 100644
--- a/dlls/opengl32/opengl_ext.h
+++ b/dlls/opengl32/opengl_ext.h
@@ -64,5 +64,10 @@
 
 const GLubyte* internal_glGetString(GLenum name);
 void internal_glGetIntegerv(GLenum pname, GLint* params);
+void internal_glDisable(GLenum cap);
+void internal_glEnable(GLenum cap);
+GLboolean internal_glIsEnabled(GLenum cap);
+void internal_glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void internal_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
 
 #endif /* __DLLS_OPENGL32_OPENGL_EXT_H */
diff --git a/dlls/opengl32/opengl_norm.c b/dlls/opengl32/opengl_norm.c
index 8374a86..047770f 100644
--- a/dlls/opengl32/opengl_norm.c
+++ b/dlls/opengl32/opengl_norm.c
@@ -815,7 +815,7 @@
 void WINAPI wine_glDisable( GLenum cap ) {
   TRACE("(%d)\n", cap );
   ENTER_GL();
-  glDisable( cap );
+  internal_glDisable( cap );
   LEAVE_GL();
 }
 
@@ -915,7 +915,7 @@
 void WINAPI wine_glEnable( GLenum cap ) {
   TRACE("(%d)\n", cap );
   ENTER_GL();
-  glEnable( cap );
+  internal_glEnable( cap );
   LEAVE_GL();
 }
 
@@ -1772,7 +1772,7 @@
   GLboolean ret_value;
   TRACE("(%d)\n", cap );
   ENTER_GL();
-  ret_value = glIsEnabled( cap );
+  ret_value = internal_glIsEnabled( cap );
   LEAVE_GL();
   return ret_value;
 }
@@ -2889,7 +2889,7 @@
 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 );
+  internal_glScissor( x, y, width, height );
   LEAVE_GL();
 }
 
@@ -3759,6 +3759,6 @@
 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 );
+  internal_glViewport( x, y, width, height );
   LEAVE_GL();
 }
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 1191850..51cc71c 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -49,7 +49,12 @@
 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);
 } wine_wgl_t;
 
 /** global wgl object */
@@ -86,8 +91,7 @@
   GLXFBConfig fb_conf;
   GLXContext ctx;
   BOOL do_escape;
-  struct wine_glcontext *next;
-  struct wine_glcontext *prev;
+  /* ... more stuff here */
 } Wine_GLContext;
 
 void enter_gl(void)
@@ -557,9 +561,34 @@
     return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE);
 }
 
+void internal_glEnable(GLenum cap)
+{
+  wine_wgl.p_wglEnable(cap);
+}
+
+GLboolean internal_glIsEnabled(GLenum cap)
+{
+    return wine_wgl.p_wglIsEnabled(cap);
+}
+
+void internal_glDisable(GLenum cap)
+{
+    wine_wgl.p_wglDisable(cap);
+}
+
+void internal_glScissor( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+    wine_wgl.p_wglScissor(x, y, width, height);
+}
+
+void internal_glViewport( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+    wine_wgl.p_wglViewport(x, y, width, height);
+}
+
 const GLubyte * internal_glGetString(GLenum name) {
   const char* GL_Extensions = NULL;
-  
+
   if (GL_EXTENSIONS != name) {
     return glGetString(name);
   }
@@ -641,7 +670,12 @@
   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");
 
   internal_gl_disabled_extensions[0] = 0;
   if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey)) {
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 3b67c79..927abfc 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -74,6 +74,10 @@
     GLXFBConfig fb_conf;
     GLXContext ctx;
     BOOL do_escape;
+    X11DRV_PDEVICE *physDev;
+    RECT viewport;
+    RECT scissor;
+    BOOL scissor_enabled;
     struct wine_glcontext *next;
     struct wine_glcontext *prev;
 } Wine_GLContext;
@@ -253,13 +257,18 @@
 MAKE_FUNCPTR(glBitmap)
 MAKE_FUNCPTR(glCopyTexSubImage1D)
 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(glScissor)
+MAKE_FUNCPTR(glViewport)
 #undef MAKE_FUNCPTR
 
 static BOOL X11DRV_WineGL_InitOpenglInfo(void)
@@ -377,15 +386,20 @@
 /* Standard OpenGL calls */
 LOAD_FUNCPTR(glBindTexture)
 LOAD_FUNCPTR(glBitmap)
-LOAD_FUNCPTR(glEndList)
 LOAD_FUNCPTR(glCopyTexSubImage1D)
 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(glScissor)
+LOAD_FUNCPTR(glViewport)
 #undef LOAD_FUNCPTR
 
 /* It doesn't matter if these fail. They'll only be used if the driver reports
@@ -539,7 +553,7 @@
 {
     Wine_GLContext *ret;
     for (ret = context_list; ret; ret = ret->next) {
-        if (d == get_drawable( ret->hdc )) {
+        if (d == ret->physDev->drawable) {
             return ret->hdc;
         }
     }
@@ -1318,6 +1332,7 @@
     ret = alloc_context();
     wine_tsx11_unlock();
     ret->hdc = hdc;
+    ret->physDev = physDev;
     ret->display = gdi_display;
     ret->fb_conf = cur_cfg;
     /*ret->vis = vis;*/
@@ -1424,6 +1439,47 @@
     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(void)
+{
+    int dy;
+    int width;
+    int height;
+    RECT rc;
+    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+
+    TRACE("\n");
+
+    if (ctx && ctx->physDev)
+    {
+        GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */
+
+        dy = ctx->physDev->drawable_rect.bottom - 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;
+
+        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);
+
+    }
+}
 
 /**
  * X11DRV_wglMakeCurrent
@@ -1466,10 +1522,19 @@
         TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
         ret = pglXMakeCurrent(ctx->display, drawable, ctx->ctx);
         NtCurrentTeb()->glContext = ctx;
-        if(ret && type == OBJ_MEMDC)
+        if(ret)
         {
-            ctx->do_escape = TRUE;
-            pglDrawBuffer(GL_FRONT_LEFT);
+            ctx->physDev = physDev;
+
+            if (type == OBJ_MEMDC)
+            {
+                ctx->do_escape = TRUE;
+                pglDrawBuffer(GL_FRONT_LEFT);
+            }
+            else
+            {
+                sync_current_drawable();
+            }
         }
     }
     wine_tsx11_unlock();
@@ -1541,7 +1606,7 @@
         if (org->ctx == NULL) {
             wine_tsx11_lock();
             describeContext(org);
-            org->ctx = pglXCreateContext(org->display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
+            org->ctx = pglXCreateContext(org->display, org->vis, NULL, GetObjectType(org->physDev->hdc) == OBJ_MEMDC ? False : True);
             wine_tsx11_unlock();
             TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
         }
@@ -1549,7 +1614,7 @@
             wine_tsx11_lock();
             describeContext(dest);
             /* Create the destination context with display lists shared */
-            dest->ctx = pglXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
+            dest->ctx = pglXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->physDev->hdc) == OBJ_MEMDC ? False : True);
             wine_tsx11_unlock();
             TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
             return TRUE;
@@ -1722,7 +1787,33 @@
      return TRUE;
 }
 
-/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ 
+static void WINAPI X11DRV_wglDisable(GLenum cap)
+{
+    if (cap == GL_SCISSOR_TEST)
+    {
+       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+       ctx->scissor_enabled = FALSE;
+    }
+    else
+    {
+       pglDisable(cap);
+    }
+}
+
+static void WINAPI X11DRV_wglEnable(GLenum cap)
+{
+    if (cap == GL_SCISSOR_TEST)
+    {
+       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+       ctx->scissor_enabled = TRUE;
+    }
+    else
+    {
+       pglEnable(cap);
+    }
+}
+
+/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
 static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
     TRACE("pname: 0x%x, params: %p\n", pname, params);
     if (pname == GL_DEPTH_BITS) { 
@@ -1749,6 +1840,47 @@
     }
 }
 
+static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap)
+{
+    GLboolean enabled;
+
+    if (cap == GL_SCISSOR_TEST)
+    {
+       Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+       enabled = ctx->scissor_enabled;
+    }
+    else
+    {
+       enabled = pglIsEnabled(cap);
+    }
+
+    return enabled;
+}
+
+static void WINAPI X11DRV_wglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+
+    ctx->scissor.left = x;
+    ctx->scissor.top = y;
+    ctx->scissor.right = x + width;
+    ctx->scissor.bottom = y + height;
+
+    sync_current_drawable();
+}
+
+static void WINAPI X11DRV_wglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
+
+    ctx->viewport.left = x;
+    ctx->viewport.top = y;
+    ctx->viewport.right = x + width;
+    ctx->viewport.bottom = y + height;
+
+    sync_current_drawable();
+}
+
 /**
  * X11DRV_wglGetExtensionsStringARB
  *
@@ -2673,7 +2805,12 @@
 {
   "",
   {
+    { "wglDisable", X11DRV_wglDisable },
+    { "wglEnable", X11DRV_wglEnable },
     { "wglGetIntegerv", X11DRV_wglGetIntegerv },
+    { "wglIsEnabled", X11DRV_wglIsEnabled },
+    { "wglScissor", X11DRV_wglScissor },
+    { "wglViewport", X11DRV_wglViewport },
   }
 };