[PATCH] Add wglCopyContext support to WGL.

Roderick Colenbrander thunderbird2k at gmx.net
Sun Nov 11 14:32:12 CST 2007


---
 dlls/gdi32/gdi32.spec             |    1 +
 dlls/gdi32/gdi_private.h          |    1 +
 dlls/gdi32/opengl.c               |   25 +++++++++++++++++++++
 dlls/opengl32/make_opengl         |    2 +-
 dlls/opengl32/opengl32.spec       |    2 +-
 dlls/opengl32/wgl.c               |   11 ---------
 dlls/winex11.drv/opengl.c         |   44 +++++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/winex11.drv.spec |    1 +
 8 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index b0c8e12..025dd25 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -498,6 +498,7 @@
 ################################################################
 # Wine extensions: OpenGL support
 #
+@ stdcall wglCopyContext(long long long)
 @ stdcall wglCreateContext(long)
 @ stdcall wglDeleteContext(long)
 @ stdcall wglGetCurrentContext()
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 3bba769..3e49642 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -223,6 +223,7 @@ typedef struct tagDC_FUNCS
     BOOL     (*pWidenPath)(PHYSDEV);
 
     /* OpenGL32 */
+    BOOL     (*pwglCopyContext)(HGLRC, HGLRC, UINT);
     HGLRC    (*pwglCreateContext)(PHYSDEV);
     BOOL     (*pwglDeleteContext)(HGLRC);
     PROC     (*pwglGetProcAddress)(LPCSTR);
diff --git a/dlls/gdi32/opengl.c b/dlls/gdi32/opengl.c
index aebf17a..f948cda 100644
--- a/dlls/gdi32/opengl.c
+++ b/dlls/gdi32/opengl.c
@@ -60,6 +60,31 @@ static DC* OPENGL_GetDefaultDC(void)
 }
 
 /***********************************************************************
+ *		wglCopyContext (OPENGL32.@)
+ */
+BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
+{
+    DC *dc;
+    BOOL ret = FALSE;
+    OPENGL_Context ctx = (OPENGL_Context)hglrcSrc;
+
+    TRACE("hglrcSrc: (%p), hglrcDst: (%p), mask: %#x\n", hglrcSrc, hglrcDst, mask);
+    /* If no context is set, this call doesn't have a purpose */
+    if(!hglrcSrc || !hglrcDst)
+        return FALSE;
+
+    /* Retrieve the HDC associated with the context to access the display driver */
+    dc = get_dc_ptr(ctx->hdc);
+    if (!dc) return FALSE;
+
+    if (!dc->funcs->pwglCopyContext) FIXME(" :stub\n");
+    else ret = dc->funcs->pwglCopyContext(hglrcSrc, hglrcDst, mask);
+
+    release_dc_ptr( dc );
+    return ret;
+}
+
+/***********************************************************************
  *		wglCreateContext (OPENGL32.@)
  */
 HGLRC WINAPI wglCreateContext(HDC hdc)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl
index f473cf7..824dd1c 100755
--- a/dlls/opengl32/make_opengl
+++ b/dlls/opengl32/make_opengl
@@ -616,7 +616,7 @@ foreach (sort keys %norm_functions) {
 print SPEC "@  stub    glGetLevelParameterfv
 @  stub    glGetLevelParameteriv
 @  stdcall wglChoosePixelFormat(long ptr) gdi32.ChoosePixelFormat
-@  stdcall wglCopyContext(long long long)
+@  stdcall wglCopyContext(long long long) gdi32.wglCopyContext
 @  stdcall wglCreateContext(long) gdi32.wglCreateContext
 @  stdcall wglCreateLayerContext(long long)
 @  stdcall wglDeleteContext(long) gdi32.wglDeleteContext
diff --git a/dlls/opengl32/opengl32.spec b/dlls/opengl32/opengl32.spec
index 8b7b28a..762fb5e 100644
--- a/dlls/opengl32/opengl32.spec
+++ b/dlls/opengl32/opengl32.spec
@@ -375,7 +375,7 @@
 @  stdcall glVertexPointer( long long long ptr ) wine_glVertexPointer
 @  stdcall glViewport( long long long long ) wine_glViewport
 @  stdcall wglChoosePixelFormat(long ptr) gdi32.ChoosePixelFormat
-@  stdcall wglCopyContext(long long long)
+@  stdcall wglCopyContext(long long long) gdi32.wglCopyContext
 @  stdcall wglCreateContext(long) gdi32.wglCreateContext
 @  stdcall wglCreateLayerContext(long long)
 @  stdcall wglDeleteContext(long) gdi32.wglDeleteContext
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index ec91cfe..d157488 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -121,17 +121,6 @@ HGLRC WINAPI wglCreateLayerContext(HDC hdc,
 }
 
 /***********************************************************************
- *		wglCopyContext (OPENGL32.@)
- */
-BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
-			   HGLRC hglrcDst,
-			   UINT mask) {
-  FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask);
-
-  return FALSE;
-}
-
-/***********************************************************************
  *		wglDescribeLayerPlane (OPENGL32.@)
  */
 BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index c510a3b..1e24b32 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -211,6 +211,7 @@ static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
 /* GLX 1.0 */
 MAKE_FUNCPTR(glXChooseVisual)
+MAKE_FUNCPTR(glXCopyContext)
 MAKE_FUNCPTR(glXCreateContext)
 MAKE_FUNCPTR(glXCreateGLXPixmap)
 MAKE_FUNCPTR(glXGetCurrentContext)
@@ -379,6 +380,7 @@ static BOOL has_opengl(void)
 #define LOAD_FUNCPTR(f) if((p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f)) == NULL) goto sym_not_found;
 /* GLX 1.0 */
 LOAD_FUNCPTR(glXChooseVisual)
+LOAD_FUNCPTR(glXCopyContext)
 LOAD_FUNCPTR(glXCreateContext)
 LOAD_FUNCPTR(glXCreateGLXPixmap)
 LOAD_FUNCPTR(glXGetCurrentContext)
@@ -1508,6 +1510,38 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
 }
 
 /**
+ * X11DRV_wglCopyContext
+ *
+ * For OpenGL32 wglCopyContext.
+ */
+BOOL X11DRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) {
+    Wine_GLContext *src = (Wine_GLContext*)hglrcSrc;
+    Wine_GLContext *dst = (Wine_GLContext*)hglrcDst;
+
+    TRACE("hglrcSrc: (%p), hglrcDst: (%p), mask: %#x\n", hglrcSrc, hglrcDst, mask);
+
+    /* There is a slight difference in the way GL contexts share display lists in WGL and GLX.
+     * In case of GLX you need to specify this at context creation time but in case of WGL you
+     * do this using wglShareLists which you can call after creating the context.
+     * To emulate WGL we try to delay the creation of the context until wglShareLists or wglMakeCurrent.
+     * Upto now that works fine.
+     *
+     * The delayed GLX context creation could cause issues for wglCopyContext as it might get called
+     * when there is no GLX context yet. Warn the user about it and let him report a bug report.
+     * The chance this will cause problems is small as at the time of writing Wine has had OpenGL support
+     * for more than 7 years and this function has remained a stub ever since then.
+     */
+    if(!src->ctx || !dst->ctx) {
+        WARN("No source or destination context available! This could indicate a Wine bug.");
+        return FALSE;
+    }
+    pglXCopyContext(gdi_display, src->ctx, dst->ctx, mask);
+
+    /* As opposed to wglCopyContext, glXCopyContext doesn't return anything, so hopefully we passed */
+    return TRUE;
+}
+
+/**
  * X11DRV_wglCreateContext
  *
  * For OpenGL32 wglCreateContext.
@@ -3457,6 +3491,16 @@ BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
 }
 
 /**
+ * X11DRV_wglCopyContext
+ *
+ * For OpenGL32 wglCopyContext.
+ */
+BOOL X11DRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+    return FALSE;
+}
+
+/**
  * X11DRV_wglCreateContext
  *
  * For OpenGL32 wglCreateContext.
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 05c7f72..87db841 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -132,6 +132,7 @@
 @ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
 
 # OpenGL
+@ cdecl wglCopyContext(long long long) X11DRV_wglCopyContext
 @ cdecl wglCreateContext(ptr) X11DRV_wglCreateContext
 @ cdecl wglDeleteContext(long) X11DRV_wglDeleteContext
 @ cdecl wglGetProcAddress(str) X11DRV_wglGetProcAddress
-- 
1.5.2.4


--========GMX181161194817104759323--



More information about the wine-patches mailing list