diff options
author | Sven Gothel <[email protected]> | 2010-10-14 21:26:43 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-10-14 21:26:43 +0200 |
commit | 774138544e1eec3330309ad682fa05154a07ab8d (patch) | |
tree | a9d612e98f1d16390763f54ab1888ff66f081a22 /src/nativewindow/classes/javax | |
parent | d7faeb8b96f5aba76967096006af4c420d964fef (diff) |
JOGL: Reenable Applet/Webstart/RCP support for JOGL + AWT + X11
Changed GLProfile/NativeWindowFactory/.. initialization methodology:
GLProfile:
public static synchronized void initSingleton(final boolean firstUIActionOnProcess);
NativeWindowFactory:
public static synchronized void initSingleton(final boolean firstUIActionOnProcess);
+++
Introducing NativeWindow ToolkitLock, implementations are
NullToolkitLock
JAWTToolkitLock
X11JAWTToolkitLock
X11ToolkitLock
AbstractGraphicsDevice provides generic global toolkit locking methods,
implemented by the ToolkitLock interface.
ToolkitLock's are aggregated in NativeWindow's DefaultGraphicsDevice
to implement it's superclass lock()/unlock() methods.
This enables a device specific locking strategy, ie on X11/AWT utilizing
JAWT && X11 locking, and maybe none for others (NEWT).
No locking is required for X11 / AWT, in case the above mentioned
initialization happened as a 'firstUIActionOnProcess'.
The ToolkitLock factory is currently a hardcoded part of NativeWindowFactory.
We may have to allow 3rd party NativeWindow implementations
to register custom ones.
+++
com.jogamp.opengl.impl.GLDrawableImpl cleanup:
Dealing with all locking code, providing all public methods. Exceptions are commented.
Specializations x11/windows/.. only contains platform code.
Pulled down access qualifiers if possible public -> protected.
com.jogamp.nativewindow.impl.x11.X11Util
Wrapping all X11Lib method with the new locking code.
com.jogamp.nativewindow.impl.jawt.JAWTUtil
Utilize global SunToolkit.awtLock() is available,
the fallback to global JAWT.lock().
The latter just invokes the first.
javax.media.nativewindow.awt.AWTGraphicsDevice
setHandle(long handle) -> setSubType(String type, long handle)
which also resets the ToolkitLock respecting the new type.
This ensures correct locking after the sub type has been determined,
ie AWT using an X11 peer.
+++
Misc Changes done on the way ..
GLCanvas:
Fixed inversed this.drawableHelper.isExternalAnimatorAnimating() condition,
which disabled normal repaint.
GLJPanel:
Removed drawableHelper.isExternalAnimatorAnimating() condition,
which disabled painting, since the animation thread just updates the source image.
NEWT WindowImpl:
When reparenting back to parent and 'refit' child if it's size exceeds it's parent.
More 'Fix: Memory consumption' commit 6ced17f0325d5719e992b246ffd156e5b39694b4.
NEWTEvent:
Removed code to evaluate the 'system event' attribute, need to find a better approach.
Diffstat (limited to 'src/nativewindow/classes/javax')
9 files changed, 385 insertions, 78 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index c133df5b4..b003db8f5 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -56,7 +57,15 @@ public interface AbstractGraphicsDevice extends Cloneable { */ public long getHandle(); + /** + * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ public void lock(); + /** + * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ public void unlock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index e18b7b2dc..ca0f106f5 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -32,18 +32,46 @@ package javax.media.nativewindow; +import com.jogamp.nativewindow.impl.NativeWindowFactoryImpl; + public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice { private String type; protected long handle; + protected ToolkitLock toolkitLock; + /** + * Create an instance with the system default {@link ToolkitLock}, + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + */ public DefaultGraphicsDevice(String type) { this.type = type; this.handle = 0; + setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) ); } + /** + * Create an instance with the system default {@link ToolkitLock}. + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + * @param handle + */ public DefaultGraphicsDevice(String type, long handle) { this.type = type; this.handle = handle; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) ); + } + + /** + * Create an instance with the given {@link ToolkitLock} instance. + * @param type + * @param handle + * @param locker + */ + public DefaultGraphicsDevice(String type, long handle, ToolkitLock locker) { + this.type = type; + this.handle = handle; + setToolkitLock( locker ); } public Object clone() { @@ -62,10 +90,46 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice return handle; } - public void lock() { + /** + * Set the internal ToolkitLock, which is used within the + * {@link #lock()} and {@link #unlock()} implementation. + * + * @param locker the ToolkitLock, if null, {@link com.jogamp.nativewindow.impl.NullToolkitLock} is being used + */ + protected void setToolkitLock(ToolkitLock locker) { + this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ; + } + + /** + * @return the used ToolkitLock + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final ToolkitLock getToolkitLock() { + return toolkitLock; + } + + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void lock() { + toolkitLock.lock(); } - public void unlock() { + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void unlock() { + toolkitLock.unlock(); } public String toString() { diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index 0a1a91876..75c8aea22 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -78,7 +78,7 @@ public abstract class GraphicsConfigurationFactory { if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) { try { GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory) - ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", new Object[] {}, + ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", null, GraphicsConfigurationFactory.class.getClassLoader()); registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory); } catch (Exception e) { @@ -198,9 +198,29 @@ public abstract class GraphicsConfigurationFactory { * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) * @see javax.media.nativewindow.DefaultGraphicsConfiguration#setChosenCapabilities(Capabilities caps) */ - public abstract AbstractGraphicsConfiguration + public final AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) + throws IllegalArgumentException, NativeWindowException { + if(null==screen) { + throw new NativeWindowException("Screen is null"); + } + AbstractGraphicsDevice device = screen.getDevice(); + if(null==device) { + throw new NativeWindowException("Screen's Device is null"); + } + device.lock(); + try { + return chooseGraphicsConfigurationImpl(capabilities, chooser, screen); + } finally { + device.unlock(); + } + } + + protected abstract AbstractGraphicsConfiguration + chooseGraphicsConfigurationImpl(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen screen) throws IllegalArgumentException, NativeWindowException; } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java index ef45a79d3..a5b71fbf8 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java @@ -1,6 +1,5 @@ /** * Copyright 2010 JogAmp Community. All rights reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -63,14 +62,17 @@ public interface NativeSurface extends SurfaceUpdatedListener { * This call allows recursion from the same thread.<P> * * The implementation may want to aquire the - * application level {@link com.jogamp.common.util.RecursiveToolkitLock} + * application level {@link com.jogamp.common.util.locks.RecursiveLock} * first before proceeding with a native surface lock. <P> * + * The implementation shall also invoke {@link AbstractGraphicsDevice#lock()} + * for the initial lock (recursive count zero).<P> + * * @return {@link #LOCK_SUCCESS}, {@link #LOCK_SURFACE_CHANGED} or {@link #LOCK_SURFACE_NOT_READY}. * * @throws RuntimeException after timeout when waiting for the surface lock * - * @see com.jogamp.common.util.RecursiveToolkitLock + * @see com.jogamp.common.util.locks.RecursiveLock */ public int lockSurface(); @@ -79,10 +81,13 @@ public interface NativeSurface extends SurfaceUpdatedListener { * * Shall not modify the surface handle, see {@link #lockSurface()} <P> * + * The implementation shall also invoke {@link AbstractGraphicsDevice#unlock()} + * for the final unlock (recursive count zero).<P> + * * @throws RuntimeException if surface is not locked * * @see #lockSurface - * @see com.jogamp.common.util.RecursiveToolkitLock + * @see com.jogamp.common.util.locks.RecursiveLock */ public void unlockSurface() throws NativeWindowException ; @@ -102,14 +107,6 @@ public interface NativeSurface extends SurfaceUpdatedListener { public Thread getSurfaceLockOwner(); /** - * Return the lock-exception, or null if not locked. - * - * The lock-exception is created at {@link #lockSurface()} - * and hence holds the locker's call stack. - */ - public Exception getSurfaceLockStack(); - - /** * Provide a mechanism to utilize custom (pre-) swap surface * code. This method is called before the render toolkit (e.g. JOGL) * swaps the buffer/surface. The implementation may itself apply the swapping, diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index f716e8ac9..7897460a0 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,13 +33,14 @@ package javax.media.nativewindow; -import java.lang.reflect.*; import java.security.*; import java.util.*; import com.jogamp.common.util.*; import com.jogamp.common.jvm.JVMUtil; import com.jogamp.nativewindow.impl.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; /** Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the {@link NativeWindow} interface, @@ -74,9 +76,20 @@ public abstract class NativeWindowFactory { private static String nativeOSNamePure; private static String nativeWindowingTypeCustom; private static String nativeOSNameCustom; - private static final boolean isAWTAvailable; + private static boolean isAWTAvailable; public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String JAWTUtilClassName = "com.jogamp.nativewindow.impl.jawt.JAWTUtil" ; public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; + public static final String X11JAWTToolkitLockClassName = "com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock" ; + public static final String X11ToolkitLockClassName = "com.jogamp.nativewindow.impl.x11.X11ToolkitLock" ; + private static Class jawtUtilClass; + private static Method jawtUtilGetJAWTToolkitMethod; + private static Method jawtUtilInitMethod; + private static Class x11JAWTToolkitLockClass; + private static Constructor x11JAWTToolkitLockConstructor; + private static Class x11ToolkitLockClass; + private static Constructor x11ToolkitLockConstructor; + private static boolean isFirstUIActionOnProcess; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -100,54 +113,117 @@ public abstract class NativeWindowFactory { static { JVMUtil.initSingleton(); + } - // Gather the windowing OS first - AccessControlContext acc = AccessController.getContext(); - nativeOSNamePure = Debug.getProperty("os.name", false, acc); - nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase()); - nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc); - if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) { - nativeOSNameCustom = nativeOSNamePure; - nativeWindowingTypeCustom = nativeWindowingTypePure; - } else { - nativeWindowingTypeCustom = nativeOSNameCustom; - } - - ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + static boolean initialized = false; + + /** + * Static one time initialization of this factory.<br> + * This initialization method <b>must be called</b> once by the program or utilizing modules!<br> + * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, + * otherwise <code>false</code>. + */ + public static synchronized void initSingleton(final boolean firstUIActionOnProcess) { + if(!initialized) { + initialized = true; + + if(DEBUG) { + Throwable td = new Throwable("Info: NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); + td.printStackTrace(); + } - if( TYPE_X11.equals(nativeWindowingTypePure) ) { - ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { }, cl ); - } + // Gather the windowing OS first + AccessControlContext acc = AccessController.getContext(); + nativeOSNamePure = Debug.getProperty("os.name", false, acc); + nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase()); + nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc); + if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) { + nativeOSNameCustom = nativeOSNamePure; + nativeWindowingTypeCustom = nativeWindowingTypePure; + } else { + nativeWindowingTypeCustom = nativeOSNameCustom; + } - registeredFactories = Collections.synchronizedMap(new HashMap()); + ClassLoader cl = NativeWindowFactory.class.getClassLoader(); - String factoryClassName = null; + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + // explicit initialization of X11Util + ReflectionUtil.callStaticMethod(X11UtilClassName, "initSingleton", + new Class[] { boolean.class }, + new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + } + isFirstUIActionOnProcess = firstUIActionOnProcess; + + if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && + ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && + ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ) { + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader()); + jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", null); + jawtUtilInitMethod.setAccessible(true); + jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{}); + jawtUtilGetJAWTToolkitMethod.setAccessible(true); + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + if(null != jawtUtilClass && null != jawtUtilGetJAWTToolkitMethod && null != jawtUtilInitMethod) { + ReflectionUtil.callMethod(null, jawtUtilInitMethod, null); + + Object resO = ReflectionUtil.callStaticMethod(JAWTUtilClassName, "isHeadlessMode", null, null, cl ); + if(resO instanceof Boolean) { + // AWT is only available in case all above classes are available + // and AWT is not int headless mode + isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE); + } else { + isAWTAvailable = false; + } + } else { + isAWTAvailable = false; + } + } else { + isAWTAvailable = false; + } - // register our default factory -> NativeWindow - NativeWindowFactory factory = new NativeWindowFactoryImpl(); - nativeWindowClass = javax.media.nativewindow.NativeWindow.class; - registerFactory(nativeWindowClass, factory); - defaultFactory = factory; - - // We break compile-time dependencies on the AWT here to - // make it easier to run this code on mobile devices - isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && - ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && - ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ; - - if ( isAWTAvailable ) { - // register either our default factory or (if exist) the X11/AWT one -> AWT Component - registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory); - } + registeredFactories = Collections.synchronizedMap(new HashMap()); + + // register our default factory -> NativeWindow + NativeWindowFactory factory = new NativeWindowFactoryImpl(); + nativeWindowClass = javax.media.nativewindow.NativeWindow.class; + registerFactory(nativeWindowClass, factory); + defaultFactory = factory; + + if ( isAWTAvailable ) { + // register either our default factory or (if exist) the X11/AWT one -> AWT Component + registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory); + } - if(DEBUG) { - System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+ - ", defaultFactory "+factory); + if( TYPE_X11 == nativeWindowingTypePure ) { + // passing through RuntimeException if not exists intended + x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl); + x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } ); + if( isAWTAvailable() ) { + x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl); + x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } ); + } + } + + if(DEBUG) { + System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory); + } } } - public static void initSingleton() { - // just exist to ensure static init has been run + /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, + otherwise false. */ + public static boolean isFirstUIActionOnProcess() { + return isFirstUIActionOnProcess; } /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ @@ -171,6 +247,91 @@ public abstract class NativeWindowFactory { return defaultFactory; } + /** + * Provides the system default {@link ToolkitLock}, a singleton instance. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} + * in case of a <b>X11 system</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock getDefaultToolkitLock() { + return getDefaultToolkitLock(getNativeWindowType(false)); + } + + /** + * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} + * in case of a <b>X11 type</b> or <b>AWT type / X11 system</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock getDefaultToolkitLock(String type) { + if( isAWTAvailable() && !isFirstUIActionOnProcess() && + ( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) ) { + return getAWTToolkitLock(); + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock getAWTToolkitLock() { + Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod, null); + + if(resO instanceof ToolkitLock) { + return (ToolkitLock) resO; + } else { + throw new RuntimeException("JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock"); + } + } + + public static ToolkitLock getNullToolkitLock() { + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + /** + * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock} + * in case of a <b>X11 type</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * or a {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock} + * in case of a <b>X11 type</b> <em>and</em> <b>no AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); + } + if( !isFirstUIActionOnProcess() ) { + if( isAWTAvailable() ) { + return createX11AWTToolkitLock(deviceHandle); + } else { + return createX11ToolkitLock(deviceHandle); + } + } + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected static ToolkitLock createX11ToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + /** Returns the appropriate NativeWindowFactory to handle window objects of the given type. The windowClass might be {@link NativeWindow NativeWindow}, in which case the client has diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java new file mode 100644 index 000000000..09c89ebe3 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java @@ -0,0 +1,45 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +import com.jogamp.nativewindow.impl.Debug; +import java.security.AccessController; + +/** + * Marker for a singleton global recursive blocking lock implementation, + * optionally locking a native windowing toolkit as well. + * <br> + * One use case is the AWT locking on X11, see {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock}. + */ +public interface ToolkitLock { + public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.TraceLock", true, AccessController.getContext()); + + public void lock(); + public void unlock(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java index d326b9159..e91261211 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java @@ -43,17 +43,18 @@ import javax.media.nativewindow.*; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import javax.media.nativewindow.AbstractGraphicsDevice; -import com.jogamp.nativewindow.impl.*; /** A wrapper for an AWT GraphicsDevice allowing it to be handled in a toolkit-independent manner. */ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { private GraphicsDevice device; + private String subType; protected AWTGraphicsDevice(GraphicsDevice device) { super(NativeWindowFactory.TYPE_AWT); this.device = device; + this.subType = null; } public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice) { @@ -73,14 +74,23 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl /** * In case the native handle was specified, e.g. using X11, - * we shall be able to mark it. + * we shall be able to mark it.<br> + * This will also set the subType, queried with {@link #getSubType()} + * and reset the ToolkitLock type with {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)} + * and {@link #setToolkitLock(javax.media.nativewindow.ToolkitLock)}. */ - public void setHandle(long handle) { + public void setSubType(String subType, long handle) { this.handle = handle; + this.subType = subType; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) ); + } + + public String getSubType() { + return subType; } public String toString() { - return getClass().toString()+"[type "+getType()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; + return getClass().toString()+"[type "+getType()+"[subType "+getSubType()+"], awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java index 192abf775..31744702d 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -33,14 +33,14 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; -import com.jogamp.nativewindow.impl.*; -import com.jogamp.nativewindow.impl.x11.X11Util; /** Encapsulates a graphics device on X11 platforms. */ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable { - /** Constructs a new X11GraphicsDevice corresponding to the given native display handle. */ + /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default + * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}. + */ public X11GraphicsDevice(long display) { super(NativeWindowFactory.TYPE_X11, display); if(0==display) { @@ -48,17 +48,19 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl } } - public Object clone() { - return super.clone(); - } - - public void lock() { - X11Util.XLockDisplay(handle); + /** + * @param display the Display connection + * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT + */ + public X11GraphicsDevice(long display, ToolkitLock locker) { + super(NativeWindowFactory.TYPE_X11, display, locker); + if(0==display) { + throw new NativeWindowException("null display"); + } } - public void unlock() { - X11Util.XUnlockDisplay(handle); + public Object clone() { + return super.clone(); } - } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java index 97bdc37cf..73af5f852 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -34,7 +34,6 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; import com.jogamp.nativewindow.impl.x11.X11Util; -import com.jogamp.nativewindow.impl.x11.X11Lib; /** Encapsulates a screen index on X11 platforms. Objects of this type are passed to {@link @@ -57,21 +56,21 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl /** Creates a new X11GraphicsScreen using a thread local display connection */ public static AbstractGraphicsScreen createDefault() { long display = X11Util.createThreadLocalDisplay(null); - int scrnIdx = X11Lib.DefaultScreen(display); + int scrnIdx = X11Util.DefaultScreen(display); return createScreenDevice(display, scrnIdx); } public long getDefaultVisualID() { // It still could be an AWT hold handle .. long display = getDevice().getHandle(); - int scrnIdx = X11Lib.DefaultScreen(display); - return X11Lib.DefaultVisualID(display, scrnIdx); + int scrnIdx = X11Util.DefaultScreen(display); + return X11Util.DefaultVisualID(display, scrnIdx); } private static int fetchScreen(X11GraphicsDevice device, int screen) { // It still could be an AWT hold handle .. long display = device.getHandle(); - if(X11Lib.XineramaEnabled(display)) { + if(X11Util.XineramaEnabled(display)) { screen = 0; // Xinerama -> 1 screen } return screen; |