Some fixes for dumb X errors :-)

Alexandre Julliard julliard at winehq.com
Mon Jan 21 14:52:22 CST 2002


Lionel Ulmer <lionel.ulmer at free.fr> writes:

> PS for Alexandre: we once discussed how we could 'streamline' this X error
>    handling (ie to prevent doing the same kind of code at three different
>    locations in the Wine code). Did you progress on this issue or not ?

Yes, here's what I came up with. Basically you have to wrap the call
that might fail with X11DRV_expect_error/X11DRV_check_error. Would
this work for what you need to do?

Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /opt/cvs-commit/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.47
diff -u -r1.47 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	2001/11/30 23:15:32	1.47
+++ dlls/x11drv/x11drv_main.c	2002/01/21 18:58:48
@@ -63,6 +63,12 @@
 static char *desktop_geometry;
 static XVisualInfo *desktop_vi;
 
+static x11drv_error_callback err_callback;   /* current callback for error */
+static Display *err_callback_display;        /* display callback is set for */
+static void *err_callback_arg;               /* error callback argument */
+static int err_callback_result;              /* error callback result */
+static int (*old_error_handler)( Display *, XErrorEvent * );
+
 #define IS_OPTION_TRUE(ch) \
     ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
 #define IS_OPTION_FALSE(ch) \
@@ -97,12 +103,57 @@
 }
 #endif /* NO_REENTRANT_X11 */
 
+
+/***********************************************************************
+ *		X11DRV_expect_error
+ *
+ * Setup a callback function that will be called on an X error.  The
+ * callback must return non-zero if the error is the one it expected.
+ * This function acquires the x11 lock; X11DRV_check_error must be
+ * called in all cases to release it.
+ */
+void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
+{
+    wine_tsx11_lock();
+    XSync( display, False );
+    err_callback         = callback;
+    err_callback_display = display;
+    err_callback_arg     = arg;
+    err_callback_result  = 0;
+}
+
+
+/***********************************************************************
+ *		X11DRV_check_error
+ *
+ * Check if an expected X11 error occurred; return non-zero if yes.
+ * Also release the x11 lock obtained in X11DRV_expect_error.
+ */
+int X11DRV_check_error(void)
+{
+    int ret = err_callback_result;
+    XSync( err_callback_display, False );
+    err_callback = NULL;
+    wine_tsx11_unlock();
+    return ret;
+}
+
+
 /***********************************************************************
  *		error_handler
  */
-static int error_handler(Display *display, XErrorEvent *error_evt)
+static int error_handler( Display *display, XErrorEvent *error_evt )
 {
-    DebugBreak();  /* force an entry in the debugger */
+    if (err_callback && display == err_callback_display)
+    {
+        if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
+        {
+            TRACE( "got expected error\n" );
+            return 0;
+        }
+    }
+    if (synchronous) DebugBreak();  /* force an entry in the debugger */
+    old_error_handler( display, error_evt );
     return 0;
 }
 
@@ -297,6 +348,7 @@
     screen = DefaultScreenOfDisplay( display );
     visual = DefaultVisual( display, DefaultScreen(display) );
     root_window = DefaultRootWindow( display );
+    old_error_handler = XSetErrorHandler( error_handler );
 
     /* Initialize screen depth */
 
@@ -328,11 +380,7 @@
      */
     TSXOpenIM( display, NULL, NULL, NULL);
 
-    if (synchronous)
-    {
-        XSetErrorHandler( error_handler );
-        XSynchronize( display, True );
-    }
+    if (synchronous) XSynchronize( display, True );
 
     screen_width  = WidthOfScreen( screen );
     screen_height = HeightOfScreen( screen );
Index: include/x11drv.h
===================================================================
RCS file: /opt/cvs-commit/wine/include/x11drv.h,v
retrieving revision 1.95
diff -u -r1.95 x11drv.h
--- include/x11drv.h	2002/01/04 18:27:45	1.95
+++ include/x11drv.h	2002/01/21 18:59:08
@@ -391,7 +391,9 @@
 extern void X11DRV_SetFocus( HWND hwnd );
 extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
 
-extern void X11DRV_expect_error( unsigned char request, unsigned char error, XID id );
+typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void *arg );
+
+extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg );
 extern int X11DRV_check_error(void);
 extern void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data );
 extern void X11DRV_set_iconic_state( WND *win );


-- 
Alexandre Julliard
julliard at winehq.com




More information about the wine-devel mailing list