diff options
author | Sven Gothel <[email protected]> | 2010-05-27 14:34:52 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-05-27 14:34:52 +0200 |
commit | c787f50d77e2491eb0d8201d534a6fa4885a929e (patch) | |
tree | 654b2c68c90323458be6375d352f5fc6df1e8a63 | |
parent | 944bef5e70e0e8fe85a147fa7304c35f18d1957b (diff) |
Fix NativeWindow/NEWT Unique Display Naming, X11 use real NULL Display name
Use proper (X11) Display names to avoid multiple Display instances.
The problem was in case of 'wrapping' another X11 Display,
a previous Display instance used 'nil' to reflect the null default Display
but the wrapped instance (using a Display handle) the proper Display name.
Now all (X11) Display's are using the proper Display name instead of a dummy 'nil' name.
- Fix: NEWT null Display name is validated upfront, instead of changing it later
- Fix: Nativewindow's X11Util gathers the systems NULL Display name and offers
a validation method
- Fix: NEWT X11 Display validates the NULL Display name properly
9 files changed, 108 insertions, 62 deletions
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 196e8f4e2..08b2ceec9 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -54,6 +54,8 @@ public class X11Util { private static final boolean DEBUG = Debug.debug("X11Util"); private static final boolean DEBUG_XDISPLAY_LOCK = false; + public static final String nullDisplayName; + static { NWJNILibLoader.loadNativeWindow("x11"); @@ -67,6 +69,18 @@ public class X11Util { // It seems like (Oracle's) AWT's Display locking is buggy. // initialize( ! NativeWindowFactory.isAWTAvailable() ) ; + + long dpy = X11Lib.XOpenDisplay(null); + XLockDisplay(dpy); + try { + nullDisplayName = X11Lib.XDisplayString(dpy); + } finally { + XUnlockDisplay(dpy); + } + X11Lib.XCloseDisplay(dpy); + if(DEBUG) { + System.out.println("X11 Display(NULL) <"+nullDisplayName+">"); + } } public static void initSingleton() { @@ -82,8 +96,6 @@ public class X11Util { private static ThreadLocal currentDisplayMap = new ThreadLocal(); - public static final String nullDeviceName = "nil" ; - public static class NamedDisplay extends RecursiveToolkitLock implements Cloneable { String name; long handle; @@ -98,7 +110,6 @@ public class X11Util { } public final String getName() { return name; } - public final String getNameSafe() { return null == name ? nullDeviceName : name; } public final long getHandle() { return handle; } public final int getRefCount() { return refCount; } public final boolean isUncloseable() { return unCloseable; } @@ -134,6 +145,20 @@ public class X11Util { return num; } + /** + * @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 ; + } + + public static String validateDisplayName(String name, long handle) { + if(null==name && 0!=handle) { + name = getNameOfDisplay(handle); + } + return ( null == name ) ? nullDisplayName : name ; + } + /** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */ public static Map getCurrentDisplayMap() { return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone(); @@ -146,6 +171,7 @@ public class X11Util { /** Returns this thread named display. If it doesn not exist, it is being created, otherwise the reference count is increased */ public static long createThreadLocalDisplay(String name) { + name = validateDisplayName(name); NamedDisplay namedDpy = getCurrentDisplay(name); if(null==namedDpy) { long dpy = X11Lib.XOpenDisplay(name); @@ -179,6 +205,7 @@ public class X11Util { or the reference count goes below 0. */ public static long closeThreadLocalDisplay(String name) { + name = validateDisplayName(name); NamedDisplay namedDpy = getCurrentDisplay(name); if(null==namedDpy) { throw new RuntimeException("X11Util.Display: Display("+name+") with given name is not mapped to TLS in thread "+Thread.currentThread().getName()); @@ -220,18 +247,24 @@ public class X11Util { } public static boolean setSynchronizeDisplay(long handle, boolean onoff) { - String name; + boolean res=false; XLockDisplay(handle); - boolean res = X11Lib.XSynchronize(handle, onoff); - XUnlockDisplay(handle); + try { + res = X11Lib.XSynchronize(handle, onoff); + } finally { + XUnlockDisplay(handle); + } return res; } public static String getNameOfDisplay(long handle) { String name; XLockDisplay(handle); - name = X11Lib.XDisplayString(handle); - XUnlockDisplay(handle); + try { + name = X11Lib.XDisplayString(handle); + } finally { + XUnlockDisplay(handle); + } return name; } @@ -299,7 +332,7 @@ public class X11Util { Map displayMap = getCurrentDisplayMapImpl(); NamedDisplay oldDisplay = null; synchronized(displayMap) { - oldDisplay = (NamedDisplay) displayMap.put(newDisplay.getNameSafe(), newDisplay); + oldDisplay = (NamedDisplay) displayMap.put(newDisplay.getName(), newDisplay); displayMap.notifyAll(); } return oldDisplay; @@ -310,7 +343,7 @@ public class X11Util { private static NamedDisplay removeCurrentDisplay(NamedDisplay ndpy) { Map displayMap = getCurrentDisplayMapImpl(); synchronized(displayMap) { - NamedDisplay ndpyDel = (NamedDisplay) displayMap.remove(ndpy.getNameSafe()); + NamedDisplay ndpyDel = (NamedDisplay) displayMap.remove(ndpy.getName()); if(ndpyDel!=ndpy) { throw new RuntimeException("Wrong mapping req: "+ndpy+", got "+ndpyDel); } @@ -321,7 +354,6 @@ public class X11Util { /** Returns the thread local display mapped to the given name */ private static NamedDisplay getCurrentDisplay(String name) { - if(null==name) name=nullDeviceName; Map displayMap = getCurrentDisplayMapImpl(); return (NamedDisplay) displayMap.get(name); } diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 6705db970..674a45ded 100755 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -127,17 +127,18 @@ public abstract class Display { /** Make sure to reuse a Display with the same name */ protected static Display create(String type, String name, final long handle) { try { - if(null==name && 0!=handle) { - name="wrapping-0x"+Long.toHexString(handle); // may change within implementation .. - } + Class displayClass = getDisplayClass(type); + Display tmpDisplay = (Display) displayClass.newInstance(); + name = tmpDisplay.validateDisplayName(name, handle); + if(DEBUG) { dumpDisplayMap("Display.create("+getFQName(type, name)+") BEGIN"); } Display display = getCurrentDisplay(type, name); if(null==display) { - Class displayClass = getDisplayClass(type); - display = (Display) displayClass.newInstance(); - display.name=name; + display = tmpDisplay; + tmpDisplay = null; + display.name = name; display.type=type; display.refCount=1; @@ -155,11 +156,11 @@ public abstract class Display { display.edt = display.edtUtil.start(); display.edtUtil.invokeAndWait(new Runnable() { public void run() { - f_dpy.createNative(handle); + f_dpy.createNative(); } } ); } else { - display.createNative(handle); + display.createNative(); } if(null==display.aDevice) { throw new RuntimeException("Display.createNative() failed to instanciate an AbstractGraphicsDevice"); @@ -169,6 +170,7 @@ public abstract class Display { System.err.println("Display.create("+getFQName(type, name)+") NEW: "+display+" "+Thread.currentThread()); } } else { + tmpDisplay = null; synchronized(display) { display.refCount++; if(DEBUG) { @@ -224,7 +226,7 @@ public abstract class Display { } } - protected abstract void createNative(long handle); + protected abstract void createNative(); protected abstract void closeNative(); public final String getType() { @@ -241,6 +243,13 @@ public abstract class Display { static final String nilString = "nil" ; + protected String validateDisplayName(String name, long handle) { + if(null==name && 0!=handle) { + name="wrapping-0x"+Long.toHexString(handle); + } + return ( null == name ) ? nilString : name ; + } + public static final String getFQName(String type, String name) { if(null==type) type=nilString; if(null==name) name=nilString; @@ -276,32 +285,49 @@ public abstract class Display { private LinkedList/*<NEWTEvent>*/ events = new LinkedList(); protected void dispatchMessages() { - NEWTEvent e; - do { + if(!events.isEmpty()) { synchronized(events) { - if (!events.isEmpty()) { - e = (NEWTEvent) events.removeFirst(); - } else { - e = null; - } - } - if (e != null) { - Object source = e.getSource(); - if(source instanceof Window) { - ((Window)source).sendEvent(e); - } else { - throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + while (!events.isEmpty()) { + NEWTEvent e = (NEWTEvent) events.removeFirst(); + Object source = e.getSource(); + if(source instanceof Window) { + ((Window)source).sendEvent(e); + } else { + throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + } } + events.notifyAll(); } - } while (e != null); + } dispatchMessagesNative(); } public void enqueueEvent(NEWTEvent e) { + enqueueEvent(false, e); + } + + public void enqueueEvent(boolean wait, NEWTEvent e) { synchronized(events) { + if(DEBUG) { + System.out.println("Display.enqueueEvent: START - wait "+wait+", "+e); + } events.addLast(e); } + if(wait && !events.isEmpty()) { + synchronized(events) { + while(!events.isEmpty()) { + try { + events.wait(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + } + if(DEBUG) { + System.out.println("Display.enqueueEvent: END - wait "+wait+", "+e); + } } diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java index b0b518c59..f54e66f07 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java @@ -44,7 +44,7 @@ public class AWTDisplay extends Display { public AWTDisplay() { } - protected void createNative(long handle) { + protected void createNative() { aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null); // default } diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java index ac27da9ef..d19aaf796 100644 --- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java @@ -58,10 +58,10 @@ public class Display extends com.jogamp.newt.Display { public Display() { } - protected void createNative(long handle) { + protected void createNative() { synchronized(Display.class) { if(0==initCounter) { - displayHandle = (0 == handle) ? CreateDisplay() : handle; + displayHandle = CreateDisplay(); if(0==displayHandle) { throw new NativeWindowException("Couldn't initialize GDL Display"); } diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java index 6e1119a9d..0c4362a9e 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java @@ -70,7 +70,7 @@ public class MacDisplay extends Display { MainThread.invoke(false, dispatchAction); } - protected void createNative(long handle) { + protected void createNative() { aDevice = new MacOSXGraphicsDevice(); } diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java index c08499359..c2d323e56 100644 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java @@ -56,10 +56,8 @@ public class Display extends com.jogamp.newt.Display { public Display() { } - protected void createNative(long handle) { - if( 0 == handle ) { - handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight); - } + protected void createNative() { + long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight); if (handle == EGL.EGL_NO_DISPLAY) { throw new NativeWindowException("BC EGL CreateDisplay failed"); } diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java index bb5f1cc7a..2ab30773f 100755 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java @@ -57,12 +57,9 @@ public class KDDisplay extends Display { public KDDisplay() { } - protected void createNative(long handle) { + protected void createNative() { // FIXME: map name to EGL_*_DISPLAY - // FIXME: what do to with external handle ? - if(0==handle) { - handle = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); - } + long handle = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); if (handle == EGL.EGL_NO_DISPLAY) { throw new NativeWindowException("eglGetDisplay failed"); } diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java index f75c11cfb..ef033d1c8 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java @@ -60,7 +60,7 @@ public class WindowsDisplay extends Display { public WindowsDisplay() { } - protected void createNative(long handle) { + protected void createNative() { aDevice = new WindowsGraphicsDevice(); } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java index 3b0868620..54fe0542b 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java @@ -60,19 +60,12 @@ public class X11Display extends Display { public X11Display() { } - protected void createNative(long handle) { - if(0 != handle) { - // Can't use that Display handle directly, - // but we open up a new connection to the same Display by it's name - String newName = X11Util.getNameOfDisplay(handle); - if(DEBUG) { - System.out.println("Changing Display Name (provided handle): "+name+" -> 0x"+ - Long.toHexString(handle)+" : "+newName); - } - handle = 0; - name = newName; - } - handle= X11Util.createThreadLocalDisplay(name); + protected String validateDisplayName(String name, long handle) { + return X11Util.validateDisplayName(name, handle); + } + + protected void createNative() { + long handle= X11Util.createThreadLocalDisplay(name); if( 0 == handle ) { throw new RuntimeException("Error creating display: "+name); } |