diff options
Diffstat (limited to 'src/nativewindow')
4 files changed, 152 insertions, 37 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 39fe4fadc..aa0851bcf 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -80,20 +80,25 @@ public abstract class NativeWindowFactory { private static NativeWindowFactory defaultFactory; private static Map<Class<?>, NativeWindowFactory> registeredFactories; + private static Class<?> nativeWindowClass; private static String nativeWindowingTypePure; private static String nativeWindowingTypeCustom; private static boolean isAWTAvailable; - public static final String AWTComponentClassName = "java.awt.Component" ; - public static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ; - public static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util"; - public static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil"; - public static final String GDIClassName = "jogamp.nativewindow.windows.GDI"; - public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ; - public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ; + + private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ; + private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util"; + private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil"; + private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil"; + private static Class<?> jawtUtilClass; private static Method jawtUtilGetJAWTToolkitMethod; private static Method jawtUtilInitMethod; + + public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ; + public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ; + private static Class<?> x11JAWTToolkitLockClass; private static Constructor<?> x11JAWTToolkitLockConstructor; private static Class<?> x11ToolkitLockClass; @@ -137,16 +142,18 @@ public abstract class NativeWindowFactory { static boolean initialized = false; - private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { + private static void initSingletonNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { isFirstUIActionOnProcess = firstUIActionOnProcess; - - String clazzName = null; + + final String clazzName; if( TYPE_X11.equals(nativeWindowingTypePure) ) { clazzName = X11UtilClassName; } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) { clazzName = GDIClassName; } else if( TYPE_MACOSX.equals(nativeWindowingTypePure) ) { clazzName = OSXUtilClassName; + } else { + clazzName = null; } if( null != clazzName ) { ReflectionUtil.callStaticMethod(clazzName, "initSingleton", @@ -157,7 +164,7 @@ public abstract class NativeWindowFactory { requiresToolkitLock = res.booleanValue(); } else { requiresToolkitLock = false; - } + } } /** @@ -183,6 +190,8 @@ public abstract class NativeWindowFactory { System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); } + final ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + // Gather the windowing OS first AccessControlContext acc = AccessController.getContext(); nativeWindowingTypePure = _getNativeWindowingType(); @@ -193,11 +202,9 @@ public abstract class NativeWindowFactory { nativeWindowingTypeCustom = tmp; } - final ClassLoader cl = NativeWindowFactory.class.getClassLoader(); - if(firstUIActionOnProcess) { // X11 initialization before possible AWT initialization - initNativeImpl(true, cl); + initSingletonNativeImpl(true, cl); } isAWTAvailable = false; // may be set to true below @@ -232,7 +239,7 @@ public abstract class NativeWindowFactory { } if(!firstUIActionOnProcess) { // X11 initialization after possible AWT initialization - initNativeImpl(false, cl); + initSingletonNativeImpl(false, cl); } registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>()); @@ -271,6 +278,8 @@ public abstract class NativeWindowFactory { if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START"); } + registeredFactories.clear(); + registeredFactories = null; // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() .. if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END"); diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java index 157f750f1..43d446915 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java @@ -51,7 +51,7 @@ import jogamp.nativewindow.jawt.JAWTUtil; import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.nativewindow.jawt.JAWT_DrawingSurface; import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; -import jogamp.nativewindow.windows.GDI; +import jogamp.nativewindow.windows.GDIUtil; public class WindowsJAWTWindow extends JAWTWindow { @@ -137,7 +137,7 @@ public class WindowsJAWTWindow extends JAWTWindow { } protected Point getLocationOnScreenNativeImpl(int x, int y) { - return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); + return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); } // Variables for lockSurface/unlockSurface diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java new file mode 100644 index 000000000..be531d9ee --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -0,0 +1,101 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.windows; + +import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.NativeWindowException; + +import jogamp.nativewindow.NWJNILibLoader; +import jogamp.nativewindow.Debug; +import jogamp.nativewindow.x11.X11Util; + +public class GDIUtil { + private static final boolean DEBUG = Debug.debug("GDIUtil"); + + private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ; + private static RegisteredClassFactory dummyWindowClassFactory; + private static boolean isInit = false; + + public static synchronized void initSingleton(boolean firstX11ActionOnProcess) { + if(!isInit) { + synchronized(X11Util.class) { + if(!isInit) { + isInit = true; + NWJNILibLoader.loadNativeWindow("win32"); + + if( !initIDs0() ) { + throw new NativeWindowException("GDI: Could not initialized native stub"); + } + + if(DEBUG) { + System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess); + } + + dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0()); + } + } + } + } + + public static boolean requiresToolkitLock() { return false; } + + private static RegisteredClass dummyWindowClass = null; + private static Object dummyWindowSync = new Object(); + + public static long CreateDummyWindow(int x, int y, int width, int height) { + synchronized(dummyWindowSync) { + dummyWindowClass = dummyWindowClassFactory.getSharedClass(); + return CreateDummyWindow0(dummyWindowClass.getHandle(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height); + } + } + + public static boolean DestroyDummyWindow(long hwnd) { + boolean res; + synchronized(dummyWindowSync) { + if( null == dummyWindowClass ) { + throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null"); + } + res = GDI.DestroyWindow(hwnd); + dummyWindowClassFactory.releaseSharedClass(); + } + return res; + } + + public static Point GetRelativeLocation(long src_win, long dest_win, int src_x, int src_y) { + return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y); + } + + public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc); + public static native boolean DestroyWindowClass(long hInstance, String className); + + private static native boolean initIDs0(); + private static native long getDummyWndProc0(); + private static native Object GetRelativeLocation0(long src_win, long dest_win, int src_x, int src_y); + + static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height); +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java index 15e0a67cb..00bedfc8e 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java @@ -34,34 +34,44 @@ import javax.media.nativewindow.NativeWindowException; public class RegisteredClassFactory { static final boolean DEBUG = Debug.debug("RegisteredClass"); - private static ArrayList sharedClasses = new ArrayList(); + private static ArrayList<RegisteredClassFactory> registeredFactories = new ArrayList<RegisteredClassFactory>(); + private String classBaseName; - long wndProc; + private long wndProc; private RegisteredClass sharedClass = null; private int classIter = 0; private int sharedRefCount = 0; - private Object sync = new Object(); + private final Object sync = new Object(); /** - * Intended for a JVM shutdown hook, hence little synchronization + * Release the {@link RegisteredClass} of all {@link RegisteredClassFactory}. */ public static void shutdownSharedClasses() { - synchronized(sharedClasses) { - for(int i=0; i<sharedClasses.size(); i++) { - RegisteredClass sc = (RegisteredClass) sharedClasses.get(i); - GDI.DestroyWindowClass(sc.getHandle(), sc.getName()); - if(DEBUG) { - System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc); + synchronized(registeredFactories) { + for(int j=0; j<registeredFactories.size(); j++) { + final RegisteredClassFactory rcf = registeredFactories.get(j); + synchronized(rcf.sync) { + if(null != rcf.sharedClass) { + GDIUtil.DestroyWindowClass(rcf.sharedClass.getHandle(), rcf.sharedClass.getName()); + rcf.sharedClass = null; + rcf.sharedRefCount = 0; + rcf.classIter = 0; + if(DEBUG) { + System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+" shutdownSharedClasses : "+rcf.sharedClass); + } + } } } - sharedClasses.clear(); } } public RegisteredClassFactory(String classBaseName, long wndProc) { this.classBaseName = classBaseName; this.wndProc = wndProc; + synchronized(registeredFactories) { + registeredFactories.add(this); + } } public RegisteredClass getSharedClass() throws NativeWindowException { @@ -76,19 +86,17 @@ public class RegisteredClassFactory { } String clazzName = null; boolean registered = false; - while ( !registered && Integer.MAX_VALUE >= classIter ) { + final int classIterMark = classIter - 1; + while ( !registered && classIterMark != classIter ) { // Retry with next clazz name, this could happen if more than one JVM is running clazzName = classBaseName + classIter; classIter++; - registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc); + registered = GDIUtil.CreateWindowClass(hInstance, clazzName, wndProc); } if( !registered ) { throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName); } sharedClass = new RegisteredClass(hInstance, clazzName); - synchronized(sharedClasses) { - sharedClasses.add(sharedClass); - } if(DEBUG) { System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass); } @@ -113,10 +121,7 @@ public class RegisteredClassFactory { throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); } if( 0 == sharedRefCount ) { - GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName()); - synchronized(sharedClasses) { - sharedClasses.remove(sharedClass); - } + GDIUtil.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName()); if(DEBUG) { System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass); } |