summaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/com/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/classes/com/jogamp')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java39
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java54
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java7
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java18
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java45
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java36
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java74
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java37
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java14
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java15
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java175
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java81
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java297
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java641
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java110
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java11
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java508
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java13
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java16
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java122
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java33
21 files changed, 1853 insertions, 493 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
new file mode 100644
index 000000000..c98bf5436
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,39 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookMutableSize extends UpstreamSurfaceHookMutableSize {
+ final UpstreamSurfaceHook upstream;
+
+ /**
+ * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+ * @param width initial width
+ * @param height initial height
+ */
+ public DelegatedUpstreamSurfaceHookMutableSize(UpstreamSurfaceHook upstream, int width, int height) {
+ super(width, height);
+ this.upstream = upstream;
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(null != upstream) {
+ upstream.create(s);
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(null != upstream) {
+ upstream.destroy(s);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ "+ width + "x" + height + ", " + upstream + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
new file mode 100644
index 000000000..1557f4e51
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
@@ -0,0 +1,54 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookWithSurfaceSize implements UpstreamSurfaceHook {
+ final UpstreamSurfaceHook upstream;
+ final NativeSurface surface;
+
+ /**
+ * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+ * @param surface mandatory {@link NativeSurface} used for {@link #getWidth(ProxySurface)} and {@link #getHeight(ProxySurface)}
+ */
+ public DelegatedUpstreamSurfaceHookWithSurfaceSize(UpstreamSurfaceHook upstream, NativeSurface surface) {
+ this.upstream = upstream;
+ this.surface = surface;
+ if(null == surface) {
+ throw new IllegalArgumentException("given surface is null");
+ }
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(null != upstream) {
+ upstream.create(s);
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(null != upstream) {
+ upstream.destroy(s);
+ }
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return surface.getWidth();
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return surface.getHeight();
+ }
+
+ @Override
+ public String toString() {
+ final String us_s = null != surface ? ( surface.getClass().getName() + ": 0x" + Long.toHexString(surface.getSurfaceHandle()) + " " +surface.getWidth() + "x" + surface.getHeight() ) : "nil";
+ return getClass().getSimpleName()+"["+upstream+", "+us_s+"]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java
index 2d5af86b9..8b8ccb191 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -37,7 +37,14 @@ public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
super(screen, capsChosen, capsRequested);
}
+ @Override
public void setChosenCapabilities(CapabilitiesImmutable caps) {
super.setChosenCapabilities(caps);
}
+
+ @Override
+ public void setScreen(AbstractGraphicsScreen screen) {
+ super.setScreen(screen);
+ }
+
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java
index 38bd70a90..a8dd9165c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,17 +20,18 @@
* 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 com.jogamp.nativewindow;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.JogampVersion;
import com.jogamp.common.util.VersionUtil;
+
import java.util.jar.Manifest;
public class NativeWindowVersion extends JogampVersion {
@@ -45,9 +46,10 @@ public class NativeWindowVersion extends JogampVersion {
if(null == jogampCommonVersionInfo) { // volatile: ok
synchronized(NativeWindowVersion.class) {
if( null == jogampCommonVersionInfo ) {
- final String packageName = "javax.media.nativewindow";
- final Manifest mf = VersionUtil.getManifest(NativeWindowVersion.class.getClassLoader(), packageName);
- jogampCommonVersionInfo = new NativeWindowVersion(packageName, mf);
+ final String packageName1 = "javax.media.nativewindow"; // atomic packaging - and identity
+ final String packageName2 = "javax.media.opengl"; // all packaging
+ final Manifest mf = VersionUtil.getManifest(NativeWindowVersion.class.getClassLoader(), new String[]{ packageName1, packageName2 } );
+ jogampCommonVersionInfo = new NativeWindowVersion(packageName1, mf);
}
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
new file mode 100644
index 000000000..5838c7a56
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,45 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class UpstreamSurfaceHookMutableSize implements UpstreamSurfaceHook.MutableSize {
+ int width, height;
+
+ /**
+ * @param width initial width
+ * @param height initial height
+ */
+ public UpstreamSurfaceHookMutableSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public final void setSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return width;
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return height;
+ }
+ @Override
+ public void create(ProxySurface s) { /* nop */ }
+
+ @Override
+ public void destroy(ProxySurface s) { /* nop */ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ "+ width + "x" + height + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java
new file mode 100644
index 000000000..e6fcc049c
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java
@@ -0,0 +1,36 @@
+package com.jogamp.nativewindow;
+
+public class UpstreamSurfaceHookMutableSizePos extends UpstreamSurfaceHookMutableSize {
+ int x, y;
+
+ /**
+ * @param width initial width
+ * @param height initial height
+ */
+ public UpstreamSurfaceHookMutableSizePos(int x, int y, int width, int height) {
+ super(width, height);
+ this.x= x;
+ this.y= y;
+ }
+
+ // @Override
+ public final void setPos(int x, int y) {
+ this.x= x;
+ this.y= y;
+ }
+
+ public final int getX() {
+ return x;
+ }
+
+ public final int getY() {
+ return y;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ "+ x + "/" + y + " " + width + "x" + height + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
deleted file mode 100644
index f2993abab..000000000
--- a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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 com.jogamp.nativewindow;
-
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.SurfaceChangeable;
-
-
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
- protected long surfaceHandle;
-
- public WrappedSurface(AbstractGraphicsConfiguration cfg) {
- this(cfg, 0);
- }
-
- public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle) {
- super(cfg);
- surfaceHandle=handle;
- }
-
- protected final void invalidateImpl() {
- surfaceHandle = 0;
- }
-
- final public long getSurfaceHandle() {
- return surfaceHandle;
- }
-
- final public void setSurfaceHandle(long surfaceHandle) {
- this.surfaceHandle=surfaceHandle;
- }
-
- final protected int lockSurfaceImpl() {
- return LOCK_SUCCESS;
- }
-
- final protected void unlockSurfaceImpl() {
- }
-
- public String toString() {
- 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/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
index 61d5e5c0d..aa9b876dd 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -1,22 +1,22 @@
/*
* 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
* 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
@@ -29,11 +29,11 @@
* 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.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -57,7 +57,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
private GraphicsConfiguration config;
AbstractGraphicsConfiguration encapsulated;
- public AWTGraphicsConfiguration(AWTGraphicsScreen screen,
+ public AWTGraphicsConfiguration(AWTGraphicsScreen screen,
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
GraphicsConfiguration config, AbstractGraphicsConfiguration encapsulated) {
super(screen, capsChosen, capsRequested);
@@ -71,16 +71,17 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
this.config = config;
this.encapsulated=null;
}
-
+
/**
- * @param capsChosen if null, <code>capsRequested</code> is copied and aligned
- * with the graphics Capabilities of the AWT Component to produce the chosen Capabilities.
+ * @param capsChosen if null, <code>capsRequested</code> is copied and aligned
+ * with the graphics {@link Capabilities} of the AWT Component to produce the chosen {@link Capabilities}.
* Otherwise the <code>capsChosen</code> is used.
+ * @param capsRequested if null, default {@link Capabilities} are used, otherwise the given values.
*/
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);
+ throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsConfiguration @ "+awtComp);
}
final GraphicsDevice awtGraphicsDevice = awtGfxConfig.getDevice();
if(null==awtGraphicsDevice) {
@@ -91,12 +92,15 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
final AWTGraphicsDevice awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
final AWTGraphicsScreen awtScreen = new AWTGraphicsScreen(awtDevice);
+ if(null==capsRequested) {
+ capsRequested = new Capabilities();
+ }
if(null==capsChosen) {
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc);
}
- final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice);
- final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen);
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice, capsChosen);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen, VisualIDHolder.VID_UNDEFINED);
if(config instanceof AWTGraphicsConfiguration) {
return (AWTGraphicsConfiguration) config;
}
@@ -105,10 +109,11 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
// open access to superclass method
+ @Override
public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
super.setChosenCapabilities(capsChosen);
}
-
+
@Override
public Object clone() {
return super.clone();
@@ -167,7 +172,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
public String toString() {
return getClass().getSimpleName()+"[" + getScreen() +
",\n\tchosen " + capabilitiesChosen+
- ",\n\trequested " + capabilitiesRequested+
+ ",\n\trequested " + capabilitiesRequested+
",\n\t" + config +
",\n\tencapsulated "+encapsulated+"]";
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java
index 635e6d263..a7fa53577 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java
@@ -1,22 +1,22 @@
/*
* 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
* 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
@@ -29,11 +29,11 @@
* 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.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java
index f4ee06e28..83d6efa75 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java
@@ -1,22 +1,22 @@
/*
* 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
* 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
@@ -29,11 +29,11 @@
* 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.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -87,6 +87,7 @@ public class AWTGraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
return new AWTGraphicsScreen(AWTGraphicsDevice.createDefault());
}
+ @Override
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java
new file mode 100644
index 000000000..44163fc73
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright 2013 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 com.jogamp.nativewindow.awt;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.print.PrinterJob;
+
+import jogamp.nativewindow.awt.AWTMisc;
+
+/**
+ * Interface describing print lifecycle to support AWT printing,
+ * e.g. on AWT {@link javax.media.opengl.GLAutoDrawable GLAutoDrawable}s.
+ * <a name="impl"><h5>Implementations</h5></a>
+ * <p>
+ * Implementing {@link javax.media.opengl.GLAutoDrawable GLAutoDrawable} classes based on AWT
+ * supporting {@link Component#print(Graphics)} shall implement this interface.
+ * </p>
+ * <a name="usage"><h5>Usage</h5></a>
+ * <p>
+ * Users attempting to print an AWT {@link Container} containing {@link AWTPrintLifecycle} elements
+ * shall consider decorating the {@link Container#printAll(Graphics)} call with<br>
+ * {@link #setupPrint(double, double, int, int, int) setupPrint(..)} and {@link #releasePrint()}
+ * on all {@link AWTPrintLifecycle} elements in the {@link Container}.<br>
+ * To minimize this burden, a user can use {@link Context#setupPrint(Container, double, double, int, int, int) Context.setupPrint(..)}:
+ * <pre>
+ * Container cont;
+ * double scaleGLMatXY = 72.0/glDPI;
+ * int numSamples = 0; // leave multisampling as-is
+ * PrinterJob job;
+ * ...
+ final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(cont, scaleGLMatXY, scaleGLMatXY, numSamples);
+ try {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
+ try {
+ job.print();
+ } catch (PrinterException ex) {
+ ex.printStackTrace();
+ }
+ } });
+ } finally {
+ ctx.releasePrint();
+ }
+ *
+ * </pre>
+ * </p>
+ */
+public interface AWTPrintLifecycle {
+
+ public static final int DEFAULT_PRINT_TILE_SIZE = 1024;
+
+
+ /**
+ * Shall be called before {@link PrinterJob#print()}.
+ * <p>
+ * See <a href="#usage">Usage</a>.
+ * </p>
+ * @param scaleMatX {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatX * width pixels
+ * @param scaleMatY {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatY * height pixels
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ * @param tileWidth custom tile width for {@link com.jogamp.opengl.util.TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
+ * @param tileHeight custom tile height for {@link com.jogamp.opengl.util.TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
+ */
+ void setupPrint(double scaleMatX, double scaleMatY, int numSamples, int tileWidth, int tileHeight);
+
+ /**
+ * Shall be called after {@link PrinterJob#print()}.
+ * <p>
+ * See <a href="#usage">Usage</a>.
+ * </p>
+ */
+ void releasePrint();
+
+ /**
+ * Convenient {@link AWTPrintLifecycle} context simplifying calling {@link AWTPrintLifecycle#setupPrint(double, double, int, int, int) setupPrint(..)}
+ * and {@link AWTPrintLifecycle#releasePrint()} on all {@link AWTPrintLifecycle} elements of a {@link Container}.
+ * <p>
+ * See <a href="#usage">Usage</a>.
+ * </p>
+ */
+ public static class Context {
+ /**
+ * <p>
+ * See <a href="#usage">Usage</a>.
+ * </p>
+ *
+ * @param c container to be traversed through to perform {@link AWTPrintLifecycle#setupPrint(double, double, int, int, int) setupPrint(..)} on all {@link AWTPrintLifecycle} elements.
+ * @param scaleMatX {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatX * width pixels
+ * @param scaleMatY {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatY * height pixels
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ * @param tileWidth custom tile width for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
+ * @param tileHeight custom tile height for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
+ * @return the context
+ */
+ public static Context setupPrint(Container c, double scaleMatX, double scaleMatY, int numSamples, int tileWidth, int tileHeight) {
+ final Context t = new Context(c, scaleMatX, scaleMatY, numSamples, tileWidth, tileHeight);
+ t.setupPrint(c);
+ return t;
+ }
+
+ /**
+ * <p>
+ * See <a href="#usage">Usage</a>.
+ * </p>
+ */
+ public void releasePrint() {
+ count = AWTMisc.performAction(cont, AWTPrintLifecycle.class, releaseAction);
+ }
+
+ /**
+ * @return count of performed actions of last {@link #setupPrint(Container, double, double, int, int, int) setupPrint(..)} or {@link #releasePrint()}.
+ */
+ public int getCount() { return count; }
+
+ private final Container cont;
+ private final double scaleMatX;
+ private final double scaleMatY;
+ private final int numSamples;
+ private final int tileWidth;
+ private final int tileHeight;
+ private int count;
+
+ private final AWTMisc.ComponentAction setupAction = new AWTMisc.ComponentAction() {
+ @Override
+ public void run(Component c) {
+ ((AWTPrintLifecycle)c).setupPrint(scaleMatX, scaleMatY, numSamples, tileWidth, tileHeight);
+ } };
+ private final AWTMisc.ComponentAction releaseAction = new AWTMisc.ComponentAction() {
+ @Override
+ public void run(Component c) {
+ ((AWTPrintLifecycle)c).releasePrint();
+ } };
+
+ private Context(Container c, double scaleMatX, double scaleMatY, int numSamples, int tileWidth, int tileHeight) {
+ this.cont = c;
+ this.scaleMatX = scaleMatX;
+ this.scaleMatY = scaleMatY;
+ this.numSamples = numSamples;
+ this.tileWidth = tileWidth;
+ this.tileHeight = tileHeight;
+ this.count = 0;
+ }
+ private void setupPrint(Container c) {
+ count = AWTMisc.performAction(c, AWTPrintLifecycle.class, setupAction);
+ }
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
index d78b4ac15..aadecb455 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
@@ -33,22 +33,31 @@ import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
+
import javax.media.nativewindow.WindowClosingProtocol;
import jogamp.nativewindow.awt.AWTMisc;
public class AWTWindowClosingProtocol implements WindowClosingProtocol {
- private Component comp;
- private Runnable closingOperation;
- private volatile boolean closingListenerSet = false;
- private Object closingListenerLock = new Object();
+ private final Component comp;
+ private Window listenTo;
+ private final Runnable closingOperationClose;
+ private final Runnable closingOperationNOP;
+ private final Object closingListenerLock = new Object();
private WindowClosingMode defaultCloseOperation = WindowClosingMode.DISPOSE_ON_CLOSE;
private boolean defaultCloseOperationSetByUser = false;
- public AWTWindowClosingProtocol(Component comp, Runnable closingOperation) {
+ /**
+ * @param comp mandatory AWT component which AWT Window is being queried by parent traversal
+ * @param closingOperationClose mandatory closing operation, triggered if windowClosing and {@link WindowClosingMode#DISPOSE_ON_CLOSE}
+ * @param closingOperationNOP optional closing operation, triggered if windowClosing and {@link WindowClosingMode#DO_NOTHING_ON_CLOSE}
+ */
+ public AWTWindowClosingProtocol(Component comp, Runnable closingOperationClose, Runnable closingOperationNOP) {
this.comp = comp;
- this.closingOperation = closingOperation;
+ this.listenTo = null;
+ this.closingOperationClose = closingOperationClose;
+ this.closingOperationNOP = closingOperationNOP;
}
class WindowClosingAdapter extends WindowAdapter {
@@ -59,54 +68,46 @@ public class AWTWindowClosingProtocol implements WindowClosingProtocol {
if( WindowClosingMode.DISPOSE_ON_CLOSE == op ) {
// we have to issue this call right away,
// otherwise the window gets destroyed
- closingOperation.run();
+ closingOperationClose.run();
+ } else if( null != closingOperationNOP ){
+ closingOperationNOP.run();
}
}
}
WindowListener windowClosingAdapter = new WindowClosingAdapter();
- final boolean addClosingListenerImpl() {
- Window w = AWTMisc.getWindow(comp);
- if(null!=w) {
- w.addWindowListener(windowClosingAdapter);
- return true;
- }
- return false;
- }
-
/**
- * Adds this closing listener to the components Window if exist and only one time.<br>
- * Hence you may call this method every time to ensure it has been set,
- * ie in case the Window parent is not available yet.
+ * Adds this closing listener to the components Window if exist and only one time.
+ * <p>
+ * If the closing listener is already added, and {@link IllegalStateException} is thrown.
+ * </p>
*
- * @return
+ * @return true if added, otherwise false.
+ * @throws IllegalStateException
*/
- public final boolean addClosingListenerOneShot() {
- if(!closingListenerSet) { // volatile: ok
+ public final boolean addClosingListener() throws IllegalStateException {
synchronized(closingListenerLock) {
- if(!closingListenerSet) {
- closingListenerSet=addClosingListenerImpl();
- return closingListenerSet;
- }
+ if(null != listenTo) {
+ throw new IllegalStateException("WindowClosingListener already set");
+ }
+ listenTo = AWTMisc.getWindow(comp);
+ if(null!=listenTo) {
+ listenTo.addWindowListener(windowClosingAdapter);
+ return true;
+ }
}
- }
- return false;
+ return false;
}
public final boolean removeClosingListener() {
- if(closingListenerSet) { // volatile: ok
synchronized(closingListenerLock) {
- if(closingListenerSet) {
- Window w = AWTMisc.getWindow(comp);
- if(null!=w) {
- w.removeWindowListener(windowClosingAdapter);
- closingListenerSet = false;
- return true;
- }
- }
+ if(null != listenTo) {
+ listenTo.removeWindowListener(windowClosingAdapter);
+ listenTo = null;
+ return true;
+ }
}
- }
- return false;
+ return false;
}
/**
@@ -115,6 +116,7 @@ public class AWTWindowClosingProtocol implements WindowClosingProtocol {
* otherwise return the AWT/Swing close operation value translated to
* a {@link WindowClosingProtocol} value .
*/
+ @Override
public final WindowClosingMode getDefaultCloseOperation() {
synchronized(closingListenerLock) {
if(defaultCloseOperationSetByUser) {
@@ -125,6 +127,7 @@ public class AWTWindowClosingProtocol implements WindowClosingProtocol {
return AWTMisc.getNWClosingOperation(comp);
}
+ @Override
public final WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
synchronized(closingListenerLock) {
final WindowClosingMode _op = defaultCloseOperation;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java
new file mode 100644
index 000000000..eeec66376
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java
@@ -0,0 +1,297 @@
+/**
+ * Copyright 2013 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 com.jogamp.nativewindow.awt;
+
+import java.awt.Point;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.nio.IntBuffer;
+import java.util.Hashtable;
+
+import com.jogamp.common.nio.Buffers;
+
+/**
+ * {@link DataBuffer} specialization using NIO direct buffer of type {@link DataBuffer#TYPE_INT} as storage.
+ */
+public final class DirectDataBufferInt extends DataBuffer {
+
+ public static class DirectWritableRaster extends WritableRaster {
+ protected DirectWritableRaster(SampleModel sampleModel, DirectDataBufferInt dataBuffer, Point origin) {
+ super(sampleModel, dataBuffer, origin);
+ }
+ }
+
+ public static class BufferedImageInt extends BufferedImage {
+ final int customImageType;
+ public BufferedImageInt (int customImageType, ColorModel cm, WritableRaster raster, Hashtable<?,?> properties) {
+ super(cm, raster, false /* isRasterPremultiplied */, properties);
+ this.customImageType = customImageType;
+ }
+
+ /**
+ * @return one of the custom image-type values {@link BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB},
+ * {@link BufferedImage#TYPE_INT_ARGB_PRE TYPE_INT_ARGB_PRE},
+ * {@link BufferedImage#TYPE_INT_RGB TYPE_INT_RGB} or {@link BufferedImage#TYPE_INT_BGR TYPE_INT_BGR}.
+ */
+ public int getCustomType() {
+ return customImageType;
+ }
+
+ @Override
+ public String toString() {
+ return "BufferedImageInt@"+Integer.toHexString(hashCode())
+ +": custom/internal type = "+customImageType+"/"+getType()
+ +" "+getColorModel()+" "+getRaster();
+ }
+ }
+
+ /**
+ * Creates a {@link BufferedImageInt} using a {@link DirectColorModel direct color model} in {@link ColorSpace#CS_sRGB sRGB color space}.<br>
+ * It uses a {@link DirectWritableRaster} utilizing {@link DirectDataBufferInt} storage.
+ * <p>
+ * Note that due to using the custom storage type {@link DirectDataBufferInt}, the resulting
+ * {@link BufferedImage}'s {@link BufferedImage#getType() image-type} is of {@link BufferedImage#TYPE_CUSTOM TYPE_CUSTOM}.
+ * We are not able to change this detail, since the AWT image implementation associates the {@link BufferedImage#getType() image-type}
+ * with a build-in storage-type.
+ * Use {@link BufferedImageInt#getCustomType()} to retrieve the custom image-type, which will return the <code>imageType</code>
+ * value passed here.
+ * </p>
+ *
+ * @param width
+ * @param height
+ * @param imageType one of {@link BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}, {@link BufferedImage#TYPE_INT_ARGB_PRE TYPE_INT_ARGB_PRE},
+ * {@link BufferedImage#TYPE_INT_RGB TYPE_INT_RGB} or {@link BufferedImage#TYPE_INT_BGR TYPE_INT_BGR}.
+ * @param location origin, if <code>null</code> 0/0 is assumed.
+ * @param properties <code>Hashtable</code> of
+ * <code>String</code>/<code>Object</code> pairs. Used for {@link BufferedImage#getProperty(String)} etc.
+ * @return
+ */
+ public static BufferedImageInt createBufferedImage(int width, int height, int imageType, Point location, Hashtable<?,?> properties) {
+ final ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ final int transferType = DataBuffer.TYPE_INT;
+ final int bpp, rmask, gmask, bmask, amask;
+ final boolean alphaPreMul;
+ switch( imageType ) {
+ case BufferedImage.TYPE_INT_ARGB:
+ bpp = 32;
+ rmask = 0x00ff0000;
+ gmask = 0x0000ff00;
+ bmask = 0x000000ff;
+ amask = 0xff000000;
+ alphaPreMul = false;
+ break;
+ case BufferedImage.TYPE_INT_ARGB_PRE:
+ bpp = 32;
+ rmask = 0x00ff0000;
+ gmask = 0x0000ff00;
+ bmask = 0x000000ff;
+ amask = 0xff000000;
+ alphaPreMul = true;
+ break;
+ case BufferedImage.TYPE_INT_RGB:
+ bpp = 24;
+ rmask = 0x00ff0000;
+ gmask = 0x0000ff00;
+ bmask = 0x000000ff;
+ amask = 0x0;
+ alphaPreMul = false;
+ break;
+ case BufferedImage.TYPE_INT_BGR:
+ bpp = 24;
+ rmask = 0x000000ff;
+ gmask = 0x0000ff00;
+ bmask = 0x00ff0000;
+ amask = 0x0;
+ alphaPreMul = false;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported imageType, must be [INT_ARGB, INT_ARGB_PRE, INT_RGB, INT_BGR], has "+imageType);
+ }
+ final ColorModel colorModel = new DirectColorModel(colorSpace, bpp, rmask, gmask, bmask, amask, alphaPreMul, transferType);
+ final int[] bandMasks;
+ if ( 0 != amask ) {
+ bandMasks = new int[4];
+ bandMasks[3] = amask;
+ }
+ else {
+ bandMasks = new int[3];
+ }
+ bandMasks[0] = rmask;
+ bandMasks[1] = gmask;
+ bandMasks[2] = bmask;
+
+ final DirectDataBufferInt dataBuffer = new DirectDataBufferInt(width*height);
+ if( null == location ) {
+ location = new Point(0,0);
+ }
+ final SinglePixelPackedSampleModel sppsm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
+ width, height, width /* scanLineStride */, bandMasks);
+ // IntegerComponentRasters must haveinteger DataBuffers:
+ // final WritableRaster raster = new IntegerInterleavedRaster(sppsm, dataBuffer, location);
+ // Not public:
+ // final WritableRaster raster = new SunWritableRaster(sppsm, dataBuffer, location);
+ final WritableRaster raster = new DirectWritableRaster(sppsm, dataBuffer, location);
+
+ return new BufferedImageInt(imageType, colorModel, raster, properties);
+ }
+
+ /** Default data bank. */
+ private IntBuffer data;
+
+ /** All data banks */
+ private IntBuffer bankdata[];
+
+ /**
+ * Constructs an nio integer-based {@link DataBuffer} with a single bank
+ * and the specified size.
+ *
+ * @param size The size of the {@link DataBuffer}.
+ */
+ public DirectDataBufferInt(int size) {
+ super(TYPE_INT, size);
+ data = Buffers.newDirectIntBuffer(size);
+ bankdata = new IntBuffer[1];
+ bankdata[0] = data;
+ }
+
+ /**
+ * Constructs an nio integer-based {@link DataBuffer} with the specified number of
+ * banks, all of which are the specified size.
+ *
+ * @param size The size of the banks in the {@link DataBuffer}.
+ * @param numBanks The number of banks in the a{@link DataBuffer}.
+ */
+ public DirectDataBufferInt(int size, int numBanks) {
+ super(TYPE_INT,size,numBanks);
+ bankdata = new IntBuffer[numBanks];
+ for (int i= 0; i < numBanks; i++) {
+ bankdata[i] = Buffers.newDirectIntBuffer(size);
+ }
+ data = bankdata[0];
+ }
+
+ /**
+ * Constructs an nio integer-based {@link DataBuffer} with a single bank using the
+ * specified array.
+ * <p>
+ * Only the first <code>size</code> elements should be used by accessors of
+ * this {@link DataBuffer}. <code>dataArray</code> must be large enough to
+ * hold <code>size</code> elements.
+ * </p>
+ *
+ * @param dataArray The integer array for the {@link DataBuffer}.
+ * @param size The size of the {@link DataBuffer} bank.
+ */
+ public DirectDataBufferInt(IntBuffer dataArray, int size) {
+ super(TYPE_INT,size);
+ data = dataArray;
+ bankdata = new IntBuffer[1];
+ bankdata[0] = data;
+ }
+
+ /**
+ * Returns the default (first) int data array in {@link DataBuffer}.
+ *
+ * @return The first integer data array.
+ */
+ public IntBuffer getData() {
+ return data;
+ }
+
+ /**
+ * Returns the data array for the specified bank.
+ *
+ * @param bank The bank whose data array you want to get.
+ * @return The data array for the specified bank.
+ */
+ public IntBuffer getData(int bank) {
+ return bankdata[bank];
+ }
+
+ /**
+ * Returns the requested data array element from the first (default) bank.
+ *
+ * @param i The data array element you want to get.
+ * @return The requested data array element as an integer.
+ * @see #setElem(int, int)
+ * @see #setElem(int, int, int)
+ */
+ @Override
+ public int getElem(int i) {
+ return data.get(i+offset);
+ }
+
+ /**
+ * Returns the requested data array element from the specified bank.
+ *
+ * @param bank The bank from which you want to get a data array element.
+ * @param i The data array element you want to get.
+ * @return The requested data array element as an integer.
+ * @see #setElem(int, int)
+ * @see #setElem(int, int, int)
+ */
+ @Override
+ public int getElem(int bank, int i) {
+ return bankdata[bank].get(i+offsets[bank]);
+ }
+
+ /**
+ * Sets the requested data array element in the first (default) bank
+ * to the specified value.
+ *
+ * @param i The data array element you want to set.
+ * @param val The integer value to which you want to set the data array element.
+ * @see #getElem(int)
+ * @see #getElem(int, int)
+ */
+ @Override
+ public void setElem(int i, int val) {
+ data.put(i+offset, val);
+ }
+
+ /**
+ * Sets the requested data array element in the specified bank
+ * to the integer value <code>i</code>.
+ * @param bank The bank in which you want to set the data array element.
+ * @param i The data array element you want to set.
+ * @param val The integer value to which you want to set the specified data array element.
+ * @see #getElem(int)
+ * @see #getElem(int, int)
+ */
+ @Override
+ public void setElem(int bank, int i, int val) {
+ bankdata[bank].put(i+offsets[bank], val);
+ }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 02dd746a0..20ab7a2ee 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2003 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
@@ -29,7 +29,7 @@
* 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.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
@@ -37,14 +37,25 @@
package com.jogamp.nativewindow.awt;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import java.awt.Component;
import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Window;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
import java.applet.Applet;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
@@ -53,11 +64,14 @@ import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.PixelRectangle;
import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
import jogamp.nativewindow.SurfaceUpdatedHelper;
+import jogamp.nativewindow.awt.AWTMisc;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWT_Rectangle;
@@ -67,12 +81,13 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
// user properties
protected boolean shallUseOffscreenLayer = false;
-
+
// lifetime: forever
- protected Component component;
- private AWTGraphicsConfiguration config; // control access due to delegation
- private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ protected final Component component;
+ private final AWTGraphicsConfiguration config; // control access due to delegation
+ private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ private final RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private final JAWTComponentListener jawtComponentListener;
// lifetime: valid after lock but may change with each 1st lock, purges after invalidate
private boolean isApplet;
@@ -81,13 +96,14 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected long drawable;
protected Rectangle bounds;
protected Insets insets;
-
+ private volatile long offscreenSurfaceLayer;
+
private long drawable_old;
-
+
/**
* Constructed by {@link jogamp.nativewindow.NativeWindowFactoryImpl#getNativeWindow(Object, AbstractGraphicsConfiguration)}
* via this platform's specialization (X11, OSX, Windows, ..).
- *
+ *
* @param comp
* @param config
*/
@@ -98,29 +114,142 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
if(! ( config instanceof AWTGraphicsConfiguration ) ) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
}
+ this.component = (Component)comp;
this.config = (AWTGraphicsConfiguration) config;
- init((Component)comp);
- }
-
- private void init(Component windowObject) throws NativeWindowException {
+ this.jawtComponentListener = new JAWTComponentListener();
invalidate();
- this.component = windowObject;
this.isApplet = false;
+ this.offscreenSurfaceLayer = 0;
+ }
+ private static String id(Object obj) { return "0x" + ( null!=obj ? Integer.toHexString(obj.hashCode()) : "nil" ); }
+ private String jawtStr() { return "JAWTWindow["+id(JAWTWindow.this)+"]"; }
+
+ private class JAWTComponentListener implements ComponentListener, HierarchyListener {
+ private boolean isShowing;
+
+ private String str(final Object obj) {
+ if( null == obj ) {
+ return "0xnil: null";
+ } else if( obj instanceof Component ) {
+ final Component c = (Component)obj;
+ return id(obj)+": "+c.getClass().getSimpleName()+"[visible "+c.isVisible()+", showing "+c.isShowing()+", valid "+c.isValid()+
+ ", displayable "+c.isDisplayable()+", "+c.getX()+"/"+c.getY()+" "+c.getWidth()+"x"+c.getHeight()+"]";
+ } else {
+ return id(obj)+": "+obj.getClass().getSimpleName()+"[..]";
+ }
+ }
+ private String s(final ComponentEvent e) {
+ return "visible[isShowing "+isShowing+"],"+Platform.getNewline()+
+ " ** COMP "+str(e.getComponent())+Platform.getNewline()+
+ " ** SOURCE "+str(e.getSource())+Platform.getNewline()+
+ " ** THIS "+str(component)+Platform.getNewline()+
+ " ** THREAD "+getThreadName();
+ }
+ private String s(final HierarchyEvent e) {
+ return "visible[isShowing "+isShowing+"], changeBits 0x"+Long.toHexString(e.getChangeFlags())+Platform.getNewline()+
+ " ** COMP "+str(e.getComponent())+Platform.getNewline()+
+ " ** SOURCE "+str(e.getSource())+Platform.getNewline()+
+ " ** CHANGED "+str(e.getChanged())+Platform.getNewline()+
+ " ** CHANGEDPARENT "+str(e.getChangedParent())+Platform.getNewline()+
+ " ** THIS "+str(component)+Platform.getNewline()+
+ " ** THREAD "+getThreadName();
+ }
+ @Override
+ public final String toString() {
+ return "visible[isShowing "+isShowing+"],"+Platform.getNewline()+
+ " ** THIS "+str(component)+Platform.getNewline()+
+ " ** THREAD "+getThreadName();
+ }
+
+ private JAWTComponentListener() {
+ isShowing = component.isShowing();
+ AWTEDTExecutor.singleton.invoke(false, new Runnable() { // Bug 952: Avoid deadlock via AWTTreeLock acquisition ..
+ @Override
+ public void run() {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".attach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+ }
+ component.addComponentListener(JAWTComponentListener.this);
+ component.addHierarchyListener(JAWTComponentListener.this);
+ } } );
+ }
+
+ private final void detach() {
+ AWTEDTExecutor.singleton.invoke(false, new Runnable() { // Bug 952: Avoid deadlock via AWTTreeLock acquisition ..
+ @Override
+ public void run() {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".detach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+ }
+ component.removeComponentListener(JAWTComponentListener.this);
+ component.removeHierarchyListener(JAWTComponentListener.this);
+ } } );
+ }
+
+ @Override
+ public final void componentResized(ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentResized: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentMoved(ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentMoved: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentShown(ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentShown: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentHidden(ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentHidden: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void hierarchyChanged(HierarchyEvent e) {
+ final boolean wasShowing = isShowing;
+ isShowing = component.isShowing();
+ int action = 0;
+ if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags() ) ) {
+ if( e.getChanged() != component && wasShowing != isShowing ) {
+ // A parent component changed and caused a 'showing' state change,
+ // propagate to offscreen-layer!
+ layoutSurfaceLayerIfEnabled(isShowing);
+ action = 1;
+ }
+ }
+ if(DEBUG) {
+ final java.awt.Component changed = e.getChanged();
+ final boolean displayable = changed.isDisplayable();
+ final boolean showing = changed.isShowing();
+ System.err.println(jawtStr()+".hierarchyChanged: action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+isShowing+"], "+s(e));
+ }
+ }
}
-
- public void setShallUseOffscreenLayer(boolean v) {
- shallUseOffscreenLayer = v;
- }
-
- public final boolean getShallUseOffscreenLayer() {
- return shallUseOffscreenLayer;
- }
-
- public final boolean isOffscreenLayerSurfaceEnabled() {
- return isOffscreenLayerSurface;
- }
-
+
+ private static String getThreadName() { return Thread.currentThread().getName(); }
+
protected synchronized void invalidate() {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".invalidate() - "+jawtComponentListener.toString());
+ if( isSurfaceLayerAttached() ) {
+ System.err.println("OffscreenSurfaceLayer still attached: 0x"+Long.toHexString(offscreenSurfaceLayer));
+ }
+ // Thread.dumpStack();
+ }
invalidateNative();
jawt = null;
isOffscreenLayerSurface = false;
@@ -131,33 +260,38 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
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);
+ protected final boolean updateBounds(JAWT_Rectangle jawtBounds) {
+ final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
+ final boolean changed = !bounds.equals(jb);
+
+ if(changed) {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.updateBounds: "+bounds+" -> "+jb);
+ // Thread.dumpStack();
+ }
+ bounds.set(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
+
+ if(component instanceof Container) {
+ final java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.set(contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
+ }
}
+ return changed;
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
-
+
+ @Override
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()}.
+
+ /**
+ * 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;
@@ -168,70 +302,141 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return jawt;
}
- /**
- * {@inheritDoc}
- */
- public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ //
+ // OffscreenLayerOption
+ //
+
+ @Override
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ @Override
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ @Override
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
+ //
+ // OffscreenLayerSurface
+ //
+
+ @Override
+ 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}
+ attachSurfaceLayerImpl(layerHandle);
+ offscreenSurfaceLayer = layerHandle;
+ component.repaint();
+ }
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ /**
+ * Layout the offscreen layer according to the implementing class's constraints.
+ * <p>
+ * This method allows triggering a re-layout of the offscreen surface
+ * in case the implementation requires it.
+ * </p>
+ * <p>
+ * Call this method if any parent or ancestor's layout has been changed,
+ * which could affects the layout of this surface.
+ * </p>
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
*/
- public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException {
- if( !isOffscreenLayerSurfaceEnabled() ) {
- throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
+ protected void layoutSurfaceLayerImpl(long layerHandle, boolean visible) {}
+
+ private final void layoutSurfaceLayerIfEnabled(boolean visible) throws NativeWindowException {
+ if( isOffscreenLayerSurfaceEnabled() && 0 != offscreenSurfaceLayer ) {
+ layoutSurfaceLayerImpl(offscreenSurfaceLayer, visible);
}
- int lockRes = lockSurface();
- if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
- throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+
+
+ @Override
+ public final void detachSurfaceLayer() throws NativeWindowException {
+ if( 0 == offscreenSurfaceLayer) {
+ throw new NativeWindowException("No offscreen layer attached: "+this);
}
- try {
- if(DEBUG) {
- System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
- }
- detachSurfaceLayerImpl(layerHandle);
- } finally {
- unlockSurface();
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): osh "+toHexString(offscreenSurfaceLayer));
}
- }
- protected abstract void detachSurfaceLayerImpl(final long layerHandle);
-
- //
- // SurfaceUpdateListener
- //
+ detachSurfaceLayerImpl(offscreenSurfaceLayer, detachSurfaceLayerNotify);
+ }
+ private final Runnable detachSurfaceLayerNotify = new Runnable() {
+ @Override
+ public void run() {
+ offscreenSurfaceLayer = 0;
+ }
+ };
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ /**
+ * @param detachNotify Runnable to be called before native detachment
+ */
+ protected void detachSurfaceLayerImpl(final long layerHandle, final Runnable detachNotify) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
}
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+
+ @Override
+ public final long getAttachedSurfaceLayer() {
+ return offscreenSurfaceLayer;
}
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ @Override
+ public final boolean isSurfaceLayerAttached() {
+ return 0 != offscreenSurfaceLayer;
+ }
+
+ @Override
+ public final void setChosenCapabilities(CapabilitiesImmutable caps) {
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ config.setChosenCapabilities(caps);
+ }
+
+ @Override
+ public final RecursiveLock getLock() {
+ return surfaceLock;
+ }
+
+ @Override
+ public final boolean setCursor(final PixelRectangle pixelrect, final PointImmutable hotSpot) {
+ AWTEDTExecutor.singleton.invoke(false, new Runnable() {
+ public void run() {
+ Cursor c = null;
+ if( null == pixelrect || null == hotSpot ) {
+ c = Cursor.getDefaultCursor();
+ } else {
+ final java.awt.Point awtHotspot = new java.awt.Point(hotSpot.getX(), hotSpot.getY());
+ try {
+ c = AWTMisc.getCursor(pixelrect, awtHotspot);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if( null != c ) {
+ component.setCursor(c);
+ }
+ } } );
+ return true;
+ }
+
+ @Override
+ public final boolean hideCursor() {
+ AWTEDTExecutor.singleton.invoke(false, new Runnable() {
+ public void run() {
+ component.setCursor(AWTMisc.getNullCursor());
+ } } );
+ return true;
}
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
- }
-
//
// NativeSurface
//
@@ -243,59 +448,65 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
c = c.getParent();
}
}
-
+
/**
- * If JAWT offscreen layer is supported,
+ * 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;
protected void dumpJAWTInfo() {
- if(null != jawt) {
- System.err.println("JAWT version: 0x"+Integer.toHexString(jawt.getCachedVersion())+
- ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(jawt)+
- ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds+", insets "+insets);
- } else {
- System.err.println("JAWT n/a, bounds "+bounds+", insets "+insets);
- }
+ System.err.println(jawt2String(null).toString());
// Thread.dumpStack();
}
-
- public final int lockSurface() throws NativeWindowException {
+
+ @Override
+ public final int lockSurface() throws NativeWindowException, RuntimeException {
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 = getGraphicsConfiguration().getScreen().getDevice();
- adevice.lock();
+ if( !component.isDisplayable() ) {
+ // W/o native peer, we cannot utilize JAWT for locking.
+ surfaceLock.unlock();
+ if(DEBUG) {
+ System.err.println("JAWTWindow: Can't lock surface, component peer n/a. Component displayable "+component.isDisplayable()+", "+component);
+ Thread.dumpStack();
+ }
+ } else {
+ determineIfApplet();
try {
- jawt = fetchJAWTImpl();
- isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
- res = lockSurfaceImpl();
- if(LOCK_SUCCESS == res && drawable_old != drawable) {
- res = LOCK_SURFACE_CHANGED;
- if(DEBUG) {
- System.err.println("JAWTWindow: surface change 0x"+Long.toHexString(drawable_old)+" -> 0x"+Long.toHexString(drawable));
- // Thread.dumpStack();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
+ adevice.lock();
+ try {
+ if(null == jawt) { // no need to re-fetch for each frame
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
+ }
+ res = lockSurfaceImpl();
+ if(LOCK_SUCCESS == res && drawable_old != drawable) {
+ res = LOCK_SURFACE_CHANGED;
+ if(DEBUG) {
+ System.err.println("JAWTWindow: surface change "+toHexString(drawable_old)+" -> "+toHexString(drawable));
+ // Thread.dumpStack();
+ }
+ }
+ } finally {
+ if (LOCK_SURFACE_NOT_READY >= res) {
+ adevice.unlock();
}
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
- adevice.unlock();
+ surfaceLock.unlock();
}
}
- } finally {
- if (LOCK_SURFACE_NOT_READY >= res) {
- surfaceLock.unlock();
- }
}
}
return res;
@@ -303,6 +514,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected abstract void unlockSurfaceImpl() throws NativeWindowException;
+ @Override
public final void unlockSurface() {
surfaceLock.validateLocked();
drawable_old = drawable;
@@ -310,7 +522,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
if (surfaceLock.getHoldCount() == 1) {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
- unlockSurfaceImpl();
+ if(null != jawt) {
+ unlockSurfaceImpl();
+ }
} finally {
adevice.unlock();
}
@@ -318,47 +532,68 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
surfaceLock.unlock();
}
+ @Override
public final boolean isSurfaceLockedByOtherThread() {
return surfaceLock.isLockedByOtherThread();
}
- public final boolean isSurfaceLocked() {
- return surfaceLock.isLocked();
- }
-
+ @Override
public final Thread getSurfaceLockOwner() {
return surfaceLock.getOwner();
}
+ @Override
public boolean surfaceSwap() {
return false;
}
+ @Override
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ @Override
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
+
+ @Override
public long getSurfaceHandle() {
return drawable;
}
-
- public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
- return config;
- }
-
+
+ @Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
+ @Override
public final long getDisplayHandle() {
return getGraphicsConfiguration().getScreen().getDevice().getHandle();
}
+ @Override
public final int getScreenIndex() {
return getGraphicsConfiguration().getScreen().getIndex();
}
- public int getWidth() {
+ @Override
+ public final int getWidth() {
return component.getWidth();
}
- public int getHeight() {
+ @Override
+ public final int getHeight() {
return component.getHeight();
}
@@ -366,41 +601,55 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
// NativeWindow
//
- public synchronized void destroy() {
- invalidate();
- component = null; // don't dispose the AWT component, since we are merely an immutable uplink
+ @Override
+ public void destroy() {
+ surfaceLock.lock();
+ try {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".destroy @ Thread "+getThreadName());
+ }
+ jawtComponentListener.detach();
+ invalidate();
+ } finally {
+ surfaceLock.unlock();
+ }
}
+ @Override
public final NativeWindow getParent() {
return null;
}
+ @Override
public long getWindowHandle() {
return drawable;
}
-
+
+ @Override
public final int getX() {
return component.getX();
}
+ @Override
public final int getY() {
return component.getY();
}
-
+
/**
* {@inheritDoc}
- *
+ *
* <p>
- * This JAWT default implementation is currently still using
+ * 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
+ * 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>
+ * </p>
*/
+ @Override
public Point getLocationOnScreen(Point storage) {
Point los = getLocationOnScreenNative(storage);
if(null == los) {
@@ -410,7 +659,11 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this);
Thread.dumpStack();
}
- return getLocationOnScreenNonBlocking(storage, component);
+ if( null == storage ) {
+ storage = new Point();
+ }
+ getLocationOnScreenNonBlocking(storage, component);
+ return storage;
}
java.awt.Point awtLOS = component.getLocationOnScreen();
if(null!=storage) {
@@ -421,7 +674,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
return los;
}
-
+
protected Point getLocationOnScreenNative(Point storage) {
int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
@@ -442,50 +695,84 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
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;
+ protected static Component getLocationOnScreenNonBlocking(Point storage, Component comp) {
+ final java.awt.Insets insets = new java.awt.Insets(0, 0, 0, 0); // DEBUG
+ Component last = null;
while(null != comp) {
- x += comp.getX();
- y += comp.getY();
+ final int dx = comp.getX();
+ final int dy = comp.getY();
+ if( DEBUG ) {
+ final java.awt.Insets ins = AWTMisc.getInsets(comp, false);
+ if( null != ins ) {
+ insets.bottom += ins.bottom;
+ insets.top += ins.top;
+ insets.left += ins.left;
+ insets.right += ins.right;
+ }
+ System.err.print("LOS: "+storage+" + "+comp.getClass().getName()+"["+dx+"/"+dy+", vis "+comp.isVisible()+", ins "+ins+" -> "+insets+"] -> ");
+ }
+ storage.translate(dx, dy);
+ if( DEBUG ) {
+ System.err.println(storage);
+ }
+ last = comp;
+ if( comp instanceof Window ) { // top-level heavy-weight ?
+ break;
+ }
comp = comp.getParent();
}
- if(null!=storage) {
- storage.translate(x, y);
- return storage;
- }
- return new Point(x, y);
+ return last;
}
-
+
+ @Override
public boolean hasFocus() {
return component.hasFocus();
}
-
+
+ protected StringBuilder jawt2String(StringBuilder sb) {
+ if( null == sb ) {
+ sb = new StringBuilder();
+ }
+ sb.append("JVM version: ").append(Platform.JAVA_VERSION).append(" (").
+ append(Platform.JAVA_VERSION_NUMBER).
+ append(" update ").append(Platform.JAVA_VERSION_UPDATE).append(")").append(Platform.getNewline());
+ if(null != jawt) {
+ sb.append("JAWT version: 0x").append(Integer.toHexString(jawt.getCachedVersion())).
+ append(", CA_LAYER: ").append(JAWTUtil.isJAWTUsingOffscreenLayer(jawt)).
+ append(", isLayeredSurface ").append(isOffscreenLayerSurfaceEnabled()).append(", bounds ").append(bounds).append(", insets ").append(insets);
+ } else {
+ sb.append("JAWT n/a, bounds ").append(bounds).append(", insets ").append(insets);
+ }
+ return sb;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("JAWT-Window["+
- "windowHandle 0x"+Long.toHexString(getWindowHandle())+
- ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", bounds "+bounds+", insets "+insets+
- ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface);
- if(null!=component) {
- sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
- ", visible "+component.isVisible());
- } else {
- sb.append(", component NULL");
- }
+ sb.append(jawtStr()+"[");
+ jawt2String(sb);
+ sb.append( ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface+
+ ", attachedSurfaceLayer "+toHexString(getAttachedSurfaceLayer())+
+ ", windowHandle "+toHexString(getWindowHandle())+
+ ", surfaceHandle "+toHexString(getSurfaceHandle())+
+ ", bounds "+bounds+", insets "+insets
+ );
+ sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+ ", visible "+component.isVisible());
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
- ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+ ",\n\tconfig "+config+
",\n\tawtComponent "+getAWTComponent()+
",\n\tsurfaceLock "+surfaceLock+"]");
return sb.toString();
}
+ protected final String toHexString(long l) {
+ return "0x"+Long.toHexString(l);
+ }
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 4ee336176..6dc52a702 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -1,21 +1,21 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. 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
@@ -36,25 +36,111 @@ import javax.media.nativewindow.*;
/** Encapsulates a graphics device on EGL platforms.
*/
-
public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- boolean closeDisplay = false;
+ final long[] nativeDisplayID = new long[1];
+ /* final */ EGLDisplayLifecycleCallback eglLifecycleCallback;
+
+ /**
+ * Hack to allow inject a EGL termination call.
+ * <p>
+ * FIXME: This shall be removed when relocated EGL to the nativewindow package,
+ * since then it can be utilized directly.
+ * </p>
+ */
+ public interface EGLDisplayLifecycleCallback {
+ /**
+ * Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
+ * inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID, or <code>0</code> if not successful
+ */
+ public long eglGetAndInitDisplay(long[] nativeDisplayID);
+
+ /**
+ * Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
+ * @param eglDisplayHandle
+ */
+ void eglTerminate(long eglDisplayHandle);
+ }
/**
* Note that this is not an open connection, ie no native display handle exist.
* This constructor exist to setup a default device connection/unit.<br>
*/
- public EGLGraphicsDevice(String connection, int unitID) {
- super(NativeWindowFactory.TYPE_EGL, connection, unitID);
+ public EGLGraphicsDevice() {
+ super(NativeWindowFactory.TYPE_EGL, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ this.eglLifecycleCallback = null;
}
- /** Constructs a new EGLGraphicsDevice corresponding to the given EGL display handle. */
- public EGLGraphicsDevice(long eglDisplay, String connection, int unitID) {
+ public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
+ this.nativeDisplayID[0] = nativeDisplayID;
+ this.eglLifecycleCallback = eglLifecycleCallback;
}
-
+
+ public long getNativeDisplayID() { return nativeDisplayID[0]; }
+
+ @Override
public Object clone() {
return super.clone();
}
+
+ /**
+ * Opens the EGL device if handle is null and it's {@link EGLDisplayLifecycleCallback} is valid.
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ */
+ @Override
+ public boolean open() {
+ if(null != eglLifecycleCallback && 0 == handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.open(): "+this);
+ }
+ handle = eglLifecycleCallback.eglGetAndInitDisplay(nativeDisplayID);
+ if(0 == handle) {
+ throw new NativeWindowException("EGLGraphicsDevice.open() failed: "+this);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Closes the EGL device if handle is not null and it's {@link EGLDisplayLifecycleCallback} is valid.
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ */
+ @Override
+ public boolean close() {
+ if(null != eglLifecycleCallback && 0 != handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.close(): "+this);
+ }
+ eglLifecycleCallback.eglTerminate(handle);
+ }
+ return super.close();
+ }
+
+ @Override
+ public boolean isHandleOwner() {
+ return null != eglLifecycleCallback;
+ }
+ @Override
+ public void clearHandleOwner() {
+ eglLifecycleCallback = null;
+ }
+ @Override
+ protected Object getHandleOwnership() {
+ return eglLifecycleCallback;
+ }
+ @Override
+ protected Object setHandleOwnership(Object newOwnership) {
+ final EGLDisplayLifecycleCallback oldOwnership = eglLifecycleCallback;
+ eglLifecycleCallback = (EGLDisplayLifecycleCallback) newOwnership;
+ return oldOwnership;
+ }
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java
index 0dc788c17..99ca006fa 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java
@@ -1,21 +1,21 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. 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
@@ -43,6 +43,7 @@ public class MacOSXGraphicsDevice extends DefaultGraphicsDevice implements Clone
super(NativeWindowFactory.TYPE_MACOSX, AbstractGraphicsDevice.DEFAULT_CONNECTION, unitID);
}
+ @Override
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index f4309617b..36bf646d5 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -30,62 +30,119 @@ package com.jogamp.nativewindow.swt;
import com.jogamp.common.os.Platform;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
+import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.VisualIDHolder;
+
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.x11.X11Lib;
public class SWTAccessor {
- static final Field swt_control_handle;
- static final boolean swt_uses_long_handles;
-
+ private static final boolean DEBUG = true;
+
+ private static final Field swt_control_handle;
+ private static final boolean swt_uses_long_handles;
+
+ private static Object swt_osx_init = new Object();
+ private static Field swt_osx_control_view = null;
+ private static Field swt_osx_view_id = null;
+
+ private static final String nwt;
+ public static final boolean isOSX;
+ public static final boolean isWindows;
+ public static final boolean isX11;
+ public static final boolean isX11GTK;
+
// X11/GTK, Windows/GDI, ..
- static final String str_handle = "handle";
-
+ private static final String str_handle = "handle";
+
// OSX/Cocoa
- static final String str_view = "view"; // OSX
- static final String str_id = "id"; // OSX
+ private static final String str_osx_view = "view"; // OSX
+ private static final String str_osx_id = "id"; // OSX
// static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView";
-
- static final Method swt_control_internal_new_GC;
- static final Method swt_control_internal_dispose_GC;
- static final String str_internal_new_GC = "internal_new_GC";
- static final String str_internal_dispose_GC = "internal_dispose_GC";
-
- static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
- static final Class<?> OS_gtk_class;
- static final Method OS_gtk_widget_realize;
- static final Method OS_gtk_widget_unrealize;
- static final Method OS_GTK_WIDGET_WINDOW;
- static final Method OS_gdk_x11_drawable_get_xdisplay;
- static final Method OS_gdk_x11_drawable_get_xid;
- static final String str_gtk_widget_realize = "gtk_widget_realize";
- static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
- static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW";
- static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay";
- static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
-
+
+ private static final Method swt_control_internal_new_GC;
+ private static final Method swt_control_internal_dispose_GC;
+ private static final String str_internal_new_GC = "internal_new_GC";
+ private static final String str_internal_dispose_GC = "internal_dispose_GC";
+
+ private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
+ public static final Class<?> OS_gtk_class;
+ private static final String str_OS_gtk_version = "GTK_VERSION";
+ public static final VersionNumber OS_gtk_version;
+
+ private static final Method OS_gtk_widget_realize;
+ private static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3)
+ private static final Method OS_GTK_WIDGET_WINDOW;
+ private static final Method OS_gtk_widget_get_window;
+ private static final Method OS_gdk_x11_drawable_get_xdisplay;
+ private static final Method OS_gdk_x11_display_get_xdisplay;
+ private static final Method OS_gdk_window_get_display;
+ private static final Method OS_gdk_x11_drawable_get_xid;
+ private static final Method OS_gdk_x11_window_get_xid;
+ private static final Method OS_gdk_window_set_back_pixmap;
+
+ private static final String str_gtk_widget_realize = "gtk_widget_realize";
+ private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
+ private static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW";
+ private static final String str_gtk_widget_get_window = "gtk_widget_get_window";
+ private static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay";
+ private static final String str_gdk_x11_display_get_xdisplay = "gdk_x11_display_get_xdisplay";
+ private static final String str_gdk_window_get_display = "gdk_window_get_display";
+ private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
+ private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid";
+ private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap";
+
+ private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0);
+ private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0);
+ private static final VersionNumber GTK_VERSION_3_0_0 = new VersionNumber(3, 0, 0);
+
+ private static VersionNumber GTK_VERSION(int version) {
+ // return (major << 16) + (minor << 8) + micro;
+ final int micro = ( version ) & 0x0f;
+ final int minor = ( version >> 8 ) & 0x0f;
+ final int major = ( version >> 16 ) & 0x0f;
+ return new VersionNumber(major, minor, micro);
+ }
+
static {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ NativeWindowFactory.initSingleton(); // last resort ..
+ return null;
+ } } );
+
+ nwt = NativeWindowFactory.getNativeWindowType(false);
+ isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
+ isX11 = NativeWindowFactory.TYPE_X11 == nwt;
+
Field f = null;
-
- if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
+ if( !isOSX ) {
try {
f = Control.class.getField(str_handle);
} catch (Exception ex) {
throw new NativeWindowException(ex);
}
- }
+ }
swt_control_handle = f; // maybe null !
-
+
boolean ulh;
if (null != swt_control_handle) {
ulh = swt_control_handle.getGenericType().toString().equals(long.class.toString());
@@ -95,7 +152,7 @@ public class SWTAccessor {
swt_uses_long_handles = ulh;
// System.err.println("SWT long handles: " + swt_uses_long_handles);
// System.err.println("Platform 64bit: "+Platform.is64Bit());
-
+
Method m=null;
try {
m = ReflectionUtil.getMethod(Control.class, str_internal_new_GC, new Class[] { GCData.class });
@@ -103,51 +160,88 @@ public class SWTAccessor {
throw new NativeWindowException(ex);
}
swt_control_internal_new_GC = m;
-
+
try {
if(swt_uses_long_handles) {
- m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { long.class, GCData.class });
+ m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { long.class, GCData.class });
} else {
- m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { int.class, GCData.class });
+ m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { int.class, GCData.class });
}
} catch (NoSuchMethodException ex) {
throw new NativeWindowException(ex);
}
swt_control_internal_dispose_GC = m;
- Class<?> c=null;
- Method m1=null, m2=null, m3=null, m4=null, m5=null;
- Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
- if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) {
+ Class<?> c=null;
+ VersionNumber _gtk_version = new VersionNumber(0, 0, 0);
+ Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null;
+ final Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
+ if( isX11 ) {
+ // mandatory
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
- m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
- m2 = c.getDeclaredMethod(str_gtk_widget_unrealize, handleType);
- m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
- m4 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
- m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
+ Field field_OS_gtk_version = c.getField(str_OS_gtk_version);
+ _gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null));
+ m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
+ if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
+ m4 = c.getDeclaredMethod(str_gtk_widget_get_window, handleType);
+ } else {
+ m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
+ m6 = c.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
+ m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType);
+ } else {
+ m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
+ m9 = c.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
+ } else {
+ m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
+ }
+ ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class);
} catch (Exception ex) { throw new NativeWindowException(ex); }
+ // optional
+ try {
+ m2 = c.getDeclaredMethod(str_gtk_widget_unrealize, handleType);
+ } catch (Exception ex) { }
}
OS_gtk_class = c;
+ OS_gtk_version = _gtk_version;
OS_gtk_widget_realize = m1;
OS_gtk_widget_unrealize = m2;
OS_GTK_WIDGET_WINDOW = m3;
- OS_gdk_x11_drawable_get_xdisplay = m4;
- OS_gdk_x11_drawable_get_xid = m5;
+ OS_gtk_widget_get_window = m4;
+ OS_gdk_x11_drawable_get_xdisplay = m5;
+ OS_gdk_x11_display_get_xdisplay = m6;
+ OS_gdk_window_get_display = m7;
+ OS_gdk_x11_drawable_get_xid = m8;
+ OS_gdk_x11_window_get_xid = m9;
+ OS_gdk_window_set_back_pixmap = ma;
+
+ isX11GTK = isX11 && null != OS_gtk_class;
+
+ if(DEBUG) {
+ System.err.println("SWTAccessor.<init>: GTK Version: "+OS_gtk_version);
+ }
}
- static Object getIntOrLong(long arg) {
+ private static Number getIntOrLong(long arg) {
if(swt_uses_long_handles) {
return new Long(arg);
}
return new Integer((int) arg);
}
-
- static void callStaticMethodL2V(Method m, long arg) {
+
+ private static void callStaticMethodL2V(Method m, long arg) {
ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
}
-
- static long callStaticMethodL2L(Method m, long arg) {
+
+ private static void callStaticMethodLLZ2V(Method m, long arg0, long arg1, boolean arg3) {
+ ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
+ }
+
+ private static long callStaticMethodL2L(Method m, long arg) {
Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
if(o instanceof Number) {
return ((Number)o).longValue();
@@ -155,82 +249,194 @@ public class SWTAccessor {
throw new InternalError("SWT method "+m.getName()+" didn't return int or long but "+o.getClass());
}
}
-
+
+ //
+ // Public properties
+ //
+
public static boolean isUsingLongHandles() {
return swt_uses_long_handles;
}
- public static long getHandle(Control swtControl) {
+ public static boolean useX11GTK() { return isX11GTK; }
+ public static VersionNumber GTK_VERSION() { return OS_gtk_version; }
+
+ //
+ // Common GTK
+ //
+
+ public static long gdk_widget_get_window(long handle) {
+ final long window;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
+ window = callStaticMethodL2L(OS_gtk_widget_get_window, handle);
+ } else {
+ window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
+ }
+ if(0 == window) {
+ throw new NativeWindowException("Null gtk-window-handle of SWT handle 0x"+Long.toHexString(handle));
+ }
+ return window;
+ }
+
+ public static long gdk_window_get_xdisplay(long window) {
+ final long xdisplay;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
+ final long display = callStaticMethodL2L(OS_gdk_window_get_display, window);
+ if(0 == display) {
+ throw new NativeWindowException("Null display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display);
+ } else {
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window);
+ }
+ if(0 == xdisplay) {
+ throw new NativeWindowException("Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xdisplay;
+ }
+
+ public static long gdk_window_get_xwindow(long window) {
+ final long xWindow;
+ if (OS_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window);
+ } else {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window);
+ }
+ if(0 == xWindow) {
+ throw new NativeWindowException("Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xWindow;
+ }
+
+ public static void gdk_window_set_back_pixmap(long window, long pixmap, boolean parent_relative) {
+ callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative);
+ }
+
+ //
+ // Common any toolkit
+ //
+
+ /**
+ * @param swtControl the SWT Control to retrieve the native widget-handle from
+ * @return the native widget-handle
+ * @throws NativeWindowException if the widget handle is null
+ */
+ public static long getHandle(Control swtControl) throws NativeWindowException {
long h = 0;
- if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( isOSX ) {
+ synchronized(swt_osx_init) {
+ try {
+ if(null == swt_osx_view_id) {
+ swt_osx_control_view = Control.class.getField(str_osx_view);
+ Object view = swt_osx_control_view.get(swtControl);
+ swt_osx_view_id = view.getClass().getField(str_osx_id);
+ h = swt_osx_view_id.getLong(view);
+ } else {
+ h = swt_osx_view_id.getLong( swt_osx_control_view.get(swtControl) );
+ }
+ } catch (Exception ex) {
+ throw new NativeWindowException(ex);
+ }
+ }
+ } else {
try {
- Field fView = Control.class.getField(str_view);
- Object view = fView.get(swtControl);
- Field fId = view.getClass().getField(str_id);
- return fId.getLong(view);
+ h = swt_control_handle.getLong(swtControl);
} catch (Exception ex) {
throw new NativeWindowException(ex);
- }
+ }
}
-
- try {
- h = swt_control_handle.getLong(swtControl);
- } catch (Exception ex) {
- throw new NativeWindowException(ex);
+ if(0 == h) {
+ throw new NativeWindowException("Null widget-handle of SWT "+swtControl.getClass().getName()+": "+swtControl.toString());
}
return h;
}
- public static void setRealized(final Control swtControl, final boolean realize) {
+ public static void setRealized(final Control swtControl, final boolean realize)
+ throws NativeWindowException
+ {
+ if(!realize && swtControl.isDisposed()) {
+ return;
+ }
final long handle = getHandle(swtControl);
-
+
if(null != OS_gtk_class) {
invoke(true, new Runnable() {
+ @Override
public void run() {
if(realize) {
callStaticMethodL2V(OS_gtk_widget_realize, handle);
- } else {
+ } else if(null != OS_gtk_widget_unrealize) {
callStaticMethodL2V(OS_gtk_widget_unrealize, handle);
- }
+ }
}
});
}
}
-
- public static AbstractGraphicsDevice getDevice(Control swtControl) {
- long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
- long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
- long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- // 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);
+
+ /**
+ * @param swtControl the SWT Control to retrieve the native device handle from
+ * @return the AbstractGraphicsDevice w/ the native device handle
+ * @throws NativeWindowException if the widget handle is null
+ * @throws UnsupportedOperationException if the windowing system is not supported
+ */
+ public static AbstractGraphicsDevice getDevice(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
+ final long handle = getHandle(swtControl);
+ if( isX11GTK ) {
+ final long xdisplay0 = gdk_window_get_xdisplay( gdk_widget_get_window( handle ) );
+ return new X11GraphicsDevice(xdisplay0, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( isWindows ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( isOSX ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+ }
+
+ /**
+ * @param device
+ * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen
+ * @return
+ */
+ public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
+ return NativeWindowFactory.createScreen(device, screen);
}
-
- public static long getWindowHandle(Control swtControl) {
- long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
- long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
- return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle);
+
+ public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
+ if( isX11 ) {
+ return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( isWindows || isOSX ) {
+ return VisualIDHolder.VID_UNDEFINED;
+ }
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+ }
+
+ /**
+ * @param swtControl the SWT Control to retrieve the native window handle from
+ * @return the native window handle
+ * @throws NativeWindowException if the widget handle is null
+ * @throws UnsupportedOperationException if the windowing system is not supported
+ */
+ public static long getWindowHandle(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
+ final long handle = getHandle(swtControl);
+ if(0 == handle) {
+ throw new NativeWindowException("Null SWT handle of SWT control "+swtControl);
+ }
+ if( isX11GTK ) {
+ return gdk_window_get_xwindow( gdk_widget_get_window( handle ) );
+ }
+ if( isWindows || isOSX ) {
return handle;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
-
+
public static long newGC(final Control swtControl, final GCData gcData) {
final Object[] o = new Object[1];
invoke(true, new Runnable() {
+ @Override
public void run() {
o[0] = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC, new Object[] { gcData });
}
@@ -244,6 +450,7 @@ public class SWTAccessor {
public static void disposeGC(final Control swtControl, final long gc, final GCData gcData) {
invoke(true, new Runnable() {
+ @Override
public void run() {
if(swt_uses_long_handles) {
ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Long(gc), gcData });
@@ -253,13 +460,128 @@ public class SWTAccessor {
}
});
}
-
+
+ /**
+ * Runs the specified action in an SWT compatible thread, which is:
+ * <ul>
+ * <li>Mac OSX
+ * <ul>
+ * <!--li>AWT EDT: In case AWT is available, the AWT EDT is the OSX UI main thread</li-->
+ * <li><i>Main Thread</i>: Run on OSX UI main thread. 'wait' is implemented on Java site via lock/wait on {@link RunnableTask} to not freeze OSX main thread.</li>
+ * </ul></li>
+ * <li>Linux, Windows, ..
+ * <ul>
+ * <li>Current thread.</li>
+ * </ul></li>
+ * </ul>
+ * @see Platform#AWT_AVAILABLE
+ * @see Platform#getOSType()
+ */
public static void invoke(boolean wait, Runnable runnable) {
- if(Platform.OS_TYPE == Platform.OSType.MACOS) {
+ if( isOSX ) {
+ // Use SWT main thread! Only reliable config w/ -XStartOnMainThread !?
OSXUtil.RunOnMainThread(wait, runnable);
} else {
runnable.run();
- }
+ }
+ }
+
+ /**
+ * Runs the specified action on the SWT UI thread.
+ * <p>
+ * If <code>display</code> is disposed or the current thread is the SWT UI thread
+ * {@link #invoke(boolean, Runnable)} is being used.
+ * @see #invoke(boolean, Runnable)
+ */
+ public static void invoke(org.eclipse.swt.widgets.Display display, boolean wait, Runnable runnable) {
+ if( display.isDisposed() || Thread.currentThread() == display.getThread() ) {
+ invoke(wait, runnable);
+ } else if( wait ) {
+ display.syncExec(runnable);
+ } else {
+ display.asyncExec(runnable);
+ }
+ }
+
+ //
+ // Specific X11 GTK ChildWindow - Using plain X11 native parenting (works well)
+ //
+
+ public static long createCompatibleX11ChildWindow(AbstractGraphicsScreen screen, Control swtControl, int visualID, int width, int height) {
+ final long handle = getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+ gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ final long x11ParentHandle = gdk_window_get_xwindow(parentWindow);
+ final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.getDevice().getHandle(), screen.getIndex(), visualID, width, height, true, true);
+
+ return x11WindowHandle;
+ }
+
+ public static void resizeX11Window(AbstractGraphicsDevice device, Rectangle clientArea, long x11Window) {
+ X11Lib.SetWindowPosSize(device.getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+ }
+ public static void destroyX11Window(AbstractGraphicsDevice device, long x11Window) {
+ X11Lib.DestroyWindow(device.getHandle(), x11Window);
+ }
+
+ //
+ // Specific X11 SWT/GTK ChildWindow - Using SWT/GTK native parenting (buggy - sporadic resize flickering, sporadic drop of rendering)
+ //
+ // FIXME: Need to use reflection for 32bit access as well !
+ //
+
+ // public static final int GDK_WA_TYPE_HINT = 1 << 9;
+ // public static final int GDK_WA_VISUAL = 1 << 6;
+
+ public static long createCompatibleGDKChildWindow(Control swtControl, int visualID, int width, int height) {
+ return 0;
+ /**
+ final long handle = SWTAccessor.getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+
+ final long screen = OS.gdk_screen_get_default ();
+ final long gdkvisual = OS.gdk_x11_screen_lookup_visual (screen, visualID);
+
+ final GdkWindowAttr attrs = new GdkWindowAttr();
+ attrs.width = width > 0 ? width : 1;
+ attrs.height = height > 0 ? height : 1;
+ attrs.event_mask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK |
+ OS.GDK_FOCUS_CHANGE_MASK | OS.GDK_POINTER_MOTION_MASK |
+ OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK |
+ OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK |
+ OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK |
+ OS.GDK_POINTER_MOTION_HINT_MASK;
+ attrs.window_type = OS.GDK_WINDOW_CHILD;
+ attrs.visual = gdkvisual;
+
+ final long childWindow = OS.gdk_window_new (parentWindow, attrs, OS.GDK_WA_VISUAL|GDK_WA_TYPE_HINT);
+ OS.gdk_window_set_user_data (childWindow, handle);
+ OS.gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ OS.gdk_window_show (childWindow);
+ OS.gdk_flush();
+ return childWindow; */
+ }
+
+ public static void showGDKWindow(long gdkWindow) {
+ /* OS.gdk_window_show (gdkWindow);
+ OS.gdk_flush(); */
+ }
+ public static void focusGDKWindow(long gdkWindow) {
+ /*
+ OS.gdk_window_show (gdkWindow);
+ OS.gdk_window_focus(gdkWindow, 0);
+ OS.gdk_flush(); */
+ }
+ public static void resizeGDKWindow(Rectangle clientArea, long gdkWindow) {
+ /**
+ OS.gdk_window_move (gdkWindow, clientArea.x, clientArea.y);
+ OS.gdk_window_resize (gdkWindow, clientArea.width, clientArea.height);
+ OS.gdk_flush(); */
+ }
+
+ public static void destroyGDKWindow(long gdkWindow) {
+ // OS.gdk_window_destroy (gdkWindow);
}
-
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java
index 5cabdf150..643982715 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java
@@ -1,21 +1,21 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. 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
@@ -34,7 +34,7 @@ package com.jogamp.nativewindow.windows;
import javax.media.nativewindow.*;
-/**
+/**
* Encapsulates a graphics device on Windows platforms.<br>
*/
public class WindowsGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
@@ -47,6 +47,7 @@ public class WindowsGraphicsDevice extends DefaultGraphicsDevice implements Clon
super(NativeWindowFactory.TYPE_WINDOWS, connection, unitID);
}
+ @Override
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
index 0d2914c7d..120c86584 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
@@ -1,22 +1,22 @@
/*
* 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
@@ -48,7 +48,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
- public X11GraphicsConfiguration(X11GraphicsScreen screen,
+ public X11GraphicsConfiguration(X11GraphicsScreen screen,
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
XVisualInfo info) {
super(screen, capsChosen, capsRequested);
@@ -71,12 +71,12 @@ public class X11GraphicsConfiguration extends MutableGraphicsConfiguration imple
final public int getXVisualID() {
return (null!=info)?(int)info.getVisualid():0;
}
-
+
@Override
public String toString() {
return getClass().getSimpleName()+"["+getScreen()+", visualID 0x" + Long.toHexString(getXVisualID()) +
",\n\tchosen " + capabilitiesChosen+
- ",\n\trequested " + capabilitiesRequested+
+ ",\n\trequested " + capabilitiesRequested+
"]";
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 308756b54..863e53bde 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -1,22 +1,22 @@
/*
* 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
@@ -33,7 +33,6 @@
package com.jogamp.nativewindow.x11;
-import jogamp.nativewindow.Debug;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
@@ -46,8 +45,8 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- public static final boolean DEBUG = Debug.debug("GraphicsDevice");
- final boolean closeDisplay;
+ /* final */ boolean handleOwner;
+ final boolean isXineramaEnabled;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
* {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
@@ -57,25 +56,21 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public X11GraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
- closeDisplay = false;
+ handleOwner = false;
+ isXineramaEnabled = false;
}
/** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
- * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long)
*/
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, X11Lib.XDisplayString(display), unitID, display);
- if(0==display) {
- throw new NativeWindowException("null display");
- }
- closeDisplay = owner;
+ this(display, unitID, NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_X11, display), owner);
}
/**
* @param display the Display connection
- * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
*/
public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) {
@@ -83,16 +78,83 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
if(0==display) {
throw new NativeWindowException("null display");
}
- closeDisplay = owner;
+ handleOwner = owner;
+ isXineramaEnabled = X11Util.XineramaIsEnabled(this);
+ }
+
+ /**
+ * Constructs a new X11GraphicsDevice corresponding to the given display connection.
+ * <p>
+ * The constructor opens the native connection and takes ownership.
+ * </p>
+ * @param displayConnection the semantic display connection name
+ * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
+ */
+ public X11GraphicsDevice(String displayConnection, int unitID, ToolkitLock locker) {
+ super(NativeWindowFactory.TYPE_X11, displayConnection, unitID, 0, locker);
+ handleOwner = true;
+ open();
+ isXineramaEnabled = X11Util.XineramaIsEnabled(this);
+ }
+
+ private static int getDefaultScreenImpl(long dpy) {
+ return X11Lib.DefaultScreen(dpy);
}
+ /**
+ * Returns the default screen number as referenced by the display connection, i.e. 'somewhere:0.1' -> 1
+ * <p>
+ * Implementation uses the XLib macro <code>DefaultScreen(display)</code>.
+ * </p>
+ */
+ public int getDefaultScreen() {
+ final long display = getHandle();
+ if(0==display) {
+ throw new NativeWindowException("null display");
+ }
+ final int ds = getDefaultScreenImpl(display);
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.getDefaultDisplay() of "+this+": "+ds+", count "+X11Lib.ScreenCount(display));
+ }
+ return ds;
+ }
+
+ public int getDefaultVisualID() {
+ final long display = getHandle();
+ if(0==display) {
+ throw new NativeWindowException("null display");
+ }
+ return X11Lib.DefaultVisualID(display, getDefaultScreenImpl(display));
+ }
+
+ public final boolean isXineramaEnabled() {
+ return isXineramaEnabled;
+ }
+
+ @Override
public Object clone() {
return super.clone();
}
+ @Override
+ public boolean open() {
+ if(handleOwner && 0 == handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.open(): "+this);
+ }
+ handle = X11Util.openDisplay(connection);
+ if(0 == handle) {
+ throw new NativeWindowException("X11GraphicsDevice.open() failed: "+this);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
public boolean close() {
- // FIXME: shall we respect the unitID ?
- if(closeDisplay && 0 != handle) {
+ if(handleOwner && 0 != handle) {
if(DEBUG) {
System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this);
}
@@ -100,5 +162,23 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
return super.close();
}
-}
+ @Override
+ public boolean isHandleOwner() {
+ return handleOwner;
+ }
+ @Override
+ public void clearHandleOwner() {
+ handleOwner = false;
+ }
+ @Override
+ protected Object getHandleOwnership() {
+ return Boolean.valueOf(handleOwner);
+ }
+ @Override
+ protected Object setHandleOwnership(Object newOwnership) {
+ final Boolean oldOwnership = Boolean.valueOf(handleOwner);
+ handleOwner = ((Boolean) newOwnership).booleanValue();
+ return oldOwnership;
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 94013ec38..700937829 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -1,22 +1,22 @@
/*
* 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
@@ -33,10 +33,12 @@
package com.jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeWindowException;
import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
/** Encapsulates a screen index on X11
platforms. Objects of this type are passed to {@link
@@ -48,7 +50,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Constructs a new X11GraphicsScreen corresponding to the given native screen index. */
public X11GraphicsScreen(X11GraphicsDevice device, int screen) {
- super(device, fetchScreen(device, screen));
+ super(device, device.isXineramaEnabled() ? 0 : screen);
}
public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
@@ -56,21 +58,12 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
}
- public long getDefaultVisualID() {
+ public int getVisualID() {
// It still could be an AWT hold handle ..
- long display = getDevice().getHandle();
- 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 ..
- if(X11Util.XineramaIsEnabled(device.getHandle())) {
- screen = 0; // Xinerama -> 1 screen
- }
- return screen;
+ return X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
}
+ @Override
public Object clone() {
return super.clone();
}