summaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java17
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java18
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java3
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java48
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java51
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java22
-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.java35
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java5
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java85
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java61
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java273
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java228
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java28
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java27
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java18
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java46
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java10
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m220
24 files changed, 1109 insertions, 167 deletions
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/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index fa3923dcf..e510c0b78 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -60,9 +60,9 @@ 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();
@@ -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..b2a2bc4ee 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>
*
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
index 76ac72953..e3ee85cf4 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
@@ -126,4 +126,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..b6c850098 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,
@@ -470,4 +475,33 @@ 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 a {@link OffscreenLayerSurface} is found.
+ * </p>
+ *
+ * @param surface The surface to query.
+ * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerSurface#isOffscreenLayerSurfaceEnabled()}.
+ * @return
+ */
+ public static OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled) {
+ if(surface instanceof OffscreenLayerSurface) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface;
+ return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ if(surface instanceof NativeWindow) {
+ NativeWindow nw = ((NativeWindow) surface).getParent();
+ while(null != nw) {
+ if(nw instanceof OffscreenLayerSurface) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw;
+ return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ nw = nw.getParent();
+ }
+ }
+ return null;
+ }
}
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..82ae0f39e
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -0,0 +1,51 @@
+/**
+ * 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 {
+ /** Returns true if this instance uses an offscreen layer, otherwise false. */
+ public boolean isOffscreenLayerSurfaceEnabled();
+
+ /**
+ * 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..7380d19b6 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,6 +28,8 @@
package javax.media.nativewindow;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
@@ -38,6 +40,7 @@ public abstract class ProxySurface implements NativeSurface {
protected int height;
protected int scrnIndex;
protected int width;
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
public ProxySurface(AbstractGraphicsConfiguration cfg) {
invalidate();
@@ -73,7 +76,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,9 +85,22 @@ 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 ?
@@ -143,5 +159,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..38ad2d795 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -41,6 +41,7 @@
package javax.media.nativewindow.awt;
import javax.media.nativewindow.*;
+
import java.awt.Component;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -98,12 +99,42 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
if(null==capsChosen) {
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
- capsChosen = setupCapabilitiesRGBABits(capsChosen, gc);
+ capsChosen = setupCapabilitiesRGBABits(capsRequested, gc);
}
return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig);
}
- @Override
+ public void updateGraphicsConfiguration(Component awtComp)
+ {
+ 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);
+ }
+ }
+ if(null==awtScreen) {
+ throw new NativeWindowException("native peer n/a: "+awtComp);
+ }
+ config = awtGfxConfig;
+ setScreen(awtScreen);
+
+ CapabilitiesImmutable caps = ( null != getChosenCapabilities() ) ? getChosenCapabilities() : getRequestedCapabilities();
+ GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
+ setChosenCapabilities(setupCapabilitiesRGBABits(caps, gc));
+ }
+
+ // open access to superclass method
+ public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
+ super.setChosenCapabilities(capsChosen);
+ }
+
+ @Override
public Object clone() {
return super.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..9869e1eb3 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
@@ -32,8 +32,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 +43,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/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/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index d34d4e58f..5cb7d5aca 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -32,11 +32,16 @@
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.NativeSurface;
+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 +49,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 +71,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..65ecc48fe 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) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index c1c97eece..ddf453bab 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -42,6 +42,8 @@ import java.awt.EventQueue;
import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
@@ -55,6 +57,7 @@ public class JAWTUtil {
// 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 +78,63 @@ 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();
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 +164,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 +224,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 +232,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtLock failed", e);
}
} else {
- JAWT.getJAWT().Lock();
+ jawtLockObject.Lock();
}
}
@@ -207,7 +242,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 +250,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..0f97b0b9f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
@@ -42,48 +42,101 @@ import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
import java.awt.Window;
+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.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 {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
+ // user properties
+ protected boolean shallUseOffscreenLayer = false;
+
// lifetime: forever
protected Component component;
- protected AbstractGraphicsConfiguration config;
+ protected AWTGraphicsConfiguration config;
+ 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) {
+ /**
+ * 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");
+ }
+ this.config = (AWTGraphicsConfiguration) config;
init((Component)comp);
}
private void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
+ this.isApplet = false;
validateNative();
}
+
+ /**
+ * Request an JAWT offscreen layer if supported.
+ * Shall be called before {@link #lockSurface()}.
+ *
+ * @see #getShallUseOffscreenLayer()
+ * @see #isOffscreenLayerSurfaceEnabled()
+ */
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ /**
+ * Implementors shall ensure that all native handles are valid, eg. the {@link javax.media.nativewindow.awt.AWTGraphicsDevice AWTGraphicsDevice}'s
+ * subtype via {@link javax.media.nativewindow.awt.AWTGraphicsDevice#setSubType(String, long) awtGraphicsDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle)}.
+ * <p>
+ * This method may be called several times,
+ * hence the implementation shall check for valid values 1st and bail out early if satisfied.
+ * </p>
+ * @throws NativeWindowException
+ */
protected abstract void validateNative() throws NativeWindowException;
protected synchronized void invalidate() {
- component = null;
+ invalidateNative();
+ jawt = null;
+ isOffscreenLayerSurface = false;
drawable= 0;
bounds = new Rectangle();
}
+ protected abstract void invalidateNative();
protected final void updateBounds(JAWT_Rectangle jawtBounds) {
bounds.setX(jawtBounds.getX());
@@ -100,14 +153,91 @@ public abstract class JAWTWindow implements NativeWindow {
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}
+ * @see #setShallUseOffscreenLayer(boolean)
+ */
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
+ /**
+ * {@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,17 +245,39 @@ 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 {
+ validateNative();
surfaceLock.lock();
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();
adevice.lock();
try {
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
res = lockSurfaceImpl();
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
@@ -169,15 +321,14 @@ 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() {
return config;
}
@@ -190,15 +341,11 @@ public abstract class JAWTWindow implements NativeWindow {
return config.getScreen().getIndex();
}
- public final void setSize(int width, int height) {
- component.setSize(width, height);
- }
-
- public final int getWidth() {
+ public int getWidth() {
return component.getWidth();
}
- public final int getHeight() {
+ public int getHeight() {
return component.getHeight();
}
@@ -207,12 +354,13 @@ public abstract class JAWTWindow implements NativeWindow {
//
public synchronized void destroy() {
+ invalidate();
if(null!=component) {
if(component instanceof Window) {
((Window)component).dispose();
}
+ component = null;
}
- invalidate();
}
public final NativeWindow getParent() {
@@ -222,7 +370,7 @@ public abstract class JAWTWindow implements NativeWindow {
public long getWindowHandle() {
return drawable;
}
-
+
public final int getX() {
return component.getX();
}
@@ -230,44 +378,85 @@ 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);
-
+
+ public boolean hasFocus() {
+ return component.hasFocus();
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index d4f6a95d4..70fc1d62f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -41,37 +41,96 @@
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.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 +146,83 @@ 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) config.getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ config.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);
+ } else {
+ System.err.println("JAWT n/a, bounds "+bounds);
}
- // 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/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index 982b94888..adb9353ce 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -47,6 +47,7 @@ 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;
@@ -61,15 +62,24 @@ public class WindowsJAWTWindow extends JAWTWindow {
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 +104,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 +115,11 @@ 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;
if(null!=ds) {
if (null!=dsi) {
ds.FreeDrawingSurfaceInfo(dsi);
@@ -119,7 +127,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
@@ -131,7 +139,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
return windowHandle;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 2319d6269..236d380d8 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -48,6 +48,7 @@ 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;
@@ -60,7 +61,7 @@ public class X11JAWTWindow extends JAWTWindow {
}
protected void validateNative() throws NativeWindowException {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ final AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
if(awtDevice.getHandle() != 0) {
// subtype and handle set already, done
@@ -85,10 +86,23 @@ public class X11JAWTWindow extends JAWTWindow {
}
awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
}
+
+ protected void invalidateNative() { }
+ 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 +127,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 +137,6 @@ public class X11JAWTWindow extends JAWTWindow {
if (drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
@@ -136,14 +149,14 @@ 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) {
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
index b576b0c6b..6dbf36612 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;
}
@@ -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..a93ab2ac1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -1,5 +1,7 @@
package jogamp.nativewindow.macosx;
+import java.nio.Buffer;
+
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Point;
@@ -34,6 +36,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 +86,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/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index b669bce75..910e564af 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -33,8 +33,14 @@
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 {
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e19d5ecf7..d7a2feff3 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,182 @@ 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]];
+
+ // force surface creation
+ // [myView lockFocus];
+ // [myView unlockFocus];
+
+ [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);
+ NSView* mView = [mWin contentView];
+
+ if(NULL!=mView) {
+ [mWin setContentView: nil];
+ [mView release];
+ }
+ [mWin orderOut: mWin];
+ [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];
+
+ // 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];
+ // simple 1:1 layout !
+ [subLayer setFrame:lRectRoot];
+ DBG_PRINT("CALayer::AddCASublayer0.0: %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:^(){
+ [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 +401,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;
+}
+