diff options
Diffstat (limited to 'src/nativewindow')
6 files changed, 162 insertions, 17 deletions
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 b3c706ed8..527d7750d 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java @@ -42,6 +42,7 @@ import javax.media.nativewindow.*; import java.awt.GraphicsEnvironment; import java.lang.reflect.*; +import java.security.*; public class JAWTUtil { @@ -53,6 +54,12 @@ public class JAWTUtil { 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; + static { JAWTJNILibLoader.loadAWTImpl(); JAWTJNILibLoader.loadNativeWindow("awt"); @@ -73,6 +80,32 @@ public class JAWTUtil { 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; + } + }); + 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; } private static Exception lockedStack; @@ -99,6 +132,30 @@ public class JAWTUtil { return headlessMode; } + private static void awtLock() { + if(useSunToolkitAWTLock) { + try { + sunToolkitAWTLockMethod.invoke(null, null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtLock failed", e); + } + } else { + JAWT.getJAWT().Lock(); + } + } + + private static void awtUnlock() { + if(useSunToolkitAWTLock) { + try { + sunToolkitAWTUnlockMethod.invoke(null, null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtUnlock failed", e); + } + } else { + JAWT.getJAWT().Unlock(); + } + } + public static synchronized void lockToolkit() throws NativeWindowException { if (isJava2DQueueFlusherThread()) return; @@ -115,7 +172,7 @@ public class JAWTUtil { return; } - JAWT.getJAWT().Lock(); + awtLock(); } public static synchronized void unlockToolkit() { @@ -130,7 +187,7 @@ public class JAWTUtil { return; } - JAWT.getJAWT().Unlock(); + awtUnlock(); } } 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 f2977e8f0..77bf93204 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 @@ -37,6 +37,7 @@ package com.jogamp.nativewindow.impl.jawt.x11; import javax.media.nativewindow.*; +import javax.media.nativewindow.awt.*; import javax.media.nativewindow.x11.*; import com.jogamp.nativewindow.impl.x11.*; @@ -53,6 +54,19 @@ public class X11JAWTWindow extends JAWTWindow { } protected void initNative() throws NativeWindowException { + if(0==config.getScreen().getDevice().getHandle()) { + AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice(); + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice()); + if(0==displayHandle) { + displayHandle = X11Util.createThreadLocalDefaultDisplay(); + } + awtDevice.setHandle(displayHandle); + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + } } public synchronized int lockSurface() throws NativeWindowException { 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 d93302e57..196e8f4e2 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -56,7 +56,17 @@ public class X11Util { static { NWJNILibLoader.loadNativeWindow("x11"); - initialize(); + + // No concurrent threading support in case AWT could be used, + // Mixing AWT and X11/NEWT results in a segmentation fault: + // C pthread_mutex_lock+0x4 + // J sun.awt.X11.XlibWrapper.XGetDefault + // J sun.awt.X11.XToolkit.initializeMultiClickTime + // J sun.awt.X11.XToolkit.getMultiClickTime + // + // It seems like (Oracle's) AWT's Display locking is buggy. + // + initialize( ! NativeWindowFactory.isAWTAvailable() ) ; } public static void initSingleton() { @@ -142,6 +152,8 @@ public class X11Util { if(0==dpy) { throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName()); } + // if you like to debug and synchronize X11 commands .. + // setSynchronizeDisplay(dpy, true); namedDpy = new NamedDisplay(name, dpy); addCurrentDisplay( namedDpy ); synchronized(globalLock) { @@ -207,6 +219,22 @@ public class X11Util { return closeThreadLocalDisplay(ndpy.getName()); } + public static boolean setSynchronizeDisplay(long handle, boolean onoff) { + String name; + XLockDisplay(handle); + boolean res = X11Lib.XSynchronize(handle, onoff); + XUnlockDisplay(handle); + return res; + } + + public static String getNameOfDisplay(long handle) { + String name; + XLockDisplay(handle); + name = X11Lib.XDisplayString(handle); + XUnlockDisplay(handle); + return name; + } + public static void XLockDisplay(long handle) { if(DEBUG_XDISPLAY_LOCK) { NamedDisplay ndpy; @@ -298,5 +326,5 @@ public class X11Util { return (NamedDisplay) displayMap.get(name); } - private static native void initialize(); + private static native void initialize(boolean initConcurrentThreadSupport); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 944fdee74..2125fb4c0 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -74,6 +74,8 @@ public abstract class NativeWindowFactory { private static String nativeOSNamePure; private static String nativeWindowingTypeCustom; private static String nativeOSNameCustom; + private static final boolean isAWTAvailable; + private static final String awtComponentClassName = "java.awt.Component" ; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -123,21 +125,17 @@ public abstract class NativeWindowFactory { // We break compile-time dependencies on the AWT here to // make it easier to run this code on mobile devices - Class componentClass = null; - if ( ReflectionUtil.isClassAvailable("java.awt.Component") && - ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") ) { - try { - componentClass = ReflectionUtil.getClass("java.awt.Component", false); - } catch (Exception e) { } - } + isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && + ReflectionUtil.isClassAvailable(awtComponentClassName) && + ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") ; boolean toolkitLockForced = Debug.getBooleanProperty("nativewindow.locking", true, acc); - boolean awtToolkitLockDisabled = Debug.getBooleanProperty("java.awt.headless", true, acc) || + boolean awtToolkitLockDisabled = !isAWTAvailable || Debug.getBooleanProperty("nativewindow.nolocking", true, acc) ; NativeWindowFactory _factory = null; - if( !awtToolkitLockDisabled && null!=componentClass && TYPE_X11.equals(nativeWindowingTypeCustom) ) { + if( !awtToolkitLockDisabled && TYPE_X11.equals(nativeWindowingTypeCustom) ) { // There are certain operations that may be done by // user-level native code which must share the display // connection with the underlying window toolkit. In JOGL, @@ -195,9 +193,9 @@ public abstract class NativeWindowFactory { factory = _factory; } - if(null!=componentClass) { + if ( isAWTAvailable ) { // register either our default factory or (if exist) the X11/AWT one -> AWT Component - registerFactory(componentClass, factory); + registerFactory(ReflectionUtil.getClass(awtComponentClassName, false), factory); } defaultFactory = factory; @@ -207,6 +205,9 @@ public abstract class NativeWindowFactory { } } + /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ + public static boolean isAWTAvailable() { return isAWTAvailable; } + public static String getNativeOSName(boolean useCustom) { return useCustom?nativeOSNameCustom:nativeOSNamePure; } diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java index 9b48f8f6e..f56248e67 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java @@ -40,7 +40,9 @@ package javax.media.nativewindow.awt; import javax.media.nativewindow.*; +import java.awt.Component; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; import java.awt.Transparency; import java.awt.image.ColorModel; import javax.media.nativewindow.AbstractGraphicsConfiguration; @@ -67,6 +69,40 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple this.encapsulated=null; } + /** + * @param capsChosen if null, <code>capsRequested</code> is copied and aligned + * with the graphics capabilties of the AWT Component to produce the chosen Capabilties. + * Otherwise the <code>capsChosen</code> is used. + */ + public static AWTGraphicsConfiguration create(Component awtComp, Capabilities capsChosen, Capabilities capsRequested) + { + AWTGraphicsScreen awtScreen = null; + AWTGraphicsDevice awtDevice = null; + GraphicsDevice awtGraphicsDevice = null; + GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration(); + if(null!=awtGfxConfig) { + awtGraphicsDevice = awtGfxConfig.getDevice(); + if(null!=awtGraphicsDevice) { + // Create Device/Screen + awtDevice = new AWTGraphicsDevice(awtGraphicsDevice); + awtScreen = new AWTGraphicsScreen(awtDevice); + } + } + if(null==awtScreen) { + // use defaults since no native peer is available yet + awtScreen = (AWTGraphicsScreen) AWTGraphicsScreen.createScreenDevice(-1); + awtDevice = (AWTGraphicsDevice) awtScreen.getDevice(); + awtGraphicsDevice = awtDevice.getGraphicsDevice(); + } + + if(null==capsChosen) { + capsChosen = (Capabilities) capsRequested.clone() ; + GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration(); + setupCapabilitiesRGBABits(capsChosen, gc); + } + return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig); + } + public Object clone() { return super.clone(); } diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index b8a5004c4..23ff5f854 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -247,8 +247,18 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) { static int _initialized=0; JNIEXPORT void JNICALL -Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused) { +Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused, jboolean initConcurrentThreadSupport) { if(0==_initialized) { + if( JNI_TRUE == initConcurrentThreadSupport ) { + if( 0 == XInitThreads() ) { + fprintf(stderr, "Warning: XInitThreads() failed\n"); + } else { + fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n"); + } + } else { + fprintf(stderr, "Info: XInitThreads() _not_ called for concurrent Thread support\n"); + } + _initClazzAccess(env); x11ErrorHandlerEnable(1, env); x11IOErrorHandlerEnable(1, env); @@ -350,7 +360,6 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jcla XUnlockDisplay((Display *) (intptr_t) display); } - /* Java->C glue code: * Java package: com.jogamp.nativewindow.impl.x11.X11Lib * Java method: int XCloseDisplay(long display) |