All these patches are required to fix Cladun X2 crash at start.
-- v2: winex11.drv: Don't compare error event serial if it's zero. winex11.drv: Lock display when expecting error events. winex11.drv: Handle X errors from glXCopyContext().
From: Zhiyi Zhang zzhang@codeweavers.com
glxCopyContext() may throw X errors and cause the current process to exit. For example, Mesa doesn't support glxCopyContext() for direct rendering contexts and ends up using the code path for indirect rendering contexts. When Xorg receives such requests, it rejects them because they're for direct rendering contexts and reports an X error. We also can't use indirect rendering context because it needs to be explicitly enabled in xorg.conf and has poor performance. So handle this error before graphics drivers implement the support.
Fix Cladun X2 crash at start.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winex11.drv/opengl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 8d6afba9a6f..7ceaeb7c2df 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1711,9 +1711,21 @@ static BOOL WINAPI glxdrv_wglCopyContext(struct wgl_context *src, struct wgl_con { TRACE("%p -> %p mask %#x\n", src, dst, mask);
- pglXCopyContext(gdi_display, src->ctx, dst->ctx, mask); + X11DRV_expect_error( gdi_display, GLXErrorHandler, NULL ); + pglXCopyContext( gdi_display, src->ctx, dst->ctx, mask ); + XSync( gdi_display, False ); + if (X11DRV_check_error()) + { + static unsigned int once; + + if (!once++) + { + ERR("glXCopyContext failed. glXCopyContext() for direct rendering contexts not " + "implemented in the host graphics driver?\n"); + } + return FALSE; + }
- /* As opposed to wglCopyContext, glXCopyContext doesn't return anything, so hopefully we passed */ return TRUE; }
From: Zhiyi Zhang zzhang@codeweavers.com
If the display is not locked, another thread could take the error event and handle it with the default error handlers and thus not handled by the current thread with the specified error handlers.
Fix Cladun X2 crash at start.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winex11.drv/x11drv_main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index cd2ea87190a..4fe450237d3 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -273,6 +273,7 @@ static inline BOOL ignore_error( Display *display, XErrorEvent *event ) void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg ) { pthread_mutex_lock( &error_mutex ); + XLockDisplay( display ); err_callback = callback; err_callback_display = display; err_callback_arg = arg; @@ -291,6 +292,7 @@ int X11DRV_check_error(void) { int res = err_callback_result; err_callback = NULL; + XUnlockDisplay( err_callback_display ); pthread_mutex_unlock( &error_mutex ); return res; }
This merge request was approved by Alexandre Julliard.
From: Zhiyi Zhang zzhang@codeweavers.com
Sometimes error event serial is zero. For example, NVIDIA driver may send X_GLXCopyContext errors with the event serial set to zero. When it's zero, previously the error handler passes the error to the default error handler and cause application crashes.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winex11.drv/x11drv_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 4fe450237d3..44d4763b316 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -304,7 +304,7 @@ int X11DRV_check_error(void) static int error_handler( Display *display, XErrorEvent *error_evt ) { if (err_callback && display == err_callback_display && - (long)(error_evt->serial - err_serial) >= 0) + (!error_evt->serial || error_evt->serial >= err_serial)) { if ((err_callback_result = err_callback( display, error_evt, err_callback_arg ))) {