aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/classes/com')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java12
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java35
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java13
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java22
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java46
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/UpstreamWindowHookMutableSizePos.java56
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java59
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsDevice.java20
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java33
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java175
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java85
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java199
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java297
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java624
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java58
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/macosx/MacOSXGraphicsDevice.java13
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java523
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/windows/WindowsGraphicsDevice.java17
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java22
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java82
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java31
21 files changed, 1929 insertions, 493 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
index 22c95f3dd..e785af788 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
@@ -11,29 +11,29 @@ public class DelegatedUpstreamSurfaceHookMutableSize extends UpstreamSurfaceHook
* @param width initial width
* @param height initial height
*/
- public DelegatedUpstreamSurfaceHookMutableSize(UpstreamSurfaceHook upstream, int width, int height) {
+ public DelegatedUpstreamSurfaceHookMutableSize(final UpstreamSurfaceHook upstream, final int width, final int height) {
super(width, height);
this.upstream = upstream;
}
@Override
- public final void create(ProxySurface s) {
+ public final void create(final ProxySurface s) {
if(null != upstream) {
upstream.create(s);
}
}
@Override
- public final void destroy(ProxySurface s) {
+ public final void destroy(final ProxySurface s) {
if(null != upstream) {
upstream.destroy(s);
}
}
-
+
@Override
public String toString() {
- return getClass().getSimpleName()+"[ "+ width + "x" + height + ", " + upstream + "]";
+ return getClass().getSimpleName()+"[ "+ pixWidth + "x" + pixHeight + ", " + upstream + "]";
}
-
+
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
index 85e24582c..abcc166cb 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
@@ -10,9 +10,9 @@ public class DelegatedUpstreamSurfaceHookWithSurfaceSize implements UpstreamSurf
/**
* @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)}
+ * @param surface mandatory {@link NativeSurface} used for {@link #getSurfaceWidth(ProxySurface)} and {@link #getSurfaceHeight(ProxySurface)}, not used for {@link #getUpstreamSurface()}.
*/
- public DelegatedUpstreamSurfaceHookWithSurfaceSize(UpstreamSurfaceHook upstream, NativeSurface surface) {
+ public DelegatedUpstreamSurfaceHookWithSurfaceSize(final UpstreamSurfaceHook upstream, final NativeSurface surface) {
this.upstream = upstream;
this.surface = surface;
if(null == surface) {
@@ -20,35 +20,46 @@ public class DelegatedUpstreamSurfaceHookWithSurfaceSize implements UpstreamSurf
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Returns <code>null</code>.
+ * </p>
+ */
+ @Override
+ public final NativeSurface getUpstreamSurface() {
+ return null;
+ }
+
@Override
- public final void create(ProxySurface s) {
+ public final void create(final ProxySurface s) {
if(null != upstream) {
upstream.create(s);
}
}
@Override
- public final void destroy(ProxySurface s) {
+ public final void destroy(final ProxySurface s) {
if(null != upstream) {
upstream.destroy(s);
}
}
@Override
- public final int getWidth(ProxySurface s) {
- return surface.getWidth();
+ public final int getSurfaceWidth(final ProxySurface s) {
+ return surface.getSurfaceWidth();
}
@Override
- public final int getHeight(ProxySurface s) {
- return surface.getHeight();
- }
-
+ public final int getSurfaceHeight(final ProxySurface s) {
+ return surface.getSurfaceHeight();
+ }
+
@Override
public String toString() {
- final String us_s = null != surface ? ( surface.getClass().getName() + ": 0x" + Long.toHexString(surface.getSurfaceHandle()) + " " +surface.getWidth() + "x" + surface.getHeight() ) : "nil";
+ final String us_s = null != surface ? ( surface.getClass().getName() + ": 0x" + Long.toHexString(surface.getSurfaceHandle()) + " " +surface.getSurfaceWidth() + "x" + surface.getSurfaceHeight() ) : "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..a137d46c3 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -32,12 +32,19 @@ import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.DefaultGraphicsConfiguration;
public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
- public MutableGraphicsConfiguration(AbstractGraphicsScreen screen,
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ public MutableGraphicsConfiguration(final AbstractGraphicsScreen screen,
+ final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested) {
super(screen, capsChosen, capsRequested);
}
- public void setChosenCapabilities(CapabilitiesImmutable caps) {
+ @Override
+ public void setChosenCapabilities(final CapabilitiesImmutable caps) {
super.setChosenCapabilities(caps);
}
+
+ @Override
+ public void setScreen(final 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..7c1a88e6a 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,24 +20,25 @@
* 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 {
protected static volatile NativeWindowVersion jogampCommonVersionInfo;
- protected NativeWindowVersion(String packageName, Manifest mf) {
+ protected NativeWindowVersion(final String packageName, final Manifest mf) {
super(packageName, mf);
}
@@ -45,16 +46,17 @@ 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);
}
}
}
return jogampCommonVersionInfo;
}
- public static void main(String args[]) {
+ public static void main(final String args[]) {
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
System.err.println(NativeWindowVersion.getInstance());
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
index 29c540ac4..45d12be5e 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
@@ -1,45 +1,57 @@
package com.jogamp.nativewindow;
+import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.UpstreamSurfaceHook;
public class UpstreamSurfaceHookMutableSize implements UpstreamSurfaceHook.MutableSize {
- int width, height;
+ int pixWidth, pixHeight;
/**
* @param width initial width
* @param height initial height
*/
- public UpstreamSurfaceHookMutableSize(int width, int height) {
- this.width = width;
- this.height = height;
+ public UpstreamSurfaceHookMutableSize(final int width, final int height) {
+ this.pixWidth = width;
+ this.pixHeight = height;
}
@Override
- public final void setSize(int width, int height) {
- this.width = width;
- this.height = height;
+ public final void setSurfaceSize(final int width, final int height) {
+ this.pixWidth = width;
+ this.pixHeight = height;
}
-
+
@Override
- public final int getWidth(ProxySurface s) {
- return width;
+ public final int getSurfaceWidth(final ProxySurface s) {
+ return pixWidth;
}
@Override
- public final int getHeight(ProxySurface s) {
- return height;
+ public final int getSurfaceHeight(final ProxySurface s) {
+ return pixHeight;
}
@Override
- public void create(ProxySurface s) { /* nop */ }
+ public void create(final ProxySurface s) { /* nop */ }
@Override
- public void destroy(ProxySurface s) { /* nop */ }
-
+ public void destroy(final ProxySurface s) { /* nop */ }
+
@Override
public String toString() {
- return getClass().getSimpleName()+"[ "+ width + "x" + height + "]";
+ return getClass().getSimpleName()+"[pixel "+ pixWidth + "x" + pixHeight + "]";
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Returns <code>null</code>.
+ * </p>
+ */
+ @Override
+ public final NativeSurface getUpstreamSurface() {
+ return null;
}
-
+
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamWindowHookMutableSizePos.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamWindowHookMutableSizePos.java
new file mode 100644
index 000000000..b509f118a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamWindowHookMutableSizePos.java
@@ -0,0 +1,56 @@
+package com.jogamp.nativewindow;
+
+public class UpstreamWindowHookMutableSizePos extends UpstreamSurfaceHookMutableSize {
+ int winX, winY, winWidth, winHeight;
+
+ /**
+ * @param winX initial window x-pos
+ * @param winY initial window y-pos
+ * @param winWidth initial window width
+ * @param winHeight initial window height
+ * @param pixWidth initial surface pixel width, FIXME: pixel-dim == window-dim 'for now' ?
+ * @param pixHeight initial surface pixel height, FIXME: pixel-dim == window-dim 'for now' ?
+ */
+ public UpstreamWindowHookMutableSizePos(final int winX, final int winY, final int winWidth, final int winHeight, final int pixWidth, final int pixHeight) {
+ super(pixWidth, pixHeight);
+ this.winX= winX;
+ this.winY= winY;
+ this.winWidth = winWidth;
+ this.winHeight = winHeight;
+ }
+
+ // @Override
+ public final void setWinPos(final int winX, final int winY) {
+ this.winX= winX;
+ this.winY= winY;
+ }
+ // @Override
+ public final void setWinSize(final int winWidth, final int winHeight) {
+ this.winWidth= winWidth;
+ this.winHeight= winHeight;
+ // FIXME HiDPI: Use pixelScale ?!
+ // FIXME HiDPI: Consider setting winWidth/winHeight by setSurfaceSize(..) (back-propagation)
+ this.setSurfaceSize(winWidth, winHeight);
+ }
+
+ public final int getX() {
+ return winX;
+ }
+
+ public final int getY() {
+ return winY;
+ }
+ public final int getWidth() {
+ return winWidth;
+ }
+ public final int getHeight() {
+ return winHeight;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[window "+ winX + "/" + winY + " " + winWidth + "x" + winHeight + ", pixel " + pixWidth + "x" + pixHeight + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
index 2a152ff35..3a62825a2 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.
*/
@@ -54,33 +54,34 @@ import jogamp.nativewindow.Debug;
handled in a toolkit-independent manner. */
public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
- private GraphicsConfiguration config;
+ private final GraphicsConfiguration config;
AbstractGraphicsConfiguration encapsulated;
- public AWTGraphicsConfiguration(AWTGraphicsScreen screen,
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- GraphicsConfiguration config, AbstractGraphicsConfiguration encapsulated) {
+ public AWTGraphicsConfiguration(final AWTGraphicsScreen screen,
+ final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
+ final GraphicsConfiguration config, final AbstractGraphicsConfiguration encapsulated) {
super(screen, capsChosen, capsRequested);
this.config = config;
this.encapsulated=encapsulated;
}
- private AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- GraphicsConfiguration config) {
+ private AWTGraphicsConfiguration(final AWTGraphicsScreen screen, final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
+ final GraphicsConfiguration config) {
super(screen, capsChosen, capsRequested);
this.config = config;
this.encapsulated=null;
}
-
+
/**
- * @param capsChosen if null, <code>capsRequested</code> is copied and aligned
- * with the graphics 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) {
+ public static AWTGraphicsConfiguration create(final 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,8 +92,11 @@ 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();
+ final GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc);
}
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice, capsChosen);
@@ -105,10 +109,11 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
// open access to superclass method
- public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
+ @Override
+ public void setChosenCapabilities(final CapabilitiesImmutable capsChosen) {
super.setChosenCapabilities(capsChosen);
}
-
+
@Override
public Object clone() {
return super.clone();
@@ -131,16 +136,16 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
* @param gc the GraphicsConfiguration from which to derive the RGBA bit depths
* @return the passed Capabilities
*/
- public static CapabilitiesImmutable setupCapabilitiesRGBABits(CapabilitiesImmutable capabilitiesIn, GraphicsConfiguration gc) {
- Capabilities capabilities = (Capabilities) capabilitiesIn.cloneMutable();
+ public static CapabilitiesImmutable setupCapabilitiesRGBABits(final CapabilitiesImmutable capabilitiesIn, final GraphicsConfiguration gc) {
+ final Capabilities capabilities = (Capabilities) capabilitiesIn.cloneMutable();
- ColorModel cm = gc.getColorModel();
+ final ColorModel cm = gc.getColorModel();
if(null==cm) {
throw new NativeWindowException("Could not determine AWT ColorModel");
}
- int cmBitsPerPixel = cm.getPixelSize();
+ final int cmBitsPerPixel = cm.getPixelSize();
int bitsPerPixel = 0;
- int[] bitesPerComponent = cm.getComponentSize();
+ final int[] bitesPerComponent = cm.getComponentSize();
if(bitesPerComponent.length>=3) {
capabilities.setRedBits(bitesPerComponent[0]);
bitsPerPixel += bitesPerComponent[0];
@@ -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..219f4bb92 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.
*/
@@ -48,15 +48,15 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
/** A wrapper for an AWT GraphicsDevice allowing it to be
handled in a toolkit-independent manner. */
public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- private GraphicsDevice device;
+ private final GraphicsDevice device;
- public AWTGraphicsDevice(GraphicsDevice device, int unitID) {
+ public AWTGraphicsDevice(final GraphicsDevice device, final int unitID) {
super(NativeWindowFactory.TYPE_AWT, device.getIDstring(), unitID);
this.device = device;
}
public static AWTGraphicsDevice createDefault() {
- GraphicsDevice awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ final GraphicsDevice awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
return new AWTGraphicsDevice(awtDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsScreen.java
index f4ee06e28..6fc35f719 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.
*/
@@ -51,35 +51,35 @@ import javax.media.nativewindow.*;
public class AWTGraphicsScreen extends DefaultGraphicsScreen implements Cloneable {
- public AWTGraphicsScreen(AWTGraphicsDevice device) {
+ public AWTGraphicsScreen(final AWTGraphicsDevice device) {
super(device, findScreenIndex(device.getGraphicsDevice()));
}
- public static GraphicsDevice getScreenDevice(int index) {
+ public static GraphicsDevice getScreenDevice(final int index) {
if(index<0) return null;
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] gs = ge.getScreenDevices();
+ final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice[] gs = ge.getScreenDevices();
if(index<gs.length) {
return gs[index];
}
return null;
}
- public static int findScreenIndex(GraphicsDevice awtDevice) {
+ public static int findScreenIndex(final GraphicsDevice awtDevice) {
if(null==awtDevice) return -1;
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] gs = ge.getScreenDevices();
+ final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice[] gs = ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
if(gs[j] == awtDevice) return j;
}
return -1;
}
- public static AbstractGraphicsScreen createScreenDevice(GraphicsDevice awtDevice, int unitID) {
+ public static AbstractGraphicsScreen createScreenDevice(final GraphicsDevice awtDevice, final int unitID) {
return new AWTGraphicsScreen(new AWTGraphicsDevice(awtDevice, unitID));
}
- public static AbstractGraphicsScreen createScreenDevice(int index, int unitID) {
+ public static AbstractGraphicsScreen createScreenDevice(final int index, final int unitID) {
return createScreenDevice(getScreenDevice(index), unitID);
}
@@ -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..b0a7fbc76
--- /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(final Container c, final double scaleMatX, final double scaleMatY, final int numSamples, final int tileWidth, final 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(final Component c) {
+ ((AWTPrintLifecycle)c).setupPrint(scaleMatX, scaleMatY, numSamples, tileWidth, tileHeight);
+ } };
+ private final AWTMisc.ComponentAction releaseAction = new AWTMisc.ComponentAction() {
+ @Override
+ public void run(final Component c) {
+ ((AWTPrintLifecycle)c).releasePrint();
+ } };
+
+ private Context(final Container c, final double scaleMatX, final double scaleMatY, final int numSamples, final int tileWidth, final 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(final 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..496e6e07b 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
@@ -33,80 +33,81 @@ 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(final Component comp, final Runnable closingOperationClose, final Runnable closingOperationNOP) {
this.comp = comp;
- this.closingOperation = closingOperation;
+ this.listenTo = null;
+ this.closingOperationClose = closingOperationClose;
+ this.closingOperationNOP = closingOperationNOP;
}
class WindowClosingAdapter extends WindowAdapter {
@Override
- public void windowClosing(WindowEvent e) {
+ public void windowClosing(final WindowEvent e) {
final WindowClosingMode op = AWTWindowClosingProtocol.this.getDefaultCloseOperation();
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,7 +127,8 @@ public class AWTWindowClosingProtocol implements WindowClosingProtocol {
return AWTMisc.getNWClosingOperation(comp);
}
- public final WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
+ @Override
+ public final WindowClosingMode setDefaultCloseOperation(final WindowClosingMode op) {
synchronized(closingListenerLock) {
final WindowClosingMode _op = defaultCloseOperation;
defaultCloseOperation = op;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java
new file mode 100644
index 000000000..2026ada0f
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java
@@ -0,0 +1,199 @@
+package com.jogamp.nativewindow.awt;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.jogamp.common.util.RunnableTask;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+/**
+ * Instance of this class holds information about a {@link ThreadGroup} associated {@link sun.awt.AppContext}.
+ * <p>
+ * Non intrusive workaround for Bug 983 and Bug 1004, see {@link #getCachedThreadGroup()}.
+ * </p>
+ */
+public class AppContextInfo {
+ private static final boolean DEBUG;
+
+ private static final Method getAppContextMethod;
+ private static final Object mainThreadAppContextLock = new Object();
+ private volatile WeakReference<Object> mainThreadAppContextWR = null;
+ private volatile WeakReference<ThreadGroup> mainThreadGroupWR = null;
+
+ static {
+ DEBUG = JAWTUtil.DEBUG;
+ final Method[] _getAppContextMethod = { null };
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ try {
+ final Class<?> appContextClass = Class.forName("sun.awt.AppContext");
+ _getAppContextMethod[0] = appContextClass.getMethod("getAppContext");
+ } catch(final Throwable ex) {
+ System.err.println("Bug 1004: Caught @ static: "+ex.getMessage());
+ ex.printStackTrace();
+ }
+ return null;
+ } } );
+ getAppContextMethod = _getAppContextMethod[0];
+ }
+
+ public AppContextInfo(final String info) {
+ update(info);
+ }
+
+ /**
+ * Returns <code>true</code> if this instance has valid {@link sun.awt.AppContext} information,
+ * i.e. {@link #getCachedThreadGroup()} returns not <code>null</code>.
+ */
+ public final boolean isValid() {
+ return null != getCachedThreadGroup();
+ }
+
+ /**
+ * Returns the {@link ThreadGroup} belonging to the
+ * last known {@link sun.awt.AppContext} as queried via {@link #update(String)}.
+ * <p>
+ * Returns <code>null</code> if no {@link sun.awt.AppContext} has been queried.
+ * </p>
+ * <p>
+ * The returned {@link ThreadGroup} allows users to create a custom thread
+ * belonging to it and hence mitigating Bug 983 and Bug 1004.
+ * </p>
+ * <p>
+ * {@link #update(String)} should be called from a thread belonging to the
+ * desired {@link sun.awt.AppContext}, i.e. early from within the special threaded application.
+ * </p>
+ * <p>
+ * E.g. {@link JAWTWindow} issues {@link #update(String)} in it's constructor.
+ * </p>
+ */
+ public final ThreadGroup getCachedThreadGroup() {
+ final WeakReference<ThreadGroup> tgRef = mainThreadGroupWR;
+ return null != tgRef ? tgRef.get() : null;
+ }
+
+ /**
+ * Invokes <code>runnable</code> on a {@link Thread} belonging to the {@link sun.awt.AppContext} {@link ThreadGroup},
+ * see {@link #getCachedThreadGroup()}.
+ * <p>
+ * {@link #update(String)} is issued first, which returns <code>true</code>
+ * if the current thread belongs to an AppContext {@link ThreadGroup}.
+ * In this case the <code>runnable</code> is invoked on the current thread,
+ * otherwise a new {@link Thread} will be started.
+ * </p>
+ * <p>
+ * If a new {@link Thread} is required, the AppContext {@link ThreadGroup} is being used
+ * if {@link #isValid() available}, otherwise the default system {@link ThreadGroup}.
+ * </p>
+ *
+ * @param waitUntilDone if <code>true</code>, waits until <code>runnable</code> execution is completed, otherwise returns immediately.
+ * @param runnable the {@link Runnable} to be executed. If <code>waitUntilDone</code> is <code>true</code>,
+ * the runnable <b>must exist</b>, i.e. not loop forever.
+ * @param threadBaseName the base name for the new thread if required.
+ * The resulting thread name will have either '-OnAppContextTG' or '-OnSystemTG' appended
+ * @return the {@link Thread} used to invoke the <code>runnable</code>, which may be the current {@link Thread} or a newly created one, see above.
+ */
+ public Thread invokeOnAppContextThread(final boolean waitUntilDone, final Runnable runnable, final String threadBaseName) {
+ final Thread t;
+ if( update("invoke") ) {
+ t = Thread.currentThread();
+ if( DEBUG ) {
+ System.err.println("Bug 1004: Invoke.0 on current AppContext thread: "+t+" "+toHexString(t.hashCode()));
+ }
+ runnable.run();
+ } else {
+ final ThreadGroup tg = getCachedThreadGroup();
+ final String tName = threadBaseName + ( null != tg ? "-OnAppContextTG" : "-OnSystemTG" );
+ t = RunnableTask.invokeOnNewThread(tg, waitUntilDone, runnable, tName);
+ if( DEBUG ) {
+ final int tgHash = null != tg ? tg.hashCode() : 0;
+ System.err.println("Bug 1004: Invoke.1 on new AppContext thread: "+t+" "+toHexString(t.hashCode())+", tg "+tg+" "+toHexString(tgHash));
+ }
+ }
+ return t;
+ }
+
+ /**
+ * Update {@link sun.awt.AppContext} information for the current ThreadGroup if uninitialized or {@link sun.awt.AppContext} changed.
+ * <p>
+ * See {@link #getCachedThreadGroup()} for usage.
+ * </p>
+ * @param info informal string for logging purposes
+ * @return <code>true</code> if the current ThreadGroup is mapped to an {@link sun.awt.AppContext} and the information is good, otherwise false.
+ */
+ public final boolean update(final String info) {
+ if ( null != getAppContextMethod ) {
+ // Test whether the current thread's ThreadGroup is mapped to an AppContext.
+ final Object thisThreadAppContext = fetchAppContext();
+ final boolean tgMapped = null != thisThreadAppContext;
+
+ final Thread thread = Thread.currentThread();
+ final ThreadGroup threadGroup = thread.getThreadGroup();
+ final Object mainThreadAppContext;
+ {
+ final WeakReference<Object> _mainThreadAppContextWR = mainThreadAppContextWR;
+ mainThreadAppContext = null != _mainThreadAppContextWR ? _mainThreadAppContextWR.get() : null;
+ }
+
+ if( tgMapped ) { // null != thisThreadAppContext
+ // Update info is possible
+ if( null == mainThreadAppContext ||
+ mainThreadAppContext != thisThreadAppContext ) {
+ // GC'ed or 1st fetch !
+ final int mainThreadAppContextHash = null != mainThreadAppContext ? mainThreadAppContext.hashCode() : 0;
+ final int thisThreadAppContextHash;
+ synchronized(mainThreadAppContextLock) {
+ mainThreadGroupWR = new WeakReference<ThreadGroup>(threadGroup);
+ mainThreadAppContextWR = new WeakReference<Object>(thisThreadAppContext);
+ thisThreadAppContextHash = thisThreadAppContext.hashCode();
+ }
+ if( DEBUG ) {
+ System.err.println("Bug 1004[TGMapped "+tgMapped+"]: Init AppContext @ "+info+" on thread "+thread.getName()+" "+toHexString(thread.hashCode())+
+ ": tg "+threadGroup.getName()+" "+toHexString(threadGroup.hashCode())+
+ " -> appCtx [ main "+mainThreadAppContext+" "+toHexString(mainThreadAppContextHash)+
+ " -> this "+thisThreadAppContext+" "+toHexString(thisThreadAppContextHash) + " ] ");
+ }
+ } else {
+ // old info is OK
+ if( DEBUG ) {
+ final int mainThreadAppContextHash = mainThreadAppContext.hashCode();
+ final int thisThreadAppContextHash = thisThreadAppContext.hashCode();
+ System.err.println("Bug 1004[TGMapped "+tgMapped+"]: OK AppContext @ "+info+" on thread "+thread.getName()+" "+toHexString(thread.hashCode())+
+ ": tg "+threadGroup.getName()+" "+toHexString(threadGroup.hashCode())+
+ " : appCtx [ this "+thisThreadAppContext+" "+toHexString(thisThreadAppContextHash)+
+ " , main "+mainThreadAppContext+" "+toHexString(mainThreadAppContextHash) + " ] ");
+ }
+ }
+ return true;
+ } else {
+ if( DEBUG ) {
+ final int mainThreadAppContextHash = null != mainThreadAppContext ? mainThreadAppContext.hashCode() : 0;
+ final int thisThreadAppContextHash = null != thisThreadAppContext ? thisThreadAppContext.hashCode() : 0;
+ System.err.println("Bug 1004[TGMapped "+tgMapped+"]: No AppContext @ "+info+" on thread "+thread.getName()+" "+toHexString(thread.hashCode())+
+ ": tg "+threadGroup.getName()+" "+toHexString(threadGroup.hashCode())+
+ " -> appCtx [ this "+thisThreadAppContext+" "+toHexString(thisThreadAppContextHash)+
+ " -> main "+mainThreadAppContext+" "+toHexString(mainThreadAppContextHash) + " ] ");
+ }
+ }
+ }
+ return false;
+ }
+ private static Object fetchAppContext() {
+ try {
+ return getAppContextMethod.invoke(null);
+ } catch(final Exception ex) {
+ System.err.println("Bug 1004: Caught: "+ex.getMessage());
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ private static String toHexString(final int i) {
+ return "0x"+Integer.toHexString(i);
+ }
+
+}
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..c7055099f
--- /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(final SampleModel sampleModel, final DirectDataBufferInt dataBuffer, final Point origin) {
+ super(sampleModel, dataBuffer, origin);
+ }
+ }
+
+ public static class BufferedImageInt extends BufferedImage {
+ final int customImageType;
+ public BufferedImageInt (final int customImageType, final ColorModel cm, final WritableRaster raster, final 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(final int width, final int height, final int imageType, Point location, final 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 final IntBuffer data;
+
+ /** All data banks */
+ private final 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(final 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(final int size, final 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(final IntBuffer dataArray, final 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(final 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(final 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(final int bank, final 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(final int i, final 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(final int bank, final int i, final 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 a62d08ccf..6498ebd1e 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -37,13 +37,22 @@
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;
@@ -52,29 +61,37 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.OffscreenLayerOption;
import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ScalableSurface;
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.common.os.PlatformPropsImpl;
+import jogamp.nativewindow.SurfaceScaleUtils;
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;
-public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, OffscreenLayerOption {
+public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, OffscreenLayerOption, ScalableSurface {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
// 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 AppContextInfo appContextInfo;
+ 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;
@@ -83,7 +100,11 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected long drawable;
protected Rectangle bounds;
protected Insets insets;
- private long offscreenSurfaceLayer;
+ private volatile long offscreenSurfaceLayer;
+
+ private final int[] nativePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ private final int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ protected final int[] reqPixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
private long drawable_old;
@@ -94,25 +115,150 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
* @param comp
* @param config
*/
- protected JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
+ protected JAWTWindow(final Object comp, final AbstractGraphicsConfiguration config) {
if (config == null) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
}
if(! ( config instanceof AWTGraphicsConfiguration ) ) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
}
+ appContextInfo = new AppContextInfo("<init>");
+ 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(final Object obj) { return ( null!=obj ? 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(final ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentResized: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentMoved(final ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentMoved: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentShown(final ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentShown: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void componentHidden(final ComponentEvent e) {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".componentHidden: "+s(e));
+ }
+ layoutSurfaceLayerIfEnabled(isShowing);
+ }
+
+ @Override
+ public final void hierarchyChanged(final 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));
+ }
+ }
+ }
+
+ 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;
@@ -120,37 +266,88 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
drawable_old = 0;
bounds = new Rectangle();
insets = new Insets();
+ hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
+ hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
+ nativePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
+ nativePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
}
protected abstract void invalidateNative();
- protected final boolean updateBounds(JAWT_Rectangle jawtBounds) {
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Per default impl. only works for not yet {@link #isRealized() realized} instances,
+ * current exception OSX.
+ * </p>
+ */
+ @Override
+ public void setSurfaceScale(final int[] pixelScale) {
+ SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG ? getClass().getSimpleName() : null);
+ }
+
+ @Override
+ public final int[] getRequestedSurfaceScale(final int[] result) {
+ System.arraycopy(reqPixelScale, 0, result, 0, 2);
+ return result;
+ }
+
+ @Override
+ public final int[] getCurrentSurfaceScale(final int[] result) {
+ System.arraycopy(hasPixelScale, 0, result, 0, 2);
+ return result;
+ }
+
+ @Override
+ public final int[] getNativeSurfaceScale(final int[] result) {
+ System.arraycopy(nativePixelScale, 0, result, 0, 2);
+ return result;
+ }
+
+ /**
+ * Updates bounds and pixelScale
+ * @return true if bounds or pixelScale has changed, otherwise false
+ */
+ protected final boolean updateLockedData(final 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) {
+ final boolean changedBounds = !bounds.equals(jb);
+
+ if( changedBounds ) {
+ if( DEBUG ) {
System.err.println("JAWTWindow.updateBounds: "+bounds+" -> "+jb);
- Thread.dumpStack();
}
- bounds.setX(jawtBounds.getX());
- bounds.setY(jawtBounds.getY());
- bounds.setWidth(jawtBounds.getWidth());
- bounds.setHeight(jawtBounds.getHeight());
-
+ bounds.set(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), 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);
+ final java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.set(contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
}
}
- return changed;
+ {
+ final int ps = JAWTUtil.getPixelScale(config.getAWTGraphicsConfiguration());
+ nativePixelScale[0] = ps;
+ nativePixelScale[1] = ps;
+ }
+
+ return updatePixelScale() || changedBounds;
+ }
+
+ /**
+ * Update pixelScale
+ * @return true if pixelScale has changed, otherwise false
+ */
+ protected final boolean updatePixelScale() {
+ return SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, nativePixelScale, DEBUG ? getClass().getSimpleName() : null);
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
+ /** @return the safe pixelScale value for x-direction, i.e. never negative or zero. Updated with lock. */
+ protected final int getPixelScaleX() { return hasPixelScale[0]; }
+
+ /** @return the safe pixelScale value for y-direction, i.e. never negative or zero. Updated with lock. */
+ protected final int getPixelScaleY() { return hasPixelScale[1]; }
+
@Override
public final InsetsImmutable getInsets() { return insets; }
@@ -174,9 +371,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
//
// OffscreenLayerOption
//
-
+
@Override
- public void setShallUseOffscreenLayer(boolean v) {
+ public void setShallUseOffscreenLayer(final boolean v) {
shallUseOffscreenLayer = v;
}
@@ -199,83 +396,126 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
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) + ", bounds "+bounds);
- }
- attachSurfaceLayerImpl(layerHandle);
- offscreenSurfaceLayer = layerHandle;
- } finally {
- unlockSurface();
+ attachSurfaceLayerImpl(layerHandle);
+ offscreenSurfaceLayer = layerHandle;
+ appContextInfo.invokeOnAppContextThread(false /* waitUntilDone */, repaintTask, "Repaint");
+ }
+ private final Runnable repaintTask = new Runnable() {
+ @Override
+ public void run() {
+ final Component c = component;
+ if( DEBUG ) {
+ System.err.println("Bug 1004: RepaintTask on "+Thread.currentThread()+": Has Comp "+(null != c));
+ }
+ if( null != c ) {
+ c.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
+ */
+ protected void layoutSurfaceLayerImpl(final long layerHandle, final boolean visible) {}
+
+ private final void layoutSurfaceLayerIfEnabled(final boolean visible) throws NativeWindowException {
+ if( isOffscreenLayerSurfaceEnabled() && 0 != offscreenSurfaceLayer ) {
+ layoutSurfaceLayerImpl(offscreenSurfaceLayer, visible);
}
}
- protected abstract void attachSurfaceLayerImpl(final long layerHandle);
+
@Override
public final void detachSurfaceLayer() throws NativeWindowException {
- if( !isOffscreenLayerSurfaceEnabled() ) {
- throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
- }
if( 0 == offscreenSurfaceLayer) {
throw new NativeWindowException("No offscreen layer attached: "+this);
}
- int lockRes = lockSurface();
- if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
- throw new NativeWindowException("Could not lock (offscreen layer): "+this);
- }
- try {
- if(DEBUG) {
- System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(offscreenSurfaceLayer));
- }
- detachSurfaceLayerImpl(offscreenSurfaceLayer);
- offscreenSurfaceLayer = 0;
- } finally {
- unlockSurface();
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): osh "+toHexString(offscreenSurfaceLayer));
}
+ detachSurfaceLayerImpl(offscreenSurfaceLayer, detachSurfaceLayerNotify);
+ }
+ private final Runnable detachSurfaceLayerNotify = new Runnable() {
+ @Override
+ public void run() {
+ offscreenSurfaceLayer = 0;
+ }
+ };
+
+ /**
+ * @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");
}
- protected abstract void detachSurfaceLayerImpl(final long layerHandle);
- protected final long getAttachedSurfaceLayer() {
+
+ @Override
+ public final long getAttachedSurfaceLayer() {
return offscreenSurfaceLayer;
}
-
+
@Override
public final boolean isSurfaceLayerAttached() {
return 0 != offscreenSurfaceLayer;
}
-
- @Override
- public final void setChosenCapabilities(CapabilitiesImmutable caps) {
- ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
- getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
- }
-
- //
- // SurfaceUpdateListener
- //
@Override
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ public final void setChosenCapabilities(final CapabilitiesImmutable caps) {
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ config.setChosenCapabilities(caps);
}
@Override
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ public final RecursiveLock getLock() {
+ return surfaceLock;
}
@Override
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ 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 (final Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if( null != c ) {
+ component.setCursor(c);
+ }
+ } } );
+ return true;
}
@Override
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ public final boolean hideCursor() {
+ AWTEDTExecutor.singleton.invoke(false, new Runnable() {
+ public void run() {
+ final Cursor cursor = AWTMisc.getNullCursor();
+ if( null != cursor ) {
+ component.setCursor(cursor);
+ }
+ } } );
+ return true;
}
//
@@ -303,13 +543,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
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();
}
@@ -319,32 +553,41 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
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 {
- 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 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;
@@ -386,19 +629,35 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
@Override
- public long getSurfaceHandle() {
- return drawable;
+ public void addSurfaceUpdatedListener(final SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(final int index, final SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ @Override
+ public void removeSurfaceUpdatedListener(final SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void surfaceUpdated(final Object updater, final NativeSurface ns, final long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
}
- public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
- return config;
+ @Override
+ public long getSurfaceHandle() {
+ return drawable;
}
@Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
-
+
@Override
public final long getDisplayHandle() {
return getGraphicsConfiguration().getScreen().getDevice().getHandle();
@@ -410,25 +669,55 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
@Override
- public final int getWidth() {
- return component.getWidth();
+ public final int getSurfaceWidth() {
+ return getWidth() * getPixelScaleX();
}
@Override
- public final int getHeight() {
- return component.getHeight();
+ public final int getSurfaceHeight() {
+ return getHeight() * getPixelScaleY();
}
+ @Override
+ public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
+ pixelUnitsAndResult[0] /= getPixelScaleX();
+ pixelUnitsAndResult[1] /= getPixelScaleY();
+ return pixelUnitsAndResult;
+ }
+
+ @Override
+ public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
+ windowUnitsAndResult[0] *= getPixelScaleX();
+ windowUnitsAndResult[1] *= getPixelScaleY();
+ return windowUnitsAndResult;
+ }
+
+ @Override
+ public final NativeSurface getNativeSurface() { return this; }
+
//
// NativeWindow
//
@Override
+ public final int getWidth() {
+ return component.getWidth();
+ }
+
+ @Override
+ public final int getHeight() {
+ return component.getHeight();
+ }
+
+ @Override
public void destroy() {
surfaceLock.lock();
try {
+ if(DEBUG) {
+ System.err.println(jawtStr()+".destroy @ Thread "+getThreadName());
+ }
+ jawtComponentListener.detach();
invalidate();
- component = null; // don't dispose the AWT component, since we are merely an immutable uplink
} finally {
surfaceLock.unlock();
}
@@ -478,9 +767,13 @@ 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();
+ final java.awt.Point awtLOS = component.getLocationOnScreen();
if(null!=storage) {
los = storage.translate(awtLOS.x, awtLOS.y);
} else {
@@ -490,8 +783,8 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return los;
}
- protected Point getLocationOnScreenNative(Point storage) {
- int lockRes = lockSurface();
+ protected Point getLocationOnScreenNative(final Point storage) {
+ final int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
if(DEBUG) {
System.err.println("Warning: JAWT Lock couldn't be acquired: "+this);
@@ -500,7 +793,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return null;
}
try {
- Point d = getLocationOnScreenNativeImpl(0, 0);
+ final Point d = getLocationOnScreenNativeImpl(0, 0);
if(null!=d) {
if(null!=storage) {
storage.translate(d.getX(),d.getY());
@@ -514,19 +807,33 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
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(final 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
@@ -534,26 +841,53 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return component.hasFocus();
}
+ protected StringBuilder jawt2String(StringBuilder sb) {
+ if( null == sb ) {
+ sb = new StringBuilder();
+ }
+ sb.append("JVM version: ").append(PlatformPropsImpl.JAVA_VERSION).append(" (").
+ append(PlatformPropsImpl.JAVA_VERSION_NUMBER).
+ append(" update ").append(PlatformPropsImpl.JAVA_VERSION_UPDATE).append(")").append(Platform.getNewline());
+ if(null != jawt) {
+ sb.append("JAWT version: ").append(toHexString(jawt.getCachedVersion())).
+ append(", CA_LAYER: ").append(JAWTUtil.isJAWTUsingOffscreenLayer(jawt)).
+ append(", isLayeredSurface ").append(isOffscreenLayerSurfaceEnabled()).
+ append(", bounds ").append(bounds).append(", insets ").append(insets).
+ append(", pixelScale ").append(getPixelScaleX()).append("x").append(getPixelScaleY());
+ } 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");
- }
+ final StringBuilder sb = new StringBuilder();
+
+ 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(", window ["+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+
+ "], pixels[s "+getPixelScaleX()+"x"+getPixelScaleY()+" -> "+getSurfaceWidth()+"x"+getSurfaceHeight()+"]"+
+ ", visible "+component.isVisible());
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
- ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+ ",\n\tconfig "+config+
",\n\tawtComponent "+getAWTComponent()+
",\n\tsurfaceLock "+surfaceLock+"]");
return sb.toString();
}
+
+ protected static final String toHexString(final long l) {
+ return "0x"+Long.toHexString(l);
+ }
+ protected static final String toHexString(final int i) {
+ return "0x"+Integer.toHexString(i);
+ }
+
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index b824350ff..d21994ea5 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
@@ -38,14 +38,14 @@ import javax.media.nativewindow.*;
*/
public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
final long[] nativeDisplayID = new long[1];
- final EGLDisplayLifecycleCallback eglLifecycleCallback;
+ /* 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>
+ * </p>
*/
public interface EGLDisplayLifecycleCallback {
/**
@@ -55,14 +55,14 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
* @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>
@@ -73,19 +73,25 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
this.eglLifecycleCallback = null;
}
- public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
+ public EGLGraphicsDevice(final long nativeDisplayID, final long eglDisplay, final String connection, final int unitID, final 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) {
@@ -100,7 +106,13 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
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) {
@@ -111,10 +123,24 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
return super.close();
}
-
+
+ @Override
+ public boolean isHandleOwner() {
+ return null != eglLifecycleCallback;
+ }
+ @Override
+ public void clearHandleOwner() {
+ eglLifecycleCallback = null;
+ }
+ @Override
+ protected Object getHandleOwnership() {
+ return eglLifecycleCallback;
+ }
@Override
- public String toString() {
- return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", eglLifecycleCallback "+(null != eglLifecycleCallback)+"]";
+ protected Object setHandleOwnership(final 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..ff149447e 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
@@ -39,10 +39,11 @@ import javax.media.nativewindow.*;
public class MacOSXGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
/** Constructs a new MacOSXGraphicsDevice */
- public MacOSXGraphicsDevice(int unitID) {
+ public MacOSXGraphicsDevice(final int unitID) {
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 1cc796086..d29e2abbc 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -30,70 +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.DefaultGraphicsScreen;
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 com.jogamp.nativewindow.x11.X11GraphicsScreen;
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(final 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 {
- Field f = null;
-
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ NativeWindowFactory.initSingleton(); // last resort ..
+ return null;
+ } } );
- if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
+ nwt = NativeWindowFactory.getNativeWindowType(false);
+ isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
+ isX11 = NativeWindowFactory.TYPE_X11 == nwt;
+
+ Field f = null;
+ if( !isOSX ) {
try {
f = Control.class.getField(str_handle);
- } catch (Exception ex) {
+ } catch (final 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());
@@ -103,164 +152,291 @@ 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 });
- } catch (Exception ex) {
+ } catch (final Exception ex) {
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) {
+ } catch (final 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 == nwt ) {
+ 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);
+ final 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 (final Exception ex) { throw new NativeWindowException(ex); }
+ // optional
+ try {
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);
- } catch (Exception ex) { throw new NativeWindowException(ex); }
+ } catch (final 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(final long arg) {
if(swt_uses_long_handles) {
- return new Long(arg);
+ return Long.valueOf(arg);
}
- return new Integer((int) arg);
+ return Integer.valueOf((int) arg);
}
-
- static void callStaticMethodL2V(Method m, long arg) {
+
+ private static void callStaticMethodL2V(final Method m, final long arg) {
ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
}
-
- static long callStaticMethodL2L(Method m, long arg) {
- Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
+
+ private static void callStaticMethodLLZ2V(final Method m, final long arg0, final long arg1, final boolean arg3) {
+ ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
+ }
+
+ private static long callStaticMethodL2L(final Method m, final long arg) {
+ final Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
if(o instanceof Number) {
return ((Number)o).longValue();
} else {
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(final 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(final 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(final 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(final long window, final long pixmap, final 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(final 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);
+ final 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 (final 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);
- } catch (Exception ex) {
+ h = swt_control_handle.getLong(swtControl);
+ } catch (final 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);
- 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(final 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 */);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+ if( isWindows ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isOSX ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
- public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
- if( null != OS_gtk_class ) {
- return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
- }
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
- return new DefaultGraphicsScreen(device, screen);
- }
- 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(final AbstractGraphicsDevice device, final int screen) {
+ return NativeWindowFactory.createScreen(device, screen);
}
- public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
- if( null != OS_gtk_class ) {
+
+ public static int getNativeVisualID(final AbstractGraphicsDevice device, final long windowHandle) {
+ if( isX11 ) {
return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return VisualIDHolder.VID_UNDEFINED;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
-
- 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);
+
+ /**
+ * @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(final 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 ) );
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return handle;
}
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 });
}
@@ -274,39 +450,138 @@ 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 });
+ ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { Long.valueOf(gc), gcData });
} else {
- ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Integer((int)gc), gcData });
+ ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { Integer.valueOf((int)gc), gcData });
}
}
});
}
-
+
/**
* 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.</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></li>
* </ul>
* @see Platform#AWT_AVAILABLE
* @see Platform#getOSType()
*/
- public static void invoke(boolean wait, Runnable runnable) {
- if( Platform.OS_TYPE == Platform.OSType.MACOS ) {
+ public static void invoke(final boolean wait, final Runnable runnable) {
+ if( isOSX ) {
// Use SWT main thread! Only reliable config w/ -XStartOnMainThread !?
- OSXUtil.RunOnMainThread(wait, runnable);
+ OSXUtil.RunOnMainThread(wait, false, 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(final org.eclipse.swt.widgets.Display display, final boolean wait, final 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(final AbstractGraphicsScreen screen, final Control swtControl, final int visualID, final int width, final 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(final AbstractGraphicsDevice device, final Rectangle clientArea, final long x11Window) {
+ X11Lib.SetWindowPosSize(device.getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+ }
+ public static void destroyX11Window(final AbstractGraphicsDevice device, final 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(final Control swtControl, final int visualID, final int width, final 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(final long gdkWindow) {
+ /* OS.gdk_window_show (gdkWindow);
+ OS.gdk_flush(); */
+ }
+ public static void focusGDKWindow(final long gdkWindow) {
+ /*
+ OS.gdk_window_show (gdkWindow);
+ OS.gdk_window_focus(gdkWindow, 0);
+ OS.gdk_flush(); */
+ }
+ public static void resizeGDKWindow(final Rectangle clientArea, final 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(final 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..ef0cbddd7 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,19 +34,20 @@ package com.jogamp.nativewindow.windows;
import javax.media.nativewindow.*;
-/**
+/**
* Encapsulates a graphics device on Windows platforms.<br>
*/
public class WindowsGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
/** Constructs a new WindowsGraphicsDevice */
- public WindowsGraphicsDevice(int unitID) {
+ public WindowsGraphicsDevice(final int unitID) {
this(AbstractGraphicsDevice.DEFAULT_CONNECTION, unitID);
}
- public WindowsGraphicsDevice(String connection, int unitID) {
+ public WindowsGraphicsDevice(final String connection, final int unitID) {
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..223cb5194 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,9 +48,9 @@ import jogamp.nativewindow.x11.XVisualInfo;
public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
- public X11GraphicsConfiguration(X11GraphicsScreen screen,
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- XVisualInfo info) {
+ public X11GraphicsConfiguration(final X11GraphicsScreen screen,
+ final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
+ final XVisualInfo info) {
super(screen, capsChosen, capsRequested);
this.info = info;
}
@@ -64,19 +64,19 @@ public class X11GraphicsConfiguration extends MutableGraphicsConfiguration imple
return info;
}
- final protected void setXVisualInfo(XVisualInfo info) {
+ final protected void setXVisualInfo(final XVisualInfo info) {
this.info = info;
}
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 152384980..fea4e7019 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
@@ -45,7 +45,8 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- final boolean handleOwner;
+ /* 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>
@@ -53,41 +54,54 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
* This constructor exist to setup a default device connection.
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int)
*/
- public X11GraphicsDevice(String connection, int unitID) {
+ public X11GraphicsDevice(final String connection, final int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
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");
- }
- handleOwner = owner;
+ public X11GraphicsDevice(final long display, final int unitID, final boolean 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) {
+ public X11GraphicsDevice(final long display, final int unitID, final ToolkitLock locker, final boolean owner) {
super(NativeWindowFactory.TYPE_X11, X11Lib.XDisplayString(display), unitID, display, locker);
if(0==display) {
throw new NativeWindowException("null display");
}
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(final String displayConnection, final int unitID, final ToolkitLock locker) {
+ super(NativeWindowFactory.TYPE_X11, displayConnection, unitID, 0, locker);
+ handleOwner = true;
+ open();
+ isXineramaEnabled = X11Util.XineramaIsEnabled(this);
}
- private static int getDefaultScreenImpl(long dpy) {
+ private static int getDefaultScreenImpl(final long dpy) {
return X11Lib.DefaultScreen(dpy);
}
-
+
/**
* Returns the default screen number as referenced by the display connection, i.e. 'somewhere:0.1' -> 1
* <p>
@@ -105,7 +119,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
return ds;
}
-
+
public int getDefaultVisualID() {
final long display = getHandle();
if(0==display) {
@@ -113,7 +127,11 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
return X11Lib.DefaultVisualID(display, getDefaultScreenImpl(display));
}
-
+
+ public final boolean isXineramaEnabled() {
+ return isXineramaEnabled;
+ }
+
@Override
public Object clone() {
return super.clone();
@@ -133,7 +151,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
}
return false;
}
-
+
@Override
public boolean close() {
if(handleOwner && 0 != handle) {
@@ -144,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(final 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 5f3c220ca..8ebf3c379 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
@@ -47,11 +49,11 @@ import jogamp.nativewindow.x11.X11Util;
public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneable {
/** Constructs a new X11GraphicsScreen corresponding to the given native screen index. */
- public X11GraphicsScreen(X11GraphicsDevice device, int screen) {
- super(device, fetchScreen(device, screen));
+ public X11GraphicsScreen(final X11GraphicsDevice device, final int screen) {
+ super(device, device.isXineramaEnabled() ? 0 : screen);
}
- public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
+ public static AbstractGraphicsScreen createScreenDevice(final long display, final int screenIdx, final boolean owner) {
if(0==display) throw new NativeWindowException("display is null");
return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
}
@@ -60,15 +62,8 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
// It still could be an AWT hold handle ..
return X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
}
-
- 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;
- }
+ @Override
public Object clone() {
return super.clone();
}