diff options
Diffstat (limited to 'src/nativewindow')
3 files changed, 122 insertions, 31 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index b6a052253..bf37b8d0c 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -37,8 +37,10 @@ import java.io.File; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import jogamp.nativewindow.Debug; @@ -108,7 +110,9 @@ public abstract class NativeWindowFactory { private static boolean requiresToolkitLock; private static boolean desktopHasThreadingIssues; + // Shutdown hook mechanism for the factory private static volatile boolean isJVMShuttingDown = false; + private static final List<Runnable> customShutdownHooks = new ArrayList<Runnable>(); /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -160,6 +164,11 @@ public abstract class NativeWindowFactory { Platform.initSingleton(); // last resort .. _DEBUG[0] = Debug.debug("NativeWindow"); _tmp[0] = Debug.getProperty("nativewindow.ws.name", true); + Runtime.getRuntime().addShutdownHook( + new Thread(new Runnable() { + public void run() { + NativeWindowFactory.shutdown(true); + } }, "NativeWindowFactory_ShutdownHook" ) ) ; return null; } } ) ; @@ -204,6 +213,72 @@ public abstract class NativeWindowFactory { } } + /** Returns true if the JVM is shutting down, otherwise false. */ + public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; } + + /** + * Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory instance. + * + * @param head if true add runnable at the start, otherwise at the end + * @param runnable runnable to be added. + */ + public static void addCustomShutdownHook(boolean head, Runnable runnable) { + synchronized( customShutdownHooks ) { + if( !customShutdownHooks.contains( runnable ) ) { + if( head ) { + customShutdownHooks.add(0, runnable); + } else { + customShutdownHooks.add( runnable ); + } + } + } + } + + /** + * Cleanup resources at JVM shutdown + */ + public static synchronized void shutdown(boolean _isJVMShuttingDown) { + isJVMShuttingDown = _isJVMShuttingDown; + if(DEBUG) { + System.err.println("NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown+", on thread "+Thread.currentThread().getName()); + } + synchronized(customShutdownHooks) { + final int cshCount = customShutdownHooks.size(); + for(int i=0; i < cshCount; i++) { + try { + if( DEBUG ) { + System.err.println("NativeWindowFactory.shutdown - customShutdownHook #"+(i+1)+"/"+cshCount); + } + customShutdownHooks.get(i).run(); + } catch(Throwable t) { + System.err.println("NativeWindowFactory.shutdown: Catched "+t.getClass().getName()+" during customShutdownHook #"+(i+1)+"/"+cshCount); + if( DEBUG ) { + t.printStackTrace(); + } + } + } + customShutdownHooks.clear(); + } + if(DEBUG) { + System.err.println("NativeWindowFactory.shutdown(): Post customShutdownHook"); + } + + if(initialized) { + initialized = false; + if(null != registeredFactories) { + registeredFactories.clear(); + registeredFactories = null; + } + GraphicsConfigurationFactory.shutdown(); + } + + shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown + // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); + } + } + private static void shutdownNativeImpl(final ClassLoader cl) { final String clazzName; if( TYPE_X11 == nativeWindowingTypePure ) { @@ -310,29 +385,6 @@ public abstract class NativeWindowFactory { } } - public static synchronized void shutdown(boolean _isJVMShuttingDown) { - isJVMShuttingDown = _isJVMShuttingDown; - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown); - } - if(initialized) { - initialized = false; - if(null != registeredFactories) { - registeredFactories.clear(); - registeredFactories = null; - } - GraphicsConfigurationFactory.shutdown(); - } - shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown - // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); - } - } - - /** Returns true if the JVM is shutting down, otherwise false. */ - public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; } - /** @return true if the underlying toolkit requires locking, otherwise false. */ public static boolean requiresToolkitLock() { return requiresToolkitLock; diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java index d77cd75ef..2524f107a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java +++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java @@ -27,6 +27,7 @@ */ package jogamp.nativewindow.awt; +import java.awt.FocusTraversalPolicy; import java.awt.Window; import java.awt.Component; import java.awt.Container; @@ -68,6 +69,44 @@ public class AWTMisc { return (Container) c; } + public static Component getNextFocus(Component comp) { + Container focusContainer = comp.getFocusCycleRootAncestor(); + while ( focusContainer != null && + ( !focusContainer.isShowing() || !focusContainer.isFocusable() || !focusContainer.isEnabled() ) ) + { + comp = focusContainer; + focusContainer = comp.getFocusCycleRootAncestor(); + } + Component next = null; + if (focusContainer != null) { + final FocusTraversalPolicy policy = focusContainer.getFocusTraversalPolicy(); + next = policy.getComponentAfter(focusContainer, comp); + if (next == null) { + next = policy.getDefaultComponent(focusContainer); + } + } + return next; + } + + public static Component getPrevFocus(Component comp) { + Container focusContainer = comp.getFocusCycleRootAncestor(); + while ( focusContainer != null && + ( !focusContainer.isShowing() || !focusContainer.isFocusable() || !focusContainer.isEnabled() ) ) + { + comp = focusContainer; + focusContainer = comp.getFocusCycleRootAncestor(); + } + Component prev = null; + if (focusContainer != null) { + final FocusTraversalPolicy policy = focusContainer.getFocusTraversalPolicy(); + prev = policy.getComponentBefore(focusContainer, comp); + if (prev == null) { + prev = policy.getDefaultComponent(focusContainer); + } + } + return prev; + } + /** * Issue this when your non AWT toolkit gains focus to clear AWT menu path */ diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 2d9c42e09..bbc58b73a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -98,10 +98,10 @@ public class X11Util implements ToolkitProperties { private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true); private static String nullDisplayName = null; private static volatile boolean isInit = false; - private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues + private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues, or GLRendererQuirks.DontCloseX11Display private static boolean hasThreadingIssues = false; // ATI/AMD X11 driver issues - private static Object setX11ErrorHandlerLock = new Object(); + private static final Object setX11ErrorHandlerLock = new Object(); private static final String X11_EXTENSION_ATIFGLRXDRI = "ATIFGLRXDRI"; private static final String X11_EXTENSION_ATIFGLEXTENSION = "ATIFGLEXTENSION"; @@ -207,12 +207,12 @@ public class X11Util implements ToolkitProperties { } } - synchronized(globalLock) { - // Only at JVM shutdown time, since AWT impl. seems to - // dislike closing of X11 Display's (w/ ATI driver). - if( isJVMShuttingDown ) { - isInit = false; - closePendingDisplayConnections(); + // Only at JVM shutdown time, since AWT impl. seems to + // dislike closing of X11 Display's (w/ ATI driver). + if( isJVMShuttingDown ) { + synchronized(globalLock) { + isInit = false; + closePendingDisplayConnections(); openDisplayList.clear(); reusableDisplayList.clear(); pendingDisplayList.clear(); |