jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
changeset 2802 d05a9dcc8296
parent 2660 3c98e01dcbcf
child 2803 e0fa1a27f1c1
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed May 06 20:06:23 2009 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Fri May 15 15:40:35 2009 +0400
@@ -149,63 +149,78 @@
             setBackingStoreType();
         }
         m_removeSourceEvents = SunToolkit.getMethod(EventQueue.class, "removeSourceEvents", new Class[] {Object.class, Boolean.TYPE}) ;
+
+        noisyAwtHandler = AccessController.doPrivileged(new GetBooleanAction("sun.awt.noisyerrorhandler"));
+    }
+
+    //---- ERROR HANDLER CODE ----//
+
+    /*
+     * Error handler at the moment of XToolkit initialization
+     */
+    private static long saved_error_handler;
+
+    /*
+     * XErrorEvent being handled
+     */
+    static volatile XErrorEvent saved_error;
+
+    /*
+     * Current error handler or null if no error handler is set
+     */
+    private static XErrorHandler current_error_handler;
+
+    /*
+     * Value of sun.awt.noisyerrorhandler system property
+     */
+    private static boolean noisyAwtHandler;
+
+    public static void WITH_XERROR_HANDLER(XErrorHandler handler) {
+        saved_error = null;
+        current_error_handler = handler;
     }
 
-    // Error handler stuff
-    static XErrorEvent saved_error;
-    static long saved_error_handler;
-    static XErrorHandler curErrorHandler;
-    // Should be called under LOCK, before releasing LOCK RESTORE_XERROR_HANDLER should be called
-    static void WITH_XERROR_HANDLER(XErrorHandler handler) {
-        saved_error = null;
-        curErrorHandler = handler;
-        XSync();
-        saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
+    public static void RESTORE_XERROR_HANDLER() {
+        current_error_handler = null;
     }
-    static void XERROR_SAVE(XErrorEvent event) {
-        saved_error = event;
-    }
+
     // Should be called under LOCK
-    static void RESTORE_XERROR_HANDLER() {
-       XSync();
-        XlibWrapper.XSetErrorHandler(saved_error_handler);
-        curErrorHandler = null;
-    }
-    // Should be called under LOCK
-    static int SAVED_ERROR_HANDLER(long display, XErrorEvent error) {
-        return XlibWrapper.CallErrorHandler(saved_error_handler, display, error.pData);
+    public static int SAVED_ERROR_HANDLER(long display, XErrorEvent error) {
+        if (saved_error_handler != 0) {
+            // Default XErrorHandler may just terminate the process. Don't call it.
+            // return XlibWrapper.CallErrorHandler(saved_error_handler, display, error.pData);
+        }
+        if (log.isLoggable(Level.FINE)) {
+            log.log(Level.FINE, "Unhandled XErrorEvent: " +
+                    "id=" + error.get_resourceid() + ", " +
+                    "serial=" + error.get_serial() + ", " +
+                    "ec=" + error.get_error_code() + ", " +
+                    "rc=" + error.get_request_code() + ", " +
+                    "mc=" + error.get_minor_code());
+        }
+        return 0;
     }
-    interface XErrorHandler {
-        int handleError(long display, XErrorEvent err);
-    }
-    static int GlobalErrorHandler(long display, long event_ptr) {
+
+    // Called from the native code when an error occurs
+    private static int globalErrorHandler(long display, long event_ptr) {
+        if (noisyAwtHandler) {
+            XlibWrapper.PrintXErrorEvent(display, event_ptr);
+        }
         XErrorEvent event = new XErrorEvent(event_ptr);
+        saved_error = event;
         try {
-            if (curErrorHandler != null) {
-                return curErrorHandler.handleError(display, event);
+            if (current_error_handler != null) {
+                return current_error_handler.handleError(display, event);
             } else {
                 return SAVED_ERROR_HANDLER(display, event);
             }
-        } finally {
+        } catch (Throwable z) {
+            log.log(Level.FINE, "Error in GlobalErrorHandler", z);
         }
+        return 0;
     }
 
-/*
- * Instead of validating window id, we simply call XGetWindowProperty,
- * but temporary install this function as the error handler to ignore
- * BadWindow error.
- */
-    static XErrorHandler IgnoreBadWindowHandler = new XErrorHandler() {
-            public int handleError(long display, XErrorEvent err) {
-                XERROR_SAVE(err);
-                if (err.get_error_code() == XConstants.BadWindow) {
-                    return 0;
-                } else {
-                    return SAVED_ERROR_HANDLER(display, err);
-                }
-            }
-        };
-
+    //---- END OF ERROR HANDLER CODE ----//
 
     private native static void initIDs();
     native static void waitForEvents(long nextTaskTime);
@@ -302,25 +317,34 @@
             areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
             //set system property if not yet assigned
             System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
+
+            saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
         } finally {
             awtUnlock();
         }
 
         Runtime.getRuntime().addShutdownHook(new Thread() {
-                public void run() {
-                    XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
-                    if (peer != null) {
-                        peer.dispose();
-                    }
-                    if (xs != null) {
-                        ((XAWTXSettings)xs).dispose();
-                    }
-                    freeXKB();
-                    if (log.isLoggable(Level.FINE)) {
-                        dumpPeers();
-                    }
+            public void run() {
+                XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
+                if (peer != null) {
+                    peer.dispose();
+                }
+                if (xs != null) {
+                    ((XAWTXSettings)xs).dispose();
                 }
-            });
+                freeXKB();
+                if (log.isLoggable(Level.FINE)) {
+                    dumpPeers();
+                }
+
+                awtLock();
+                try {
+                    XlibWrapper.XSetErrorHandler(saved_error_handler);
+                } finally {
+                    awtUnlock();
+                }
+            }
+        });
     }
 
     static String getCorrectXIDString(String val) {
@@ -2409,8 +2433,6 @@
         return new XDesktopPeer();
     }
 
-    public static native void setNoisyXErrorHandler();
-
     public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
         return areExtraMouseButtonsEnabled;
     }