aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-12-01 16:43:55 +0100
committerSven Gothel <[email protected]>2011-12-01 16:43:55 +0100
commit2c0a0981f7e1376064abd981c79c65c9d1b57410 (patch)
tree272ad58d1ca39641c8b389ce8056f06e5d62fc54 /src/nativewindow
parent77e9d16a3ad5131a2197bb3cad2309827c3a796a (diff)
Move manual GDI utils to GDIUtil ; Minor cleanup.
RegisteredClassFactory: Reference the factories itself instead of the RegisteredClass. This enables the shutdown hook to clear the factories state, which is required for proper recreation.
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java39
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java101
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java45
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);
}