aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/classes')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java5
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java8
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java50
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java27
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java54
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java121
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java50
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java60
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java112
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java6
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java12
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java55
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java394
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java9
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java68
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java24
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java21
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java243
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java45
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java18
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java26
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java9
22 files changed, 1137 insertions, 280 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java
index 22f2d544f..96f6ab2ba 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java
@@ -35,9 +35,8 @@ package com.jogamp.nativewindow.impl;
import javax.media.nativewindow.*;
public class GraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory {
- public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
- CapabilitiesChooser chooser,
- AbstractGraphicsScreen screen) {
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) {
return new DefaultGraphicsConfiguration(screen, capabilities, capabilities);
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java
index 8f82bed2b..34f5d6267 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java
@@ -41,6 +41,12 @@ import javax.media.nativewindow.*;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
protected static final boolean DEBUG = Debug.debug("NativeWindow");
+ private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
+
+ 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 {
@@ -56,7 +62,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
throw new IllegalArgumentException("AbstractGraphicsConfiguration is null with a non NativeWindow object");
}
- if (ReflectionUtil.instanceOf(winObj, AWTComponentClassName)) {
+ if (NativeWindowFactory.isAWTAvailable() && ReflectionUtil.instanceOf(winObj, AWTComponentClassName)) {
return getAWTNativeWindow(winObj, config);
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java
new file mode 100644
index 000000000..5a03cba7f
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java
@@ -0,0 +1,50 @@
+/**
+ * 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 com.jogamp.nativewindow.impl;
+
+import javax.media.nativewindow.ToolkitLock;
+
+/**
+ * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock}
+ * without any locking. Since there is no locking it all,
+ * it is intrinsically recursive.
+ */
+public class NullToolkitLock implements ToolkitLock {
+
+ /** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */
+ protected NullToolkitLock() { }
+
+ public final void lock() {
+ if(TRACE_LOCK) { System.err.println("NullToolkitLock.lock()"); }
+ }
+
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); }
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java
index 9d9f360cd..eebcdb0ab 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java
@@ -43,10 +43,10 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.SurfaceChangeable;
-import com.jogamp.common.util.RecursiveToolkitLock;
+import com.jogamp.common.util.locks.RecursiveLock;
public class ProxySurface implements NativeSurface, SurfaceChangeable {
- private RecursiveToolkitLock recurLock = new RecursiveToolkitLock();
+ private RecursiveLock recurLock = new RecursiveLock();
protected int width, height, scrnIndex;
protected long surfaceHandle, displayHandle;
protected AbstractGraphicsConfiguration config;
@@ -78,31 +78,36 @@ public class ProxySurface implements NativeSurface, SurfaceChangeable {
surfaceHandle=0;
}
- public synchronized int lockSurface() throws NativeWindowException {
+ public final int lockSurface() throws NativeWindowException {
recurLock.lock();
+
+ if(recurLock.getRecursionCount() == 0) {
+ config.getScreen().getDevice().lock();
+ }
return LOCK_SUCCESS;
}
- public synchronized void unlockSurface() {
+ public final void unlockSurface() {
+ recurLock.validateLocked();
+
+ if(recurLock.getRecursionCount()==0) {
+ config.getScreen().getDevice().unlock();
+ }
recurLock.unlock();
}
- public synchronized boolean isSurfaceLockedByOtherThread() {
+ public final boolean isSurfaceLockedByOtherThread() {
return recurLock.isLockedByOtherThread();
}
- public synchronized boolean isSurfaceLocked() {
+ public final boolean isSurfaceLocked() {
return recurLock.isLocked();
}
- public Thread getSurfaceLockOwner() {
+ public final Thread getSurfaceLockOwner() {
return recurLock.getOwner();
}
- public Exception getSurfaceLockStack() {
- return recurLock.getLockedStack();
- }
-
public boolean surfaceSwap() {
return false;
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java
new file mode 100644
index 000000000..017d74874
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java
@@ -0,0 +1,54 @@
+/**
+ * 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 com.jogamp.nativewindow.impl.jawt;
+
+import javax.media.nativewindow.ToolkitLock;
+
+/**
+ * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock}
+ * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()}.
+ * <br>
+ * This strategy should only be used if AWT is using the underlying native windowing toolkit
+ * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call
+ * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets.
+ */
+public class JAWTToolkitLock implements ToolkitLock {
+
+ /** Singleton via {@link JAWTUtil#getJAWTToolkitLock()} */
+ protected JAWTToolkitLock() {}
+
+ public final void lock() {
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); }
+ JAWTUtil.lockToolkit();
+ }
+
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); }
+ JAWTUtil.unlockToolkit();
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
index 7127bacf9..ff62c9521 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
@@ -40,27 +40,28 @@ import com.jogamp.nativewindow.impl.*;
import javax.media.nativewindow.*;
-import com.jogamp.common.util.RecursiveToolkitLock;
+import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.GraphicsEnvironment;
import java.lang.reflect.*;
import java.security.*;
public class JAWTUtil {
+ protected static final boolean DEBUG = Debug.debug("JAWT");
// See whether we're running in headless mode
private static final boolean headlessMode;
// Java2D magic ..
- private static final Class j2dClazz;
private static final Method isQueueFlusherThread;
private static final boolean j2dExist;
private static Class sunToolkitClass;
private static Method sunToolkitAWTLockMethod;
private static Method sunToolkitAWTUnlockMethod;
- private static final boolean hasSunToolkitAWTLock;
- private static final boolean useSunToolkitAWTLock;
+ private static boolean hasSunToolkitAWTLock;
+
+ private static final JAWTToolkitLock jawtToolkitLock;
static {
JAWTJNILibLoader.loadAWTImpl();
@@ -68,45 +69,53 @@ public class JAWTUtil {
headlessMode = GraphicsEnvironment.isHeadless();
- boolean ok=false;
- Class jC=null;
- Method m=null;
- if(!headlessMode) {
+ boolean ok = false;
+ Class jC = null;
+ Method m = null;
+ if (!headlessMode) {
try {
jC = Class.forName("com.jogamp.opengl.impl.awt.Java2D");
m = jC.getMethod("isQueueFlusherThread", null);
ok = true;
- } catch (Exception e) {}
+ } catch (Exception e) {
+ }
}
- j2dClazz = jC;
isQueueFlusherThread = m;
j2dExist = ok;
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- try {
- sunToolkitClass = Class.forName("sun.awt.SunToolkit");
- sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[] {});
- sunToolkitAWTLockMethod.setAccessible(true);
- sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[] {});
- sunToolkitAWTUnlockMethod.setAccessible(true);
- } catch (Exception e) {
- // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
- }
- return null;
+ try {
+ sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{});
+ sunToolkitAWTLockMethod.setAccessible(true);
+ sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{});
+ sunToolkitAWTUnlockMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
+ }
+ return null;
+ }
+ });
+ boolean _hasSunToolkitAWTLock = false;
+ if (null != sunToolkitAWTLockMethod && null != sunToolkitAWTUnlockMethod) {
+ try {
+ sunToolkitAWTLockMethod.invoke(null, null);
+ sunToolkitAWTUnlockMethod.invoke(null, null);
+ _hasSunToolkitAWTLock = true;
+ } catch (Exception e) {
}
- });
- boolean _hasSunToolkitAWTLock = false;
- if ( null!=sunToolkitAWTLockMethod && null!=sunToolkitAWTUnlockMethod ) {
- try {
- sunToolkitAWTLockMethod.invoke(null, null);
- sunToolkitAWTUnlockMethod.invoke(null, null);
- _hasSunToolkitAWTLock = true;
- } catch (Exception e) {}
- }
- hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
- // useSunToolkitAWTLock = hasSunToolkitAWTLock;
- useSunToolkitAWTLock = false;
+ }
+ hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
+ // hasSunToolkitAWTLock = false;
+
+ jawtToolkitLock = new JAWTToolkitLock();
+
+ if (DEBUG) {
+ System.err.println("JAWTUtil: Has sun.awt.SunToolkit.awtLock/awtUnlock " + hasSunToolkitAWTLock);
+ System.err.println("JAWTUtil: Has Java2D " + j2dExist);
+ System.err.println("JAWTUtil: Is headless " + headlessMode);
+ }
}
public static void initSingleton() {
@@ -132,8 +141,14 @@ public class JAWTUtil {
return headlessMode;
}
- private static void awtLock() {
- if(useSunToolkitAWTLock) {
+ /**
+ * Locks the AWT's global ReentrantLock.<br>
+ *
+ * JAWT's native Lock() function calls SunToolkit.awtLock(),
+ * which just uses AWT's global ReentrantLock.<br>
+ */
+ public static void awtLock() {
+ if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, null);
} catch (Exception e) {
@@ -144,8 +159,14 @@ public class JAWTUtil {
}
}
- private static void awtUnlock() {
- if(useSunToolkitAWTLock) {
+ /**
+ * Unlocks the AWT's global ReentrantLock.<br>
+ *
+ * JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
+ * which just uses AWT's global ReentrantLock.<br>
+ */
+ public static void awtUnlock() {
+ if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, null);
} catch (Exception e) {
@@ -156,36 +177,20 @@ public class JAWTUtil {
}
}
- private static RecursiveToolkitLock recurLock = new RecursiveToolkitLock();
-
- public static synchronized void lockToolkit() throws NativeWindowException {
- recurLock.lock();
-
- if(recurLock.getRecursionCount()==0 &&
- !isJava2DQueueFlusherThread() &&
- !headlessMode) {
+ public static void lockToolkit() throws NativeWindowException {
+ if(!isJava2DQueueFlusherThread() && !headlessMode) {
awtLock();
}
}
- public static synchronized void unlockToolkit() {
- recurLock.validateLocked();
-
- if(recurLock.getRecursionCount()==0 &&
- !isJava2DQueueFlusherThread() &&
- !headlessMode) {
+ public static void unlockToolkit() {
+ if(!isJava2DQueueFlusherThread() && !headlessMode) {
awtUnlock();
}
-
- recurLock.unlock();
- }
-
- public static boolean isToolkitLocked() {
- return recurLock.isLocked();
}
- public static Exception getLockedStack() {
- return recurLock.getLockedStack();
+ public static JAWTToolkitLock getJAWTToolkitLock() {
+ return jawtToolkitLock;
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
index ad0b6104b..00d64b4e4 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
@@ -38,7 +38,7 @@
package com.jogamp.nativewindow.impl.jawt;
import com.jogamp.nativewindow.impl.*;
-import com.jogamp.common.util.RecursiveToolkitLock;
+import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
import java.awt.Window;
@@ -48,14 +48,7 @@ import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
public abstract class JAWTWindow implements NativeWindow {
- protected static final boolean DEBUG = Debug.debug("JAWT");
-
- // See whether we're running in headless mode
- private static boolean headlessMode;
-
- static {
- headlessMode = GraphicsEnvironment.isHeadless();
- }
+ protected static final boolean DEBUG = JAWTUtil.DEBUG;
// lifetime: forever
protected Component component;
@@ -113,47 +106,60 @@ public abstract class JAWTWindow implements NativeWindow {
// NativeSurface
//
- private RecursiveToolkitLock recurLock = new RecursiveToolkitLock();
+ private RecursiveLock recurLock = new RecursiveLock();
protected abstract int lockSurfaceImpl() throws NativeWindowException;
- public final synchronized int lockSurface() throws NativeWindowException {
+ public final int lockSurface() throws NativeWindowException {
+ int res = LOCK_SURFACE_NOT_READY;
+
recurLock.lock();
if(recurLock.getRecursionCount() == 0) {
- return lockSurfaceImpl();
+ config.getScreen().getDevice().lock();
+ try {
+ res = lockSurfaceImpl();
+ } finally {
+ // Unlock in case surface couldn't be locked
+ if(LOCK_SURFACE_NOT_READY >= res ) {
+ config.getScreen().getDevice().unlock();
+ recurLock.unlock();
+ }
+ }
+ } else {
+ res = LOCK_SUCCESS;
}
- return LOCK_SUCCESS;
+ return res;
}
protected abstract void unlockSurfaceImpl() throws NativeWindowException;
- public synchronized void unlockSurface() {
+ public final void unlockSurface() {
recurLock.validateLocked();
if(recurLock.getRecursionCount()==0) {
- unlockSurfaceImpl();
+ try {
+ unlockSurfaceImpl();
+ } finally {
+ config.getScreen().getDevice().unlock();
+ }
}
recurLock.unlock();
}
- public synchronized boolean isSurfaceLockedByOtherThread() {
+ public final boolean isSurfaceLockedByOtherThread() {
return recurLock.isLockedByOtherThread();
}
- public synchronized boolean isSurfaceLocked() {
+ public final boolean isSurfaceLocked() {
return recurLock.isLocked();
}
- public Thread getSurfaceLockOwner() {
+ public final Thread getSurfaceLockOwner() {
return recurLock.getOwner();
}
- public Exception getSurfaceLockStack() {
- return recurLock.getLockedStack();
- }
-
public boolean surfaceSwap() {
return false;
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java
new file mode 100644
index 000000000..7eaac2ca6
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java
@@ -0,0 +1,60 @@
+/**
+ * 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 com.jogamp.nativewindow.impl.jawt.x11;
+
+import com.jogamp.nativewindow.impl.jawt.*;
+import com.jogamp.nativewindow.impl.x11.X11Util;
+import javax.media.nativewindow.ToolkitLock;
+
+/**
+ * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
+ * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
+ * <br>
+ * This strategy should only be used if AWT is using the underlying native windowing toolkit
+ * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call
+ * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets.
+ */
+public class X11JAWTToolkitLock implements ToolkitLock {
+ long displayHandle;
+
+ public X11JAWTToolkitLock(long displayHandle) {
+ this.displayHandle = displayHandle;
+ }
+
+ public final void lock() {
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); }
+ JAWTUtil.lockToolkit();
+ X11Util.XLockDisplay(displayHandle);
+ }
+
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); }
+ X11Util.XUnlockDisplay(displayHandle);
+ JAWTUtil.unlockToolkit();
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
index c74a62b7e..4a2c9ada3 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
@@ -60,79 +60,65 @@ public class X11JAWTWindow extends JAWTWindow {
if(0==displayHandle) {
displayHandle = X11Util.createThreadLocalDisplay(null);
}
- awtDevice.setHandle(displayHandle);
+ awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
}
}
protected int lockSurfaceImpl() throws NativeWindowException {
- // JAWTUtil.lockToolkit();
- // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock();
- try {
- int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- unlockSurface();
- return LOCK_SURFACE_NOT_READY;
- }
- int res = ds.Lock();
- dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
- if (!dsLocked) {
- unlockSurface();
- throw new NativeWindowException("Unable to lock surface");
- }
- // See whether the surface changed and if so destroy the old
- // OpenGL context so it will be recreated (NOTE: removeNotify
- // should handle this case, but it may be possible that race
- // conditions can cause this code to be triggered -- should test
- // more)
- if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
- ret = LOCK_SURFACE_CHANGED;
- }
- dsi = ds.GetDrawingSurfaceInfo();
- if (dsi == null) {
- unlockSurface();
- return LOCK_SURFACE_NOT_READY;
- }
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
- if (x11dsi == null) {
- unlockSurface();
- return LOCK_SURFACE_NOT_READY;
- }
- drawable = x11dsi.getDrawable();
- if (drawable == 0) {
- unlockSurface();
- return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
- }
- return ret;
- } finally {
- // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock();
- // JAWTUtil.unlockToolkit();
+ int ret = NativeWindow.LOCK_SUCCESS;
+ ds = JAWT.getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ unlockSurface();
+ return LOCK_SURFACE_NOT_READY;
}
+ int res = ds.Lock();
+ dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
+ if (!dsLocked) {
+ unlockSurface();
+ throw new NativeWindowException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated (NOTE: removeNotify
+ // should handle this case, but it may be possible that race
+ // conditions can cause this code to be triggered -- should test
+ // more)
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ret = LOCK_SURFACE_CHANGED;
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ unlockSurface();
+ return LOCK_SURFACE_NOT_READY;
+ }
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ if (x11dsi == null) {
+ unlockSurface();
+ return LOCK_SURFACE_NOT_READY;
+ }
+ drawable = x11dsi.getDrawable();
+ if (drawable == 0) {
+ unlockSurface();
+ return LOCK_SURFACE_NOT_READY;
+ } else {
+ updateBounds(dsi.getBounds());
+ }
+ return ret;
}
protected void unlockSurfaceImpl() throws NativeWindowException {
- // JAWTUtil.lockToolkit();
- // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock();
- try {
- if(null!=ds) {
- if (null!=dsi) {
- ds.FreeDrawingSurfaceInfo(dsi);
- }
- if (dsLocked) {
- ds.Unlock();
- }
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ if(null!=ds) {
+ if (null!=dsi) {
+ ds.FreeDrawingSurfaceInfo(dsi);
+ }
+ if (dsLocked) {
+ ds.Unlock();
}
- ds = null;
- dsi = null;
- x11dsi = null;
- } finally {
- // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock();
- // JAWTUtil.unlockToolkit();
+ JAWT.getJAWT().FreeDrawingSurface(ds);
}
+ ds = null;
+ dsi = null;
+ x11dsi = null;
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java
index 7cca6f9f3..081975afb 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java
@@ -89,7 +89,7 @@ public class X11SunJDKReflection {
}
try {
- return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, new Object[] {})).intValue();
+ return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, null)).intValue();
} catch (Exception e) {
return 0;
}
@@ -101,7 +101,7 @@ public class X11SunJDKReflection {
}
try {
- return ((Long) x11GraphicsDeviceGetDisplayMethod.invoke(device, new Object[] {})).longValue();
+ return ((Long) x11GraphicsDeviceGetDisplayMethod.invoke(device, null)).longValue();
} catch (Exception e) {
return 0;
}
@@ -124,7 +124,7 @@ public class X11SunJDKReflection {
}
try {
- return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, new Object[] {})).intValue();
+ return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, null)).intValue();
} catch (Exception e) {
return 0;
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java
index fbf4524a4..87324a57c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java
@@ -38,13 +38,11 @@ import com.jogamp.nativewindow.impl.x11.XVisualInfo;
import com.jogamp.nativewindow.impl.x11.X11Lib;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
- public AbstractGraphicsConfiguration
- chooseGraphicsConfiguration(Capabilities capabilities,
- CapabilitiesChooser chooser,
- AbstractGraphicsScreen screen)
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
throws IllegalArgumentException, NativeWindowException {
- if(null==screen || !(screen instanceof X11GraphicsScreen)) {
+ if(!(screen instanceof X11GraphicsScreen)) {
throw new NativeWindowException("Only valid X11GraphicsScreen are allowed");
}
return new X11GraphicsConfiguration((X11GraphicsScreen)screen, capabilities, capabilities, getXVisualInfo(screen, capabilities));
@@ -58,7 +56,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
int num[] = { -1 };
long display = screen.getDevice().getHandle();
- XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
+ XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
if(xvis==null || num[0]<1) {
return null;
@@ -84,7 +82,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
vinfo_template.setC_class(c_class);
long display = screen.getDevice().getHandle();
- XVisualInfo[] vinfos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
+ XVisualInfo[] vinfos = X11Util.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/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java
new file mode 100644
index 000000000..2e0e911b9
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java
@@ -0,0 +1,55 @@
+/**
+ * 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 com.jogamp.nativewindow.impl.x11;
+
+import javax.media.nativewindow.ToolkitLock;
+
+/**
+ * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
+ * utilizing {@link X11Util#XLockDisplay(long)}.
+ * <br>
+ * This strategy should not be used in case XInitThreads() is being used,
+ * or a higher level toolkit lock is required, ie AWT lock.
+ */
+public class X11ToolkitLock implements ToolkitLock {
+ long displayHandle;
+
+ public X11ToolkitLock(long displayHandle) {
+ this.displayHandle = displayHandle;
+ }
+
+ public final void lock() {
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); }
+ X11Util.XLockDisplay(displayHandle);
+ }
+
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); }
+ X11Util.XUnlockDisplay(displayHandle);
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
index 6871cd5f2..3e991e52e 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
@@ -38,11 +38,15 @@ import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import com.jogamp.common.util.LongObjectHashMap;
-import com.jogamp.common.util.RecursiveToolkitLock;
+import com.jogamp.common.util.locks.RecursiveLock;
import javax.media.nativewindow.*;
import com.jogamp.nativewindow.impl.*;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.security.AccessController;
/**
* Contains a thread safe X11 utility to retrieve thread local display connection,<br>
@@ -52,25 +56,58 @@ import com.jogamp.nativewindow.impl.*;
* where an application heavily utilizing this class on temporary new threads.<br>
*/
public class X11Util {
- private static final boolean DEBUG = Debug.debug("X11Util");
+ private static final boolean DEBUG = Debug.debug("X11Util");
- public static final String nullDisplayName;
+ private static String nullDisplayName = null;
+ private static boolean isFirstX11ActionOnProcess = false;
+ private static boolean isInit = false;
- static {
- NWJNILibLoader.loadNativeWindow("x11");
+ public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ if(!isInit) {
+ NWJNILibLoader.loadNativeWindow("x11");
- initialize( true );
+ /**
+ * Always issue XInitThreads() since we have independent
+ * off-thread created Display connections able to utilize multithreading, ie NEWT */
+ initialize( true );
+ // initialize( firstX11ActionOnProcess );
+ isFirstX11ActionOnProcess = firstX11ActionOnProcess;
- long dpy = X11Lib.XOpenDisplay(null);
- nullDisplayName = X11Lib.XDisplayString(dpy);
- X11Lib.XCloseDisplay(dpy);
- if(DEBUG) {
- System.out.println("X11 Display(NULL) <"+nullDisplayName+">");
+ if(DEBUG) {
+ System.out.println("X11Util.isFirstX11ActionOnProcess: "+isFirstX11ActionOnProcess);
+ }
+ isInit = true;
}
}
- public static void initSingleton() {
- // just exist to ensure static init has been run
+ public static boolean isFirstX11ActionOnProcess() {
+ return isFirstX11ActionOnProcess;
+ }
+
+ public static String getNullDisplayName() {
+ if(null==nullDisplayName) {
+ synchronized(X11Util.class) {
+ if(null==nullDisplayName) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ long dpy = X11Lib.XOpenDisplay(null);
+ X11Util.XLockDisplay(dpy);
+ try {
+ nullDisplayName = X11Lib.XDisplayString(dpy);
+ } finally {
+ X11Util.XUnlockDisplay(dpy);
+ }
+ X11Lib.XCloseDisplay(dpy);
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ if(DEBUG) {
+ System.out.println("X11 Display(NULL) <"+nullDisplayName+">");
+ }
+ }
+ }
+ }
+ return nullDisplayName;
}
private X11Util() {}
@@ -82,7 +119,7 @@ public class X11Util {
private static ThreadLocal currentDisplayMap = new ThreadLocal();
- public static class NamedDisplay extends RecursiveToolkitLock implements Cloneable {
+ public static class NamedDisplay extends RecursiveLock implements Cloneable {
String name;
long handle;
int refCount;
@@ -147,7 +184,7 @@ public class X11Util {
name = validateDisplayName(name);
NamedDisplay namedDpy = getCurrentDisplay(name);
if(null==namedDpy) {
- long dpy = X11Lib.XOpenDisplay(name);
+ long dpy = XOpenDisplay(name);
if(0==dpy) {
throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
}
@@ -199,7 +236,7 @@ public class X11Util {
if(null==globalNamedDisplayMap.remove(dpy)) { throw new RuntimeException("Internal: "+namedDpy); }
}
if(!namedDpy.isUncloseable()) {
- X11Lib.XCloseDisplay(dpy);
+ XCloseDisplay(dpy);
}
} else if(DEBUG) {
Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
@@ -281,7 +318,7 @@ public class X11Util {
/** Returns this created named display. */
public static long createDisplay(String name) {
name = validateDisplayName(name);
- long dpy = X11Lib.XOpenDisplay(name);
+ long dpy = XOpenDisplay(name);
if(0==dpy) {
throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection. Thread "+Thread.currentThread().getName());
}
@@ -292,7 +329,7 @@ public class X11Util {
globalNamedDisplayMap.put(dpy, namedDpy);
}
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Created new global "+namedDpy+". Thread "+Thread.currentThread().getName());
+ Exception e = new Exception("X11Util.Display: Created new "+namedDpy+". Thread "+Thread.currentThread().getName());
e.printStackTrace();
}
return namedDpy.getHandle();
@@ -312,7 +349,7 @@ public class X11Util {
}
if(!namedDpy.isUncloseable()) {
- X11Lib.XCloseDisplay(namedDpy.getHandle());
+ XCloseDisplay(namedDpy.getHandle());
}
}
@@ -320,42 +357,331 @@ public class X11Util {
* @return If name is null, it returns the previous queried NULL display name,
* otherwise the name. */
public static String validateDisplayName(String name) {
- return ( null == name ) ? nullDisplayName : name ;
+ return ( null == name ) ? getNullDisplayName() : name ;
}
public static String validateDisplayName(String name, long handle) {
if(null==name && 0!=handle) {
- name = getNameOfDisplay(handle);
+ name = XDisplayString(handle);
}
return validateDisplayName(name);
}
- public static boolean setSynchronizeDisplay(long handle, boolean onoff) {
- boolean res = X11Lib.XSynchronize(handle, onoff);
- return res;
+ /*******************************
+ **
+ ** Locked X11Lib wrapped functions
+ **
+ *******************************/
+ public static long XOpenDisplay(String arg0) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ return X11Lib.XOpenDisplay(arg0);
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+ public static int XSync(long display, boolean discard) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XSync(display, discard);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XSynchronize(long display, boolean onoff) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XSynchronize(display, onoff);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XineramaEnabled(long display) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XineramaEnabled(display);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static int DefaultScreen(long display) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.DefaultScreen(display);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static long RootWindow(long display, int screen_number) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.RootWindow(display, screen_number);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static String XDisplayString(long display) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XDisplayString(display);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static int XFlush(long display) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XFlush(display);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static int XFree(Buffer arg0) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ return X11Lib.XFree(arg0);
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static int XFreePixmap(long display, long arg1) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XFreePixmap(display, arg1);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static long DefaultVisualID(long display, int screen) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.DefaultVisualID(display, screen);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static long CreateDummyWindow(long display, int screen_index, long visualID) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.CreateDummyWindow(display, screen_index, visualID);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static void DestroyDummyWindow(long display, long window) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ X11Lib.DestroyDummyWindow(display, window);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static int XCloseDisplay(long display) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XCloseDisplay(display);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ 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) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
+ }
+
+ public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
}
- public static String getNameOfDisplay(long handle) {
- String name = X11Lib.XDisplayString(handle);
- return name;
+ 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) {
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ try {
+ X11Util.XLockDisplay(display);
+ try {
+ return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
+ } finally {
+ X11Util.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock();
+ }
}
public static void XLockDisplay(long handle) {
- if(DEBUG) {
- System.out.println("... X11 Display Lock try 0x"+Long.toHexString(handle));
+ if(ToolkitLock.TRACE_LOCK) {
+ System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle));
}
X11Lib.XLockDisplay(handle);
- if(DEBUG) {
- System.out.println("+++ X11 Display Lock got 0x"+Long.toHexString(handle));
- }
}
public static void XUnlockDisplay(long handle) {
- if(DEBUG) {
+ if(ToolkitLock.TRACE_LOCK) {
System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle));
}
X11Lib.XUnlockDisplay(handle);
}
- private static native void initialize(boolean initConcurrentThreadSupport);
+ private static native void initialize(boolean firstUIActionOnProcess);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index c133df5b4..b003db8f5 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -56,7 +57,15 @@ public interface AbstractGraphicsDevice extends Cloneable {
*/
public long getHandle();
+ /**
+ * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * The lock implementation must be recursive.
+ */
public void lock();
+ /**
+ * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * The lock implementation must be recursive.
+ */
public void unlock();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index e18b7b2dc..ca0f106f5 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -32,18 +32,46 @@
package javax.media.nativewindow;
+import com.jogamp.nativewindow.impl.NativeWindowFactoryImpl;
+
public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice {
private String type;
protected long handle;
+ protected ToolkitLock toolkitLock;
+ /**
+ * Create an instance with the system default {@link ToolkitLock},
+ * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * @param type
+ */
public DefaultGraphicsDevice(String type) {
this.type = type;
this.handle = 0;
+ setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) );
}
+ /**
+ * Create an instance with the system default {@link ToolkitLock}.
+ * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * @param type
+ * @param handle
+ */
public DefaultGraphicsDevice(String type, long handle) {
this.type = type;
this.handle = handle;
+ setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) );
+ }
+
+ /**
+ * Create an instance with the given {@link ToolkitLock} instance.
+ * @param type
+ * @param handle
+ * @param locker
+ */
+ public DefaultGraphicsDevice(String type, long handle, ToolkitLock locker) {
+ this.type = type;
+ this.handle = handle;
+ setToolkitLock( locker );
}
public Object clone() {
@@ -62,10 +90,46 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
return handle;
}
- public void lock() {
+ /**
+ * Set the internal ToolkitLock, which is used within the
+ * {@link #lock()} and {@link #unlock()} implementation.
+ *
+ * @param locker the ToolkitLock, if null, {@link com.jogamp.nativewindow.impl.NullToolkitLock} is being used
+ */
+ protected void setToolkitLock(ToolkitLock locker) {
+ this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ }
+
+ /**
+ * @return the used ToolkitLock
+ *
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
+ */
+ public final ToolkitLock getToolkitLock() {
+ return toolkitLock;
+ }
+
+ /**
+ * No lock is performed on the graphics device per default,
+ * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked.
+ *
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
+ */
+ public final void lock() {
+ toolkitLock.lock();
}
- public void unlock() {
+ /**
+ * No lock is performed on the graphics device per default,
+ * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked.
+ *
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
+ */
+ public final void unlock() {
+ toolkitLock.unlock();
}
public String toString() {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index 0a1a91876..75c8aea22 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -78,7 +78,7 @@ public abstract class GraphicsConfigurationFactory {
if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
try {
GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory)
- ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", new Object[] {},
+ ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", null,
GraphicsConfigurationFactory.class.getClassLoader());
registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory);
} catch (Exception e) {
@@ -198,9 +198,29 @@ public abstract class GraphicsConfigurationFactory {
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
* @see javax.media.nativewindow.DefaultGraphicsConfiguration#setChosenCapabilities(Capabilities caps)
*/
- public abstract AbstractGraphicsConfiguration
+ public final AbstractGraphicsConfiguration
chooseGraphicsConfiguration(Capabilities capabilities,
CapabilitiesChooser chooser,
AbstractGraphicsScreen screen)
+ throws IllegalArgumentException, NativeWindowException {
+ if(null==screen) {
+ throw new NativeWindowException("Screen is null");
+ }
+ AbstractGraphicsDevice device = screen.getDevice();
+ if(null==device) {
+ throw new NativeWindowException("Screen's Device is null");
+ }
+ device.lock();
+ try {
+ return chooseGraphicsConfigurationImpl(capabilities, chooser, screen);
+ } finally {
+ device.unlock();
+ }
+ }
+
+ protected abstract AbstractGraphicsConfiguration
+ chooseGraphicsConfigurationImpl(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen screen)
throws IllegalArgumentException, NativeWindowException;
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index ef45a79d3..a5b71fbf8 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -1,6 +1,5 @@
/**
* Copyright 2010 JogAmp Community. All rights reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -63,14 +62,17 @@ public interface NativeSurface extends SurfaceUpdatedListener {
* This call allows recursion from the same thread.<P>
*
* The implementation may want to aquire the
- * application level {@link com.jogamp.common.util.RecursiveToolkitLock}
+ * application level {@link com.jogamp.common.util.locks.RecursiveLock}
* first before proceeding with a native surface lock. <P>
*
+ * The implementation shall also invoke {@link AbstractGraphicsDevice#lock()}
+ * for the initial lock (recursive count zero).<P>
+ *
* @return {@link #LOCK_SUCCESS}, {@link #LOCK_SURFACE_CHANGED} or {@link #LOCK_SURFACE_NOT_READY}.
*
* @throws RuntimeException after timeout when waiting for the surface lock
*
- * @see com.jogamp.common.util.RecursiveToolkitLock
+ * @see com.jogamp.common.util.locks.RecursiveLock
*/
public int lockSurface();
@@ -79,10 +81,13 @@ public interface NativeSurface extends SurfaceUpdatedListener {
*
* Shall not modify the surface handle, see {@link #lockSurface()} <P>
*
+ * The implementation shall also invoke {@link AbstractGraphicsDevice#unlock()}
+ * for the final unlock (recursive count zero).<P>
+ *
* @throws RuntimeException if surface is not locked
*
* @see #lockSurface
- * @see com.jogamp.common.util.RecursiveToolkitLock
+ * @see com.jogamp.common.util.locks.RecursiveLock
*/
public void unlockSurface() throws NativeWindowException ;
@@ -102,14 +107,6 @@ public interface NativeSurface extends SurfaceUpdatedListener {
public Thread getSurfaceLockOwner();
/**
- * Return the lock-exception, or null if not locked.
- *
- * The lock-exception is created at {@link #lockSurface()}
- * and hence holds the locker's call stack.
- */
- public Exception getSurfaceLockStack();
-
- /**
* Provide a mechanism to utilize custom (pre-) swap surface
* code. This method is called before the render toolkit (e.g. JOGL)
* swaps the buffer/surface. The implementation may itself apply the swapping,
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index f716e8ac9..7897460a0 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,13 +33,14 @@
package javax.media.nativewindow;
-import java.lang.reflect.*;
import java.security.*;
import java.util.*;
import com.jogamp.common.util.*;
import com.jogamp.common.jvm.JVMUtil;
import com.jogamp.nativewindow.impl.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
/** Provides a pluggable mechanism for arbitrary window toolkits to
adapt their components to the {@link NativeWindow} interface,
@@ -74,9 +76,20 @@ public abstract class NativeWindowFactory {
private static String nativeOSNamePure;
private static String nativeWindowingTypeCustom;
private static String nativeOSNameCustom;
- private static final boolean isAWTAvailable;
+ private static boolean isAWTAvailable;
public static final String AWTComponentClassName = "java.awt.Component" ;
+ public static final String JAWTUtilClassName = "com.jogamp.nativewindow.impl.jawt.JAWTUtil" ;
public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util";
+ public static final String X11JAWTToolkitLockClassName = "com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock" ;
+ public static final String X11ToolkitLockClassName = "com.jogamp.nativewindow.impl.x11.X11ToolkitLock" ;
+ private static Class jawtUtilClass;
+ private static Method jawtUtilGetJAWTToolkitMethod;
+ private static Method jawtUtilInitMethod;
+ private static Class x11JAWTToolkitLockClass;
+ private static Constructor x11JAWTToolkitLockConstructor;
+ private static Class x11ToolkitLockClass;
+ private static Constructor x11ToolkitLockConstructor;
+ private static boolean isFirstUIActionOnProcess;
/** Creates a new NativeWindowFactory instance. End users do not
need to call this method. */
@@ -100,54 +113,117 @@ public abstract class NativeWindowFactory {
static {
JVMUtil.initSingleton();
+ }
- // Gather the windowing OS first
- AccessControlContext acc = AccessController.getContext();
- nativeOSNamePure = Debug.getProperty("os.name", false, acc);
- nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase());
- nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc);
- if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) {
- nativeOSNameCustom = nativeOSNamePure;
- nativeWindowingTypeCustom = nativeWindowingTypePure;
- } else {
- nativeWindowingTypeCustom = nativeOSNameCustom;
- }
-
- ClassLoader cl = NativeWindowFactory.class.getClassLoader();
+ static boolean initialized = false;
+
+ /**
+ * Static one time initialization of this factory.<br>
+ * This initialization method <b>must be called</b> once by the program or utilizing modules!<br>
+ * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
+ * otherwise <code>false</code>.
+ */
+ public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
+ if(!initialized) {
+ initialized = true;
+
+ if(DEBUG) {
+ Throwable td = new Throwable("Info: NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")");
+ td.printStackTrace();
+ }
- if( TYPE_X11.equals(nativeWindowingTypePure) ) {
- ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { }, cl );
- }
+ // Gather the windowing OS first
+ AccessControlContext acc = AccessController.getContext();
+ nativeOSNamePure = Debug.getProperty("os.name", false, acc);
+ nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase());
+ nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc);
+ if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) {
+ nativeOSNameCustom = nativeOSNamePure;
+ nativeWindowingTypeCustom = nativeWindowingTypePure;
+ } else {
+ nativeWindowingTypeCustom = nativeOSNameCustom;
+ }
- registeredFactories = Collections.synchronizedMap(new HashMap());
+ ClassLoader cl = NativeWindowFactory.class.getClassLoader();
- String factoryClassName = null;
+ if( TYPE_X11.equals(nativeWindowingTypePure) ) {
+ // explicit initialization of X11Util
+ ReflectionUtil.callStaticMethod(X11UtilClassName, "initSingleton",
+ new Class[] { boolean.class },
+ new Object[] { new Boolean(firstUIActionOnProcess) }, cl );
+ }
+ isFirstUIActionOnProcess = firstUIActionOnProcess;
+
+ if( !Debug.getBooleanProperty("java.awt.headless", true, acc) &&
+ ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) &&
+ ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ) {
+
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader());
+ jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", null);
+ jawtUtilInitMethod.setAccessible(true);
+ jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{});
+ jawtUtilGetJAWTToolkitMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
+ }
+ return null;
+ }
+ });
+ if(null != jawtUtilClass && null != jawtUtilGetJAWTToolkitMethod && null != jawtUtilInitMethod) {
+ ReflectionUtil.callMethod(null, jawtUtilInitMethod, null);
+
+ Object resO = ReflectionUtil.callStaticMethod(JAWTUtilClassName, "isHeadlessMode", null, null, cl );
+ if(resO instanceof Boolean) {
+ // AWT is only available in case all above classes are available
+ // and AWT is not int headless mode
+ isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE);
+ } else {
+ isAWTAvailable = false;
+ }
+ } else {
+ isAWTAvailable = false;
+ }
+ } else {
+ isAWTAvailable = false;
+ }
- // register our default factory -> NativeWindow
- NativeWindowFactory factory = new NativeWindowFactoryImpl();
- nativeWindowClass = javax.media.nativewindow.NativeWindow.class;
- registerFactory(nativeWindowClass, factory);
- defaultFactory = factory;
-
- // We break compile-time dependencies on the AWT here to
- // make it easier to run this code on mobile devices
- isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) &&
- ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) &&
- ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ;
-
- if ( isAWTAvailable ) {
- // register either our default factory or (if exist) the X11/AWT one -> AWT Component
- registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory);
- }
+ registeredFactories = Collections.synchronizedMap(new HashMap());
+
+ // register our default factory -> NativeWindow
+ NativeWindowFactory factory = new NativeWindowFactoryImpl();
+ nativeWindowClass = javax.media.nativewindow.NativeWindow.class;
+ registerFactory(nativeWindowClass, factory);
+ defaultFactory = factory;
+
+ if ( isAWTAvailable ) {
+ // register either our default factory or (if exist) the X11/AWT one -> AWT Component
+ registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory);
+ }
- if(DEBUG) {
- System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+
- ", defaultFactory "+factory);
+ if( TYPE_X11 == nativeWindowingTypePure ) {
+ // passing through RuntimeException if not exists intended
+ x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl);
+ x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } );
+ if( isAWTAvailable() ) {
+ x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl);
+ x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } );
+ }
+ }
+
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess);
+ System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
+ }
}
}
- public static void initSingleton() {
- // just exist to ensure static init has been run
+ /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>,
+ otherwise false. */
+ public static boolean isFirstUIActionOnProcess() {
+ return isFirstUIActionOnProcess;
}
/** @return true if not headless, AWT Component and NativeWindow's AWT part available */
@@ -171,6 +247,91 @@ public abstract class NativeWindowFactory {
return defaultFactory;
}
+ /**
+ * Provides the system default {@link ToolkitLock}, a singleton instance.
+ * <br>
+ * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock}
+ * in case of a <b>X11 system</b> <em>and</em> <b>AWT availability</b> and if
+ * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br>
+ * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned.
+ */
+ public static ToolkitLock getDefaultToolkitLock() {
+ return getDefaultToolkitLock(getNativeWindowType(false));
+ }
+
+ /**
+ * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance.
+ * <br>
+ * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock}
+ * in case of a <b>X11 type</b> or <b>AWT type / X11 system</b> <em>and</em> <b>AWT availability</b> and if
+ * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br>
+ * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned.
+ */
+ public static ToolkitLock getDefaultToolkitLock(String type) {
+ if( isAWTAvailable() && !isFirstUIActionOnProcess() &&
+ ( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) ) {
+ return getAWTToolkitLock();
+ }
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
+ protected static ToolkitLock getAWTToolkitLock() {
+ Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod, null);
+
+ if(resO instanceof ToolkitLock) {
+ return (ToolkitLock) resO;
+ } else {
+ throw new RuntimeException("JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock");
+ }
+ }
+
+ public static ToolkitLock getNullToolkitLock() {
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+ /**
+ * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
+ * <br>
+ * This is a {@link com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock}
+ * in case of a <b>X11 type</b> <em>and</em> <b>AWT availability</b> and if
+ * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br>
+ * or a {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock}
+ * in case of a <b>X11 type</b> <em>and</em> <b>no AWT availability</b> and if
+ * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br>
+ * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned.
+ */
+ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ if( TYPE_X11 == type ) {
+ if( 0== deviceHandle ) {
+ throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
+ }
+ if( !isFirstUIActionOnProcess() ) {
+ if( isAWTAvailable() ) {
+ return createX11AWTToolkitLock(deviceHandle);
+ } else {
+ return createX11ToolkitLock(deviceHandle);
+ }
+ }
+ }
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
+ protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
+ try {
+ return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ protected static ToolkitLock createX11ToolkitLock(long deviceHandle) {
+ try {
+ return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+
/** Returns the appropriate NativeWindowFactory to handle window
objects of the given type. The windowClass might be {@link
NativeWindow NativeWindow}, in which case the client has
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
new file mode 100644
index 000000000..09c89ebe3
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow;
+
+import com.jogamp.nativewindow.impl.Debug;
+import java.security.AccessController;
+
+/**
+ * Marker for a singleton global recursive blocking lock implementation,
+ * optionally locking a native windowing toolkit as well.
+ * <br>
+ * One use case is the AWT locking on X11, see {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock}.
+ */
+public interface ToolkitLock {
+ public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.TraceLock", true, AccessController.getContext());
+
+ public void lock();
+ public void unlock();
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
index d326b9159..e91261211 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
@@ -43,17 +43,18 @@ import javax.media.nativewindow.*;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.media.nativewindow.AbstractGraphicsDevice;
-import com.jogamp.nativewindow.impl.*;
/** A wrapper for an AWT GraphicsDevice allowing it to be
handled in a toolkit-independent manner. */
public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
private GraphicsDevice device;
+ private String subType;
protected AWTGraphicsDevice(GraphicsDevice device) {
super(NativeWindowFactory.TYPE_AWT);
this.device = device;
+ this.subType = null;
}
public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice) {
@@ -73,14 +74,23 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
/**
* In case the native handle was specified, e.g. using X11,
- * we shall be able to mark it.
+ * we shall be able to mark it.<br>
+ * This will also set the subType, queried with {@link #getSubType()}
+ * and reset the ToolkitLock type with {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}
+ * and {@link #setToolkitLock(javax.media.nativewindow.ToolkitLock)}.
*/
- public void setHandle(long handle) {
+ public void setSubType(String subType, long handle) {
this.handle = handle;
+ this.subType = subType;
+ setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) );
+ }
+
+ public String getSubType() {
+ return subType;
}
public String toString() {
- return getClass().toString()+"[type "+getType()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
+ return getClass().toString()+"[type "+getType()+"[subType "+getSubType()+"], awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
index 192abf775..31744702d 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
@@ -33,14 +33,14 @@
package javax.media.nativewindow.x11;
import javax.media.nativewindow.*;
-import com.jogamp.nativewindow.impl.*;
-import com.jogamp.nativewindow.impl.x11.X11Util;
/** Encapsulates a graphics device on X11 platforms.
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- /** Constructs a new X11GraphicsDevice corresponding to the given native display handle. */
+ /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.
+ */
public X11GraphicsDevice(long display) {
super(NativeWindowFactory.TYPE_X11, display);
if(0==display) {
@@ -48,17 +48,19 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
}
- public Object clone() {
- return super.clone();
- }
-
- public void lock() {
- X11Util.XLockDisplay(handle);
+ /**
+ * @param display the Display connection
+ * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ */
+ public X11GraphicsDevice(long display, ToolkitLock locker) {
+ super(NativeWindowFactory.TYPE_X11, display, locker);
+ if(0==display) {
+ throw new NativeWindowException("null display");
+ }
}
- public void unlock() {
- X11Util.XUnlockDisplay(handle);
+ public Object clone() {
+ return super.clone();
}
-
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index 97bdc37cf..73af5f852 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -34,7 +34,6 @@ package javax.media.nativewindow.x11;
import javax.media.nativewindow.*;
import com.jogamp.nativewindow.impl.x11.X11Util;
-import com.jogamp.nativewindow.impl.x11.X11Lib;
/** Encapsulates a screen index on X11
platforms. Objects of this type are passed to {@link
@@ -57,21 +56,21 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Creates a new X11GraphicsScreen using a thread local display connection */
public static AbstractGraphicsScreen createDefault() {
long display = X11Util.createThreadLocalDisplay(null);
- int scrnIdx = X11Lib.DefaultScreen(display);
+ int scrnIdx = X11Util.DefaultScreen(display);
return createScreenDevice(display, scrnIdx);
}
public long getDefaultVisualID() {
// It still could be an AWT hold handle ..
long display = getDevice().getHandle();
- int scrnIdx = X11Lib.DefaultScreen(display);
- return X11Lib.DefaultVisualID(display, scrnIdx);
+ int scrnIdx = X11Util.DefaultScreen(display);
+ return X11Util.DefaultVisualID(display, scrnIdx);
}
private static int fetchScreen(X11GraphicsDevice device, int screen) {
// It still could be an AWT hold handle ..
long display = device.getHandle();
- if(X11Lib.XineramaEnabled(display)) {
+ if(X11Util.XineramaEnabled(display)) {
screen = 0; // Xinerama -> 1 screen
}
return screen;