diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index b0c8e12f2a4..025dd25fef6 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 3bba76999bb..3e4964233eb 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 aebf17ada83..f948cda04b5 100644 --- a/dlls/gdi32/opengl.c +++ b/dlls/gdi32/opengl.c @@ -59,6 +59,31 @@ static DC* OPENGL_GetDefaultDC(void) return get_dc_ptr(default_hdc); } +/*********************************************************************** + * 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.@) */ diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index f473cf71931..824dd1c2611 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 8b7b28a020c..762fb5ed997 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 ec91cfe9dfd..d1574885935 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -120,17 +120,6 @@ HGLRC WINAPI wglCreateLayerContext(HDC hdc, return NULL; } -/*********************************************************************** - * wglCopyContext (OPENGL32.@) - */ -BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, - HGLRC hglrcDst, - UINT mask) { - FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask); - - return FALSE; -} - /*********************************************************************** * wglDescribeLayerPlane (OPENGL32.@) */ diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index c510a3b17b5..ed085ba6717 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) @@ -1507,6 +1509,38 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev, return TRUE; } +/** + * 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) { + FIXME("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 * @@ -3456,6 +3490,16 @@ BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) { return FALSE; } +/** + * 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 * diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 05c7f72b9f1..87db8412d16 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