aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/classes/jogamp')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java19
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java85
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java8
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java10
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java82
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java300
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java232
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java36
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java24
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java56
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java71
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java17
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java101
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java45
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java23
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java406
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java185
23 files changed, 1244 insertions, 549 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
new file mode 100644
index 000000000..ee3ab73ba
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2011 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 jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsConfiguration;
+
+public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
+ public MutableGraphicsConfiguration(AbstractGraphicsScreen screen,
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ }
+
+ public void setChosenCapabilities(CapabilitiesImmutable caps) {
+ super.setChosenCapabilities(caps);
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
index 2b6d3c016..4cf8f448e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
@@ -33,6 +33,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import com.jogamp.common.jvm.JNILibLoaderBase;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.cache.TempJarCache;
public class NWJNILibLoader extends JNILibLoaderBase {
@@ -40,9 +41,10 @@ public class NWJNILibLoader extends JNILibLoaderBase {
public static void loadNativeWindow(final String ossuffix) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
+ Platform.initSingleton();
final String libName = "nativewindow_"+ossuffix ;
if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) {
- addNativeJarLibs(NWJNILibLoader.class, "jogl.all", "jogl-all", new String[] { "nativewindow" } );
+ addNativeJarLibs(NWJNILibLoader.class, "jogl-all", new String[] { "nativewindow" } );
}
loadLibrary(libName, false);
return null;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index d34d4e58f..223078ebf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -32,11 +32,15 @@
package jogamp.nativewindow;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.*;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
-import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
@@ -44,13 +48,10 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
public static ToolkitLock getNullToolkitLock() {
return nullToolkitLock;
}
-
+
// This subclass of NativeWindowFactory handles the case of
// NativeWindows being passed in
protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException {
- if (null == winObj) {
- throw new IllegalArgumentException("winObj is null");
- }
if (winObj instanceof NativeWindow) {
// Use the NativeWindow directly
return (NativeWindow) winObj;
@@ -69,7 +70,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
"javax.media.nativewindow.NativeWindow or "+AWTComponentClassName);
}
- private Constructor nativeWindowConstructor = null;
+ private Constructor<?> nativeWindowConstructor = null;
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
new file mode 100644
index 000000000..4877d5c4f
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -0,0 +1,85 @@
+/**
+ * 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 jogamp.nativewindow;
+
+import java.util.ArrayList;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+
+public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
+ private Object surfaceUpdatedListenersLock = new Object();
+ private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
+
+ //
+ // Management Utils
+ //
+ public int size() { return surfaceUpdatedListeners.size(); }
+ public SurfaceUpdatedListener get(int i) { return surfaceUpdatedListeners.get(i); }
+
+ //
+ // Implementation of NativeSurface SurfaceUpdatedListener methods
+ //
+
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ addSurfaceUpdatedListener(-1, l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size();
+ }
+ surfaceUpdatedListeners.add(index, l);
+ }
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners.remove(l);
+ }
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index 4c2b1c875..074fab563 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -33,7 +33,7 @@ import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.SurfaceChangeable;
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
+public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
protected long surfaceHandle;
public WrappedSurface(AbstractGraphicsConfiguration cfg) {
@@ -65,6 +65,10 @@ public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
}
public String toString() {
- return "WrappedSurface[config " + config + ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) + ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) + ", size " + getWidth() + "x" + getHeight() + "]";
+ return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
+ ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
+ ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
+ ", size " + getWidth() + "x" + getHeight() +
+ ", surfaceLock "+surfaceLock+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2c8538278..354bb83e3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -40,14 +40,15 @@
package jogamp.nativewindow.jawt;
import javax.media.nativewindow.NativeWindowFactory;
+
import jogamp.nativewindow.NWJNILibLoader;
import java.awt.Toolkit;
import java.security.AccessController;
import java.security.PrivilegedAction;
-public class JAWTJNILibLoader extends NWJNILibLoader {
- public static void loadAWTImpl() {
+public class JAWTJNILibLoader extends NWJNILibLoader {
+ static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
// Make sure that awt.dll is loaded before loading jawt.dll. Otherwise
@@ -73,4 +74,9 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
}
});
}
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index c1c97eece..21e9a3e09 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -37,24 +37,28 @@
package jogamp.nativewindow.jawt;
-import jogamp.nativewindow.*;
import java.awt.EventQueue;
-
-import javax.media.nativewindow.*;
-
-
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
-import java.lang.reflect.*;
-import java.security.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Map;
+import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.Debug;
+
+import com.jogamp.common.os.Platform;
+
public class JAWTUtil {
protected static final boolean DEBUG = Debug.debug("JAWT");
// See whether we're running in headless mode
private static final boolean headlessMode;
+ private static final JAWT jawtLockObject;
// Java2D magic ..
private static final Method isQueueFlusherThread;
@@ -75,31 +79,67 @@ public class JAWTUtil {
boolean ok;
}
+ /**
+ * Returns true if this platform's JAWT implementation supports
+ * or uses offscreen layer.
+ */
+ public static boolean isOffscreenLayerSupported() {
+ return Platform.OS_TYPE == Platform.OSType.MACOS &&
+ Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0;
+ }
+
+ /**
+ * @param useOffscreenLayerIfAvailable
+ * @return
+ */
+ public static JAWT getJAWT(boolean useOffscreenLayerIfAvailable) {
+ int jawt_version_flags = JAWTFactory.JAWT_VERSION_1_4;
+ if(useOffscreenLayerIfAvailable) {
+ switch(Platform.OS_TYPE) {
+ case MACOS:
+ if(Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0) {
+ jawt_version_flags |= JAWT.JAWT_MACOSX_USE_CALAYER;
+ }
+ }
+ }
+ return JAWT.getJAWT(jawt_version_flags);
+ }
+
+ public static boolean isJAWTUsingOffscreenLayer(JAWT jawt) {
+ return 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER );
+ }
+
static {
- JAWTJNILibLoader.loadAWTImpl();
+ if(DEBUG) {
+ System.err.println("JAWTUtil initialization (JAWT/JNI/...");
+ // Thread.dumpStack();
+ }
+ JAWTJNILibLoader.initSingleton();
JAWTJNILibLoader.loadNativeWindow("awt");
headlessMode = GraphicsEnvironment.isHeadless();
-
boolean ok = false;
- Class jC = null;
+ Class<?> jC = null;
Method m = null;
if (!headlessMode) {
+ jawtLockObject = getJAWT(false); // don't care for offscreen layer here
try {
jC = Class.forName("jogamp.opengl.awt.Java2D");
m = jC.getMethod("isQueueFlusherThread", (Class[])null);
ok = true;
} catch (Exception e) {
}
+ } else {
+ jawtLockObject = null; // headless !
}
isQueueFlusherThread = m;
j2dExist = ok;
- PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction() {
+ PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
PrivilegedDataBlob1 d = new PrivilegedDataBlob1();
try {
- final Class sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ final Class<?> sunToolkitClass = Class.forName("sun.awt.SunToolkit");
d.sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{});
d.sunToolkitAWTLockMethod.setAccessible(true);
d.sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{});
@@ -129,21 +169,21 @@ public class JAWTUtil {
jawtToolkitLock = new JAWTToolkitLock();
// trigger native AWT toolkit / properties initialization
- Map desktophints = null;
+ Map<?,?> desktophints = null;
try {
if(EventQueue.isDispatchThread()) {
- desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
} else {
- final ArrayList desktophintsBucket = new ArrayList(1);
+ final ArrayList<Map<?,?>> desktophintsBucket = new ArrayList<Map<?,?>>(1);
EventQueue.invokeAndWait(new Runnable() {
public void run() {
- Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ Map<?,?> _desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
if(null!=_desktophints) {
desktophintsBucket.add(_desktophints);
}
}
});
- desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ;
+ desktophints = ( desktophintsBucket.size() > 0 ) ? desktophintsBucket.get(0) : null ;
}
} catch (InterruptedException ex) {
ex.printStackTrace();
@@ -189,7 +229,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtLock() {
+ private static void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -197,7 +237,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtLock failed", e);
}
} else {
- JAWT.getJAWT().Lock();
+ jawtLockObject.Lock();
}
}
@@ -207,7 +247,7 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtUnlock() {
+ private static void awtUnlock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -215,7 +255,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtUnlock failed", e);
}
} else {
- JAWT.getJAWT().Unlock();
+ jawtLockObject.Unlock();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
index 2c80392ad..be697b3e0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
@@ -41,73 +41,190 @@ import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
-import java.awt.Window;
+import java.awt.Container;
+import java.applet.Applet;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
-public abstract class JAWTWindow implements NativeWindow {
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
+public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, OffscreenLayerOption {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
+ // user properties
+ protected boolean shallUseOffscreenLayer = false;
+
// lifetime: forever
protected Component component;
- protected AbstractGraphicsConfiguration config;
+ private AWTGraphicsConfiguration config; // control access due to delegation
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- // lifetime: valid after lock, forever until invalidate
+ // lifetime: valid after lock but may change with each 1st lock, purges after invalidate
+ private boolean isApplet;
+ private JAWT jawt;
+ private boolean isOffscreenLayerSurface;
protected long drawable;
protected Rectangle bounds;
-
- public JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
+ protected Insets insets;
+
+ /**
+ * Constructed by {@link jogamp.nativewindow.NativeWindowFactoryImpl#getNativeWindow(Object, AbstractGraphicsConfiguration)}
+ * via this platform's specialization (X11, OSX, Windows, ..).
+ *
+ * @param comp
+ * @param config
+ */
+ protected JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
if (config == null) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
}
- this.config = config;
+ if(! ( config instanceof AWTGraphicsConfiguration ) ) {
+ throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
+ }
+ this.config = (AWTGraphicsConfiguration) config;
init((Component)comp);
}
private void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
- validateNative();
+ this.isApplet = false;
}
- protected abstract void validateNative() throws NativeWindowException;
-
+
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
protected synchronized void invalidate() {
- component = null;
+ invalidateNative();
+ jawt = null;
+ isOffscreenLayerSurface = false;
drawable= 0;
bounds = new Rectangle();
+ insets = new Insets();
}
+ protected abstract void invalidateNative();
protected final void updateBounds(JAWT_Rectangle jawtBounds) {
bounds.setX(jawtBounds.getX());
bounds.setY(jawtBounds.getY());
bounds.setWidth(jawtBounds.getWidth());
bounds.setHeight(jawtBounds.getHeight());
+
+ if(component instanceof Container) {
+ java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.setLeftWidth(contInsets.left);
+ insets.setRightWidth(contInsets.right);
+ insets.setTopHeight(contInsets.top);
+ insets.setBottomHeight(contInsets.bottom);
+ }
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
- public final InsetsImmutable getInsets() { return Insets.getZero(); }
+ public final InsetsImmutable getInsets() { return insets; }
public final Component getAWTComponent() {
return component;
}
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #lockSurface()}.
+ */
+ public final boolean isApplet() {
+ return isApplet;
+ }
+ /** Returns the underlying JAWT instance created @ {@link #lockSurface()}. */
+ public final JAWT getJAWT() {
+ return jawt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new NativeWindowException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ attachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void attachSurfaceLayerImpl(final long layerHandle);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ detachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void detachSurfaceLayerImpl(final long layerHandle);
+
//
// SurfaceUpdateListener
//
- public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- // nop
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
//
// NativeSurface
@@ -115,6 +232,24 @@ public abstract class JAWTWindow implements NativeWindow {
private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private void determineIfApplet() {
+ Component c = component;
+ while(!isApplet && null != c) {
+ isApplet = c instanceof Applet;
+ c = c.getParent();
+ }
+ }
+
+ /**
+ * If JAWT offscreen layer is supported,
+ * implementation shall respect {@link #getShallUseOffscreenLayer()}
+ * and may respect {@link #isApplet()}.
+ *
+ * @return The JAWT instance reflecting offscreen layer support, etc.
+ *
+ * @throws NativeWindowException
+ */
+ protected abstract JAWT fetchJAWTImpl() throws NativeWindowException;
protected abstract int lockSurfaceImpl() throws NativeWindowException;
public final int lockSurface() throws NativeWindowException {
@@ -122,10 +257,13 @@ public abstract class JAWTWindow implements NativeWindow {
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
+ determineIfApplet();
try {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
res = lockSurfaceImpl();
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
@@ -147,7 +285,7 @@ public abstract class JAWTWindow implements NativeWindow {
surfaceLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -169,36 +307,35 @@ public abstract class JAWTWindow implements NativeWindow {
return surfaceLock.getOwner();
}
- public final boolean surfaceSwap() {
+ public boolean surfaceSwap() {
return false;
}
- public final void surfaceUpdated(Object updater, NativeWindow window, long when) { }
-
- public final long getSurfaceHandle() {
+ public long getSurfaceHandle() {
return drawable;
}
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+
+ public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
return config;
}
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
public final long getDisplayHandle() {
- return config.getScreen().getDevice().getHandle();
+ return getGraphicsConfiguration().getScreen().getDevice().getHandle();
}
public final int getScreenIndex() {
- return config.getScreen().getIndex();
- }
-
- public final void setSize(int width, int height) {
- component.setSize(width, height);
+ return getGraphicsConfiguration().getScreen().getIndex();
}
- public final int getWidth() {
+ public int getWidth() {
return component.getWidth();
}
- public final int getHeight() {
+ public int getHeight() {
return component.getHeight();
}
@@ -207,12 +344,8 @@ public abstract class JAWTWindow implements NativeWindow {
//
public synchronized void destroy() {
- if(null!=component) {
- if(component instanceof Window) {
- ((Window)component).dispose();
- }
- }
- invalidate();
+ invalidate();
+ component = null; // don't dispose the AWT component, since we are merely an immutable uplink
}
public final NativeWindow getParent() {
@@ -222,7 +355,7 @@ public abstract class JAWTWindow implements NativeWindow {
public long getWindowHandle() {
return drawable;
}
-
+
public final int getX() {
return component.getX();
}
@@ -230,52 +363,94 @@ public abstract class JAWTWindow implements NativeWindow {
public final int getY() {
return component.getY();
}
-
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This JAWT default implementation is currently still using
+ * a blocking implementation. It first attempts to retrieve the location
+ * via a native implementation. If this fails, it tries the blocking AWT implementation.
+ * If the latter fails due to an external AWT tree-lock, the non block
+ * implementation {@link #getLocationOnScreenNonBlocking(Point, Component)} is being used.
+ * The latter simply traverse up to the AWT component tree and sums the rel. position.
+ * We have to determine whether the latter is good enough for all cases,
+ * currently only OS X utilizes the non blocking method per default.
+ * </p>
+ */
public Point getLocationOnScreen(Point storage) {
+ Point los = getLocationOnScreenNative(storage);
+ if(null == los) {
+ if(!Thread.holdsLock(component.getTreeLock())) {
+ // avoid deadlock ..
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this);
+ Thread.dumpStack();
+ }
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ java.awt.Point awtLOS = component.getLocationOnScreen();
+ if(null!=storage) {
+ los = storage.translate(awtLOS.x, awtLOS.y);
+ } else {
+ los = new Point(awtLOS.x, awtLOS.y);
+ }
+ }
+ return los;
+ }
+
+ protected Point getLocationOnScreenNative(Point storage) {
int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
- // FIXME: Shall we deal with already locked or unrealized surfaces ?
- System.err.println("Warning: JAWT Lock couldn't be acquired!");
- Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock couldn't be acquired: "+this);
+ Thread.dumpStack();
+ }
return null;
}
try {
- Point d = getLocationOnScreenImpl(0, 0);
+ Point d = getLocationOnScreenNativeImpl(0, 0);
if(null!=d) {
if(null!=storage) {
storage.translate(d.getX(),d.getY());
return storage;
}
- return d;
- }
- // fall through intended ..
- if(!Thread.holdsLock(component.getTreeLock())) {
- // FIXME: Verify if this check is still required!
- System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock!");
- Thread.dumpStack();
- return null; // avoid deadlock ..
}
- java.awt.Point awtLOS = component.getLocationOnScreen();
- int dx = (int) ( awtLOS.getX() + .5 ) ;
- int dy = (int) ( awtLOS.getY() + .5 ) ;
- if(null!=storage) {
- return storage.translate(dx, dy);
- }
- return new Point(dx, dy);
+ return d;
} finally {
unlockSurface();
+ }
+ }
+ protected abstract Point getLocationOnScreenNativeImpl(int x, int y);
+
+ protected static Point getLocationOnScreenNonBlocking(Point storage, Component comp) {
+ int x = 0;
+ int y = 0;
+ while(null != comp) {
+ x += comp.getX();
+ y += comp.getY();
+ comp = comp.getParent();
}
+ if(null!=storage) {
+ storage.translate(x, y);
+ return storage;
+ }
+ return new Point(x, y);
}
- protected abstract Point getLocationOnScreenImpl(int x, int y);
-
- @Override
+
+ public boolean hasFocus() {
+ return component.hasFocus();
+ }
+
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("JAWT-Window["+
"windowHandle 0x"+Long.toHexString(getWindowHandle())+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", bounds "+bounds);
+ ", bounds "+bounds+", insets "+insets+
+ ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface);
if(null!=component) {
sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
", visible "+component.isVisible());
@@ -283,8 +458,9 @@ public abstract class JAWTWindow implements NativeWindow {
sb.append(", component NULL");
}
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
- ",\n\tconfig "+config+
- ",\n\tawtComponent "+getAWTComponent()+"]");
+ ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+ ",\n\tawtComponent "+getAWTComponent()+
+ ",\n\tsurfaceLock "+surfaceLock+"]");
return sb.toString();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index d4f6a95d4..ab2986fbe 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -40,38 +40,94 @@
package jogamp.nativewindow.jawt.macosx;
-import java.awt.Component;
+import java.nio.Buffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Point;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-// import jogamp.nativewindow.macosx.OSXUtil;
-
-public class MacOSXJAWTWindow extends JAWTWindow {
+import jogamp.nativewindow.macosx.OSXUtil;
+public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
super(comp, config);
+ if(DEBUG) {
+ dumpInfo();
+ }
}
- protected void validateNative() throws NativeWindowException {
+ protected void invalidateNative() {
+ surfaceHandle=0;
+ if(isOffscreenLayerSurfaceEnabled()) {
+ if(0 != drawable) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ }
+ }
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ public long getSurfaceHandle() {
+ return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not using CALAYER");
+ }
+ if(DEBUG) {
+ System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
+ this.surfaceHandle = surfaceHandle;
+ }
+
+ public void surfaceSizeChanged(int width, int height) {
+ sscSet = true;
+ sscWidth = width;
+ sscHeight = height;
+ }
+
+ public int getWidth() {
+ return sscSet ? sscWidth : super.getWidth();
+ }
+
+ public int getHeight() {
+ return sscSet ? sscHeight: super.getHeight();
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ // use offscreen if supported and [ applet or requested ]
+ return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
+ }
protected int lockSurfaceImpl() throws NativeWindowException {
- int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ int ret = NativeWindow.LOCK_SURFACE_NOT_READY;
+ if(null == ds) {
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
int res = ds.Lock();
dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
@@ -87,37 +143,86 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
ret = NativeWindow.LOCK_SURFACE_CHANGED;
}
- if (firstLock) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- dsi = ds.GetDrawingSurfaceInfo();
- return null;
- }
- });
- } else {
- dsi = ds.GetDrawingSurfaceInfo();
+ if(null == dsi) {
+ if (firstLock) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ dsi = ds.GetDrawingSurfaceInfo();
+ return null;
+ }
+ });
+ } else {
+ dsi = ds.GetDrawingSurfaceInfo();
+ }
+ if (dsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
- if (dsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ updateBounds(dsi.getBounds());
+ if (DEBUG && firstLock ) {
+ dumpInfo();
}
firstLock = false;
- macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo();
- if (macosxdsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
- }
- drawable = macosxdsi.getCocoaViewRef();
-
- if (drawable == 0) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(getJAWT());
+ if (macosxdsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ drawable = macosxdsi.getCocoaViewRef();
+
+ if (drawable == 0) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ } else {
+ ret = NativeWindow.LOCK_SUCCESS;
+ }
} else {
- updateBounds(dsi.getBounds());
+ /**
+ * Only create a fake invisible NSWindow for the drawable handle
+ * to please frameworks requiring such (eg. NEWT).
+ *
+ * The actual surface/ca-layer shall be created/attached
+ * by the upper framework (JOGL) since they require more information.
+ */
+ if(0 == drawable) {
+ drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
+ if(0 == drawable) {
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ }
+ // fix caps reflecting offscreen!
+ Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
+ caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ }
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer();
+ if(0 == rootSurfaceLayerHandle) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not create root CALayer: "+this);
+ }
+ if(!AttachJAWTSurfaceLayer(dsi, rootSurfaceLayerHandle)) {
+ OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
+ rootSurfaceLayerHandle = 0;
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this);
+ }
+ }
+ ret = NativeWindow.LOCK_SUCCESS;
}
+
return ret;
}
-
+
protected void unlockSurfaceImpl() throws NativeWindowException {
if(null!=ds) {
if (null!=dsi) {
@@ -126,30 +231,65 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
- macosxdsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- Component c = component;
- while(null != c) {
- x += c.getX();
- y += c.getY();
- c = c.getParent();
+ private void dumpInfo() {
+ System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName());
+ if(null != getJAWT()) {
+ System.err.println("JAWT version: 0x"+Integer.toHexString(getJAWT().getCachedVersion())+
+ ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(getJAWT())+
+ ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds+", insets "+insets);
+ } else {
+ System.err.println("JAWT n/a, bounds "+bounds+", insets "+insets);
}
- // return OSXUtil.GetLocationOnScreen(getWindowHandle(), x, y);
- return new Point(x, y);
+ // Thread.dumpStack();
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * On OS X locking the surface at this point (ie after creation and for location validation)
+ * is 'tricky' since the JVM traverses through many threads and crashes at:
+ * lockSurfaceImpl() {
+ * ..
+ * ds = getJAWT().GetDrawingSurface(component);
+ * due to a SIGSEGV.
+ *
+ * Hence we have some threading / sync issues with the native JAWT implementation.
+ * </p>
+ */
+ @Override
+ public Point getLocationOnScreen(Point storage) {
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
+ private static boolean AttachJAWTSurfaceLayer(JAWT_DrawingSurfaceInfo dsi, long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ return AttachJAWTSurfaceLayer0(dsi.getBuffer(), caLayer);
+ }
+
+ private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
private boolean dsLocked;
private JAWT_DrawingSurfaceInfo dsi;
+
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
-
+
+ private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer
+
+ private long surfaceHandle = 0;
+ private int sscWidth, sscHeight;
+ private boolean sscSet = false;
+
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
index 5ad22807f..bf5c18eaf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
@@ -95,7 +95,7 @@ public class Win32SunJDKReflection {
public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index 982b94888..786682b17 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -47,10 +47,11 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
public class WindowsJAWTWindow extends JAWTWindow {
@@ -58,18 +59,24 @@ public class WindowsJAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- }
-
- @Override
- protected synchronized void invalidate() {
- super.invalidate();
+ protected void invalidateNative() {
windowHandle = 0;
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -94,7 +101,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (win32dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -104,14 +112,12 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (windowHandle == 0 || drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
protected void unlockSurfaceImpl() throws NativeWindowException {
- long startTime = 0;
+ drawable = 0; // invalid HDC
if(null!=ds) {
if (null!=dsi) {
ds.FreeDrawingSurfaceInfo(dsi);
@@ -119,7 +125,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
@@ -131,8 +137,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
return windowHandle;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
index 5d4fa0dad..743d371b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
@@ -28,9 +28,13 @@
package jogamp.nativewindow.jawt.x11;
import jogamp.nativewindow.jawt.*;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
@@ -41,20 +45,32 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11JAWTToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11JAWTToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); }
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
JAWTUtil.lockToolkit();
- X11Util.XLockDisplay(displayHandle);
+ if(null == lock) {
+ X11Lib.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
JAWTUtil.unlockToolkit();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 2319d6269..35dc2343f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -38,20 +38,17 @@
package jogamp.nativewindow.jawt.x11;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-import jogamp.nativewindow.x11.X11Util;
+import jogamp.nativewindow.x11.X11Lib;
public class X11JAWTWindow extends JAWTWindow {
@@ -59,36 +56,22 @@ public class X11JAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ protected void invalidateNative() { }
- if(awtDevice.getHandle() != 0) {
- // subtype and handle set already, done
- return;
- }
-
- long displayHandle = 0;
-
- // first try a pre-existing attached native configuration, ie native X11GraphicsDevice
- AbstractGraphicsConfiguration aconfig = (null!=config) ? config.getNativeGraphicsConfiguration() : null;
- AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
- AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null; // X11GraphicsDevice
- if(null!=adevice) {
- displayHandle = adevice.getHandle();
- }
-
- if(0 == displayHandle) {
- displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
- }
- if(0==displayHandle) {
- throw new InternalError("X11JAWTWindow: No X11 Display handle available");
- }
- awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
}
-
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -113,7 +96,8 @@ public class X11JAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (x11dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -122,8 +106,6 @@ public class X11JAWTWindow extends JAWTWindow {
if (drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
@@ -136,15 +118,15 @@ public class X11JAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
x11dsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
index b576b0c6b..08d471448 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
@@ -55,14 +55,14 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
the purposes of correctly enumerating the available visuals. */
public class X11SunJDKReflection {
- private static Class x11GraphicsDeviceClass;
- private static Method x11GraphicsDeviceGetDisplayMethod;
- private static Class x11GraphicsConfigClass;
- private static Method x11GraphicsConfigGetVisualMethod;
- private static boolean initted;
+ private static Class<?> x11GraphicsDeviceClass;
+ private static Method x11GraphicsDeviceGetDisplayMethod;
+ private static Class<?> x11GraphicsConfigClass;
+ private static Method x11GraphicsConfigGetVisualMethod;
+ private static boolean initialized;
static {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice");
@@ -72,7 +72,7 @@ public class X11SunJDKReflection {
x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig");
x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {});
x11GraphicsConfigGetVisualMethod.setAccessible(true);
- initted = true;
+ initialized = true;
} catch (Exception e) {
// Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
}
@@ -82,7 +82,7 @@ public class X11SunJDKReflection {
}
public static long graphicsDeviceGetDisplay(GraphicsDevice device) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
@@ -96,7 +96,7 @@ public class X11SunJDKReflection {
public static int graphicsConfigurationGetVisualID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
@@ -105,7 +105,7 @@ public class X11SunJDKReflection {
}
public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index cd558c05d..5b1e4b0a7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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 jogamp.nativewindow.macosx;
import javax.media.nativewindow.NativeWindowException;
@@ -34,6 +61,42 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
+ public static long CreateNSView(int x, int y, int width, int height) {
+ return CreateNSView0(x, y, width, height);
+ }
+ public static void DestroyNSView(long nsView) {
+ DestroyNSView0(nsView);
+ }
+
+ public static long CreateNSWindow(int x, int y, int width, int height) {
+ return CreateNSWindow0(x, y, width, height);
+ }
+ public static void DestroyNSWindow(long nsWindow) {
+ DestroyNSWindow0(nsWindow);
+ }
+
+ public static long CreateCALayer() {
+ return CreateCALayer0();
+ }
+ public static void AddCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ AddCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void RemoveCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ RemoveCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void DestroyCALayer(long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ DestroyCALayer0(caLayer);
+ }
+
public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) {
if(IsMainThread0()) {
runnable.run(); // don't leave the JVM
@@ -48,6 +111,14 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native long CreateNSView0(int x, int y, int width, int height);
+ private static native void DestroyNSView0(long nsView);
+ private static native long CreateNSWindow0(int x, int y, int width, int height);
+ private static native void DestroyNSWindow0(long nsWindow);
+ private static native long CreateCALayer0();
+ private static native void AddCASublayer0(long rootCALayer, long subCALayer);
+ private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
+ private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
index 1ad909897..aab1556da 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
@@ -202,7 +202,9 @@ public class SWTAccessor {
if( null != OS_gtk_class ) {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT);
+ // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
+ // to avoid locking problems !
+ return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index 68cf8af45..c8ed8e070 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -61,14 +61,22 @@ public class GDISurface extends ProxySurface {
throw new InternalError("surface not released");
}
surfaceHandle = GDI.GetDC(windowHandle);
+ /*
+ if(0 == surfaceHandle) {
+ System.err.println("****** DC Acquire: 0x"+Long.toHexString(windowHandle)+", isWindow "+GDI.IsWindow(windowHandle)+", isVisible "+GDI.IsWindowVisible(windowHandle)+", GDI LastError: "+GDI.GetLastError()+", 0x"+Long.toHexString(surfaceHandle)+", GDI LastError: "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ */
return (0 != surfaceHandle) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
}
protected void unlockSurfaceImpl() {
if (0 == surfaceHandle) {
- throw new InternalError("surface not acquired");
+ throw new InternalError("surface not acquired: "+this+", thread: "+Thread.currentThread().getName());
+ }
+ if(0 == GDI.ReleaseDC(windowHandle, surfaceHandle)) {
+ throw new NativeWindowException("DC not released: "+this+", isWindow "+GDI.IsWindow(windowHandle)+", werr "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
}
- GDI.ReleaseDC(windowHandle, surfaceHandle);
surfaceHandle=0;
}
@@ -77,11 +85,12 @@ public class GDISurface extends ProxySurface {
}
public String toString() {
- return "GDISurface[config "+config+
+ return "GDISurface[config "+getPrivateGraphicsConfiguration()+
", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
", windowHandle 0x"+Long.toHexString(windowHandle)+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", size "+getWidth()+"x"+getHeight()+"]";
+ ", size "+getWidth()+"x"+getHeight()+
+ ", surfaceLock "+surfaceLock+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
new file mode 100644
index 000000000..be531d9ee
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright 2011 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 jogamp.nativewindow.windows;
+
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.x11.X11Util;
+
+public class GDIUtil {
+ private static final boolean DEBUG = Debug.debug("GDIUtil");
+
+ private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ;
+ private static RegisteredClassFactory dummyWindowClassFactory;
+ private static boolean isInit = false;
+
+ public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ if(!isInit) {
+ synchronized(X11Util.class) {
+ if(!isInit) {
+ isInit = true;
+ NWJNILibLoader.loadNativeWindow("win32");
+
+ if( !initIDs0() ) {
+ throw new NativeWindowException("GDI: Could not initialized native stub");
+ }
+
+ if(DEBUG) {
+ System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
+ }
+
+ dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ }
+ }
+ }
+ }
+
+ public static boolean requiresToolkitLock() { return false; }
+
+ private static RegisteredClass dummyWindowClass = null;
+ private static Object dummyWindowSync = new Object();
+
+ public static long CreateDummyWindow(int x, int y, int width, int height) {
+ synchronized(dummyWindowSync) {
+ dummyWindowClass = dummyWindowClassFactory.getSharedClass();
+ return CreateDummyWindow0(dummyWindowClass.getHandle(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height);
+ }
+ }
+
+ public static boolean DestroyDummyWindow(long hwnd) {
+ boolean res;
+ synchronized(dummyWindowSync) {
+ if( null == dummyWindowClass ) {
+ throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null");
+ }
+ res = GDI.DestroyWindow(hwnd);
+ dummyWindowClassFactory.releaseSharedClass();
+ }
+ return res;
+ }
+
+ public static Point GetRelativeLocation(long src_win, long dest_win, int src_x, int src_y) {
+ return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y);
+ }
+
+ public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc);
+ public static native boolean DestroyWindowClass(long hInstance, String className);
+
+ private static native boolean initIDs0();
+ private static native long getDummyWndProc0();
+ private static native Object GetRelativeLocation0(long src_win, long dest_win, int src_x, int src_y);
+
+ static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height);
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
index 15e0a67cb..00bedfc8e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
@@ -34,34 +34,44 @@ import javax.media.nativewindow.NativeWindowException;
public class RegisteredClassFactory {
static final boolean DEBUG = Debug.debug("RegisteredClass");
- private static ArrayList sharedClasses = new ArrayList();
+ private static ArrayList<RegisteredClassFactory> registeredFactories = new ArrayList<RegisteredClassFactory>();
+
private String classBaseName;
- long wndProc;
+ private long wndProc;
private RegisteredClass sharedClass = null;
private int classIter = 0;
private int sharedRefCount = 0;
- private Object sync = new Object();
+ private final Object sync = new Object();
/**
- * Intended for a JVM shutdown hook, hence little synchronization
+ * Release the {@link RegisteredClass} of all {@link RegisteredClassFactory}.
*/
public static void shutdownSharedClasses() {
- synchronized(sharedClasses) {
- for(int i=0; i<sharedClasses.size(); i++) {
- RegisteredClass sc = (RegisteredClass) sharedClasses.get(i);
- GDI.DestroyWindowClass(sc.getHandle(), sc.getName());
- if(DEBUG) {
- System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc);
+ synchronized(registeredFactories) {
+ for(int j=0; j<registeredFactories.size(); j++) {
+ final RegisteredClassFactory rcf = registeredFactories.get(j);
+ synchronized(rcf.sync) {
+ if(null != rcf.sharedClass) {
+ GDIUtil.DestroyWindowClass(rcf.sharedClass.getHandle(), rcf.sharedClass.getName());
+ rcf.sharedClass = null;
+ rcf.sharedRefCount = 0;
+ rcf.classIter = 0;
+ if(DEBUG) {
+ System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+" shutdownSharedClasses : "+rcf.sharedClass);
+ }
+ }
}
}
- sharedClasses.clear();
}
}
public RegisteredClassFactory(String classBaseName, long wndProc) {
this.classBaseName = classBaseName;
this.wndProc = wndProc;
+ synchronized(registeredFactories) {
+ registeredFactories.add(this);
+ }
}
public RegisteredClass getSharedClass() throws NativeWindowException {
@@ -76,19 +86,17 @@ public class RegisteredClassFactory {
}
String clazzName = null;
boolean registered = false;
- while ( !registered && Integer.MAX_VALUE >= classIter ) {
+ final int classIterMark = classIter - 1;
+ while ( !registered && classIterMark != classIter ) {
// Retry with next clazz name, this could happen if more than one JVM is running
clazzName = classBaseName + classIter;
classIter++;
- registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc);
+ registered = GDIUtil.CreateWindowClass(hInstance, clazzName, wndProc);
}
if( !registered ) {
throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName);
}
sharedClass = new RegisteredClass(hInstance, clazzName);
- synchronized(sharedClasses) {
- sharedClasses.add(sharedClass);
- }
if(DEBUG) {
System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass);
}
@@ -113,10 +121,7 @@ public class RegisteredClassFactory {
throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null");
}
if( 0 == sharedRefCount ) {
- GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName());
- synchronized(sharedClasses) {
- sharedClasses.remove(sharedClass);
- }
+ GDIUtil.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName());
if(DEBUG) {
System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index b669bce75..268416266 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -33,10 +33,22 @@
package jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, new X11GraphicsConfigurationFactory());
+ }
+ private X11GraphicsConfigurationFactory() {
+ }
+
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
throws IllegalArgumentException, NativeWindowException {
@@ -55,7 +67,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
int num[] = { -1 };
long display = screen.getDevice().getHandle();
- XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
+ XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
if(xvis==null || num[0]<1) {
return null;
@@ -81,7 +93,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
vinfo_template.setC_class(c_class);
long display = screen.getDevice().getHandle();
- XVisualInfo[] vinfos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
+ XVisualInfo[] vinfos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
XVisualInfo best=null;
int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits();
for (int i = 0; vinfos!=null && i < num[0]; i++) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
index fb0aff10d..5166ef577 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
@@ -29,6 +29,9 @@ package jogamp.nativewindow.x11;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing {@link X11Util#XLockDisplay(long)}.
@@ -38,18 +41,30 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11ToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11ToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); }
- X11Util.XLockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 5c1839250..560130dd1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -33,19 +33,18 @@
package jogamp.nativewindow.x11;
-import com.jogamp.common.util.LongObjectHashMap;
-import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.NWJNILibLoader;
-
-import javax.media.nativewindow.*;
-
-import java.nio.Buffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.util.Point;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NWJNILibLoader;
+
+import com.jogamp.common.util.LongObjectHashMap;
/**
* Contains a thread safe X11 utility to retrieve display connections.
@@ -53,54 +52,88 @@ import javax.media.nativewindow.util.Point;
public class X11Util {
/**
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
- *
- * It is observed that ATI X11 drivers, eg. fglrx 8.78.6 and fglrx 11.08/8.881,
+ * <p>
+ * It is observed that ATI X11 drivers, eg.
+ * <ul>
+ * <li>fglrx 8.78.6,</li>
+ * <li>fglrx 11.08/8.881 and </li>
+ * <li>fglrx 11.11/8.911</li>
+ * </ul>
* are quite sensitive to multiple Display connections.
- * Here, closing displays shall happen in the same order as
- * they were opened, -OR- shall not be closed at all!
- * Otherwise some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
+ * With the above drivers closing displays shall happen in the same order as
+ * they were opened, <b>or</b> shall not be closed at all!
+ * If closed, some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
* You may test this, ie just reverse the destroy order below.
* See also native test: jogl/test/native/displayMultiple02.c
- *
- * Our current 'workaround' is to not close them at all if driver vendor is ATI.
+ * </p>
+ * <p>
+ * Workaround is to not close them at all if driver vendor is ATI.
+ * </p>
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
-
- public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+ /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
+ public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+
+ /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
+ public static final boolean HAS_XLOCKDISPLAY_BUG = true;
+
private static final boolean DEBUG = Debug.debug("X11Util");
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.getBooleanProperty("nativewindow.debug.X11Util.TraceDisplayLifecycle", true, AccessController.getContext());
- private static volatile String nullDisplayName = null;
- private static boolean requiresX11Lock = false;
- private static boolean isInit = false;
+ private static String nullDisplayName = null;
+ private static boolean isX11LockAvailable = false;
+ private static boolean requiresX11Lock = true;
+ private static volatile boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
private static int setX11ErrorHandlerRecCount = 0;
private static Object setX11ErrorHandlerLock = new Object();
- public static synchronized void initSingleton(final boolean firstX11ActionOnProcess) {
+ @SuppressWarnings("unused")
+ public static void initSingleton(final boolean firstX11ActionOnProcess) {
if(!isInit) {
- NWJNILibLoader.loadNativeWindow("x11");
-
- /**
- * Always issue XInitThreads() since we have independent
- * off-thread created Display connections able to utilize multithreading,
- * ie NEWT (jogamp.newt.x11.X11Display.createNativeImpl()) !!
- */
- initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess );
-
- requiresX11Lock = !firstX11ActionOnProcess ;
-
- if(DEBUG) {
- System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+
- ", requiresX11Lock "+requiresX11Lock);
+ synchronized(X11Util.class) {
+ if(!isInit) {
+ isInit = true;
+ NWJNILibLoader.loadNativeWindow("x11");
+
+ final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
+ final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess );
+ isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+
+ final long dpy = X11Lib.XOpenDisplay(null);
+ try {
+ nullDisplayName = X11Lib.XDisplayString(dpy);
+ } finally {
+ X11Lib.XCloseDisplay(dpy);
+ }
+
+ if(DEBUG) {
+ System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
+ ", requiresX11Lock "+requiresX11Lock+
+ ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
+ ", isX11LockAvailable "+isX11LockAvailable+
+ ", X11 Display(NULL) <"+nullDisplayName+">");
+ // Thread.dumpStack();
+ }
+ }
}
- isInit = true;
}
}
+
+ public static synchronized boolean isNativeLockAvailable() {
+ return isX11LockAvailable;
+ }
+
+ public static synchronized boolean requiresToolkitLock() {
+ return requiresX11Lock;
+ }
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
synchronized(setX11ErrorHandlerLock) {
@@ -121,42 +154,7 @@ public class X11Util {
}
}
- public static boolean requiresToolkitLock() {
- return requiresX11Lock;
- }
-
- public static void lockDefaultToolkit(long dpyHandle) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- if(requiresX11Lock) {
- X11Util.XLockDisplay(dpyHandle);
- }
- }
-
- public static void unlockDefaultToolkit(long dpyHandle) {
- if(requiresX11Lock) {
- X11Util.XUnlockDisplay(dpyHandle);
- }
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
-
public static String getNullDisplayName() {
- if(null==nullDisplayName) { // volatile: ok
- synchronized(X11Util.class) {
- if(null==nullDisplayName) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- long dpy = X11Lib.XOpenDisplay(null);
- try {
- nullDisplayName = X11Lib.XDisplayString(dpy);
- } finally {
- X11Lib.XCloseDisplay(dpy);
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- if(DEBUG) {
- System.out.println("X11 Display(NULL) <"+nullDisplayName+">");
- }
- }
- }
- }
return nullDisplayName;
}
@@ -224,7 +222,6 @@ public class X11Util {
public final void setUncloseable(boolean v) { unCloseable = v; }
public final boolean isUncloseable() { return unCloseable; }
-
public final Throwable getCreationStack() { return creationStack; }
@Override
@@ -238,20 +235,22 @@ public class X11Util {
}
}
- /** Returns the number of unclosed X11 Displays.
+ /**
+ * Cleanup resources.
+ * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>,
+ * keep alive all references (open display connection) for restart on same ClassLoader.
+ *
+ * @return number of unclosed X11 Displays.<br>
* @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
- */
+ */
public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
if(DEBUG||verbose||pendingDisplayList.size() > 0) {
- String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")" ;
+ System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
if(DEBUG) {
- Exception e = new Exception(msg);
- e.printStackTrace();
- } else {
- System.err.println(msg);
+ Thread.dumpStack();
}
if( openDisplayList.size() > 0) {
X11Util.dumpOpenDisplayConnections();
@@ -264,10 +263,11 @@ public class X11Util {
synchronized(globalLock) {
if(realXCloseOpenAndPendingDisplays) {
closePendingDisplayConnections();
+ openDisplayList.clear();
+ pendingDisplayList.clear();
+ openDisplayMap.clear();
+ shutdown0();
}
- openDisplayList.clear();
- pendingDisplayList.clear();
- openDisplayMap.clear();
}
return num;
}
@@ -304,9 +304,9 @@ public class X11Util {
public static void dumpOpenDisplayConnections() {
synchronized(globalLock) {
System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size());
- for(int i=0; i<pendingDisplayList.size(); i++) {
+ for(int i=0; i<openDisplayList.size(); i++) {
NamedDisplay ndpy = openDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Open["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -316,7 +316,7 @@ public class X11Util {
}
}
}
-
+
public static int getPendingDisplayConnectionNumber() {
synchronized(globalLock) {
return pendingDisplayList.size();
@@ -328,7 +328,7 @@ public class X11Util {
System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
for(int i=0; i<pendingDisplayList.size(); i++) {
NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Pending["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -384,8 +384,8 @@ public class X11Util {
}
}
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
+ // Thread.dumpStack();
}
return namedDpy.getHandle();
}
@@ -408,10 +408,6 @@ public class X11Util {
if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
if(!namedDpy.isUncloseable()) {
- if(DEBUG) {
- System.err.println("X11Util.Display: XCloseDisplay "+namedDpy+". Thread "+Thread.currentThread().getName());
- Thread.dumpStack();
- }
XCloseDisplay(namedDpy.getHandle());
} else {
// for reuse
@@ -439,7 +435,7 @@ public class X11Util {
public static String validateDisplayName(String name, long handle) {
if( ( null==name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) && 0!=handle) {
- name = XDisplayString(handle);
+ name = X11Lib.XDisplayString(handle);
}
return validateDisplayName(name);
}
@@ -455,8 +451,8 @@ public class X11Util {
try {
long handle = X11Lib.XOpenDisplay(arg0);
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
return handle;
} finally {
@@ -468,8 +464,8 @@ public class X11Util {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
}
int res = -1;
X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
@@ -487,209 +483,7 @@ public class X11Util {
}
}
- public static int XFree(Buffer arg0) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- return X11Lib.XFree(arg0);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- }
-
- public static int XSync(long display, boolean discard) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XSync(display, discard);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XSynchronize(long display, boolean onoff) {
- lockDefaultToolkit(display);
- try {
- X11Lib.XSynchronize(display, onoff);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XineramaEnabled(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XineramaEnabled(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int DefaultScreen(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultScreen(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long RootWindow(long display, int screen_number) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.RootWindow(display, screen_number);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static String XDisplayString(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XDisplayString(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFlush(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFlush(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFreePixmap(long display, long arg1) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFreePixmap(display, arg1);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long DefaultVisualID(long display, int screen) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultVisualID(display, screen);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long CreateDummyWindow(long display, int screen_index, long visualID, int width, int height) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.CreateDummyWindow(display, screen_index, visualID, width, height);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void DestroyDummyWindow(long display, long window) {
- lockDefaultToolkit(display);
- try {
- X11Lib.DestroyDummyWindow(display, window);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.GetRelativeLocation(display, screen_index, src_win, dest_win, src_x, src_y);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XLockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle));
- }
- X11Lib.XLockDisplay(handle);
- }
-
- public static void XUnlockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle));
- }
- X11Lib.XUnlockDisplay(handle);
- }
-
- private static native void initialize0(boolean firstUIActionOnProcess);
+ private static native boolean initialize0(boolean firstUIActionOnProcess);
+ private static native void shutdown0();
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..efaf4728c
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2008 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
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package jogamp.nativewindow.x11.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
+
+import jogamp.nativewindow.jawt.x11.X11SunJDKReflection;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
+
+public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, new X11AWTGraphicsConfigurationFactory());
+ }
+ private X11AWTGraphicsConfigurationFactory() {
+ }
+
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createDefault();
+ }
+
+ return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, (AWTGraphicsScreen)absScreen);
+ }
+
+ public static AWTGraphicsConfiguration chooseGraphicsConfigurationStatic(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AWTGraphicsScreen awtScreen) {
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: got "+awtScreen);
+ }
+
+ final GraphicsDevice device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
+ boolean owner = false;
+ if(0==displayHandle) {
+ displayHandle = X11Util.openDisplay(null);
+ owner = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create local X11 display");
+ }
+ } else {
+ /**
+ * Using the AWT display handle works fine with NVidia.
+ * However we experienced different results w/ AMD drivers,
+ * some work, but some behave erratic.
+ * I.e. hangs in XQueryExtension(..) via X11GraphicsScreen.
+ */
+ final String displayName = X11Lib.XDisplayString(displayHandle);
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create X11 display @ "+displayName+" / 0x"+Long.toHexString(displayHandle));
+ }
+ displayHandle = X11Util.openDisplay(displayName);
+ owner = true;
+ }
+ final ToolkitLock lock = owner ?
+ NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock
+ NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle);
+ final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner);
+ final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: made "+x11Screen);
+ }
+
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device);
+ X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ if (x11Config == null) {
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: chosen x11Config: "+x11Config);
+ }
+
+ //
+ // Match the X11/GL Visual with AWT:
+ // - choose a config AWT agnostic and then
+ // - try to find the visual within the GraphicsConfiguration
+ //
+ // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer,
+ // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify().
+ //
+ final GraphicsConfiguration[] configs = device.getConfigurations();
+ long visualID = x11Config.getVisualID();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration gc = configs[i];
+ if (gc != null) {
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
+ if(DEBUG) {
+ System.err.println("Found matching AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
+ }
+ return new AWTGraphicsConfiguration(awtScreen,
+ x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ gc, x11Config);
+ }
+ }
+ }
+
+ // try again using an AWT Colormodel compatible configuration
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsChosen, gc);
+ x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ if (x11Config == null) {
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+ visualID = x11Config.getVisualID();
+ for (int i = 0; i < configs.length; i++) {
+ gc = configs[i];
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
+ if(DEBUG) {
+ System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
+ }
+ return new AWTGraphicsConfiguration(awtScreen,
+ x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ gc, x11Config);
+ }
+ }
+
+ // Either we weren't able to reflectively introspect on the
+ // X11GraphicsConfig or something went wrong in the steps above;
+ // Let's take the default configuration as used on Windows and MacOSX then ..
+ if(DEBUG) {
+ System.err.println("!!! Using default configuration");
+ }
+
+ gc = device.getDefaultConfiguration();
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config);
+ }
+}
+