aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java13
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java9
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java27
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java63
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java23
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java15
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java166
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java61
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java48
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java38
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java8
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java61
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java38
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java10
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java32
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java13
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java19
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java85
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java8
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java10
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java82
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java300
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java232
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java36
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java24
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java56
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java71
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java17
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java101
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java45
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java23
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java406
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java185
-rw-r--r--src/nativewindow/native/JAWT_DrawingSurfaceInfo.c7
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m227
-rw-r--r--src/nativewindow/native/windows/GDImisc.c32
-rw-r--r--src/nativewindow/native/x11/Xmisc.c10
46 files changed, 1949 insertions, 759 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java
index 784343c5a..1930bdda3 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.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
@@ -50,7 +51,7 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
/**
* Return the capabilities reflecting this graphics configuration,
- * which may differ from the capabilites used to choose this configuration.
+ * which may differ from the capabilities used to choose this configuration.
*
* @return An immutable instance of the Capabilities to avoid mutation by
* the user.
@@ -61,7 +62,7 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
* Return the capabilities used to choose this graphics configuration.
*
* These may be used to reconfigure the NativeWindow in case
- * the device changes in a multi screen environment.
+ * the device changes in a multiple screen environment.
*
* @return An immutable instance of the Capabilities to avoid mutation by
* the user.
@@ -69,10 +70,10 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
public CapabilitiesImmutable getRequestedCapabilities();
/**
- * In case this instance already reflects a native configuration,
- * return this one.
- * Otherwise return the encapsuled native configuration,
- * as it shall be included e.g. in the AWT case.
+ * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+ * this method shall return the native {@link AbstractGraphicsConfiguration},
+ * otherwise this instance.
+ * @see NativeSurface#getGraphicsConfiguration()
*/
public AbstractGraphicsConfiguration getNativeGraphicsConfiguration();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 83b437612..fa25c214f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -110,14 +110,15 @@ public interface AbstractGraphicsDevice extends Cloneable {
public void unlock();
/**
- * Optionally closing the device.<br>
- * The default implementation is a NOP operation, returning false.<br>
+ * Optionally closing the device.
+ * <p>
+ * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
+ * </p>
* The specific implementing, ie {@link javax.media.nativewindow.x11.X11GraphicsDevice},
* shall have a enable/disable like {@link javax.media.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},<br>
* which shall be invoked at creation time to determine ownership/role of freeing the resource.<br>
*
- * @return true if a specialized closing operation was successfully issued, otherwise false,
- * ie no native closing operation was issued, which doesn't imply an error at all.
+ * @return true if the handle was not <code>null</code>, otherwise false.
*/
public boolean close();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
index ffa8bfae6..3eb7a6c9a 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
@@ -84,8 +84,6 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics
* The use case for setting the Capabilities at a later time is
* a change of the graphics device in a multi-screen environment.<br>
*
- * The objects reference is being used.
- *
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
protected void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index c2aa6fae9..187959a67 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -46,7 +46,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
/**
* Create an instance with the system default {@link ToolkitLock},
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.
* @param type
*/
public DefaultGraphicsDevice(String type, String connection, int unitID) {
@@ -55,12 +55,12 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = 0;
- setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) );
+ this.toolkitLock = NativeWindowFactory.getDefaultToolkitLock(type);
}
/**
* Create an instance with the system default {@link ToolkitLock}.
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * gathered via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
* @param type
* @param handle
*/
@@ -70,7 +70,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) );
+ this.toolkitLock = NativeWindowFactory.createDefaultToolkitLock(type, handle);
}
/**
@@ -85,7 +85,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- setToolkitLock( locker );
+ this.toolkitLock = null != locker ? locker : NativeWindowFactoryImpl.getNullToolkitLock();
}
@Override
@@ -140,6 +140,10 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
public boolean close() {
+ if(0 != handle) {
+ handle = 0;
+ return true;
+ }
return false;
}
@@ -152,10 +156,21 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* Set the internal ToolkitLock, which is used within the
* {@link #lock()} and {@link #unlock()} implementation.
*
+ * <p>
+ * The current ToolkitLock is being locked/unlocked while swapping the reference,
+ * ensuring no concurrent access can occur during the swap.
+ * </p>
+ *
* @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used
*/
protected void setToolkitLock(ToolkitLock locker) {
- this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ final ToolkitLock _toolkitLock = toolkitLock;
+ _toolkitLock.lock();
+ try {
+ toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ } finally {
+ _toolkitLock.unlock();
+ }
}
/**
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index fa3923dcf..259644467 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -40,7 +40,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-
/**
* Provides the mechanism by which the graphics configuration for a
* window can be chosen before the window is created. The graphics
@@ -60,12 +59,34 @@ import java.util.Map;
public abstract class GraphicsConfigurationFactory {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
- private static Map/*<Class, NativeWindowFactory>*/ registeredFactories =
- Collections.synchronizedMap(new HashMap());
- private static Class abstractGraphicsDeviceClass;
+ private static Map<Class<?>, GraphicsConfigurationFactory> registeredFactories =
+ Collections.synchronizedMap(new HashMap<Class<?>, GraphicsConfigurationFactory>());
+ private static Class<?> abstractGraphicsDeviceClass;
static {
- initialize();
+ abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class;
+
+ // Register the default no-op factory for arbitrary
+ // AbstractGraphicsDevice implementations, including
+ // AWTGraphicsDevice instances -- the OpenGL binding will take
+ // care of handling AWTGraphicsDevices on X11 platforms (as
+ // well as X11GraphicsDevices in non-AWT situations)
+ registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl());
+
+ if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
+ "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ if(NativeWindowFactory.isAWTAvailable()) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.awt.X11AWTGraphicsConfigurationFactory",
+ "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+ } catch (Exception e) { /* n/a */ }
+ }
+ }
}
protected static String getThreadName() {
@@ -85,27 +106,6 @@ public abstract class GraphicsConfigurationFactory {
protected GraphicsConfigurationFactory() {
}
- private static void initialize() {
- abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class;
-
- if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
- try {
- GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory)
- ReflectionUtil.createInstance("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory", null,
- GraphicsConfigurationFactory.class.getClassLoader());
- registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- // Register the default no-op factory for arbitrary
- // AbstractGraphicsDevice implementations, including
- // AWTGraphicsDevice instances -- the OpenGL binding will take
- // care of handling AWTGraphicsDevices on X11 platforms (as
- // well as X11GraphicsDevices in non-AWT situations)
- registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl());
- }
-
/** Returns the factory for use with the given type of
AbstractGraphicsDevice. */
public static GraphicsConfigurationFactory getFactory(AbstractGraphicsDevice device) {
@@ -122,7 +122,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- public static GraphicsConfigurationFactory getFactory(Class abstractGraphicsDeviceImplementor)
+ public static GraphicsConfigurationFactory getFactory(Class<?> abstractGraphicsDeviceImplementor)
throws IllegalArgumentException, NativeWindowException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
@@ -130,10 +130,9 @@ public abstract class GraphicsConfigurationFactory {
}
GraphicsConfigurationFactory factory = null;
- Class clazz = abstractGraphicsDeviceImplementor;
+ Class<?> clazz = abstractGraphicsDeviceImplementor;
while (clazz != null) {
- factory =
- (GraphicsConfigurationFactory) registeredFactories.get(clazz);
+ factory = registeredFactories.get(clazz);
if (factory != null) {
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory);
@@ -143,7 +142,7 @@ public abstract class GraphicsConfigurationFactory {
clazz = clazz.getSuperclass();
}
// Return the default
- factory = (GraphicsConfigurationFactory)registeredFactories.get(abstractGraphicsDeviceClass);
+ factory = registeredFactories.get(abstractGraphicsDeviceClass);
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+abstractGraphicsDeviceClass+" -> "+factory);
}
@@ -157,7 +156,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- protected static void registerFactory(Class abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
+ protected static void registerFactory(Class<?> abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
throws IllegalArgumentException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index e691ba8e6..e255dc051 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -118,6 +118,24 @@ public interface NativeSurface extends SurfaceUpdatedListener {
*/
public boolean surfaceSwap();
+ /** Appends the given {@link SurfaceUpdatedListener} to the end of the list. */
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+ /**
+ * Inserts the given {@link SurfaceUpdatedListener} at the
+ * specified position in the list.<br>
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
+ * @param l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
+
+ /** Remove the specified {@link SurfaceUpdatedListener} from the list. */
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
/**
* Returns the handle to the surface for this NativeSurface. <P>
*
@@ -149,6 +167,11 @@ public interface NativeSurface extends SurfaceUpdatedListener {
/**
* Returns the graphics configuration corresponding to this window.
+ * <p>
+ * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+ * this method shall return the native {@link AbstractGraphicsConfiguration} via {@link AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()}.
+ * </p>
+ * @see AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
public AbstractGraphicsConfiguration getGraphicsConfiguration();
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
index 76ac72953..2bc352116 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
@@ -104,20 +104,26 @@ public interface NativeWindow extends NativeSurface {
/**
* @return the current x position of the top-left corner
- * of the client area, hence excluding insets (window decorations).<br>
+ * of the client area relative to it's parent.
+ * Since the position reflects the client area, it does not include the insets.
* @see #getInsets()
*/
public int getX();
/**
* @return the current y position of the top-left corner
- * of the client area, hence excluding insets (window decorations).<br>
+ * of the client area relative to it's parent.
+ * Since the position reflects the client area, it does not include the insets.
* @see #getInsets()
*/
public int getY();
/**
- * Returns the current absolute location of this window.
+ * Returns the current position of the top-left corner
+ * of the client area in screen coordinates.
+ * <p>
+ * Since the position reflects the client area, it does not include the insets.
+ * </p>
* @param point if not null,
* {@link javax.media.nativewindow.util.Point#translate(javax.media.nativewindow.util.Point)}
* the passed {@link javax.media.nativewindow.util.Point} by this location on the screen and return it.
@@ -126,4 +132,7 @@ public interface NativeWindow extends NativeSurface {
*/
public Point getLocationOnScreen(Point point);
+ /** Returns true if this native window owns the focus, otherwise false. */
+ boolean hasFocus();
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index ef8876f50..c69b18b30 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,15 +33,20 @@
package javax.media.nativewindow;
-import java.security.*;
-import java.util.*;
-
-import com.jogamp.common.util.*;
-import com.jogamp.common.os.Platform;
-
-import jogamp.nativewindow.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NativeWindowFactoryImpl;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
/** Provides a pluggable mechanism for arbitrary window toolkits to
adapt their components to the {@link NativeWindow} interface,
@@ -75,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;
@@ -132,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",
@@ -152,7 +164,7 @@ public abstract class NativeWindowFactory {
requiresToolkitLock = res.booleanValue();
} else {
requiresToolkitLock = false;
- }
+ }
}
/**
@@ -178,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();
@@ -188,12 +202,10 @@ 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
if( !Debug.getBooleanProperty("java.awt.headless", true, acc) &&
@@ -203,7 +215,7 @@ public abstract class NativeWindowFactory {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
- jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader());
+ jawtUtilClass = Class.forName(JAWTUtilClassName, true, NativeWindowFactory.class.getClassLoader());
jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", (Class[])null);
jawtUtilInitMethod.setAccessible(true);
jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{});
@@ -227,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>());
@@ -260,6 +272,21 @@ public abstract class NativeWindowFactory {
}
}
+ public static synchronized void shutdown() {
+ if(initialized) {
+ initialized = false;
+ 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");
+ }
+ }
+ }
+
/** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>,
otherwise false. */
public static boolean isFirstUIActionOnProcess() {
@@ -319,31 +346,30 @@ public abstract class NativeWindowFactory {
* <ul>
* <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
* <ul>
- * <li>If native <b>X11 type</b> with or w/o AWT</li>
- * <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.JAWTToolkitLock} </li>
* </ul>
- * </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock getDefaultToolkitLock(String type) {
if( requiresToolkitLock() ) {
- if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) {
- if( isAWTAvailable() ) {
- return getAWTToolkitLock();
- }
+ if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+ return getAWTToolkitLock();
}
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
- protected static ToolkitLock getAWTToolkitLock() {
+ private static ToolkitLock getAWTToolkitLock() {
Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod);
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.getAWTToolkitLock()");
+ Thread.dumpStack();
+ }
if(resO instanceof ToolkitLock) {
return (ToolkitLock) resO;
} else {
@@ -363,26 +389,49 @@ public abstract class NativeWindowFactory {
* <ul>
* <li>If <b>X11 type</b> </li>
* <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
+ * </ul>
+ * </ul>
+ * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * </ul>
+ */
+ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ if( requiresToolkitLock() ) {
+ if( TYPE_X11 == type ) {
+ if( 0== deviceHandle ) {
+ throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
+ }
+ return createX11ToolkitLock(deviceHandle);
+ }
+ }
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
+ /**
+ * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
+ * <br>
+ * <ul>
+ * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
+ * <ul>
+ * <li>If <b>X11 type</b> </li>
+ * <ul>
+ * <li> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
* </ul>
- * <li> If <b>AWT not available</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
+ * <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
* </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
if( requiresToolkitLock() ) {
if( TYPE_X11 == type ) {
if( 0== deviceHandle ) {
throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
}
- if( isAWTAvailable() ) {
+ if( TYPE_AWT == sharedType && isAWTAvailable() ) {
return createX11AWTToolkitLock(deviceHandle);
}
return createX11ToolkitLock(deviceHandle);
@@ -393,6 +442,10 @@ public abstract class NativeWindowFactory {
protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
try {
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")");
+ Thread.dumpStack();
+ }
return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
} catch (Exception ex) {
throw new RuntimeException(ex);
@@ -470,4 +523,37 @@ public abstract class NativeWindowFactory {
NativeWindow. Implementors of concrete NativeWindowFactory
subclasses should override this method. */
protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException;
+
+ /**
+ * Returns the {@link OffscreenLayerSurface} instance of this {@link NativeSurface}.
+ * <p>
+ * In case this surface is a {@link NativeWindow}, we traverse from the given surface
+ * up to root until an implementation of {@link OffscreenLayerSurface} is found.
+ * In case <code>ifEnabled</code> is true, the surface must also implement {@link OffscreenLayerOption}
+ * where {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()} is <code>true</code>.
+ * </p>
+ *
+ * @param surface The surface to query.
+ * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()}.
+ * @return
+ */
+ public static OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled) {
+ if(surface instanceof OffscreenLayerSurface &&
+ ( !ifEnabled || surface instanceof OffscreenLayerOption ) ) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface;
+ return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ if(surface instanceof NativeWindow) {
+ NativeWindow nw = ((NativeWindow) surface).getParent();
+ while(null != nw) {
+ if(nw instanceof OffscreenLayerSurface &&
+ ( !ifEnabled || nw instanceof OffscreenLayerOption ) ) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw;
+ return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ nw = nw.getParent();
+ }
+ }
+ return null;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java
new file mode 100644
index 000000000..12d30b3cd
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java
@@ -0,0 +1,61 @@
+/**
+ * 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 javax.media.nativewindow;
+
+/**
+ * Handling requests for using an {@link OffscreenLayerSurface}
+ * within the implementation.
+ */
+public interface OffscreenLayerOption {
+ /**
+ * Request an offscreen layer, if supported.
+ * <p>
+ * Shall be called before the first {@link NativeWindow#lockSurface()},
+ * and hence before realization.
+ * </p>
+ *
+ * @see #getShallUseOffscreenLayer()
+ * @see #isOffscreenLayerSurfaceEnabled()
+ */
+ public void setShallUseOffscreenLayer(boolean v);
+
+ /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */
+ public boolean getShallUseOffscreenLayer();
+
+ /**
+ * Returns true if this instance uses an offscreen layer, otherwise false.
+ * <p>
+ * This instance is an offscreen layer, if {@link #setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * has been called before it's realization and first lock and the underlying implementation supports it.
+ * </p>
+ * The return value is undefined before issuing the first {@link NativeWindow#lockSurface()}.
+ *
+ * @see #setShallUseOffscreenLayer(boolean)
+ */
+ public boolean isOffscreenLayerSurfaceEnabled();
+} \ No newline at end of file
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
new file mode 100644
index 000000000..dd36509ba
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -0,0 +1,48 @@
+/**
+ * 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 javax.media.nativewindow;
+
+/**
+ * Interface specifying the offscreen layer surface protocol.
+ */
+public interface OffscreenLayerSurface {
+ /**
+ * Attach the offscreen layer to this offscreen layer surface.
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+
+ /**
+ * Detaches a previously attached offscreen layer from this offscreen layer surface.
+ * @see #attachSurfaceLayer(long)
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void detachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index e34476228..9100beac2 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,12 +28,15 @@
package javax.media.nativewindow;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
public abstract class ProxySurface implements NativeSurface {
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ private AbstractGraphicsConfiguration config; // control access due to delegation
protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
- protected AbstractGraphicsConfiguration config;
protected long displayHandle;
protected int height;
protected int scrnIndex;
@@ -42,7 +45,7 @@ public abstract class ProxySurface implements NativeSurface {
public ProxySurface(AbstractGraphicsConfiguration cfg) {
invalidate();
config = cfg;
- displayHandle=cfg.getScreen().getDevice().getHandle();
+ displayHandle=cfg.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
}
void invalidate() {
@@ -55,12 +58,16 @@ public abstract class ProxySurface implements NativeSurface {
return displayHandle;
}
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
return config;
}
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
public final int getScreenIndex() {
- return config.getScreen().getIndex();
+ return getGraphicsConfiguration().getScreen().getIndex();
}
public abstract long getSurfaceHandle();
@@ -73,7 +80,7 @@ public abstract class ProxySurface implements NativeSurface {
return height;
}
- public void setSize(int width, int height) {
+ public void surfaceSizeChanged(int width, int height) {
this.width = width;
this.height = height;
}
@@ -82,16 +89,29 @@ public abstract class ProxySurface implements NativeSurface {
return false;
}
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
+
public int lockSurface() throws NativeWindowException {
surfaceLock.lock();
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
res = lockSurfaceImpl();
@@ -113,7 +133,7 @@ public abstract class ProxySurface implements NativeSurface {
surfaceLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -143,5 +163,5 @@ public abstract class ProxySurface implements NativeSurface {
return surfaceLock.getOwner();
}
- public abstract String toString();
+ public abstract String toString();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
index fc32b57b3..956e68e61 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
@@ -41,8 +41,14 @@ package javax.media.nativewindow;
public interface SurfaceChangeable {
+ /** Sets the surface handle which is created outside of this implementation */
public void setSurfaceHandle(long surfaceHandle);
- public void setSize(int width, int height);
+
+ /**
+ * The surface's size has been determined or changed.
+ * Implementation shall update the stored surface size with the given ones.
+ */
+ public void surfaceSizeChanged(int width, int height);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
index 88e805d14..0912b5afe 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
@@ -34,8 +34,12 @@
package javax.media.nativewindow;
+/**
+ * Clients may add their SurfaceUpdateListener implementation to a {@link javax.media.nativewindow.NativeSurface}
+ * allowing to get notified after the surface has been updated, eg. after a swap buffer operation.
+ */
public interface SurfaceUpdatedListener {
- /** Notification of a surface update event.
+ /** Notification of a surface update event, eg. after a swap buffer operation.
*
* @param updater is the caller object who updated the surface,
* e.g. a JOGL GLDrawable.
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
index d83a92a5b..45a3db838 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -41,11 +41,13 @@
package javax.media.nativewindow.awt;
import javax.media.nativewindow.*;
+
import java.awt.Component;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.image.ColorModel;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+
import jogamp.nativewindow.Debug;
/** A wrapper for an AWT GraphicsConfiguration allowing it to be
@@ -63,56 +65,61 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
this.encapsulated=encapsulated;
}
- public AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- GraphicsConfiguration config) {
+ private AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ GraphicsConfiguration config) {
super(screen, capsChosen, capsRequested);
this.config = config;
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.
+ * with the graphics Capabilities of the AWT Component to produce the chosen Capabilities.
* Otherwise the <code>capsChosen</code> is used.
*/
- public static AWTGraphicsConfiguration create(Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable 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, AbstractGraphicsDevice.DEFAULT_UNIT);
- awtScreen = new AWTGraphicsScreen(awtDevice);
- }
+ public static AWTGraphicsConfiguration create(Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ final GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration();
+ if(null==awtGfxConfig) {
+ throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsConfiguration @ "+awtComp);
}
- if(null==awtScreen) {
- // use defaults since no native peer is available yet
- awtScreen = (AWTGraphicsScreen) AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
- awtDevice = (AWTGraphicsDevice) awtScreen.getDevice();
- awtGraphicsDevice = awtDevice.getGraphicsDevice();
+ final GraphicsDevice awtGraphicsDevice = awtGfxConfig.getDevice();
+ if(null==awtGraphicsDevice) {
+ throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsDevice @ "+awtGfxConfig);
}
+ // Create Device/Screen
+ final AWTGraphicsDevice awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AWTGraphicsScreen awtScreen = new AWTGraphicsScreen(awtDevice);
+
if(null==capsChosen) {
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
- capsChosen = setupCapabilitiesRGBABits(capsChosen, gc);
+ capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc);
+ }
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen);
+ if(config instanceof AWTGraphicsConfiguration) {
+ return (AWTGraphicsConfiguration) config;
}
+ // System.err.println("Info: AWTGraphicsConfiguration.create: Expected AWTGraphicsConfiguration got: "+config.getClass()+" w/ factory "+factory.getClass()+" - Unable to encapsulate native GraphicsConfiguration.");
return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig);
}
- @Override
+ // open access to superclass method
+ public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
+ super.setChosenCapabilities(capsChosen);
+ }
+
+ @Override
public Object clone() {
return super.clone();
}
- public GraphicsConfiguration getGraphicsConfiguration() {
+ /** Return the AWT {@link GraphicsConfiguration}. */
+ public GraphicsConfiguration getAWTGraphicsConfiguration() {
return config;
}
- @Override
+ @Override
public AbstractGraphicsConfiguration getNativeGraphicsConfiguration() {
return (null!=encapsulated)?encapsulated:this;
}
@@ -156,7 +163,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
return capabilities;
}
- @Override
+ @Override
public String toString() {
return getClass().getSimpleName()+"[" + getScreen() +
",\n\tchosen " + capabilitiesChosen+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
index 66a63bfcd..8ebe37626 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.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
@@ -46,26 +47,20 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
/** 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, int unitID) {
+ public AWTGraphicsDevice(GraphicsDevice device, int unitID) {
super(NativeWindowFactory.TYPE_AWT, device.getIDstring(), unitID);
this.device = device;
- this.subType = null;
}
- public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice, int unitID) {
- if(null==awtDevice) {
- awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
- unitID = AbstractGraphicsDevice.DEFAULT_UNIT;
- }
- return new AWTGraphicsDevice(awtDevice, unitID);
+ public static AWTGraphicsDevice createDefault() {
+ GraphicsDevice awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ return new AWTGraphicsDevice(awtDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- @Override
+ @Override
public Object clone() {
return super.clone();
}
@@ -74,26 +69,9 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
return device;
}
- /**
- * In case the native handle was specified, e.g. using X11,
- * 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 setSubType(String subType, long handle) {
- this.handle = handle;
- this.subType = subType;
- setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) );
- }
-
- public String getSubType() {
- return subType;
- }
-
- @Override
+ @Override
public String toString() {
- return getClass().getSimpleName()+"[type "+getType()+"[subType "+getSubType()+"], connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
+ return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java
index 383dcae80..2978d7868 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.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
@@ -42,7 +43,6 @@ package javax.media.nativewindow.awt;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.media.nativewindow.*;
-import javax.media.nativewindow.AbstractGraphicsDevice;
/** A wrapper for an AWT GraphicsDevice (screen) allowing it to be
handled in a toolkit-independent manner. */
@@ -74,17 +74,15 @@ public class AWTGraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
}
public static AbstractGraphicsScreen createScreenDevice(GraphicsDevice awtDevice, int unitID) {
- AWTGraphicsDevice device = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(awtDevice, unitID);
- return new AWTGraphicsScreen(device);
+ return new AWTGraphicsScreen(new AWTGraphicsDevice(awtDevice, unitID));
}
public static AbstractGraphicsScreen createScreenDevice(int index, int unitID) {
- GraphicsDevice awtDevice = getScreenDevice(index);
- return createScreenDevice(awtDevice, unitID);
+ return createScreenDevice(getScreenDevice(index), unitID);
}
public static AbstractGraphicsScreen createDefault() {
- return createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ return new AWTGraphicsScreen(AWTGraphicsDevice.createDefault());
}
public Object clone() {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
index 100b6b839..74439336d 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 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,8 +33,9 @@
package javax.media.nativewindow.x11;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.x11.XVisualInfo;
/** Encapsulates a graphics configuration, or OpenGL pixel format, on
@@ -42,7 +44,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
GraphicsConfigurationFactory.chooseGraphicsConfiguration()} on X11
platforms when toolkits other than the AWT are being used. */
-public class X11GraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
public X11GraphicsConfiguration(X11GraphicsScreen screen,
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
index 48fd63e3c..73c8cfd52 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 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
@@ -33,6 +34,7 @@
package javax.media.nativewindow.x11;
import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import javax.media.nativewindow.DefaultGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
@@ -44,49 +46,49 @@ import javax.media.nativewindow.ToolkitLock;
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
public static final boolean DEBUG = Debug.debug("GraphicsDevice");
- boolean closeDisplay = false;
+ final boolean closeDisplay;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
- * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.<br>
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
* Note that this is not an open connection, ie no native display handle exist.
* This constructor exist to setup a default device connection.
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int)
*/
public X11GraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
+ closeDisplay = false;
}
/** 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)}.
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long)
*/
- public X11GraphicsDevice(long display, int unitID) {
+ public X11GraphicsDevice(long display, int unitID, boolean owner) {
// FIXME: derive unitID from connection could be buggy, one DISPLAY for all screens for example..
- super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display);
+ super(NativeWindowFactory.TYPE_X11, X11Lib.XDisplayString(display), unitID, display);
if(0==display) {
throw new NativeWindowException("null display");
}
+ closeDisplay = owner;
}
/**
* @param display the Display connection
* @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
*/
- public X11GraphicsDevice(long display, int unitID, ToolkitLock locker) {
- super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display, locker);
+ public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) {
+ super(NativeWindowFactory.TYPE_X11, X11Lib.XDisplayString(display), unitID, display, locker);
if(0==display) {
throw new NativeWindowException("null display");
}
+ closeDisplay = owner;
}
public Object clone() {
return super.clone();
}
- public void setCloseDisplay(boolean close) {
- closeDisplay = close;
- if(DEBUG && close) {
- System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.setCloseDisplay(true): "+this);
- }
- }
public boolean close() {
// FIXME: shall we respect the unitID ?
if(closeDisplay && 0 != handle) {
@@ -94,10 +96,8 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this);
}
X11Util.closeDisplay(handle);
- handle = 0;
- return true;
}
- return false;
+ return super.close();
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index ffe84cb6d..6473b9f67 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 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
@@ -33,6 +34,8 @@
package javax.media.nativewindow.x11;
import javax.media.nativewindow.*;
+
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
/** Encapsulates a screen index on X11
@@ -48,22 +51,22 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
super(device, fetchScreen(device, screen));
}
- public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx) {
+ public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
if(0==display) throw new NativeWindowException("display is null");
- return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT), screenIdx);
+ return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
}
public long getDefaultVisualID() {
// It still could be an AWT hold handle ..
long display = getDevice().getHandle();
- int scrnIdx = X11Util.DefaultScreen(display);
- return X11Util.DefaultVisualID(display, scrnIdx);
+ int scrnIdx = X11Lib.DefaultScreen(display);
+ return X11Lib.DefaultVisualID(display, scrnIdx);
}
private static int fetchScreen(X11GraphicsDevice device, int screen) {
// It still could be an AWT hold handle ..
long display = device.getHandle();
- if(X11Util.XineramaEnabled(display)) {
+ if(X11Lib.XineramaEnabled(display)) {
screen = 0; // Xinerama -> 1 screen
}
return screen;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
new file mode 100644
index 000000000..ee3ab73ba
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsConfiguration;
+
+public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
+ public MutableGraphicsConfiguration(AbstractGraphicsScreen screen,
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ }
+
+ public void setChosenCapabilities(CapabilitiesImmutable caps) {
+ super.setChosenCapabilities(caps);
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
index 2b6d3c016..4cf8f448e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
@@ -33,6 +33,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import com.jogamp.common.jvm.JNILibLoaderBase;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.cache.TempJarCache;
public class NWJNILibLoader extends JNILibLoaderBase {
@@ -40,9 +41,10 @@ public class NWJNILibLoader extends JNILibLoaderBase {
public static void loadNativeWindow(final String ossuffix) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
+ Platform.initSingleton();
final String libName = "nativewindow_"+ossuffix ;
if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) {
- addNativeJarLibs(NWJNILibLoader.class, "jogl.all", "jogl-all", new String[] { "nativewindow" } );
+ addNativeJarLibs(NWJNILibLoader.class, "jogl-all", new String[] { "nativewindow" } );
}
loadLibrary(libName, false);
return null;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index d34d4e58f..223078ebf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -32,11 +32,15 @@
package jogamp.nativewindow;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.*;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
-import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
@@ -44,13 +48,10 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
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 {
- if (null == winObj) {
- throw new IllegalArgumentException("winObj is null");
- }
if (winObj instanceof NativeWindow) {
// Use the NativeWindow directly
return (NativeWindow) winObj;
@@ -69,7 +70,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
"javax.media.nativewindow.NativeWindow or "+AWTComponentClassName);
}
- private Constructor nativeWindowConstructor = null;
+ private Constructor<?> nativeWindowConstructor = null;
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
new file mode 100644
index 000000000..4877d5c4f
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -0,0 +1,85 @@
+/**
+ * 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 jogamp.nativewindow;
+
+import java.util.ArrayList;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+
+public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
+ private Object surfaceUpdatedListenersLock = new Object();
+ private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
+
+ //
+ // Management Utils
+ //
+ public int size() { return surfaceUpdatedListeners.size(); }
+ public SurfaceUpdatedListener get(int i) { return surfaceUpdatedListeners.get(i); }
+
+ //
+ // Implementation of NativeSurface SurfaceUpdatedListener methods
+ //
+
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ addSurfaceUpdatedListener(-1, l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size();
+ }
+ surfaceUpdatedListeners.add(index, l);
+ }
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners.remove(l);
+ }
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index 4c2b1c875..074fab563 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -33,7 +33,7 @@ import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.SurfaceChangeable;
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
+public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
protected long surfaceHandle;
public WrappedSurface(AbstractGraphicsConfiguration cfg) {
@@ -65,6 +65,10 @@ public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
}
public String toString() {
- return "WrappedSurface[config " + config + ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) + ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) + ", size " + getWidth() + "x" + getHeight() + "]";
+ return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
+ ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
+ ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
+ ", size " + getWidth() + "x" + getHeight() +
+ ", surfaceLock "+surfaceLock+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2c8538278..354bb83e3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -40,14 +40,15 @@
package jogamp.nativewindow.jawt;
import javax.media.nativewindow.NativeWindowFactory;
+
import jogamp.nativewindow.NWJNILibLoader;
import java.awt.Toolkit;
import java.security.AccessController;
import java.security.PrivilegedAction;
-public class JAWTJNILibLoader extends NWJNILibLoader {
- public static void loadAWTImpl() {
+public class JAWTJNILibLoader extends NWJNILibLoader {
+ static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
// Make sure that awt.dll is loaded before loading jawt.dll. Otherwise
@@ -73,4 +74,9 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
}
});
}
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index c1c97eece..21e9a3e09 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -37,24 +37,28 @@
package jogamp.nativewindow.jawt;
-import jogamp.nativewindow.*;
import java.awt.EventQueue;
-
-import javax.media.nativewindow.*;
-
-
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
-import java.lang.reflect.*;
-import java.security.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Map;
+import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.Debug;
+
+import com.jogamp.common.os.Platform;
+
public class JAWTUtil {
protected static final boolean DEBUG = Debug.debug("JAWT");
// See whether we're running in headless mode
private static final boolean headlessMode;
+ private static final JAWT jawtLockObject;
// Java2D magic ..
private static final Method isQueueFlusherThread;
@@ -75,31 +79,67 @@ public class JAWTUtil {
boolean ok;
}
+ /**
+ * Returns true if this platform's JAWT implementation supports
+ * or uses offscreen layer.
+ */
+ public static boolean isOffscreenLayerSupported() {
+ return Platform.OS_TYPE == Platform.OSType.MACOS &&
+ Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0;
+ }
+
+ /**
+ * @param useOffscreenLayerIfAvailable
+ * @return
+ */
+ public static JAWT getJAWT(boolean useOffscreenLayerIfAvailable) {
+ int jawt_version_flags = JAWTFactory.JAWT_VERSION_1_4;
+ if(useOffscreenLayerIfAvailable) {
+ switch(Platform.OS_TYPE) {
+ case MACOS:
+ if(Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0) {
+ jawt_version_flags |= JAWT.JAWT_MACOSX_USE_CALAYER;
+ }
+ }
+ }
+ return JAWT.getJAWT(jawt_version_flags);
+ }
+
+ public static boolean isJAWTUsingOffscreenLayer(JAWT jawt) {
+ return 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER );
+ }
+
static {
- JAWTJNILibLoader.loadAWTImpl();
+ if(DEBUG) {
+ System.err.println("JAWTUtil initialization (JAWT/JNI/...");
+ // Thread.dumpStack();
+ }
+ JAWTJNILibLoader.initSingleton();
JAWTJNILibLoader.loadNativeWindow("awt");
headlessMode = GraphicsEnvironment.isHeadless();
-
boolean ok = false;
- Class jC = null;
+ Class<?> jC = null;
Method m = null;
if (!headlessMode) {
+ jawtLockObject = getJAWT(false); // don't care for offscreen layer here
try {
jC = Class.forName("jogamp.opengl.awt.Java2D");
m = jC.getMethod("isQueueFlusherThread", (Class[])null);
ok = true;
} catch (Exception e) {
}
+ } else {
+ jawtLockObject = null; // headless !
}
isQueueFlusherThread = m;
j2dExist = ok;
- PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction() {
+ PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
PrivilegedDataBlob1 d = new PrivilegedDataBlob1();
try {
- final Class sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ final Class<?> sunToolkitClass = Class.forName("sun.awt.SunToolkit");
d.sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{});
d.sunToolkitAWTLockMethod.setAccessible(true);
d.sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{});
@@ -129,21 +169,21 @@ public class JAWTUtil {
jawtToolkitLock = new JAWTToolkitLock();
// trigger native AWT toolkit / properties initialization
- Map desktophints = null;
+ Map<?,?> desktophints = null;
try {
if(EventQueue.isDispatchThread()) {
- desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
} else {
- final ArrayList desktophintsBucket = new ArrayList(1);
+ final ArrayList<Map<?,?>> desktophintsBucket = new ArrayList<Map<?,?>>(1);
EventQueue.invokeAndWait(new Runnable() {
public void run() {
- Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ Map<?,?> _desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
if(null!=_desktophints) {
desktophintsBucket.add(_desktophints);
}
}
});
- desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ;
+ desktophints = ( desktophintsBucket.size() > 0 ) ? desktophintsBucket.get(0) : null ;
}
} catch (InterruptedException ex) {
ex.printStackTrace();
@@ -189,7 +229,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtLock() {
+ private static void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -197,7 +237,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtLock failed", e);
}
} else {
- JAWT.getJAWT().Lock();
+ jawtLockObject.Lock();
}
}
@@ -207,7 +247,7 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtUnlock() {
+ private static void awtUnlock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -215,7 +255,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtUnlock failed", e);
}
} else {
- JAWT.getJAWT().Unlock();
+ jawtLockObject.Unlock();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
index 2c80392ad..be697b3e0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
@@ -41,73 +41,190 @@ import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
-import java.awt.Window;
+import java.awt.Container;
+import java.applet.Applet;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
-public abstract class JAWTWindow implements NativeWindow {
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
+public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, OffscreenLayerOption {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
+ // user properties
+ protected boolean shallUseOffscreenLayer = false;
+
// lifetime: forever
protected Component component;
- protected AbstractGraphicsConfiguration config;
+ private AWTGraphicsConfiguration config; // control access due to delegation
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- // lifetime: valid after lock, forever until invalidate
+ // lifetime: valid after lock but may change with each 1st lock, purges after invalidate
+ private boolean isApplet;
+ private JAWT jawt;
+ private boolean isOffscreenLayerSurface;
protected long drawable;
protected Rectangle bounds;
-
- public JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
+ protected Insets insets;
+
+ /**
+ * Constructed by {@link jogamp.nativewindow.NativeWindowFactoryImpl#getNativeWindow(Object, AbstractGraphicsConfiguration)}
+ * via this platform's specialization (X11, OSX, Windows, ..).
+ *
+ * @param comp
+ * @param config
+ */
+ protected JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
if (config == null) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
}
- this.config = config;
+ if(! ( config instanceof AWTGraphicsConfiguration ) ) {
+ throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
+ }
+ this.config = (AWTGraphicsConfiguration) config;
init((Component)comp);
}
private void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
- validateNative();
+ this.isApplet = false;
}
- protected abstract void validateNative() throws NativeWindowException;
-
+
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
protected synchronized void invalidate() {
- component = null;
+ invalidateNative();
+ jawt = null;
+ isOffscreenLayerSurface = false;
drawable= 0;
bounds = new Rectangle();
+ insets = new Insets();
}
+ protected abstract void invalidateNative();
protected final void updateBounds(JAWT_Rectangle jawtBounds) {
bounds.setX(jawtBounds.getX());
bounds.setY(jawtBounds.getY());
bounds.setWidth(jawtBounds.getWidth());
bounds.setHeight(jawtBounds.getHeight());
+
+ if(component instanceof Container) {
+ java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.setLeftWidth(contInsets.left);
+ insets.setRightWidth(contInsets.right);
+ insets.setTopHeight(contInsets.top);
+ insets.setBottomHeight(contInsets.bottom);
+ }
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
- public final InsetsImmutable getInsets() { return Insets.getZero(); }
+ public final InsetsImmutable getInsets() { return insets; }
public final Component getAWTComponent() {
return component;
}
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #lockSurface()}.
+ */
+ public final boolean isApplet() {
+ return isApplet;
+ }
+ /** Returns the underlying JAWT instance created @ {@link #lockSurface()}. */
+ public final JAWT getJAWT() {
+ return jawt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new NativeWindowException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ attachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void attachSurfaceLayerImpl(final long layerHandle);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ detachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void detachSurfaceLayerImpl(final long layerHandle);
+
//
// SurfaceUpdateListener
//
- public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- // nop
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
//
// NativeSurface
@@ -115,6 +232,24 @@ public abstract class JAWTWindow implements NativeWindow {
private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private void determineIfApplet() {
+ Component c = component;
+ while(!isApplet && null != c) {
+ isApplet = c instanceof Applet;
+ c = c.getParent();
+ }
+ }
+
+ /**
+ * If JAWT offscreen layer is supported,
+ * implementation shall respect {@link #getShallUseOffscreenLayer()}
+ * and may respect {@link #isApplet()}.
+ *
+ * @return The JAWT instance reflecting offscreen layer support, etc.
+ *
+ * @throws NativeWindowException
+ */
+ protected abstract JAWT fetchJAWTImpl() throws NativeWindowException;
protected abstract int lockSurfaceImpl() throws NativeWindowException;
public final int lockSurface() throws NativeWindowException {
@@ -122,10 +257,13 @@ public abstract class JAWTWindow implements NativeWindow {
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
+ determineIfApplet();
try {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
res = lockSurfaceImpl();
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
@@ -147,7 +285,7 @@ public abstract class JAWTWindow implements NativeWindow {
surfaceLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -169,36 +307,35 @@ public abstract class JAWTWindow implements NativeWindow {
return surfaceLock.getOwner();
}
- public final boolean surfaceSwap() {
+ public boolean surfaceSwap() {
return false;
}
- public final void surfaceUpdated(Object updater, NativeWindow window, long when) { }
-
- public final long getSurfaceHandle() {
+ public long getSurfaceHandle() {
return drawable;
}
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+
+ public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
return config;
}
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
public final long getDisplayHandle() {
- return config.getScreen().getDevice().getHandle();
+ return getGraphicsConfiguration().getScreen().getDevice().getHandle();
}
public final int getScreenIndex() {
- return config.getScreen().getIndex();
- }
-
- public final void setSize(int width, int height) {
- component.setSize(width, height);
+ return getGraphicsConfiguration().getScreen().getIndex();
}
- public final int getWidth() {
+ public int getWidth() {
return component.getWidth();
}
- public final int getHeight() {
+ public int getHeight() {
return component.getHeight();
}
@@ -207,12 +344,8 @@ public abstract class JAWTWindow implements NativeWindow {
//
public synchronized void destroy() {
- if(null!=component) {
- if(component instanceof Window) {
- ((Window)component).dispose();
- }
- }
- invalidate();
+ invalidate();
+ component = null; // don't dispose the AWT component, since we are merely an immutable uplink
}
public final NativeWindow getParent() {
@@ -222,7 +355,7 @@ public abstract class JAWTWindow implements NativeWindow {
public long getWindowHandle() {
return drawable;
}
-
+
public final int getX() {
return component.getX();
}
@@ -230,52 +363,94 @@ public abstract class JAWTWindow implements NativeWindow {
public final int getY() {
return component.getY();
}
-
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This JAWT default implementation is currently still using
+ * a blocking implementation. It first attempts to retrieve the location
+ * via a native implementation. If this fails, it tries the blocking AWT implementation.
+ * If the latter fails due to an external AWT tree-lock, the non block
+ * implementation {@link #getLocationOnScreenNonBlocking(Point, Component)} is being used.
+ * The latter simply traverse up to the AWT component tree and sums the rel. position.
+ * We have to determine whether the latter is good enough for all cases,
+ * currently only OS X utilizes the non blocking method per default.
+ * </p>
+ */
public Point getLocationOnScreen(Point storage) {
+ Point los = getLocationOnScreenNative(storage);
+ if(null == los) {
+ if(!Thread.holdsLock(component.getTreeLock())) {
+ // avoid deadlock ..
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this);
+ Thread.dumpStack();
+ }
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ java.awt.Point awtLOS = component.getLocationOnScreen();
+ if(null!=storage) {
+ los = storage.translate(awtLOS.x, awtLOS.y);
+ } else {
+ los = new Point(awtLOS.x, awtLOS.y);
+ }
+ }
+ return los;
+ }
+
+ protected Point getLocationOnScreenNative(Point storage) {
int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
- // FIXME: Shall we deal with already locked or unrealized surfaces ?
- System.err.println("Warning: JAWT Lock couldn't be acquired!");
- Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock couldn't be acquired: "+this);
+ Thread.dumpStack();
+ }
return null;
}
try {
- Point d = getLocationOnScreenImpl(0, 0);
+ Point d = getLocationOnScreenNativeImpl(0, 0);
if(null!=d) {
if(null!=storage) {
storage.translate(d.getX(),d.getY());
return storage;
}
- return d;
- }
- // fall through intended ..
- if(!Thread.holdsLock(component.getTreeLock())) {
- // FIXME: Verify if this check is still required!
- System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock!");
- Thread.dumpStack();
- return null; // avoid deadlock ..
}
- java.awt.Point awtLOS = component.getLocationOnScreen();
- int dx = (int) ( awtLOS.getX() + .5 ) ;
- int dy = (int) ( awtLOS.getY() + .5 ) ;
- if(null!=storage) {
- return storage.translate(dx, dy);
- }
- return new Point(dx, dy);
+ return d;
} finally {
unlockSurface();
+ }
+ }
+ protected abstract Point getLocationOnScreenNativeImpl(int x, int y);
+
+ protected static Point getLocationOnScreenNonBlocking(Point storage, Component comp) {
+ int x = 0;
+ int y = 0;
+ while(null != comp) {
+ x += comp.getX();
+ y += comp.getY();
+ comp = comp.getParent();
}
+ if(null!=storage) {
+ storage.translate(x, y);
+ return storage;
+ }
+ return new Point(x, y);
}
- protected abstract Point getLocationOnScreenImpl(int x, int y);
-
- @Override
+
+ public boolean hasFocus() {
+ return component.hasFocus();
+ }
+
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("JAWT-Window["+
"windowHandle 0x"+Long.toHexString(getWindowHandle())+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", bounds "+bounds);
+ ", bounds "+bounds+", insets "+insets+
+ ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface);
if(null!=component) {
sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
", visible "+component.isVisible());
@@ -283,8 +458,9 @@ public abstract class JAWTWindow implements NativeWindow {
sb.append(", component NULL");
}
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
- ",\n\tconfig "+config+
- ",\n\tawtComponent "+getAWTComponent()+"]");
+ ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+ ",\n\tawtComponent "+getAWTComponent()+
+ ",\n\tsurfaceLock "+surfaceLock+"]");
return sb.toString();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index d4f6a95d4..ab2986fbe 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -40,38 +40,94 @@
package jogamp.nativewindow.jawt.macosx;
-import java.awt.Component;
+import java.nio.Buffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Point;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+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.macosx.OSXUtil;
-
-public class MacOSXJAWTWindow extends JAWTWindow {
+import jogamp.nativewindow.macosx.OSXUtil;
+public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
super(comp, config);
+ if(DEBUG) {
+ dumpInfo();
+ }
}
- protected void validateNative() throws NativeWindowException {
+ protected void invalidateNative() {
+ surfaceHandle=0;
+ if(isOffscreenLayerSurfaceEnabled()) {
+ if(0 != drawable) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ }
+ }
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ public long getSurfaceHandle() {
+ return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not using CALAYER");
+ }
+ if(DEBUG) {
+ System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
+ this.surfaceHandle = surfaceHandle;
+ }
+
+ public void surfaceSizeChanged(int width, int height) {
+ sscSet = true;
+ sscWidth = width;
+ sscHeight = height;
+ }
+
+ public int getWidth() {
+ return sscSet ? sscWidth : super.getWidth();
+ }
+
+ public int getHeight() {
+ return sscSet ? sscHeight: super.getHeight();
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ // use offscreen if supported and [ applet or requested ]
+ return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
+ }
protected int lockSurfaceImpl() throws NativeWindowException {
- int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ int ret = NativeWindow.LOCK_SURFACE_NOT_READY;
+ if(null == ds) {
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
int res = ds.Lock();
dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
@@ -87,37 +143,86 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
ret = NativeWindow.LOCK_SURFACE_CHANGED;
}
- if (firstLock) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- dsi = ds.GetDrawingSurfaceInfo();
- return null;
- }
- });
- } else {
- dsi = ds.GetDrawingSurfaceInfo();
+ if(null == dsi) {
+ if (firstLock) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ dsi = ds.GetDrawingSurfaceInfo();
+ return null;
+ }
+ });
+ } else {
+ dsi = ds.GetDrawingSurfaceInfo();
+ }
+ if (dsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
- if (dsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ updateBounds(dsi.getBounds());
+ if (DEBUG && firstLock ) {
+ dumpInfo();
}
firstLock = false;
- macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo();
- if (macosxdsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
- }
- drawable = macosxdsi.getCocoaViewRef();
-
- if (drawable == 0) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(getJAWT());
+ if (macosxdsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ drawable = macosxdsi.getCocoaViewRef();
+
+ if (drawable == 0) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ } else {
+ ret = NativeWindow.LOCK_SUCCESS;
+ }
} else {
- updateBounds(dsi.getBounds());
+ /**
+ * Only create a fake invisible NSWindow for the drawable handle
+ * to please frameworks requiring such (eg. NEWT).
+ *
+ * The actual surface/ca-layer shall be created/attached
+ * by the upper framework (JOGL) since they require more information.
+ */
+ if(0 == drawable) {
+ drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
+ if(0 == drawable) {
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ }
+ // fix caps reflecting offscreen!
+ Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
+ caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ }
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer();
+ if(0 == rootSurfaceLayerHandle) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not create root CALayer: "+this);
+ }
+ if(!AttachJAWTSurfaceLayer(dsi, rootSurfaceLayerHandle)) {
+ OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
+ rootSurfaceLayerHandle = 0;
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this);
+ }
+ }
+ ret = NativeWindow.LOCK_SUCCESS;
}
+
return ret;
}
-
+
protected void unlockSurfaceImpl() throws NativeWindowException {
if(null!=ds) {
if (null!=dsi) {
@@ -126,30 +231,65 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
- macosxdsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- Component c = component;
- while(null != c) {
- x += c.getX();
- y += c.getY();
- c = c.getParent();
+ private void dumpInfo() {
+ System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName());
+ if(null != getJAWT()) {
+ System.err.println("JAWT version: 0x"+Integer.toHexString(getJAWT().getCachedVersion())+
+ ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(getJAWT())+
+ ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds+", insets "+insets);
+ } else {
+ System.err.println("JAWT n/a, bounds "+bounds+", insets "+insets);
}
- // return OSXUtil.GetLocationOnScreen(getWindowHandle(), x, y);
- return new Point(x, y);
+ // Thread.dumpStack();
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * On OS X locking the surface at this point (ie after creation and for location validation)
+ * is 'tricky' since the JVM traverses through many threads and crashes at:
+ * lockSurfaceImpl() {
+ * ..
+ * ds = getJAWT().GetDrawingSurface(component);
+ * due to a SIGSEGV.
+ *
+ * Hence we have some threading / sync issues with the native JAWT implementation.
+ * </p>
+ */
+ @Override
+ public Point getLocationOnScreen(Point storage) {
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
+ private static boolean AttachJAWTSurfaceLayer(JAWT_DrawingSurfaceInfo dsi, long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ return AttachJAWTSurfaceLayer0(dsi.getBuffer(), caLayer);
+ }
+
+ private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
private boolean dsLocked;
private JAWT_DrawingSurfaceInfo dsi;
+
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
-
+
+ private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer
+
+ private long surfaceHandle = 0;
+ private int sscWidth, sscHeight;
+ private boolean sscSet = false;
+
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
index 5ad22807f..bf5c18eaf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
@@ -95,7 +95,7 @@ public class Win32SunJDKReflection {
public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index 982b94888..786682b17 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -47,10 +47,11 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+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 {
@@ -58,18 +59,24 @@ public class WindowsJAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- }
-
- @Override
- protected synchronized void invalidate() {
- super.invalidate();
+ protected void invalidateNative() {
windowHandle = 0;
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -94,7 +101,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (win32dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -104,14 +112,12 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (windowHandle == 0 || drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
protected void unlockSurfaceImpl() throws NativeWindowException {
- long startTime = 0;
+ drawable = 0; // invalid HDC
if(null!=ds) {
if (null!=dsi) {
ds.FreeDrawingSurfaceInfo(dsi);
@@ -119,7 +125,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
@@ -131,8 +137,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
return windowHandle;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
index 5d4fa0dad..743d371b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
@@ -28,9 +28,13 @@
package jogamp.nativewindow.jawt.x11;
import jogamp.nativewindow.jawt.*;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
@@ -41,20 +45,32 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11JAWTToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11JAWTToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); }
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
JAWTUtil.lockToolkit();
- X11Util.XLockDisplay(displayHandle);
+ if(null == lock) {
+ X11Lib.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
JAWTUtil.unlockToolkit();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 2319d6269..35dc2343f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -38,20 +38,17 @@
package jogamp.nativewindow.jawt.x11;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+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.x11.X11Util;
+import jogamp.nativewindow.x11.X11Lib;
public class X11JAWTWindow extends JAWTWindow {
@@ -59,36 +56,22 @@ public class X11JAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ protected void invalidateNative() { }
- if(awtDevice.getHandle() != 0) {
- // subtype and handle set already, done
- return;
- }
-
- long displayHandle = 0;
-
- // first try a pre-existing attached native configuration, ie native X11GraphicsDevice
- AbstractGraphicsConfiguration aconfig = (null!=config) ? config.getNativeGraphicsConfiguration() : null;
- AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
- AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null; // X11GraphicsDevice
- if(null!=adevice) {
- displayHandle = adevice.getHandle();
- }
-
- if(0 == displayHandle) {
- displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
- }
- if(0==displayHandle) {
- throw new InternalError("X11JAWTWindow: No X11 Display handle available");
- }
- awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
}
-
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -113,7 +96,8 @@ public class X11JAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (x11dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -122,8 +106,6 @@ public class X11JAWTWindow extends JAWTWindow {
if (drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
@@ -136,15 +118,15 @@ public class X11JAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
x11dsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
index b576b0c6b..08d471448 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
@@ -55,14 +55,14 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
the purposes of correctly enumerating the available visuals. */
public class X11SunJDKReflection {
- private static Class x11GraphicsDeviceClass;
- private static Method x11GraphicsDeviceGetDisplayMethod;
- private static Class x11GraphicsConfigClass;
- private static Method x11GraphicsConfigGetVisualMethod;
- private static boolean initted;
+ private static Class<?> x11GraphicsDeviceClass;
+ private static Method x11GraphicsDeviceGetDisplayMethod;
+ private static Class<?> x11GraphicsConfigClass;
+ private static Method x11GraphicsConfigGetVisualMethod;
+ private static boolean initialized;
static {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice");
@@ -72,7 +72,7 @@ public class X11SunJDKReflection {
x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig");
x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {});
x11GraphicsConfigGetVisualMethod.setAccessible(true);
- initted = true;
+ initialized = true;
} catch (Exception e) {
// Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
}
@@ -82,7 +82,7 @@ public class X11SunJDKReflection {
}
public static long graphicsDeviceGetDisplay(GraphicsDevice device) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
@@ -96,7 +96,7 @@ public class X11SunJDKReflection {
public static int graphicsConfigurationGetVisualID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
@@ -105,7 +105,7 @@ public class X11SunJDKReflection {
}
public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index cd558c05d..5b1e4b0a7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -1,3 +1,30 @@
+/**
+ * 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.macosx;
import javax.media.nativewindow.NativeWindowException;
@@ -34,6 +61,42 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
+ public static long CreateNSView(int x, int y, int width, int height) {
+ return CreateNSView0(x, y, width, height);
+ }
+ public static void DestroyNSView(long nsView) {
+ DestroyNSView0(nsView);
+ }
+
+ public static long CreateNSWindow(int x, int y, int width, int height) {
+ return CreateNSWindow0(x, y, width, height);
+ }
+ public static void DestroyNSWindow(long nsWindow) {
+ DestroyNSWindow0(nsWindow);
+ }
+
+ public static long CreateCALayer() {
+ return CreateCALayer0();
+ }
+ public static void AddCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ AddCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void RemoveCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ RemoveCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void DestroyCALayer(long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ DestroyCALayer0(caLayer);
+ }
+
public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) {
if(IsMainThread0()) {
runnable.run(); // don't leave the JVM
@@ -48,6 +111,14 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native long CreateNSView0(int x, int y, int width, int height);
+ private static native void DestroyNSView0(long nsView);
+ private static native long CreateNSWindow0(int x, int y, int width, int height);
+ private static native void DestroyNSWindow0(long nsWindow);
+ private static native long CreateCALayer0();
+ private static native void AddCASublayer0(long rootCALayer, long subCALayer);
+ private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
+ private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
index 1ad909897..aab1556da 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
@@ -202,7 +202,9 @@ public class SWTAccessor {
if( null != OS_gtk_class ) {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT);
+ // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
+ // to avoid locking problems !
+ return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index 68cf8af45..c8ed8e070 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -61,14 +61,22 @@ public class GDISurface extends ProxySurface {
throw new InternalError("surface not released");
}
surfaceHandle = GDI.GetDC(windowHandle);
+ /*
+ if(0 == surfaceHandle) {
+ System.err.println("****** DC Acquire: 0x"+Long.toHexString(windowHandle)+", isWindow "+GDI.IsWindow(windowHandle)+", isVisible "+GDI.IsWindowVisible(windowHandle)+", GDI LastError: "+GDI.GetLastError()+", 0x"+Long.toHexString(surfaceHandle)+", GDI LastError: "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ */
return (0 != surfaceHandle) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
}
protected void unlockSurfaceImpl() {
if (0 == surfaceHandle) {
- throw new InternalError("surface not acquired");
+ throw new InternalError("surface not acquired: "+this+", thread: "+Thread.currentThread().getName());
+ }
+ if(0 == GDI.ReleaseDC(windowHandle, surfaceHandle)) {
+ throw new NativeWindowException("DC not released: "+this+", isWindow "+GDI.IsWindow(windowHandle)+", werr "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
}
- GDI.ReleaseDC(windowHandle, surfaceHandle);
surfaceHandle=0;
}
@@ -77,11 +85,12 @@ public class GDISurface extends ProxySurface {
}
public String toString() {
- return "GDISurface[config "+config+
+ return "GDISurface[config "+getPrivateGraphicsConfiguration()+
", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
", windowHandle 0x"+Long.toHexString(windowHandle)+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", size "+getWidth()+"x"+getHeight()+"]";
+ ", size "+getWidth()+"x"+getHeight()+
+ ", surfaceLock "+surfaceLock+"]";
}
}
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);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index b669bce75..268416266 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -33,10 +33,22 @@
package jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, new X11GraphicsConfigurationFactory());
+ }
+ private X11GraphicsConfigurationFactory() {
+ }
+
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
throws IllegalArgumentException, NativeWindowException {
@@ -55,7 +67,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
int num[] = { -1 };
long display = screen.getDevice().getHandle();
- XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
+ XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
if(xvis==null || num[0]<1) {
return null;
@@ -81,7 +93,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
vinfo_template.setC_class(c_class);
long display = screen.getDevice().getHandle();
- XVisualInfo[] vinfos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
+ XVisualInfo[] vinfos = X11Lib.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/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
index fb0aff10d..5166ef577 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
@@ -29,6 +29,9 @@ package jogamp.nativewindow.x11;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing {@link X11Util#XLockDisplay(long)}.
@@ -38,18 +41,30 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11ToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11ToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); }
- X11Util.XLockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Lib.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 5c1839250..560130dd1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -33,19 +33,18 @@
package jogamp.nativewindow.x11;
-import com.jogamp.common.util.LongObjectHashMap;
-import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.NWJNILibLoader;
-
-import javax.media.nativewindow.*;
-
-import java.nio.Buffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.util.Point;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NWJNILibLoader;
+
+import com.jogamp.common.util.LongObjectHashMap;
/**
* Contains a thread safe X11 utility to retrieve display connections.
@@ -53,54 +52,88 @@ import javax.media.nativewindow.util.Point;
public class X11Util {
/**
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
- *
- * It is observed that ATI X11 drivers, eg. fglrx 8.78.6 and fglrx 11.08/8.881,
+ * <p>
+ * It is observed that ATI X11 drivers, eg.
+ * <ul>
+ * <li>fglrx 8.78.6,</li>
+ * <li>fglrx 11.08/8.881 and </li>
+ * <li>fglrx 11.11/8.911</li>
+ * </ul>
* are quite sensitive to multiple Display connections.
- * Here, closing displays shall happen in the same order as
- * they were opened, -OR- shall not be closed at all!
- * Otherwise some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
+ * With the above drivers closing displays shall happen in the same order as
+ * they were opened, <b>or</b> shall not be closed at all!
+ * If closed, some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
* You may test this, ie just reverse the destroy order below.
* See also native test: jogl/test/native/displayMultiple02.c
- *
- * Our current 'workaround' is to not close them at all if driver vendor is ATI.
+ * </p>
+ * <p>
+ * Workaround is to not close them at all if driver vendor is ATI.
+ * </p>
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
-
- public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+ /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
+ public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+
+ /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
+ public static final boolean HAS_XLOCKDISPLAY_BUG = true;
+
private static final boolean DEBUG = Debug.debug("X11Util");
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.getBooleanProperty("nativewindow.debug.X11Util.TraceDisplayLifecycle", true, AccessController.getContext());
- private static volatile String nullDisplayName = null;
- private static boolean requiresX11Lock = false;
- private static boolean isInit = false;
+ private static String nullDisplayName = null;
+ private static boolean isX11LockAvailable = false;
+ private static boolean requiresX11Lock = true;
+ private static volatile boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
private static int setX11ErrorHandlerRecCount = 0;
private static Object setX11ErrorHandlerLock = new Object();
- public static synchronized void initSingleton(final boolean firstX11ActionOnProcess) {
+ @SuppressWarnings("unused")
+ public static void initSingleton(final boolean firstX11ActionOnProcess) {
if(!isInit) {
- NWJNILibLoader.loadNativeWindow("x11");
-
- /**
- * Always issue XInitThreads() since we have independent
- * off-thread created Display connections able to utilize multithreading,
- * ie NEWT (jogamp.newt.x11.X11Display.createNativeImpl()) !!
- */
- initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess );
-
- requiresX11Lock = !firstX11ActionOnProcess ;
-
- if(DEBUG) {
- System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+
- ", requiresX11Lock "+requiresX11Lock);
+ synchronized(X11Util.class) {
+ if(!isInit) {
+ isInit = true;
+ NWJNILibLoader.loadNativeWindow("x11");
+
+ final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
+ final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess );
+ isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+
+ final long dpy = X11Lib.XOpenDisplay(null);
+ try {
+ nullDisplayName = X11Lib.XDisplayString(dpy);
+ } finally {
+ X11Lib.XCloseDisplay(dpy);
+ }
+
+ if(DEBUG) {
+ System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
+ ", requiresX11Lock "+requiresX11Lock+
+ ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
+ ", isX11LockAvailable "+isX11LockAvailable+
+ ", X11 Display(NULL) <"+nullDisplayName+">");
+ // Thread.dumpStack();
+ }
+ }
}
- isInit = true;
}
}
+
+ public static synchronized boolean isNativeLockAvailable() {
+ return isX11LockAvailable;
+ }
+
+ public static synchronized boolean requiresToolkitLock() {
+ return requiresX11Lock;
+ }
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
synchronized(setX11ErrorHandlerLock) {
@@ -121,42 +154,7 @@ public class X11Util {
}
}
- public static boolean requiresToolkitLock() {
- return requiresX11Lock;
- }
-
- public static void lockDefaultToolkit(long dpyHandle) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- if(requiresX11Lock) {
- X11Util.XLockDisplay(dpyHandle);
- }
- }
-
- public static void unlockDefaultToolkit(long dpyHandle) {
- if(requiresX11Lock) {
- X11Util.XUnlockDisplay(dpyHandle);
- }
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
-
public static String getNullDisplayName() {
- if(null==nullDisplayName) { // volatile: ok
- synchronized(X11Util.class) {
- if(null==nullDisplayName) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- long dpy = X11Lib.XOpenDisplay(null);
- try {
- nullDisplayName = X11Lib.XDisplayString(dpy);
- } finally {
- X11Lib.XCloseDisplay(dpy);
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- if(DEBUG) {
- System.out.println("X11 Display(NULL) <"+nullDisplayName+">");
- }
- }
- }
- }
return nullDisplayName;
}
@@ -224,7 +222,6 @@ public class X11Util {
public final void setUncloseable(boolean v) { unCloseable = v; }
public final boolean isUncloseable() { return unCloseable; }
-
public final Throwable getCreationStack() { return creationStack; }
@Override
@@ -238,20 +235,22 @@ public class X11Util {
}
}
- /** Returns the number of unclosed X11 Displays.
+ /**
+ * Cleanup resources.
+ * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>,
+ * keep alive all references (open display connection) for restart on same ClassLoader.
+ *
+ * @return number of unclosed X11 Displays.<br>
* @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
- */
+ */
public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
if(DEBUG||verbose||pendingDisplayList.size() > 0) {
- String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")" ;
+ System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
if(DEBUG) {
- Exception e = new Exception(msg);
- e.printStackTrace();
- } else {
- System.err.println(msg);
+ Thread.dumpStack();
}
if( openDisplayList.size() > 0) {
X11Util.dumpOpenDisplayConnections();
@@ -264,10 +263,11 @@ public class X11Util {
synchronized(globalLock) {
if(realXCloseOpenAndPendingDisplays) {
closePendingDisplayConnections();
+ openDisplayList.clear();
+ pendingDisplayList.clear();
+ openDisplayMap.clear();
+ shutdown0();
}
- openDisplayList.clear();
- pendingDisplayList.clear();
- openDisplayMap.clear();
}
return num;
}
@@ -304,9 +304,9 @@ public class X11Util {
public static void dumpOpenDisplayConnections() {
synchronized(globalLock) {
System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size());
- for(int i=0; i<pendingDisplayList.size(); i++) {
+ for(int i=0; i<openDisplayList.size(); i++) {
NamedDisplay ndpy = openDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Open["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -316,7 +316,7 @@ public class X11Util {
}
}
}
-
+
public static int getPendingDisplayConnectionNumber() {
synchronized(globalLock) {
return pendingDisplayList.size();
@@ -328,7 +328,7 @@ public class X11Util {
System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
for(int i=0; i<pendingDisplayList.size(); i++) {
NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Pending["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -384,8 +384,8 @@ public class X11Util {
}
}
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
+ // Thread.dumpStack();
}
return namedDpy.getHandle();
}
@@ -408,10 +408,6 @@ public class X11Util {
if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
if(!namedDpy.isUncloseable()) {
- if(DEBUG) {
- System.err.println("X11Util.Display: XCloseDisplay "+namedDpy+". Thread "+Thread.currentThread().getName());
- Thread.dumpStack();
- }
XCloseDisplay(namedDpy.getHandle());
} else {
// for reuse
@@ -439,7 +435,7 @@ public class X11Util {
public static String validateDisplayName(String name, long handle) {
if( ( null==name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) && 0!=handle) {
- name = XDisplayString(handle);
+ name = X11Lib.XDisplayString(handle);
}
return validateDisplayName(name);
}
@@ -455,8 +451,8 @@ public class X11Util {
try {
long handle = X11Lib.XOpenDisplay(arg0);
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
return handle;
} finally {
@@ -468,8 +464,8 @@ public class X11Util {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
}
int res = -1;
X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
@@ -487,209 +483,7 @@ public class X11Util {
}
}
- public static int XFree(Buffer arg0) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- return X11Lib.XFree(arg0);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- }
-
- public static int XSync(long display, boolean discard) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XSync(display, discard);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XSynchronize(long display, boolean onoff) {
- lockDefaultToolkit(display);
- try {
- X11Lib.XSynchronize(display, onoff);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XineramaEnabled(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XineramaEnabled(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int DefaultScreen(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultScreen(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long RootWindow(long display, int screen_number) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.RootWindow(display, screen_number);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static String XDisplayString(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XDisplayString(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFlush(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFlush(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFreePixmap(long display, long arg1) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFreePixmap(display, arg1);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long DefaultVisualID(long display, int screen) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultVisualID(display, screen);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long CreateDummyWindow(long display, int screen_index, long visualID, int width, int height) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.CreateDummyWindow(display, screen_index, visualID, width, height);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void DestroyDummyWindow(long display, long window) {
- lockDefaultToolkit(display);
- try {
- X11Lib.DestroyDummyWindow(display, window);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.GetRelativeLocation(display, screen_index, src_win, dest_win, src_x, src_y);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- 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) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- 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) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XLockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle));
- }
- X11Lib.XLockDisplay(handle);
- }
-
- public static void XUnlockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle));
- }
- X11Lib.XUnlockDisplay(handle);
- }
-
- private static native void initialize0(boolean firstUIActionOnProcess);
+ private static native boolean initialize0(boolean firstUIActionOnProcess);
+ private static native void shutdown0();
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..efaf4728c
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2008 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
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package jogamp.nativewindow.x11.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
+
+import jogamp.nativewindow.jawt.x11.X11SunJDKReflection;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
+
+public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, new X11AWTGraphicsConfigurationFactory());
+ }
+ private X11AWTGraphicsConfigurationFactory() {
+ }
+
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createDefault();
+ }
+
+ return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, (AWTGraphicsScreen)absScreen);
+ }
+
+ public static AWTGraphicsConfiguration chooseGraphicsConfigurationStatic(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AWTGraphicsScreen awtScreen) {
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: got "+awtScreen);
+ }
+
+ final GraphicsDevice device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
+ boolean owner = false;
+ if(0==displayHandle) {
+ displayHandle = X11Util.openDisplay(null);
+ owner = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create local X11 display");
+ }
+ } else {
+ /**
+ * Using the AWT display handle works fine with NVidia.
+ * However we experienced different results w/ AMD drivers,
+ * some work, but some behave erratic.
+ * I.e. hangs in XQueryExtension(..) via X11GraphicsScreen.
+ */
+ final String displayName = X11Lib.XDisplayString(displayHandle);
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create X11 display @ "+displayName+" / 0x"+Long.toHexString(displayHandle));
+ }
+ displayHandle = X11Util.openDisplay(displayName);
+ owner = true;
+ }
+ final ToolkitLock lock = owner ?
+ NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock
+ NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle);
+ final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner);
+ final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: made "+x11Screen);
+ }
+
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device);
+ X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ if (x11Config == null) {
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: chosen x11Config: "+x11Config);
+ }
+
+ //
+ // Match the X11/GL Visual with AWT:
+ // - choose a config AWT agnostic and then
+ // - try to find the visual within the GraphicsConfiguration
+ //
+ // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer,
+ // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify().
+ //
+ final GraphicsConfiguration[] configs = device.getConfigurations();
+ long visualID = x11Config.getVisualID();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration gc = configs[i];
+ if (gc != null) {
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
+ if(DEBUG) {
+ System.err.println("Found matching AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
+ }
+ return new AWTGraphicsConfiguration(awtScreen,
+ x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ gc, x11Config);
+ }
+ }
+ }
+
+ // try again using an AWT Colormodel compatible configuration
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsChosen, gc);
+ x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ if (x11Config == null) {
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+ visualID = x11Config.getVisualID();
+ for (int i = 0; i < configs.length; i++) {
+ gc = configs[i];
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
+ if(DEBUG) {
+ System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
+ }
+ return new AWTGraphicsConfiguration(awtScreen,
+ x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ gc, x11Config);
+ }
+ }
+
+ // Either we weren't able to reflectively introspect on the
+ // X11GraphicsConfig or something went wrong in the steps above;
+ // Let's take the default configuration as used on Windows and MacOSX then ..
+ if(DEBUG) {
+ System.err.println("!!! Using default configuration");
+ }
+
+ gc = device.getDefaultConfiguration();
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config);
+ }
+}
+
diff --git a/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
index 470f03a49..2a6651007 100644
--- a/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
+++ b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
@@ -59,6 +59,13 @@ Java_jogamp_nativewindow_jawt_JAWT_1DrawingSurfaceInfo_platformInfo0(JNIEnv* env
return NULL;
}
if (dsi->platformInfo == NULL) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"),
+ "platformInfo pointer is NULL");
+ return NULL;
+ }
+ if(0==PLATFORM_DSI_SIZE) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"),
+ "platformInfo size is 0");
return NULL;
}
return (*env)->NewDirectByteBuffer(env, dsi->platformInfo, PLATFORM_DSI_SIZE);
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e19d5ecf7..d64973b67 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -35,6 +35,19 @@
#include "NativewindowCommon.h"
#include "jogamp_nativewindow_macosx_OSXUtil.h"
+#include "jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow.h"
+
+#include <jawt_md.h>
+#import <JavaNativeFoundation.h>
+
+// #define VERBOSE 1
+//
+#ifdef VERBOSE
+ // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
static const char * const ClazzNameRunnable = "java/lang/Runnable";
static jmethodID runnableRunID = NULL;
@@ -81,7 +94,7 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: getLocationOnScreenImpl0
+ * Method: getLocationOnScreen0
* Signature: (JII)Ljavax/media/nativewindow/util/Point;
*/
JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnScreen0
@@ -97,7 +110,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
int dest_x=-1;
int dest_y=-1;
- NSObject *nsObj = (NSObject*) ((intptr_t) winOrView);
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
NSWindow* win = NULL;
NSView* view = NULL;
@@ -135,6 +148,189 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
return res;
}
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSView0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+ NSView * view = [[NSView alloc] initWithFrame: rect] ;
+ [view setCanDrawConcurrently: YES];
+ [pool release];
+
+ return (jlong) (intptr_t) view;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSView0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0
+ (JNIEnv *env, jclass unused, jlong nsView)
+{
+ NSView* view = (NSView*) (intptr_t) nsView;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [view release];
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSWindow0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+
+ // Allocate the window
+ NSWindow* myWindow = [[NSWindow alloc] initWithContentRect: rect
+ styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered
+ defer: YES];
+ [myWindow setReleasedWhenClosed: YES]; // default
+ [myWindow setPreservesContentDuringLiveResize: YES];
+
+ // invisible ..
+ [myWindow setOpaque: NO];
+ [myWindow setBackgroundColor: [NSColor clearColor]];
+
+ [pool release];
+
+ return (jlong) ((intptr_t) myWindow);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSWindow0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
+ (JNIEnv *env, jclass unused, jlong nsWindow)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) nsWindow);
+
+ [mWin close]; // performs release!
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateCALayer0
+ * Signature: (V)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
+ (JNIEnv *env, jclass unused)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ // CALayer* layer = [[CALayer alloc] init];
+ CALayer* layer = [CALayer layer];
+
+ // no animations for add/remove/swap sublayers etc
+ [layer removeAnimationForKey: kCAOnOrderIn];
+ [layer removeAnimationForKey: kCAOnOrderOut];
+ [layer removeAnimationForKey: kCATransition];
+
+ // initial dummy size !
+ CGRect lRect = [layer frame];
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = 32;
+ lRect.size.height = 32;
+ [layer setFrame: lRect];
+ DBG_PRINT("CALayer::CreateCALayer0: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [pool release];
+
+ return (jlong) ((intptr_t) layer);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: AddCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ CGRect lRectRoot = [rootLayer frame];
+ DBG_PRINT("CALayer::AddCASublayer0.0: Origin %p frame0: %lf/%lf %lfx%lf\n",
+ rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
+ if(lRectRoot.origin.x<0 || lRectRoot.origin.y<0) {
+ lRectRoot.origin.x = 0;
+ lRectRoot.origin.y = 0;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [rootLayer setFrame: lRectRoot];
+ }];
+ DBG_PRINT("CALayer::AddCASublayer0.1: Origin %p frame*: %lf/%lf %lfx%lf\n",
+ rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
+ }
+ DBG_PRINT("CALayer::AddCASublayer0.2: %p . %p %lf/%lf %lfx%lf (refcnt %d)\n",
+ rootLayer, subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]);
+
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ // simple 1:1 layout !
+ [subLayer setFrame:lRectRoot];
+ [rootLayer addSublayer:subLayer];
+ }];
+ DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: RemoveCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ (void)rootLayer; // no warnings
+
+ DBG_PRINT("CALayer::RemoveCASublayer0.0: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [subLayer removeFromSuperlayer];
+ }];
+ DBG_PRINT("CALayer::RemoveCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyCALayer0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
+ (JNIEnv *env, jclass unused, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* layer = (CALayer*) ((intptr_t) caLayer);
+
+ DBG_PRINT("CALayer::DestroyCALayer0.0: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [layer release]; // performs release!
+ }];
+ DBG_PRINT("CALayer::DestroyCALayer0.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
@interface MainRunnable : NSObject
{
@@ -212,10 +408,35 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: RunOnMainThread0
- * Signature: (ZLjava/lang/Runnable;)V
+ * Signature: (V)V
*/
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
(JNIEnv *env, jclass unused)
{
return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
}
+
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: AttachJAWTSurfaceLayer
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_AttachJAWTSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::attachJAWTSurfaceLayer: %p -> %p\n", surfaceLayers.layer, layer);
+ surfaceLayers.layer = [layer autorelease];
+ }];
+ JNF_COCOA_EXIT(env);
+ return JNI_TRUE;
+}
+
diff --git a/src/nativewindow/native/windows/GDImisc.c b/src/nativewindow/native/windows/GDImisc.c
index e8285008e..3ab7f9859 100644
--- a/src/nativewindow/native/windows/GDImisc.c
+++ b/src/nativewindow/native/windows/GDImisc.c
@@ -14,7 +14,7 @@
#include <stdio.h>
#include "NativewindowCommon.h"
-#include "jogamp_nativewindow_windows_GDI.h"
+#include "jogamp_nativewindow_windows_GDIUtil.h"
// #define VERBOSE_ON 1
@@ -36,12 +36,12 @@ HINSTANCE GetApplicationHandle() {
}
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc)
* C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc);
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDI_CreateWindowClass
+Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -85,12 +85,12 @@ Java_jogamp_nativewindow_windows_GDI_CreateWindowClass
}
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className)
* C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className);
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDI_DestroyWindowClass
+Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindowClass
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -116,12 +116,12 @@ Java_jogamp_nativewindow_windows_GDI_DestroyWindowClass
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, java.lang.String windowName, int x, int y, int width, int height)
* C function: HANDLE CreateDummyWindow0(HANDLE hInstance, LPCSTR className, LPCSTR windowName, int x, int y, int width, int height);
*/
JNIEXPORT jlong JNICALL
-Java_jogamp_nativewindow_windows_GDI_CreateDummyWindow0
+Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyWindow0
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -162,26 +162,26 @@ Java_jogamp_nativewindow_windows_GDI_CreateDummyWindow0
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: initIDs0
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDI_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0
(JNIEnv *env, jclass clazz)
{
if(NativewindowCommon_init(env)) {
jclass c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't find %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't find %s", ClazzNamePoint);
}
pointClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==pointClz) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't use %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't use %s", ClazzNamePoint);
}
pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
if(NULL==pointCstr) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't fetch %s.%s %s",
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't fetch %s.%s %s",
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
}
@@ -193,22 +193,22 @@ LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
}
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: getDummyWndProc0
* Signature: ()J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_windows_GDI_getDummyWndProc0
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_windows_GDIUtil_getDummyWndProc0
(JNIEnv *env, jclass clazz)
{
return (jlong) (intptr_t) DummyWndProc;
}
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: GetRelativeLocation0
* Signature: (JJII)Ljavax/media/nativewindow/util/Point;
*/
-JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDI_GetRelativeLocation0
+JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDIUtil_GetRelativeLocation0
(JNIEnv *env, jclass unused, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
{
HWND src_win = (HWND) (intptr_t) jsrc_win;
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index d481343f9..d28891cda 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -293,14 +293,16 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
}
static int _initialized=0;
+static jboolean _xinitThreadsOK=JNI_FALSE;
-JNIEXPORT void JNICALL
+JNIEXPORT jboolean JNICALL
Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) {
if(0==_initialized) {
if( JNI_TRUE == firstUIActionOnProcess ) {
if( 0 == XInitThreads() ) {
fprintf(stderr, "Warning: XInitThreads() failed\n");
} else {
+ _xinitThreadsOK=JNI_TRUE;
fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n");
}
} else {
@@ -311,6 +313,12 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jb
x11IOErrorHandlerEnable(1, env);
_initialized=1;
}
+ return _xinitThreadsOK;
+}
+
+JNIEXPORT void JNICALL
+Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ x11IOErrorHandlerEnable(0, env);
}
JNIEXPORT void JNICALL