diff options
Diffstat (limited to 'src/nativewindow')
71 files changed, 8754 insertions, 0 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java new file mode 100644 index 000000000..38bd70a90 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowVersion.java @@ -0,0 +1,62 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.nativewindow; + +import 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) { + super(packageName, mf); + } + + public static NativeWindowVersion getInstance() { + 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); + } + } + } + return jogampCommonVersionInfo; + } + + public static void main(String args[]) { + System.err.println(VersionUtil.getPlatformInfo()); + System.err.println(GlueGenVersion.getInstance()); + System.err.println(NativeWindowVersion.getInstance()); + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java new file mode 100644 index 000000000..784343c5a --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +/** A marker interface describing a graphics configuration, visual, or + pixel format in a toolkit-independent manner. */ + +public interface AbstractGraphicsConfiguration extends Cloneable { + /** + * Return the screen this graphics configuration is valid for + */ + public AbstractGraphicsScreen getScreen(); + + /** + * Return the capabilities reflecting this graphics configuration, + * which may differ from the capabilites used to choose this configuration. + * + * @return An immutable instance of the Capabilities to avoid mutation by + * the user. + */ + public CapabilitiesImmutable getChosenCapabilities(); + + /** + * Return the capabilities used to choose this graphics configuration. + * + * These may be used to reconfigure the NativeWindow in case + * the device changes in a multi screen environment. + * + * @return An immutable instance of the Capabilities to avoid mutation by + * the user. + */ + public CapabilitiesImmutable getRequestedCapabilities(); + + /** + * In case this instance already reflects a native configuration, + * return this one. + * Otherwise return the encapsuled native configuration, + * as it shall be included e.g. in the AWT case. + */ + public AbstractGraphicsConfiguration getNativeGraphicsConfiguration(); +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java new file mode 100644 index 000000000..83b437612 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -0,0 +1,123 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +/** A interface describing a graphics device in a + toolkit-independent manner. + */ + +public interface AbstractGraphicsDevice extends Cloneable { + /** Dummy connection value for a default connection where no native support for multiple devices is available */ + public static String DEFAULT_CONNECTION = "decon"; + + /** Dummy connection value for an external connection where no native support for multiple devices is available */ + public static String EXTERNAL_CONNECTION = "excon"; + + /** Default unit id for the 1st device: 0 */ + public static int DEFAULT_UNIT = 0; + + /** + * Returns the type of the underlying subsystem, ie + * NativeWindowFactory.TYPE_KD, NativeWindowFactory.TYPE_X11, .. + */ + public String getType(); + + /** + * Returns the semantic GraphicsDevice connection.<br> + * On platforms supporting remote devices, eg via tcp/ip network, + * the implementation shall return a unique name for each remote address.<br> + * On X11 for example, the connection string should be as the following example.<br> + * <ul> + * <li><code>:0.0</code> for a local connection</li> + * <li><code>remote.host.net:0.0</code> for a remote connection</li> + * </ul> + * + * To support multiple local device, see {@link #getUnitID()}. + */ + public String getConnection(); + + /** + * Returns the graphics device <code>unit ID</code>.<br> + * The <code>unit ID</code> support multiple graphics device configurations + * on a local machine.<br> + * To support remote device, see {@link #getConnection()}. + * @return + */ + public int getUnitID(); + + /** + * Returns a unique ID String of this device using {@link #getType() type}, + * {@link #getConnection() connection} and {@link #getUnitID() unitID}.<br> + * The unique ID does not reflect the instance of the device, hence the handle is not included.<br> + * The unique ID may be used as a key for semantic device mapping. + */ + public String getUniqueID(); + + /** + * Returns the native handle of the underlying native device, + * if such thing exist. + */ + public long getHandle(); + + /** + * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ + public void lock(); + + /** + * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ + public void unlock(); + + /** + * Optionally closing the device.<br> + * The default implementation is a NOP operation, returning false.<br> + * The specific implementing, ie {@link javax.media.nativewindow.x11.X11GraphicsDevice}, + * shall have a enable/disable like {@link javax.media.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},<br> + * which shall be invoked at creation time to determine ownership/role of freeing the resource.<br> + * + * @return true if a specialized closing operation was successfully issued, otherwise false, + * ie no native closing operation was issued, which doesn't imply an error at all. + */ + public boolean close(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsScreen.java new file mode 100644 index 000000000..eb2cc9120 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsScreen.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +/** A interface describing a graphics screen in a + toolkit-independent manner. + */ + +public interface AbstractGraphicsScreen extends Cloneable { + /** + * Return the device this graphics configuration is valid for + */ + public AbstractGraphicsDevice getDevice(); + + /** Returns the screen index this graphics screen is valid for + */ + public int getIndex(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java new file mode 100644 index 000000000..79d69c703 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +/** Specifies a set of capabilities that a window's rendering context + must support, such as color depth per channel. It currently + contains the minimal number of routines which allow configuration + on all supported window systems. */ +public class Capabilities implements CapabilitiesImmutable, Cloneable, Comparable { + private int redBits = 8; + private int greenBits = 8; + private int blueBits = 8; + private int alphaBits = 0; + + // Support for transparent windows containing OpenGL content + private boolean backgroundOpaque = true; + private int transparentValueRed = -1; + private int transparentValueGreen = -1; + private int transparentValueBlue = -1; + private int transparentValueAlpha = -1; + + // Switch for on- or offscreen + private boolean onscreen = true; + + /** Creates a Capabilities object. All attributes are in a default + state. + */ + public Capabilities() {} + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new NativeWindowException(e); + } + } + + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + this.redBits; + hash = ((hash << 5) - hash) + this.greenBits; + hash = ((hash << 5) - hash) + this.blueBits; + hash = ((hash << 5) - hash) + this.alphaBits; + hash = ((hash << 5) - hash) + ( this.backgroundOpaque ? 1 : 0 ); + hash = ((hash << 5) - hash) + this.transparentValueRed; + hash = ((hash << 5) - hash) + this.transparentValueGreen; + hash = ((hash << 5) - hash) + this.transparentValueBlue; + hash = ((hash << 5) - hash) + this.transparentValueAlpha; + hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 ); + return hash; + } + + public boolean equals(Object obj) { + if(this == obj) { return true; } + if(!(obj instanceof CapabilitiesImmutable)) { + return false; + } + CapabilitiesImmutable other = (CapabilitiesImmutable)obj; + boolean res = other.getRedBits()==redBits && + other.getGreenBits()==greenBits && + other.getBlueBits()==blueBits && + other.getAlphaBits()==alphaBits && + other.isBackgroundOpaque()==backgroundOpaque && + other.isOnscreen()==onscreen; + if(!backgroundOpaque) { + res = res && other.getTransparentRedValue()==transparentValueRed && + other.getTransparentGreenValue()==transparentValueGreen && + other.getTransparentBlueValue()==transparentValueBlue && + other.getTransparentAlphaValue()==transparentValueAlpha; + } + + return res; + } + + /** comparing RGBA values only */ + public int compareTo(Object o) { + if ( ! ( o instanceof Capabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a Capabilities object: " + c); + } + + final Capabilities caps = (Capabilities) o; + + final int a = ( alphaBits > 0 ) ? alphaBits : 1; + final int rgba = redBits * greenBits * blueBits * a; + + final int xa = ( caps.alphaBits ) > 0 ? caps.alphaBits : 1; + final int xrgba = caps.redBits * caps.greenBits * caps.blueBits * xa; + + if(rgba > xrgba) { + return 1; + } else if(rgba < xrgba) { + return -1; + } + + return 0; // they are equal: RGBA + } + + /** Returns the number of bits requested for the color buffer's red + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public int getRedBits() { + return redBits; + } + + /** Sets the number of bits requested for the color buffer's red + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public void setRedBits(int redBits) { + this.redBits = redBits; + } + + /** Returns the number of bits requested for the color buffer's + green component. On some systems only the color depth, which is + the sum of the red, green, and blue bits, is considered. */ + public int getGreenBits() { + return greenBits; + } + + /** Sets the number of bits requested for the color buffer's green + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public void setGreenBits(int greenBits) { + this.greenBits = greenBits; + } + + /** Returns the number of bits requested for the color buffer's blue + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public int getBlueBits() { + return blueBits; + } + + /** Sets the number of bits requested for the color buffer's blue + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public void setBlueBits(int blueBits) { + this.blueBits = blueBits; + } + + /** Returns the number of bits requested for the color buffer's + alpha component. On some systems only the color depth, which is + the sum of the red, green, and blue bits, is considered. */ + public int getAlphaBits() { + return alphaBits; + } + + /** Sets the number of bits requested for the color buffer's alpha + component. On some systems only the color depth, which is the + sum of the red, green, and blue bits, is considered. */ + public void setAlphaBits(int alphaBits) { + this.alphaBits = alphaBits; + } + + /** For on-screen OpenGL contexts on some platforms, sets whether + the background of the context should be considered opaque. On + supported platforms, setting this to false, in conjunction with + the transparency values, may allow + hardware-accelerated OpenGL content inside of windows of + arbitrary shape. To achieve this effect it is necessary to use + an OpenGL clear color with an alpha less than 1.0. The default + value for this flag is <code>true</code>; setting it to false + may incur a certain performance penalty, so it is not + recommended to arbitrarily set it to false.<br> + If not set already, the transparency values for red, green, blue and alpha + are set to their default value, which is half of the value range + of the framebuffer's corresponding component, + ie <code> redValue = ( 1 << ( redBits - 1 ) ) -1 </code>. + */ + public void setBackgroundOpaque(boolean opaque) { + backgroundOpaque = opaque; + if(!opaque) { + if(transparentValueRed<0) + transparentValueRed = ( 1 << ( getRedBits() - 1 ) ) - 1 ; + if(transparentValueGreen<0) + transparentValueGreen = ( 1 << ( getGreenBits() - 1 ) ) - 1 ; + if(transparentValueBlue<0) + transparentValueBlue = ( 1 << ( getBlueBits() - 1 ) ) - 1 ; + if(transparentValueAlpha<0) + transparentValueAlpha = ( 1 << ( getAlphaBits() - 1 ) ) - 1 ; + } + } + + /** Indicates whether the background of this OpenGL context should + be considered opaque. Defaults to true. + + @see #setBackgroundOpaque + */ + public boolean isBackgroundOpaque() { + return backgroundOpaque; + } + + /** Sets whether the drawable surface supports onscreen. + Defaults to true. + */ + public void setOnscreen(boolean onscreen) { + this.onscreen=onscreen; + } + + /** Indicates whether the drawable surface is onscreen. + Defaults to true. + */ + public boolean isOnscreen() { + return onscreen; + } + + /** Gets the transparent red value for the frame buffer configuration. + * This value is undefined if {@link #isBackgroundOpaque()} equals true. + * @see #setTransparentRedValue + */ + public int getTransparentRedValue() { return transparentValueRed; } + + /** Gets the transparent green value for the frame buffer configuration. + * This value is undefined if {@link #isBackgroundOpaque()} equals true. + * @see #setTransparentGreenValue + */ + public int getTransparentGreenValue() { return transparentValueGreen; } + + /** Gets the transparent blue value for the frame buffer configuration. + * This value is undefined if {@link #isBackgroundOpaque()} equals true. + * @see #setTransparentBlueValue + */ + public int getTransparentBlueValue() { return transparentValueBlue; } + + /** Gets the transparent alpha value for the frame buffer configuration. + * This value is undefined if {@link #isBackgroundOpaque()} equals true. + * @see #setTransparentAlphaValue + */ + public int getTransparentAlphaValue() { return transparentValueAlpha; } + + /** Sets the transparent red value for the frame buffer configuration, + ranging from 0 to the maximum frame buffer value for red. + This value is ignored if {@link #isBackgroundOpaque()} equals true.<br> + It defaults to half of the frambuffer value for red. <br> + A value of -1 is interpreted as any value. */ + public void setTransparentRedValue(int transValueRed) { transparentValueRed=transValueRed; } + + /** Sets the transparent green value for the frame buffer configuration, + ranging from 0 to the maximum frame buffer value for green. + This value is ignored if {@link #isBackgroundOpaque()} equals true.<br> + It defaults to half of the frambuffer value for green.<br> + A value of -1 is interpreted as any value. */ + public void setTransparentGreenValue(int transValueGreen) { transparentValueGreen=transValueGreen; } + + /** Sets the transparent blue value for the frame buffer configuration, + ranging from 0 to the maximum frame buffer value for blue. + This value is ignored if {@link #isBackgroundOpaque()} equals true.<br> + It defaults to half of the frambuffer value for blue.<br> + A value of -1 is interpreted as any value. */ + public void setTransparentBlueValue(int transValueBlue) { transparentValueBlue=transValueBlue; } + + /** Sets the transparent alpha value for the frame buffer configuration, + ranging from 0 to the maximum frame buffer value for alpha. + This value is ignored if {@link #isBackgroundOpaque()} equals true.<br> + It defaults to half of the frambuffer value for alpha.<br> + A value of -1 is interpreted as any value. */ + public void setTransparentAlphaValue(int transValueAlpha) { transparentValueAlpha=transValueAlpha; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + if(onscreen) { + sink.append("on-scr"); + } else { + sink.append("offscr"); + } + sink.append(", rgba ").append(redBits).append("/").append(greenBits).append("/").append(blueBits).append("/").append(alphaBits); + if(backgroundOpaque) { + sink.append(", opaque"); + } else { + sink.append(", trans-rgba 0x").append(Integer.toHexString(transparentValueRed)).append("/").append(Integer.toHexString(transparentValueGreen)).append("/").append(Integer.toHexString(transparentValueBlue)).append("/").append(Integer.toHexString(transparentValueAlpha)); + } + return sink; + } + + /** Returns a textual representation of this Capabilities + object. */ + public String toString() { + StringBuffer msg = new StringBuffer(); + msg.append("Caps["); + toString(msg); + msg.append("]"); + return msg.toString(); + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java new file mode 100644 index 000000000..a306363dc --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +import java.util.List; + +/** Provides a mechanism by which applications can customize the + window type selection for a given {@link Capabilities}. + Developers can implement this interface and pass an instance into + the method {@link GraphicsConfigurationFactory#chooseGraphicsConfiguration}; the chooser + will be called at window creation time. */ + +public interface CapabilitiesChooser { + /** Chooses the index (0..available.length - 1) of the {@link + Capabilities} most closely matching the desired one from the + list of all supported. Some of the entries in the + <code>available</code> array may be null; the chooser must + ignore these. The <em>windowSystemRecommendedChoice</em> + parameter may be provided to the chooser by the underlying + window system; if this index is valid, it is recommended, but + not necessarily required, that the chooser select that entry. + + <P> <em>Note:</em> this method is called automatically by the + {@link GraphicsConfigurationFactory#chooseGraphicsConfiguration} method + when an instance of this class is passed in to it. + It should generally not be + invoked by users directly, unless it is desired to delegate the + choice to some other CapabilitiesChooser object. + */ + public int chooseCapabilities(CapabilitiesImmutable desired, + List /*<CapabilitiesImmutable>*/ available, + int windowSystemRecommendedChoice); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java new file mode 100644 index 000000000..8fb704bad --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java @@ -0,0 +1,120 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +import com.jogamp.common.type.WriteCloneable; + +/** + * Specifies an immutable set of capabilities that a window's rendering context + * must support, such as color depth per channel. + * + * @see javax.media.nativewindow.Capabilities + */ +public interface CapabilitiesImmutable extends WriteCloneable { + + /** + * Returns the number of bits requested for the color buffer's red + * component. On some systems only the color depth, which is the sum of the + * red, green, and blue bits, is considered. + */ + int getRedBits(); + + /** + * Returns the number of bits requested for the color buffer's green + * component. On some systems only the color depth, which is the sum of the + * red, green, and blue bits, is considered. + */ + int getGreenBits(); + + /** + * Returns the number of bits requested for the color buffer's blue + * component. On some systems only the color depth, which is the sum of the + * red, green, and blue bits, is considered. + */ + int getBlueBits(); + + /** + * Returns the number of bits requested for the color buffer's alpha + * component. On some systems only the color depth, which is the sum of the + * red, green, and blue bits, is considered. + */ + int getAlphaBits(); + + /** + * Indicates whether the background of this OpenGL context should be + * considered opaque. Defaults to true. + */ + boolean isBackgroundOpaque(); + + /** + * Indicates whether the drawable surface is onscreen. Defaults to true. + */ + boolean isOnscreen(); + + /** + * Gets the transparent red value for the frame buffer configuration. This + * value is undefined if; equals true. + */ + int getTransparentRedValue(); + + /** + * Gets the transparent green value for the frame buffer configuration. This + * value is undefined if; equals true. + */ + int getTransparentGreenValue(); + + /** + * Gets the transparent blue value for the frame buffer configuration. This + * value is undefined if; equals true. + */ + int getTransparentBlueValue(); + + /** + * Gets the transparent alpha value for the frame buffer configuration. This + * value is undefined if; equals true. + */ + int getTransparentAlphaValue(); + + Object cloneMutable(); + + /** Equality over the immutable attributes of both objects */ + @Override + boolean equals(Object obj); + + /** hash code over the immutable attributes of both objects */ + @Override + int hashCode(); + + /** Return a textual representation of this object. Use the given StringBuffer [optional]. */ + StringBuffer toString(StringBuffer sink); + + /** Returns a textual representation of this object. */ + @Override + String toString(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java new file mode 100644 index 000000000..b43db8292 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +import java.util.List; + +/** <P> The default implementation of the {@link + CapabilitiesChooser} interface, which provides consistent visual + selection behavior across platforms. The precise algorithm is + deliberately left loosely specified. Some properties are: </P> + + <LI> Attempts to match as closely as possible the given + Capabilities, but will select one with fewer capabilities (i.e., + lower color depth) if necessary. + + <LI> If there is no exact match, prefers a more-capable visual to + a less-capable one. + + <LI> If there is more than one exact match, chooses an arbitrary + one. + + <LI> If a valid windowSystemRecommendedChoice parameter is + supplied, chooses that instead of using the cross-platform code. + + </UL> +*/ + +public class DefaultCapabilitiesChooser implements CapabilitiesChooser { + private static final boolean DEBUG = false; // FIXME: Debug.debug("DefaultCapabilitiesChooser"); + + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { + if (DEBUG) { + System.err.println("Desired: " + desired); + for (int i = 0; i < available.size(); i++) { + System.err.println("Available " + i + ": " + available.get(i)); + } + System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); + } + final int availnum = available.size(); + + if (windowSystemRecommendedChoice >= 0 && + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { + if (DEBUG) { + System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); + System.err.println(available.get(windowSystemRecommendedChoice)); + } + return windowSystemRecommendedChoice; + } + + // Create score array + int[] scores = new int[availnum]; + int NO_SCORE = -9999999; + int COLOR_MISMATCH_PENALTY_SCALE = 36; + for (int i = 0; i < availnum; i++) { + scores[i] = NO_SCORE; + } + // Compute score for each + for (int i = 0; i < availnum; i++) { + CapabilitiesImmutable cur = (CapabilitiesImmutable) available.get(i); + if (cur == null) { + continue; + } + int score = 0; + // Compute difference in color depth + score += (COLOR_MISMATCH_PENALTY_SCALE * + ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) - + (desired.getRedBits() + desired.getGreenBits() + desired.getBlueBits() + desired.getAlphaBits()))); + scores[i] = score; + } + + if (DEBUG) { + System.err.print("Scores: ["); + for (int i = 0; i < availnum; i++) { + if (i > 0) { + System.err.print(","); + } + System.err.print(" " + scores[i]); + } + System.err.println(" ]"); + } + + // Ready to select. Choose score closest to 0. + int scoreClosestToZero = NO_SCORE; + int chosenIndex = -1; + for (int i = 0; i < availnum; i++) { + int score = scores[i]; + if (score == NO_SCORE) { + continue; + } + // Don't substitute a positive score for a smaller negative score + if ((scoreClosestToZero == NO_SCORE) || + (Math.abs(score) < Math.abs(scoreClosestToZero) && + ((sign(scoreClosestToZero) < 0) || (sign(score) > 0)))) { + scoreClosestToZero = score; + chosenIndex = i; + } + } + if (chosenIndex < 0) { + throw new NativeWindowException("Unable to select one of the provided Capabilities"); + } + if (DEBUG) { + System.err.println("Chosen index: " + chosenIndex); + System.err.println("Chosen capabilities:"); + System.err.println(available.get(chosenIndex)); + } + + return chosenIndex; + } + + private static int sign(int score) { + if (score < 0) { + return -1; + } + return 1; + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java new file mode 100644 index 000000000..ffa8bfae6 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java @@ -0,0 +1,122 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow; + +public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphicsConfiguration { + private AbstractGraphicsScreen screen; + protected CapabilitiesImmutable capabilitiesChosen; + protected CapabilitiesImmutable capabilitiesRequested; + + public DefaultGraphicsConfiguration(AbstractGraphicsScreen screen, + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) { + if(null == screen) { + throw new NativeWindowException("Null screen"); + } + if(null == capsChosen) { + throw new NativeWindowException("Null chosen caps"); + } + if(null == capsRequested) { + throw new NativeWindowException("Null requested caps"); + } + this.screen = screen; + this.capabilitiesChosen = capsChosen; + this.capabilitiesRequested = capsRequested; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new NativeWindowException(e); + } + } + + public AbstractGraphicsScreen getScreen() { + return screen; + } + + public CapabilitiesImmutable getChosenCapabilities() { + return capabilitiesChosen; + } + + public CapabilitiesImmutable getRequestedCapabilities() { + return capabilitiesRequested; + } + + public AbstractGraphicsConfiguration getNativeGraphicsConfiguration() { + return this; + } + + /** + * Set the capabilities to a new value. + * + * The use case for setting the Capabilities at a later time is + * a change of the graphics device in a multi-screen environment.<br> + * + * The objects reference is being used. + * + * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) + */ + protected void setChosenCapabilities(CapabilitiesImmutable capsChosen) { + capabilitiesChosen = capsChosen; + } + + /** + * Set a new screen. + * + * the use case for setting a new screen at a later time is + * a change of the graphics device in a multi-screen environment.<br> + * + * A copy of the passed object is being used. + */ + protected void setScreen(DefaultGraphicsScreen screen) { + this.screen = (AbstractGraphicsScreen) screen.clone(); + } + + @Override + public String toString() { + return getClass().getSimpleName()+"[" + screen + + ",\n\tchosen " + capabilitiesChosen+ + ",\n\trequested " + capabilitiesRequested+ + "]"; + } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java new file mode 100644 index 000000000..c2aa6fae9 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow; + +import jogamp.nativewindow.NativeWindowFactoryImpl; + +public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice { + private static final String separator = "_"; + private String type; + protected String connection; + protected int unitID; + protected String uniqueID; + protected long handle; + protected ToolkitLock toolkitLock; + + /** + * Create an instance with the system default {@link ToolkitLock}, + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + */ + public DefaultGraphicsDevice(String type, String connection, int unitID) { + this.type = type; + this.connection = connection; + this.unitID = unitID; + this.uniqueID = getUniqueID(type, connection, unitID); + this.handle = 0; + setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) ); + } + + /** + * Create an instance with the system default {@link ToolkitLock}. + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + * @param handle + */ + public DefaultGraphicsDevice(String type, String connection, int unitID, long handle) { + this.type = type; + this.connection = connection; + this.unitID = unitID; + this.uniqueID = getUniqueID(type, connection, unitID); + this.handle = handle; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) ); + } + + /** + * Create an instance with the given {@link ToolkitLock} instance. + * @param type + * @param handle + * @param locker + */ + public DefaultGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) { + this.type = type; + this.connection = connection; + this.unitID = unitID; + this.uniqueID = getUniqueID(type, connection, unitID); + this.handle = handle; + setToolkitLock( locker ); + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new NativeWindowException(e); + } + } + + public final String getType() { + return type; + } + + public final String getConnection() { + return connection; + } + + public final int getUnitID() { + return unitID; + } + + public final String getUniqueID() { + return uniqueID; + } + + public final long getHandle() { + return handle; + } + + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void lock() { + toolkitLock.lock(); + } + + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void unlock() { + toolkitLock.unlock(); + } + + public boolean close() { + return false; + } + + @Override + public String toString() { + return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]"; + } + + /** + * Set the internal ToolkitLock, which is used within the + * {@link #lock()} and {@link #unlock()} implementation. + * + * @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used + */ + protected void setToolkitLock(ToolkitLock locker) { + this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ; + } + + /** + * @return the used ToolkitLock + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final ToolkitLock getToolkitLock() { + return toolkitLock; + } + + protected static String getUniqueID(String type, String connection, int unitID) { + return (type + separator + connection + separator + unitID).intern(); + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java new file mode 100644 index 000000000..f50bd0e14 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java @@ -0,0 +1,69 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow; + +public class DefaultGraphicsScreen implements Cloneable, AbstractGraphicsScreen { + AbstractGraphicsDevice device; + private int idx; + + public DefaultGraphicsScreen(AbstractGraphicsDevice device, int idx) { + this.device = device; + this.idx = idx; + } + + public static AbstractGraphicsScreen createDefault(String type) { + return new DefaultGraphicsScreen(new DefaultGraphicsDevice(type, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT), 0); + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new NativeWindowException(e); + } + } + + public AbstractGraphicsDevice getDevice() { + return device; + } + + public int getIndex() { + return idx; + } + + @Override + public String toString() { + return getClass().getSimpleName()+"["+device+", idx "+idx+"]"; + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java new file mode 100644 index 000000000..fa3923dcf --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow; + +import com.jogamp.common.util.ReflectionUtil; +import jogamp.nativewindow.Debug; +import jogamp.nativewindow.DefaultGraphicsConfigurationFactoryImpl; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + + +/** + * Provides the mechanism by which the graphics configuration for a + * window can be chosen before the window is created. The graphics + * configuration decides parameters related to hardware accelerated rendering such + * as the OpenGL pixel format. <br> + * On some window systems (EGL/OpenKODE and X11 in particular) it is necessary to + * choose the graphics configuration early at window creation time. <br> + * Note that the selection of the graphics configuration is an algorithm which does not have + * strong dependencies on the particular Java window toolkit in use + * (e.g., AWT) and therefore it is strongly desirable to factor this + * functionality out of the core {@link NativeWindowFactory} so that + * new window toolkits can replace just the {@link + * NativeWindowFactory} and reuse the graphics configuration selection + * algorithm provided by, for example, an OpenGL binding. + */ + +public abstract class GraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + private static Map/*<Class, NativeWindowFactory>*/ registeredFactories = + Collections.synchronizedMap(new HashMap()); + private static Class abstractGraphicsDeviceClass; + + static { + initialize(); + } + + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + + protected static String toHexString(int val) { + return "0x" + Integer.toHexString(val); + } + + protected static String toHexString(long val) { + return "0x" + Long.toHexString(val); + } + + /** Creates a new NativeWindowFactory instance. End users do not + need to call this method. */ + protected GraphicsConfigurationFactory() { + } + + private static void initialize() { + abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class; + + if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) { + try { + GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory) + ReflectionUtil.createInstance("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory", null, + GraphicsConfigurationFactory.class.getClassLoader()); + registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + // Register the default no-op factory for arbitrary + // AbstractGraphicsDevice implementations, including + // AWTGraphicsDevice instances -- the OpenGL binding will take + // care of handling AWTGraphicsDevices on X11 platforms (as + // well as X11GraphicsDevices in non-AWT situations) + registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl()); + } + + /** Returns the factory for use with the given type of + AbstractGraphicsDevice. */ + public static GraphicsConfigurationFactory getFactory(AbstractGraphicsDevice device) { + if (device == null) { + return getFactory(AbstractGraphicsDevice.class); + } + return getFactory(device.getClass()); + } + + /** + * Returns the graphics configuration factory for use with the + * given class, which must implement the {@link + * AbstractGraphicsDevice} interface. + * + * @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice + */ + public static GraphicsConfigurationFactory getFactory(Class abstractGraphicsDeviceImplementor) + throws IllegalArgumentException, NativeWindowException + { + if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) { + throw new IllegalArgumentException("Given class must implement AbstractGraphicsDevice"); + } + + GraphicsConfigurationFactory factory = null; + Class clazz = abstractGraphicsDeviceImplementor; + while (clazz != null) { + factory = + (GraphicsConfigurationFactory) registeredFactories.get(clazz); + if (factory != null) { + if(DEBUG) { + System.err.println("GraphicsConfigurationFactory.getFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory); + } + return factory; + } + clazz = clazz.getSuperclass(); + } + // Return the default + factory = (GraphicsConfigurationFactory)registeredFactories.get(abstractGraphicsDeviceClass); + if(DEBUG) { + System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+abstractGraphicsDeviceClass+" -> "+factory); + } + return factory; + } + + /** Registers a GraphicsConfigurationFactory handling graphics + * device objects of the given class. This does not need to be + * called by end users, only implementors of new + * GraphicsConfigurationFactory subclasses. + * + * @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice + */ + protected static void registerFactory(Class abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory) + throws IllegalArgumentException + { + if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) { + throw new IllegalArgumentException("Given class must implement AbstractGraphicsDevice"); + } + if(DEBUG) { + System.err.println("GraphicsConfigurationFactory.registerFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory); + } + registeredFactories.put(abstractGraphicsDeviceImplementor, factory); + } + + /** + * <P> Selects a graphics configuration on the specified graphics + * device compatible with the supplied {@link Capabilities}. Some + * platforms (e.g.: X11, EGL, KD) require the graphics configuration + * to be specified when the native window is created. + * These architectures have seperated their device, screen, window and drawable + * context and hence are capable of quering the capabilities for each screen. + * A fully established window is not required.</P> + * + * <P>Other platforms (e.g. Windows, MacOSX) don't offer the mentioned seperation + * and hence need a fully established window and it's drawable. + * Here the validation of the capabilities is performed later. + * In this case, the AbstractGraphicsConfiguration implementation + * must allow an overwrite of the Capabilites, for example + * {@link DefaultGraphicsConfiguration#setChosenCapabilities DefaultGraphicsConfiguration.setChosenCapabilities(..)}. + * </P> + * + * <P> + * This method is mainly intended to be both used and implemented by the + * OpenGL binding.</P> + * + * <P> The concrete data type of the passed graphics device and + * returned graphics configuration must be specified in the + * documentation binding this particular API to the underlying + * window toolkit. The Reference Implementation accepts {@link + * javax.media.nativewindow.awt.AWTGraphicsDevice AWTGraphicsDevice} objects and returns {@link + * javax.media.nativewindow.awt.AWTGraphicsConfiguration AWTGraphicsConfiguration} objects. On + * X11 platforms where the AWT is not in use, it also accepts + * {@link javax.media.nativewindow.x11.X11GraphicsDevice + * X11GraphicsDevice} objects and returns {@link + * javax.media.nativewindow.x11.X11GraphicsConfiguration + * X11GraphicsConfiguration} objects.</P> + * + * @param capsChosen the intermediate chosen capabilities to be refined by this implementation, may be equal to capsRequested + * @param capsRequested the original requested capabilities + * @param chooser the choosing implementation + * @param screen the referring Screen + * @return the complete GraphicsConfiguration + * + * @throws IllegalArgumentException if the data type of the passed + * AbstractGraphicsDevice is not supported by this + * NativeWindowFactory. + * @throws NativeWindowException if any window system-specific errors caused + * the selection of the graphics configuration to fail. + * + * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) + * @see javax.media.nativewindow.DefaultGraphicsConfiguration#setChosenCapabilities(Capabilities caps) + */ + public final AbstractGraphicsConfiguration + chooseGraphicsConfiguration(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + CapabilitiesChooser chooser, + AbstractGraphicsScreen screen) + throws IllegalArgumentException, NativeWindowException { + if(null==capsChosen) { + throw new NativeWindowException("Chosen Capabilities are null"); + } + if(null==capsRequested) { + throw new NativeWindowException("Requested Capabilities are null"); + } + if(null==screen) { + throw new NativeWindowException("Screen is null"); + } + AbstractGraphicsDevice device = screen.getDevice(); + if(null==device) { + throw new NativeWindowException("Screen's Device is null"); + } + device.lock(); + try { + return chooseGraphicsConfigurationImpl(capsChosen, capsRequested, chooser, screen); + } finally { + device.unlock(); + } + } + + protected abstract AbstractGraphicsConfiguration + chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + CapabilitiesChooser chooser, AbstractGraphicsScreen screen) + throws IllegalArgumentException, NativeWindowException; + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java new file mode 100644 index 000000000..a5b71fbf8 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java @@ -0,0 +1,163 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +/** Provides low-level information required for + hardware-accelerated rendering using a surface in a platform-independent manner.<P> + + A NativeSurface created for a particular on- or offscreen component is + expected to have the same lifetime as that component. As long as + the component is alive and realized/visible, NativeSurface must be able + provide information such as the surface handle while it is locked.<P> +*/ +public interface NativeSurface extends SurfaceUpdatedListener { + /** Unlocked state */ + public static final int LOCK_SURFACE_UNLOCKED = 0; + + /** Returned by {@link #lockSurface()} if the surface is not ready to be locked. */ + public static final int LOCK_SURFACE_NOT_READY = 1; + + /** Returned by {@link #lockSurface()} if the surface is locked, but has changed. */ + public static final int LOCK_SURFACE_CHANGED = 2; + + /** Returned by {@link #lockSurface()} if the surface is locked, and is unchanged. */ + public static final int LOCK_SUCCESS = 3; + + /** + * Lock the surface of this native window<P> + * + * The surface handle, see {@link #lockSurface()}, <br> + * shall be valid after a successfull call, + * ie return a value other than {@link #LOCK_SURFACE_NOT_READY}.<P> + * + * This call is blocking until the surface has been locked + * or a timeout is reached. The latter will throw a runtime exception. <P> + * + * This call allows recursion from the same thread.<P> + * + * The implementation may want to aquire the + * application level {@link com.jogamp.common.util.locks.RecursiveLock} + * first before proceeding with a native surface lock. <P> + * + * The implementation shall also invoke {@link AbstractGraphicsDevice#lock()} + * for the initial lock (recursive count zero).<P> + * + * @return {@link #LOCK_SUCCESS}, {@link #LOCK_SURFACE_CHANGED} or {@link #LOCK_SURFACE_NOT_READY}. + * + * @throws RuntimeException after timeout when waiting for the surface lock + * + * @see com.jogamp.common.util.locks.RecursiveLock + */ + public int lockSurface(); + + /** + * Unlock the surface of this native window + * + * Shall not modify the surface handle, see {@link #lockSurface()} <P> + * + * The implementation shall also invoke {@link AbstractGraphicsDevice#unlock()} + * for the final unlock (recursive count zero).<P> + * + * @throws RuntimeException if surface is not locked + * + * @see #lockSurface + * @see com.jogamp.common.util.locks.RecursiveLock + */ + public void unlockSurface() throws NativeWindowException ; + + /** + * Return if surface is locked by another thread, ie not the current one + */ + public boolean isSurfaceLockedByOtherThread(); + + /** + * Return if surface is locked + */ + public boolean isSurfaceLocked(); + + /** + * Return the locking owner's Thread, or null if not locked. + */ + public Thread getSurfaceLockOwner(); + + /** + * Provide a mechanism to utilize custom (pre-) swap surface + * code. This method is called before the render toolkit (e.g. JOGL) + * swaps the buffer/surface. The implementation may itself apply the swapping, + * in which case true shall be returned. + * + * @return true if this method completed swapping the surface, + * otherwise false, in which case eg the GLDrawable + * implementation has to swap the code. + */ + public boolean surfaceSwap(); + + /** + * Returns the handle to the surface for this NativeSurface. <P> + * + * The surface handle should be set/update by {@link #lockSurface()}, + * where {@link #unlockSurface()} is not allowed to modify it. + * After {@link #unlockSurface()} it is no more guaranteed + * that the surface handle is still valid. + * + * The surface handle shall reflect the platform one + * for all drawable surface operations, e.g. opengl, swap-buffer. <P> + * + * On X11 this returns an entity of type Window, + * since there is no differentiation of surface and window there. <BR> + * On Microsoft Windows this returns an entity of type HDC. + */ + public long getSurfaceHandle(); + + /** Returns the current width of this surface. */ + public int getWidth(); + + /** Returns the current height of this surface. */ + public int getHeight(); + + /** + * Returns the graphics configuration corresponding to this window. + * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) + */ + public AbstractGraphicsConfiguration getGraphicsConfiguration(); + + /** + * Convenience: Get display handle from + * AbstractGraphicsConfiguration . AbstractGraphicsScreen . AbstractGraphicsDevice + */ + public long getDisplayHandle(); + + /** + * Convenience: Get display handle from + * AbstractGraphicsConfiguration . AbstractGraphicsScreen + */ + public int getScreenIndex(); + +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java new file mode 100644 index 000000000..d65cc8c18 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +import javax.media.nativewindow.util.Point; + +/** Extend the {@link NativeSurface} interface with windowing + information such as window handle and position.<P> + + A window toolkit such as the AWT may either implement this interface + directly with one of its components, or provide and register an + implementation of {@link NativeWindowFactory NativeWindowFactory} + which can create NativeWindow objects for its components. <P> +*/ +public interface NativeWindow extends NativeSurface { + + /** + * destroys the window and releases + * windowing related resources. + */ + public void destroy(); + + /** + * @return The parent NativeWindow, or null if this NativeWindow is top level. + */ + public NativeWindow getParent(); + + /** + * Returns the window handle for this NativeWindow. <P> + * + * The window handle shall reflect the platform one + * for all window related operations, e.g. open, close, resize. <P> + * + * On X11 this returns an entity of type Window. <BR> + * On Microsoft Windows this returns an entity of type HWND. + */ + public long getWindowHandle(); + + /** Returns the current x position of this window, relative to it's parent. */ + public int getX(); + + /** Returns the current y position of this window, relative to it's parent. */ + public int getY(); + + /** + * Returns the current absolute location of this window. + * @param point if not null, + * {@link javax.media.nativewindow.util.Point#translate(javax.media.nativewindow.util.Point)} + * the passed {@link javax.media.nativewindow.util.Point} by this location on the screen and return it. + * @return either the passed non null translated point by the screen location of this NativeWindow, + * or a new instance with the screen location of this NativeWindow. + */ + public Point getLocationOnScreen(Point point); + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowException.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowException.java new file mode 100644 index 000000000..593c1e7d6 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowException.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +/** A generic exception for OpenGL errors used throughout the binding + as a substitute for {@link RuntimeException}. */ + +public class NativeWindowException extends RuntimeException { + /** Constructs a NativeWindowException object. */ + public NativeWindowException() { + super(); + } + + /** Constructs a NativeWindowException object with the specified detail + message. */ + public NativeWindowException(String message) { + super(message); + } + + /** Constructs a NativeWindowException object with the specified detail + message and root cause. */ + public NativeWindowException(String message, Throwable cause) { + super(message, cause); + } + + /** Constructs a NativeWindowException object with the specified root + cause. */ + public NativeWindowException(Throwable cause) { + super(cause); + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java new file mode 100644 index 000000000..b0f5cb3f9 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow; + +import java.security.*; +import java.util.*; + +import com.jogamp.common.util.*; +import com.jogamp.common.jvm.JVMUtil; +import jogamp.nativewindow.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +/** Provides a pluggable mechanism for arbitrary window toolkits to + adapt their components to the {@link NativeWindow} interface, + which provides a platform-independent mechanism of accessing the + information required to perform operations like + hardware-accelerated rendering using the OpenGL API. */ + +public abstract class NativeWindowFactory { + protected static final boolean DEBUG; + + /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/ + public static final String TYPE_EGL = "EGL"; + + /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)} */ + public static final String TYPE_WINDOWS = "Windows"; + + /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)} */ + public static final String TYPE_X11 = "X11"; + + /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)} */ + public static final String TYPE_MACOSX = "MacOSX"; + + /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)} */ + public static final String TYPE_AWT = "AWT"; + + /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)} */ + public static final String TYPE_DEFAULT = "default"; + + private static NativeWindowFactory defaultFactory; + private static Map/*<Class, NativeWindowFactory>*/ registeredFactories; + private static Class nativeWindowClass; + private static String nativeWindowingTypePure; + private static String nativeOSNamePure; + private static String nativeWindowingTypeCustom; + private static String nativeOSNameCustom; + private static boolean isAWTAvailable; + public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ; + public static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util"; + public static final String GDIClassName = "jogamp.nativewindow.windows.GDI"; + public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ; + public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ; + private static Class jawtUtilClass; + private static Method jawtUtilGetJAWTToolkitMethod; + private static Method jawtUtilInitMethod; + private static Class x11JAWTToolkitLockClass; + private static Constructor x11JAWTToolkitLockConstructor; + private static Class x11ToolkitLockClass; + private static Constructor x11ToolkitLockConstructor; + private static boolean isFirstUIActionOnProcess; + + /** Creates a new NativeWindowFactory instance. End users do not + need to call this method. */ + protected NativeWindowFactory() { + } + + private static String _getNativeWindowingType(String osNameLowerCase) { + if (osNameLowerCase.startsWith("kd")) { + return TYPE_EGL; + } else if (osNameLowerCase.startsWith("wind")) { + return TYPE_WINDOWS; + } else if (osNameLowerCase.startsWith("mac os x") || + osNameLowerCase.startsWith("darwin")) { + return TYPE_MACOSX; + } else if (osNameLowerCase.equals("awt")) { + return TYPE_AWT; + } else { + return TYPE_X11; + } + } + + static { + JVMUtil.initSingleton(); + DEBUG = Debug.debug("NativeWindow"); + if(DEBUG) { + Throwable td = new Throwable(Thread.currentThread().getName()+" - Info: NativeWindowFactory.<init>"); + td.printStackTrace(); + } + } + + static boolean initialized = false; + + private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { + String clazzName = null; + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + clazzName = X11UtilClassName; + } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) { + clazzName = GDIClassName; + } + if( null != clazzName ) { + ReflectionUtil.callStaticMethod(clazzName, "initSingleton", + new Class[] { boolean.class }, + new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + } + } + + /** + * Static one time initialization of this factory.<br> + * This initialization method <b>must be called</b> once by the program or utilizing modules! + * <p> + * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking: + * <ul> + * <li> {@link #getDefaultToolkitLock() getDefaultToolkitLock() }</li> + * <li> {@link #getDefaultToolkitLock(java.lang.String) getDefaultToolkitLock(type) }</li> + * <li> {@link #createDefaultToolkitLock(java.lang.String, long) createDefaultToolkitLock(type, dpyHandle) }</li> + * <li> {@link #createDefaultToolkitLockNoAWT(java.lang.String, long) createDefaultToolkitLockNoAWT(type, dpyHandle) }</li> + * </ul> + * </p> + * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, + * otherwise <code>false</code>. + */ + public static synchronized void initSingleton(final boolean firstUIActionOnProcess) { + if(!initialized) { + initialized = true; + + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); + } + + // Gather the windowing OS first + AccessControlContext acc = AccessController.getContext(); + nativeOSNamePure = Debug.getProperty("os.name", false, acc); + nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase()); + nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc); + if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) { + nativeOSNameCustom = nativeOSNamePure; + nativeWindowingTypeCustom = nativeWindowingTypePure; + } else { + nativeWindowingTypeCustom = nativeOSNameCustom; + } + + final ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + + if(firstUIActionOnProcess) { + // X11 initialization before possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); + } + isFirstUIActionOnProcess = firstUIActionOnProcess; + isAWTAvailable = false; // may be set to true below + + if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && + ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && + ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ) { + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader()); + jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", (Class[])null); + jawtUtilInitMethod.setAccessible(true); + jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{}); + jawtUtilGetJAWTToolkitMethod.setAccessible(true); + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + if(null != jawtUtilClass && null != jawtUtilGetJAWTToolkitMethod && null != jawtUtilInitMethod) { + ReflectionUtil.callMethod(null, jawtUtilInitMethod, null); + + Object resO = ReflectionUtil.callStaticMethod(JAWTUtilClassName, "isHeadlessMode", null, null, cl ); + if(resO instanceof Boolean) { + // AWT is only available in case all above classes are available + // and AWT is not int headless mode + isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE); + } + } + } + if(!firstUIActionOnProcess) { + // X11 initialization after possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); + } + registeredFactories = Collections.synchronizedMap(new HashMap()); + + // register our default factory -> NativeWindow + NativeWindowFactory factory = new NativeWindowFactoryImpl(); + nativeWindowClass = javax.media.nativewindow.NativeWindow.class; + registerFactory(nativeWindowClass, factory); + defaultFactory = factory; + + if ( isAWTAvailable ) { + // register either our default factory or (if exist) the X11/AWT one -> AWT Component + registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory); + } + + if( TYPE_X11 == nativeWindowingTypePure ) { + // passing through RuntimeException if not exists intended + x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl); + x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } ); + if( isAWTAvailable() ) { + x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl); + x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } ); + } + } + + if(DEBUG) { + System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory); + } + } + } + + /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, + otherwise false. */ + public static boolean isFirstUIActionOnProcess() { + return isFirstUIActionOnProcess; + } + + /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ + public static boolean isAWTAvailable() { return isAWTAvailable; } + + /** + * @param useCustom if false return the native value, if true return a custom value if set, otherwise fallback to the native value. + * @return the native OS name + */ + public static String getNativeOSName(boolean useCustom) { + return useCustom?nativeOSNameCustom:nativeOSNamePure; + } + + /** + * @param useCustom if false return the native value, if true return a custom value if set, otherwise fallback to the native value. + * @return a define native window type, like {@link #TYPE_X11}, .. + */ + public static String getNativeWindowType(boolean useCustom) { + return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure; + } + + /** Don't know if we shall add this factory here .. + public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) { + if(type.equals(TYPE_EGL)) { + return new + } else if(type.equals(TYPE_X11)) { + } else if(type.equals(TYPE_WINDOWS)) { + } else if(type.equals(TYPE_MACOSX)) { + } else if(type.equals(TYPE_AWT)) { + } else if(type.equals(TYPE_DEFAULT)) { + } + } */ + + /** Sets the default NativeWindowFactory. */ + public static void setDefaultFactory(NativeWindowFactory factory) { + defaultFactory = factory; + } + + /** Gets the default NativeWindowFactory. */ + public static NativeWindowFactory getDefaultFactory() { + return defaultFactory; + } + + /** + * Provides the system default {@link ToolkitLock}, a singleton instance. + * <br> + * @see #getDefaultToolkitLock(java.lang.String) + */ + public static ToolkitLock getDefaultToolkitLock() { + return getDefaultToolkitLock(getNativeWindowType(false)); + } + + /** + * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance. + * <br> + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If native <b>X11 type</b> with or w/o AWT</li> + * <ul> + * <li> If <b>AWT available</b> </li> + * <ul> + * <li> return {@link jogamp.nativewindow.jawt.JAWTToolkitLock} </li> + * </ul> + * </ul> + * </ul> + * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li> + * </ul> + */ + public static ToolkitLock getDefaultToolkitLock(String type) { + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) { + if( isAWTAvailable() ) { + return getAWTToolkitLock(); + } + } + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock getAWTToolkitLock() { + Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod, null); + + if(resO instanceof ToolkitLock) { + return (ToolkitLock) resO; + } else { + throw new RuntimeException("JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock"); + } + } + + public static ToolkitLock getNullToolkitLock() { + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + /** + * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. + * <br> + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If <b>X11 type</b> </li> + * <ul> + * <li> If <b>AWT available</b> </li> + * <ul> + * <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li> + * </ul> + * <li> If <b>AWT not available</b> </li> + * <ul> + * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li> + * </ul> + * </ul> + * </ul> + * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li> + * </ul> + */ + public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); + } + if( isAWTAvailable() ) { + return createX11AWTToolkitLock(deviceHandle); + } + return createX11ToolkitLock(deviceHandle); + } + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + /** + * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. + * <br> + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If <b>X11 type</b> </li> + * <ul> + * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li> + * </ul> + * </ul> + * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li> + * </ul> + */ + public static ToolkitLock createDefaultToolkitLockNoAWT(String type, long deviceHandle) { + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLockNoAWT() called with NULL device but on X11"); + } + return createX11ToolkitLock(deviceHandle); + } + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected static ToolkitLock createX11ToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + + /** Returns the appropriate NativeWindowFactory to handle window + objects of the given type. The windowClass might be {@link + NativeWindow NativeWindow}, in which case the client has + already assumed the responsibility of creating a compatible + NativeWindow implementation, or it might be that of a toolkit + class like {@link java.awt.Component Component}. */ + public static NativeWindowFactory getFactory(Class windowClass) throws IllegalArgumentException { + if (nativeWindowClass.isAssignableFrom(windowClass)) { + return (NativeWindowFactory) registeredFactories.get(nativeWindowClass); + } + Class clazz = windowClass; + while (clazz != null) { + NativeWindowFactory factory = (NativeWindowFactory) registeredFactories.get(clazz); + if (factory != null) { + return factory; + } + clazz = clazz.getSuperclass(); + } + throw new IllegalArgumentException("No registered NativeWindowFactory for class " + windowClass.getName()); + } + + /** Registers a NativeWindowFactory handling window objects of the + given class. This does not need to be called by end users, + only implementors of new NativeWindowFactory subclasses. */ + protected static void registerFactory(Class windowClass, NativeWindowFactory factory) { + if(DEBUG) { + System.err.println("NativeWindowFactory.registerFactory() "+windowClass+" -> "+factory); + } + registeredFactories.put(windowClass, factory); + } + + /** Converts the given window object and it's + {@link AbstractGraphicsConfiguration AbstractGraphicsConfiguration} into a + {@link NativeWindow NativeWindow} which can be operated upon by a custom + toolkit, e.g. {@link javax.media.opengl.GLDrawableFactory javax.media.opengl.GLDrawableFactory}.<br> + The object may be a component for a particular window toolkit, such as an AWT + Canvas. It may also be a NativeWindow object itself.<br> + You shall utilize {@link javax.media.nativewindow.GraphicsConfigurationFactory GraphicsConfigurationFactory} + to construct a proper {@link AbstractGraphicsConfiguration AbstractGraphicsConfiguration}.<br> + The particular implementation of the + NativeWindowFactory is responsible for handling objects from a + particular window toolkit. The built-in NativeWindowFactory + handles NativeWindow instances as well as AWT Components.<br> + + @throws IllegalArgumentException if the given window object + could not be handled by any of the registered + NativeWindowFactory instances + + @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) + */ + public static NativeWindow getNativeWindow(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException, NativeWindowException { + if (winObj == null) { + throw new IllegalArgumentException("Null window object"); + } + + return getFactory(winObj.getClass()).getNativeWindowImpl(winObj, config); + } + + /** Performs the conversion from a toolkit's window object to a + NativeWindow. Implementors of concrete NativeWindowFactory + subclasses should override this method. */ + protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException; +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java new file mode 100644 index 000000000..038580ce0 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java @@ -0,0 +1,150 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +import com.jogamp.common.util.locks.RecursiveLock; + +public abstract class ProxySurface implements NativeSurface { + protected RecursiveLock surfaceLock = new RecursiveLock(); + protected AbstractGraphicsConfiguration config; + protected long displayHandle; + protected int height; + protected int scrnIndex; + protected int width; + + public ProxySurface(AbstractGraphicsConfiguration cfg) { + invalidate(); + config = cfg; + displayHandle=cfg.getScreen().getDevice().getHandle(); + } + + void invalidate() { + displayHandle = 0; + invalidateImpl(); + } + protected abstract void invalidateImpl(); + + public final long getDisplayHandle() { + return displayHandle; + } + + public final AbstractGraphicsConfiguration getGraphicsConfiguration() { + return config; + } + + public final int getScreenIndex() { + return config.getScreen().getIndex(); + } + + public abstract long getSurfaceHandle(); + + public final int getWidth() { + return width; + } + + public final int getHeight() { + return height; + } + + public void setSize(int width, int height) { + this.width = width; + this.height = height; + } + + public boolean surfaceSwap() { + return false; + } + + public void surfaceUpdated(Object updater, NativeSurface ns, long when) { + } + + public int lockSurface() throws NativeWindowException { + surfaceLock.lock(); + int res = surfaceLock.getRecursionCount() == 0 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; + + if ( LOCK_SURFACE_NOT_READY == res ) { + try { + final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + adevice.lock(); + try { + res = lockSurfaceImpl(); + } finally { + if (LOCK_SURFACE_NOT_READY >= res) { + adevice.unlock(); + } + } + } finally { + if (LOCK_SURFACE_NOT_READY >= res) { + surfaceLock.unlock(); + } + } + } + return res; + } + + public final void unlockSurface() { + surfaceLock.validateLocked(); + + if (surfaceLock.getRecursionCount() == 0) { + final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + try { + unlockSurfaceImpl(); + } finally { + adevice.unlock(); + } + } + surfaceLock.unlock(); + } + + protected abstract int lockSurfaceImpl(); + + protected abstract void unlockSurfaceImpl() ; + + public final void validateSurfaceLocked() { + surfaceLock.validateLocked(); + } + + public final boolean isSurfaceLocked() { + return surfaceLock.isLocked(); + } + + public final boolean isSurfaceLockedByOtherThread() { + return surfaceLock.isLockedByOtherThread(); + } + + public final Thread getSurfaceLockOwner() { + return surfaceLock.getOwner(); + } + + public final int getSurfaceRecursionCount() { + return surfaceLock.getRecursionCount(); + } + + public abstract String toString(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java new file mode 100644 index 000000000..fc32b57b3 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow; + +public interface SurfaceChangeable { + + public void setSurfaceHandle(long surfaceHandle); + public void setSize(int width, int height); + +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java new file mode 100644 index 000000000..88e805d14 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package javax.media.nativewindow; + +public interface SurfaceUpdatedListener { + /** Notification of a surface update event. + * + * @param updater is the caller object who updated the surface, + * e.g. a JOGL GLDrawable. + * @param ns the updated NativeSurface + * @param when the time in ms, when the surface was updated + */ + public void surfaceUpdated(Object updater, NativeSurface ns, long when) ; +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java new file mode 100644 index 000000000..982ce469b --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java @@ -0,0 +1,45 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +import jogamp.nativewindow.Debug; +import java.security.AccessController; + +/** + * Marker for a singleton global recursive blocking lock implementation, + * optionally locking a native windowing toolkit as well. + * <br> + * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}. + */ +public interface ToolkitLock { + public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true, AccessController.getContext()); + + public void lock(); + public void unlock(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java new file mode 100644 index 000000000..949aee79c --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java @@ -0,0 +1,66 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +/** + * Protocol for handling window closing events. + * <p> + * The implementation shall obey either the user value set by this interface,<br> + * an underlying toolkit set user value or it's default, eg. {@link #DO_NOTHING_ON_CLOSE DO_NOTHING_ON_CLOSE} within an AWT environment.<br> + * If none of the above determines the operation, + * this protocol default behavior {@link #DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.</p> + */ +public interface WindowClosingProtocol { + /** + * Dispose resources on native window close operation.<br> + * This is the default behavior in case no underlying toolkit defines otherwise. + */ + int DISPOSE_ON_CLOSE = 1; + + /** + * Do nothing on native window close operation.<br> + * This is the default behavior within an AWT environment. + */ + int DO_NOTHING_ON_CLOSE = 0; + + /** + * @return the current close operation value + * @see #DISPOSE_ON_CLOSE + * @see #DO_NOTHING_ON_CLOSE + */ + int getDefaultCloseOperation(); + + /** + * @param op the new close operation value + * @return the previous close operation value + * @see #DISPOSE_ON_CLOSE + * @see #DO_NOTHING_ON_CLOSE + */ + int setDefaultCloseOperation(int op); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java new file mode 100644 index 000000000..d83a92a5b --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java @@ -0,0 +1,167 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow.awt; + +import javax.media.nativewindow.*; +import java.awt.Component; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.image.ColorModel; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import jogamp.nativewindow.Debug; + +/** A wrapper for an AWT GraphicsConfiguration allowing it to be + handled in a toolkit-independent manner. */ + +public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { + private GraphicsConfiguration config; + AbstractGraphicsConfiguration encapsulated; + + public AWTGraphicsConfiguration(AWTGraphicsScreen screen, + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + GraphicsConfiguration config, AbstractGraphicsConfiguration encapsulated) { + super(screen, capsChosen, capsRequested); + this.config = config; + this.encapsulated=encapsulated; + } + + public AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + GraphicsConfiguration config) { + super(screen, capsChosen, capsRequested); + this.config = config; + this.encapsulated=null; + } + + /** + * @param capsChosen if null, <code>capsRequested</code> is copied and aligned + * with the graphics capabilties of the AWT Component to produce the chosen Capabilties. + * Otherwise the <code>capsChosen</code> is used. + */ + public static AWTGraphicsConfiguration create(Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) + { + AWTGraphicsScreen awtScreen = null; + AWTGraphicsDevice awtDevice = null; + GraphicsDevice awtGraphicsDevice = null; + GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration(); + if(null!=awtGfxConfig) { + awtGraphicsDevice = awtGfxConfig.getDevice(); + if(null!=awtGraphicsDevice) { + // Create Device/Screen + awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT); + awtScreen = new AWTGraphicsScreen(awtDevice); + } + } + if(null==awtScreen) { + // use defaults since no native peer is available yet + awtScreen = (AWTGraphicsScreen) AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT); + awtDevice = (AWTGraphicsDevice) awtScreen.getDevice(); + awtGraphicsDevice = awtDevice.getGraphicsDevice(); + } + + if(null==capsChosen) { + GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration(); + capsChosen = setupCapabilitiesRGBABits(capsChosen, gc); + } + return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig); + } + + @Override + public Object clone() { + return super.clone(); + } + + public GraphicsConfiguration getGraphicsConfiguration() { + return config; + } + + @Override + public AbstractGraphicsConfiguration getNativeGraphicsConfiguration() { + return (null!=encapsulated)?encapsulated:this; + } + + /** + * Sets up the Capabilities' RGBA size based on the given GraphicsConfiguration's ColorModel. + * + * @param capabilities the Capabilities object whose red, green, blue, and alpha bits will be set + * @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(); + + ColorModel cm = gc.getColorModel(); + if(null==cm) { + throw new NativeWindowException("Could not determine AWT ColorModel"); + } + int cmBitsPerPixel = cm.getPixelSize(); + int bitsPerPixel = 0; + int[] bitesPerComponent = cm.getComponentSize(); + if(bitesPerComponent.length>=3) { + capabilities.setRedBits(bitesPerComponent[0]); + bitsPerPixel += bitesPerComponent[0]; + capabilities.setGreenBits(bitesPerComponent[1]); + bitsPerPixel += bitesPerComponent[1]; + capabilities.setBlueBits(bitesPerComponent[2]); + bitsPerPixel += bitesPerComponent[2]; + } + if(bitesPerComponent.length>=4) { + capabilities.setAlphaBits(bitesPerComponent[3]); + bitsPerPixel += bitesPerComponent[3]; + } else { + capabilities.setAlphaBits(0); + } + if(Debug.debugAll()) { + if(cmBitsPerPixel!=bitsPerPixel) { + System.err.println("AWT Colormodel bits per components/pixel mismatch: "+bitsPerPixel+" != "+cmBitsPerPixel); + } + } + return capabilities; + } + + @Override + public String toString() { + return getClass().getSimpleName()+"[" + getScreen() + + ",\n\tchosen " + capabilitiesChosen+ + ",\n\trequested " + capabilitiesRequested+ + ",\n\t" + config + + ",\n\tencapsulated "+encapsulated+"]"; + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java new file mode 100644 index 000000000..66a63bfcd --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2005 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow.awt; + +import javax.media.nativewindow.*; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import javax.media.nativewindow.AbstractGraphicsDevice; + +/** A wrapper for an AWT GraphicsDevice allowing it to be + handled in a toolkit-independent manner. */ + +public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { + private GraphicsDevice device; + private String subType; + + protected AWTGraphicsDevice(GraphicsDevice device, int unitID) { + super(NativeWindowFactory.TYPE_AWT, device.getIDstring(), unitID); + this.device = device; + this.subType = null; + } + + public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice, int unitID) { + if(null==awtDevice) { + awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + unitID = AbstractGraphicsDevice.DEFAULT_UNIT; + } + return new AWTGraphicsDevice(awtDevice, unitID); + } + + @Override + public Object clone() { + return super.clone(); + } + + public GraphicsDevice getGraphicsDevice() { + return device; + } + + /** + * In case the native handle was specified, e.g. using X11, + * we shall be able to mark it.<br> + * This will also set the subType, queried with {@link #getSubType()} + * and reset the ToolkitLock type with {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)} + * and {@link #setToolkitLock(javax.media.nativewindow.ToolkitLock)}. + */ + public void setSubType(String subType, long handle) { + this.handle = handle; + this.subType = subType; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) ); + } + + public String getSubType() { + return subType; + } + + @Override + public String toString() { + return getClass().getSimpleName()+"[type "+getType()+"[subType "+getSubType()+"], connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java new file mode 100644 index 000000000..383dcae80 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package javax.media.nativewindow.awt; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import javax.media.nativewindow.*; +import javax.media.nativewindow.AbstractGraphicsDevice; + +/** A wrapper for an AWT GraphicsDevice (screen) allowing it to be + handled in a toolkit-independent manner. */ + +public class AWTGraphicsScreen extends DefaultGraphicsScreen implements Cloneable { + + public AWTGraphicsScreen(AWTGraphicsDevice device) { + super(device, findScreenIndex(device.getGraphicsDevice())); + } + + public static GraphicsDevice getScreenDevice(int index) { + if(index<0) return null; + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gs = ge.getScreenDevices(); + if(index<gs.length) { + return gs[index]; + } + return null; + } + + public static int findScreenIndex(GraphicsDevice awtDevice) { + if(null==awtDevice) return -1; + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + 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) { + AWTGraphicsDevice device = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(awtDevice, unitID); + return new AWTGraphicsScreen(device); + } + + public static AbstractGraphicsScreen createScreenDevice(int index, int unitID) { + GraphicsDevice awtDevice = getScreenDevice(index); + return createScreenDevice(awtDevice, unitID); + } + + public static AbstractGraphicsScreen createDefault() { + return createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT); + } + + public Object clone() { + return super.clone(); + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java new file mode 100644 index 000000000..e7db942e4 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java @@ -0,0 +1,139 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.awt; + +import java.awt.Component; +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 int defaultCloseOperation = DISPOSE_ON_CLOSE; + private boolean defaultCloseOperationSetByUser = false; + + public AWTWindowClosingProtocol(Component comp, Runnable closingOperation) { + this.comp = comp; + this.closingOperation = closingOperation; + } + + class WindowClosingAdapter extends WindowAdapter { + @Override + public void windowClosing(WindowEvent e) { + int op = AWTWindowClosingProtocol.this.getDefaultCloseOperation(); + + if( DISPOSE_ON_CLOSE == op ) { + // we have to issue this call right away, + // otherwise the window gets destroyed + closingOperation.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. + * + * @return + */ + public final boolean addClosingListenerOneShot() { + if(!closingListenerSet) { // volatile: ok + synchronized(closingListenerLock) { + if(!closingListenerSet) { + closingListenerSet=addClosingListenerImpl(); + return closingListenerSet; + } + } + } + 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; + } + } + } + } + return false; + } + + /** + * + * @return the user set close operation if set by {@link #setDefaultCloseOperation(int) setDefaultCloseOperation(int)}, + * otherwise return the AWT/Swing close operation value translated to + * a {@link WindowClosingProtocol} value . + */ + public final int getDefaultCloseOperation() { + int op = -1; + synchronized(closingListenerLock) { + if(defaultCloseOperationSetByUser) { + op = defaultCloseOperation; + } + } + if(0 <= op) { + return op; + } + // User didn't determine the behavior, use underlying AWT behavior + return AWTMisc.getNWClosingOperation(comp); + } + + public final int setDefaultCloseOperation(int op) { + synchronized(closingListenerLock) { + int _op = defaultCloseOperation; + defaultCloseOperation = op; + defaultCloseOperationSetByUser = true; + return _op; + } + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/egl/EGLGraphicsDevice.java new file mode 100644 index 000000000..2dfd9f0ee --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/egl/EGLGraphicsDevice.java @@ -0,0 +1,60 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow.egl; + +import javax.media.nativewindow.*; + +/** Encapsulates a graphics device on EGL platforms. + */ + +public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { + boolean closeDisplay = false; + + /** + * Note that this is not an open connection, ie no native display handle exist. + * This constructor exist to setup a default device connection/unit.<br> + */ + public EGLGraphicsDevice(String connection, int unitID) { + super(NativeWindowFactory.TYPE_EGL, connection, unitID); + } + + /** Constructs a new EGLGraphicsDevice corresponding to the given EGL display handle. */ + public EGLGraphicsDevice(long eglDisplay, String connection, int unitID) { + super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay); + } + + public Object clone() { + return super.clone(); + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/macosx/MacOSXGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/macosx/MacOSXGraphicsDevice.java new file mode 100644 index 000000000..02c63758f --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/macosx/MacOSXGraphicsDevice.java @@ -0,0 +1,50 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow.macosx; + +import javax.media.nativewindow.*; + +/** Encapsulates a graphics device on MacOSX platforms. + */ + +public class MacOSXGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { + /** Constructs a new MacOSXGraphicsDevice */ + public MacOSXGraphicsDevice(int unitID) { + super(NativeWindowFactory.TYPE_MACOSX, AbstractGraphicsDevice.DEFAULT_CONNECTION, unitID); + } + + public Object clone() { + return super.clone(); + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/package.html b/src/nativewindow/classes/javax/media/nativewindow/package.html new file mode 100644 index 000000000..14730a548 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/package.html @@ -0,0 +1,117 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <title>NativeWindow Protocol Draft Public Review Specification</title> +</head> + <body> + +<h2><i>NativeWindow Protocol</i> Specification Overview</h2> + +<h3>Preface</h3> + This specification, an optional set of packages, describing a <i>protocol</i> for a + <i>native windowing interface</i> binding to Java(TM).<br> + Currently specified <i>native windowing systems</i> are:<br><br> + <ul> + <li> EGL/OpenKODE Windowing System</li> + <li> X11 Windowing System</li> + <li> Microsoft Windows</li> + <li> Apple MacOSX</li> + <li> Java's AWT</li> + </ul> + <br> + However, any other native windowing system may be added to the implementation, + using a generic string identifier and an optional specialisation of:<br><br> + <ul> + <li>{@link javax.media.nativewindow.AbstractGraphicsDevice AbstractGraphicsDevice},<br> + <br> + Shall return the new string identifier with {@link javax.media.nativewindow.AbstractGraphicsDevice#getType() getType()}</li> + <li>{@link javax.media.nativewindow.AbstractGraphicsScreen AbstractGraphicsScreen}</li> + <li>{@link javax.media.nativewindow.AbstractGraphicsConfiguration AbstractGraphicsConfiguration}</li> + </ul> + <br> + The implementor has to provide the following:<br><br> + <ul> + <li> The specialisation of the abstract class {@link javax.media.nativewindow.NativeWindowFactory NativeWindowFactory}<br> + <br> + shall be registered with {@link javax.media.nativewindow.NativeWindowFactory#registerFactory NativeWindowFactory.registerFactory(..)}.</li> + + <li> The specialisation of the abstract class {@link javax.media.nativewindow.GraphicsConfigurationFactory GraphicsConfigurationFactory}<br> + <br> + shall be registered with {@link javax.media.nativewindow.GraphicsConfigurationFactory#registerFactory GraphicsConfigurationFactory.registerFactory(..)}.</li> + </ul><br> + This protocol <i>does not</i> describe how to <i>create</i> native windows, but how to <i>bind</i> a native surface to an implementation of + and window to an implementation of {@link javax.media.nativewindow.NativeSurface NativeSurface}.<br> + {@link javax.media.nativewindow.NativeWindow NativeWindow} specializes the NativeSurface.<br> + However, an implementation of this protocol (e.g. {@link com.jogamp.newt}) may support the creation.<br> + +<h3>Dependencies</h3> + This binding has dependencies to the following: + <ul> + <li> Either of the following Java implementations:<br/> + <ul> + <li> <a href="http://java.sun.com/j2se/1.5.0/docs/api/">Java SE 1.5 or later</a> </li> + <li> A mobile JavaVM with language 1.5 support, ie: + <ul> + <li> <a href="http://developer.android.com/reference/packages.html">Dalvik API Level 7</a> </li> + <li> <a href="http://jamvm.sourceforge.net/">JamVM</a> </li> + </ul> + with + <ul> + <li> <a href="http://java.sun.com/products/foundation/">Foundation Profile 1.1.2 (JSR 219)</a> </li> + <li> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/package-summary.html"> Java 1.4 <i>java.nio</i> implementation</a> </li> + </ul></li> + </ul></li> + </ul> + <br> + +<h3>Package Structure</h3> + The packages defined by this specification include:<br/><br/> +<ul> + <li>The <b>javax.media.nativewindow</b> package<br> + <br> + This package contains Java bindings for a native windowing system.<br> + Subsequent packages contain marker type classes, containing native characteristics of the windowing system. + + <ul> + <li>The <b>javax.media.nativewindow.awt</b> package<br> + <br> + This sub package contains classes to cover the native characteristics of the AWT windowing system.</li> + + <li>The <b>javax.media.nativewindow.x11</b> package<br> + <br> + This sub package contains classes to cover the native characteristics of the X11 windowing system.</li> + + <li>The <b>javax.media.nativewindow.windows</b> package<br> + <br> + This sub package contains classes to cover the native characteristics of the Windows windowing system.</li> + + <li>The <b>javax.media.nativewindow.macosx</b> package<br> + <br> + This sub package contains classes to cover the native characteristics of the MacOSX windowing system.</li> + + <li>The <b>javax.media.nativewindow.egl</b> package<br> + <br> + This sub package contains classes to cover the native characteristics of the EGL/OpenKODE windowing system.</li> + </ul></li> +</ul> + +<h3>Factory Model</h3> +Running on a platform with a supported windowing system, the factory model shall be used +to instantiate a native window, see {@link javax.media.nativewindow.NativeWindowFactory NativeWindowFactory}.<br> +The implementor has to specialize +All supported +Regardless of the knowledge of the underly +<br> + +<h3>Revision History<br> + </h3> + +<ul> +<li> Early Draft Review, June 2009</li> +<li> 2.0.0 Maintenance Release, February 2011</li> +</ul> + <br> + <br> + <br> +</body> +</html> diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java new file mode 100644 index 000000000..4151c1537 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +public class Dimension implements Cloneable, DimensionReadOnly { + int width; + int height; + + public Dimension() { + this(0, 0); + } + + public Dimension(int width, int height) { + if(width<0 || height<0) { + throw new IllegalArgumentException("width and height must be within: ["+0+".."+Integer.MAX_VALUE+"]"); + } + this.width=width; + this.height=height; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + public int getWidth() { return width; } + public int getHeight() { return height; } + + public void setWidth(int width) { + this.width = width; + } + public void setHeight(int height) { + this.height = height; + } + public Dimension scale(int s) { + width *= s; + height *= s; + return this; + } + public Dimension add(Dimension pd) { + width += pd.width ; + height += pd.height ; + return this; + } + + public String toString() { + return new String(width+" x "+height); + } + + public boolean equals(Object obj) { + if(this == obj) { return true; } + if (obj instanceof Dimension) { + Dimension p = (Dimension)obj; + return height == p.height && + width == p.width ; + } + return false; + } + + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + width; + return ((hash << 5) - hash) + height; + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/DimensionReadOnly.java b/src/nativewindow/classes/javax/media/nativewindow/util/DimensionReadOnly.java new file mode 100644 index 000000000..442afd4ba --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/DimensionReadOnly.java @@ -0,0 +1,55 @@ +/** + * Copyright 2010 JogAmp Community. 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +/** Immutable Dimension Interface, consisting of it's read only components:<br> + * <ul> + * <li><code>width</code></li> + * <li><code>height</code></li> + * </ul> + */ +public interface DimensionReadOnly extends Cloneable { + + int getHeight(); + + int getWidth(); + + /** + * Checks whether two dimensions objects are equal. Two instances + * of <code>DimensionReadOnly</code> are equal if two components + * <code>height</code> and <code>width</code> are equal. + * @return <code>true</code> if the two dimensions are equal; + * otherwise <code>false</code>. + */ + boolean equals(Object obj); + + int hashCode(); + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java new file mode 100644 index 000000000..96a45b7b1 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package javax.media.nativewindow.util; + +/** + * Simple class representing insets. + * + * @author tdv + */ +public class Insets implements Cloneable { + public int top; + public int left; + public int bottom; + public int right; + public int hash; + + /** + * Creates and initializes a new <code>Insets</code> object with the + * specified top, left, bottom, and right insets. + * @param top the inset from the top. + * @param left the inset from the left. + * @param bottom the inset from the bottom. + * @param right the inset from the right. + */ + public Insets(int top, int left, int bottom, int right) { + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + this.hash = computeHashCode(); + } + + /** + * Checks whether two insets objects are equal. Two instances + * of <code>Insets</code> are equal if the four integer values + * of the fields <code>top</code>, <code>left</code>, + * <code>bottom</code>, and <code>right</code> are all equal. + * @return <code>true</code> if the two insets are equal; + * otherwise <code>false</code>. + */ + public boolean equals(Object obj) { + if(this == obj) { return true; } + if (obj instanceof Insets) { + Insets insets = (Insets)obj; + return ((top == insets.top) && (left == insets.left) && + (bottom == insets.bottom) && (right == insets.right)); + } + return false; + } + + /** + * Returns the hash code for this Insets. + * + * @return a hash code for this Insets. + */ + public int hashCode() { + return hash; + } + + public String toString() { + return getClass().getName() + "[top=" + top + ",left=" + left + + ",bottom=" + bottom + ",right=" + right + "]"; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + protected int computeHashCode() { + int sum1 = left + bottom; + int sum2 = right + top; + int val1 = sum1 * (sum1 + 1)/2 + left; + int val2 = sum2 * (sum2 + 1)/2 + top; + int sum3 = val1 + val2; + return sum3 * (sum3 + 1)/2 + val2; + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java new file mode 100644 index 000000000..6db0ecfe2 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +public class Point implements Cloneable, PointReadOnly { + int x; + int y; + + public Point(int x, int y) { + this.x=x; + this.y=y; + } + + public Point() { + this(0, 0); + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + public boolean equals(Object obj) { + if(this == obj) { return true; } + if (obj instanceof Point) { + Point p = (Point)obj; + return y == p.y && x == p.x; + } + return false; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + x; + hash = ((hash << 5) - hash) + y; + return hash; + } + + public String toString() { + return new String( x + " / " + y ); + } + + public void setX(int x) { this.x = x; } + public void setY(int y) { this.y = y; } + + public Point translate(Point pd) { + x += pd.x ; + y += pd.y ; + return this; + } + + public Point translate(int dx, int dy) { + x += dx ; + y += dy ; + return this; + } + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PointReadOnly.java b/src/nativewindow/classes/javax/media/nativewindow/util/PointReadOnly.java new file mode 100644 index 000000000..9caaf7fee --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/PointReadOnly.java @@ -0,0 +1,50 @@ +/** + * Copyright 2010 JogAmp Community. 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +/** Immutable Point interface */ +public interface PointReadOnly extends Cloneable { + + int getX(); + + int getY(); + + /** + * Checks whether two points objects are equal. Two instances + * of <code>PointReadOnly</code> are equal if the two components + * <code>y</code> and <code>x</code> are equal. + * @return <code>true</code> if the two points are equal; + * otherwise <code>false</code>. + */ + public boolean equals(Object obj); + + public int hashCode(); + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java new file mode 100644 index 000000000..ba24bc64e --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java @@ -0,0 +1,88 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +public class Rectangle implements Cloneable, RectangleReadOnly { + int x; + int y; + int width; + int height; + + public Rectangle() { + this(0, 0, 0, 0); + } + + public Rectangle(int x, int y, int width, int height) { + this.x=x; + this.y=y; + this.width=width; + this.height=height; + } + + protected Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + public int getX() { return x; } + public int getY() { return y; } + public int getWidth() { return width; } + public int getHeight() { return height; } + public void setX(int x) { this.x = x; } + public void setY(int y) { this.y = y; } + public void setWidth(int width) { this.width = width; } + public void setHeight(int height) { this.height = height; } + + public boolean equals(Object obj) { + if(this == obj) { return true; } + if (obj instanceof Rectangle) { + Rectangle rect = (Rectangle)obj; + return (y == rect.y) && (x == rect.x) && + (height == rect.height) && (width == rect.width); + } + return false; + } + + public int hashCode() { + int sum1 = x + height; + int sum2 = width + y; + int val1 = sum1 * (sum1 + 1)/2 + x; + int val2 = sum2 * (sum2 + 1)/2 + y; + int sum3 = val1 + val2; + return sum3 * (sum3 + 1)/2 + val2; + } + + public String toString() { + return new String("[ "+x+" / "+y+" "+width+" x "+height+" ]"); + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/RectangleReadOnly.java b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleReadOnly.java new file mode 100644 index 000000000..81a5a9f86 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleReadOnly.java @@ -0,0 +1,54 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +/** Immutable Rectangle interface */ +public interface RectangleReadOnly extends Cloneable { + + int getHeight(); + + int getWidth(); + + int getX(); + + int getY(); + + /** + * Checks whether two rect objects are equal. Two instances + * of <code>Rectangle</code> are equal if the four integer values + * of the fields <code>y</code>, <code>x</code>, + * <code>height</code>, and <code>width</code> are all equal. + * @return <code>true</code> if the two rectangles are equal; + * otherwise <code>false</code>. + */ + boolean equals(Object obj); + + int hashCode(); + +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java new file mode 100644 index 000000000..ea098b967 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java @@ -0,0 +1,95 @@ +/** + * Copyright 2010 JogAmp Community. 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.util; + +/** Immutable SurfaceSize Class, consisting of it's read only components:<br> + * <ul> + * <li>{@link javax.media.nativewindow.util.DimensionReadOnly} size in pixels</li> + * <li><code>bits per pixel</code></li> + * </ul> + */ +public class SurfaceSize implements Cloneable { + DimensionReadOnly resolution; + int bitsPerPixel; + + public SurfaceSize(DimensionReadOnly resolution, int bitsPerPixel) { + if(null==resolution || bitsPerPixel<=0) { + throw new IllegalArgumentException("resolution must be set and bitsPerPixel greater 0"); + } + this.resolution=resolution; + this.bitsPerPixel=bitsPerPixel; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + public final DimensionReadOnly getResolution() { + return resolution; + } + + public final int getBitsPerPixel() { + return bitsPerPixel; + } + + public final String toString() { + return new String("[ "+resolution+" x "+bitsPerPixel+" bpp ]"); + } + + /** + * Checks whether two size objects are equal. Two instances + * of <code>SurfaceSize</code> are equal if the two components + * <code>resolution</code> and <code>bitsPerPixel</code> + * are equal. + * @return <code>true</code> if the two dimensions are equal; + * otherwise <code>false</code>. + */ + public final boolean equals(Object obj) { + if(this == obj) { return true; } + if (obj instanceof SurfaceSize) { + SurfaceSize p = (SurfaceSize)obj; + return getResolution().equals(p.getResolution()) && + getBitsPerPixel() == p.getBitsPerPixel(); + } + return false; + } + + public final int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + getResolution().hashCode(); + hash = ((hash << 5) - hash) + getBitsPerPixel(); + return hash; + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/windows/WindowsGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/windows/WindowsGraphicsDevice.java new file mode 100644 index 000000000..5d0129e0d --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/windows/WindowsGraphicsDevice.java @@ -0,0 +1,54 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.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) { + this(AbstractGraphicsDevice.DEFAULT_CONNECTION, unitID); + } + + public WindowsGraphicsDevice(String connection, int unitID) { + super(NativeWindowFactory.TYPE_WINDOWS, connection, unitID); + } + + public Object clone() { + return super.clone(); + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java new file mode 100644 index 000000000..100b6b839 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java @@ -0,0 +1,79 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow.x11; + +import javax.media.nativewindow.*; + +import jogamp.nativewindow.x11.XVisualInfo; + +/** Encapsulates a graphics configuration, or OpenGL pixel format, on + X11 platforms. Objects of this type are returned from {@link + javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration + GraphicsConfigurationFactory.chooseGraphicsConfiguration()} on X11 + platforms when toolkits other than the AWT are being used. */ + +public class X11GraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { + private XVisualInfo info; + + public X11GraphicsConfiguration(X11GraphicsScreen screen, + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + XVisualInfo info) { + super(screen, capsChosen, capsRequested); + this.info = info; + } + + @Override + public Object clone() { + return super.clone(); + } + + public XVisualInfo getXVisualInfo() { + return info; + } + + protected void setXVisualInfo(XVisualInfo info) { + this.info = info; + } + + public long getVisualID() { + return (null!=info)?info.getVisualid():0; + } + + @Override + public String toString() { + return getClass().getSimpleName()+"["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + + ",\n\tchosen " + capabilitiesChosen+ + ",\n\trequested " + capabilitiesRequested+ + "]"; + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java new file mode 100644 index 000000000..48fd63e3c --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -0,0 +1,103 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow.x11; + +import jogamp.nativewindow.Debug; +import jogamp.nativewindow.x11.X11Util; +import javax.media.nativewindow.DefaultGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ToolkitLock; + +/** Encapsulates a graphics device on X11 platforms. + */ + +public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable { + public static final boolean DEBUG = Debug.debug("GraphicsDevice"); + boolean closeDisplay = false; + + /** Constructs a new X11GraphicsDevice corresponding to the given connection and default + * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.<br> + * Note that this is not an open connection, ie no native display handle exist. + * This constructor exist to setup a default device connection. + */ + public X11GraphicsDevice(String connection, int unitID) { + super(NativeWindowFactory.TYPE_X11, connection, unitID); + } + + /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default + * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}. + */ + public X11GraphicsDevice(long display, int unitID) { + // FIXME: derive unitID from connection could be buggy, one DISPLAY for all screens for example.. + super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display); + if(0==display) { + throw new NativeWindowException("null display"); + } + } + + /** + * @param display the Display connection + * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT + */ + public X11GraphicsDevice(long display, int unitID, ToolkitLock locker) { + super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display, locker); + if(0==display) { + throw new NativeWindowException("null display"); + } + } + + public Object clone() { + return super.clone(); + } + + public void setCloseDisplay(boolean close) { + closeDisplay = close; + if(DEBUG && close) { + System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.setCloseDisplay(true): "+this); + } + } + public boolean close() { + // FIXME: shall we respect the unitID ? + if(closeDisplay && 0 != handle) { + if(DEBUG) { + System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this); + } + X11Util.closeDisplay(handle); + handle = 0; + return true; + } + return false; + } +} + diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java new file mode 100644 index 000000000..ffe84cb6d --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -0,0 +1,75 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package javax.media.nativewindow.x11; + +import javax.media.nativewindow.*; +import jogamp.nativewindow.x11.X11Util; + +/** Encapsulates a screen index on X11 + platforms. Objects of this type are passed to {@link + javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration + GraphicsConfigurationFactory.chooseGraphicsConfiguration()} on X11 + platforms when toolkits other than the AWT are being used. */ + +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 static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx) { + if(0==display) throw new NativeWindowException("display is null"); + return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT), screenIdx); + } + + public long getDefaultVisualID() { + // It still could be an AWT hold handle .. + long display = getDevice().getHandle(); + int scrnIdx = X11Util.DefaultScreen(display); + return X11Util.DefaultVisualID(display, scrnIdx); + } + + private static int fetchScreen(X11GraphicsDevice device, int screen) { + // It still could be an AWT hold handle .. + long display = device.getHandle(); + if(X11Util.XineramaEnabled(display)) { + screen = 0; // Xinerama -> 1 screen + } + return screen; + } + + public Object clone() { + return super.clone(); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/Debug.java b/src/nativewindow/classes/jogamp/nativewindow/Debug.java new file mode 100644 index 000000000..f1cd209dc --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/Debug.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2003-2005 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow; + +import java.security.*; + +/** Helper routines for logging and debugging. */ + +public class Debug { + // Some common properties + private static boolean verbose; + private static boolean debugAll; + private static AccessControlContext localACC; + + static { + localACC=AccessController.getContext(); + verbose = isPropertyDefined("nativewindow.verbose", true); + debugAll = isPropertyDefined("nativewindow.debug", true); + if (verbose) { + Package p = Package.getPackage("javax.media.nativewindow"); + System.err.println("NativeWindow specification version " + p.getSpecificationVersion()); + System.err.println("NativeWindow implementation version " + p.getImplementationVersion()); + System.err.println("NativeWindow implementation vendor " + p.getImplementationVendor()); + } + } + + static int getIntProperty(final String property, final boolean jnlpAlias) { + return getIntProperty(property, jnlpAlias, localACC); + } + + public static int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) { + int i=0; + try { + Integer iv = Integer.valueOf(Debug.getProperty(property, jnlpAlias, acc)); + i = iv.intValue(); + } catch (NumberFormatException nfe) {} + return i; + } + + static boolean getBooleanProperty(final String property, final boolean jnlpAlias) { + return getBooleanProperty(property, jnlpAlias, localACC); + } + + public static boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) { + Boolean b = Boolean.valueOf(Debug.getProperty(property, jnlpAlias, acc)); + return b.booleanValue(); + } + + static boolean isPropertyDefined(final String property, final boolean jnlpAlias) { + return isPropertyDefined(property, jnlpAlias, localACC); + } + + public static boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) { + return (Debug.getProperty(property, jnlpAlias, acc) != null) ? true : false; + } + + static String getProperty(final String property, final boolean jnlpAlias) { + return getProperty(property, jnlpAlias, localACC); + } + + public static String getProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) { + String s=null; + if(null!=acc && acc.equals(localACC)) { + s = (String) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + String val=null; + try { + val = System.getProperty(property); + } catch (Exception e) {} + if(null==val && jnlpAlias && !property.startsWith(jnlp_prefix)) { + try { + val = System.getProperty(jnlp_prefix + property); + } catch (Exception e) {} + } + return val; + } + }); + } else { + try { + s = System.getProperty(property); + } catch (Exception e) {} + if(null==s && jnlpAlias && !property.startsWith(jnlp_prefix)) { + try { + s = System.getProperty(jnlp_prefix + property); + } catch (Exception e) {} + } + } + return s; + } + public static final String jnlp_prefix = "jnlp." ; + + public static boolean verbose() { + return verbose; + } + + public static boolean debugAll() { + return debugAll; + } + + public static boolean debug(String subcomponent) { + return debugAll() || isPropertyDefined("nativewindow.debug." + subcomponent, true); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java new file mode 100644 index 000000000..f34b740d4 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package jogamp.nativewindow; + +import javax.media.nativewindow.*; + +public class DefaultGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) { + return new DefaultGraphicsConfiguration(screen, capsChosen, capsRequested); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java new file mode 100644 index 000000000..33e2905a0 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java @@ -0,0 +1,47 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + + +package jogamp.nativewindow; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import com.jogamp.common.jvm.JNILibLoaderBase; + +public class NWJNILibLoader extends JNILibLoaderBase { + + public static void loadNativeWindow(final String ossuffix) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + loadLibrary("nativewindow_"+ossuffix, null, false); + return null; + } + }); + } + +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java new file mode 100644 index 000000000..3db8f32d2 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java @@ -0,0 +1,107 @@ +/* + * 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package jogamp.nativewindow; + +import com.jogamp.common.util.*; +import java.lang.reflect.*; + +import javax.media.nativewindow.*; + +public class NativeWindowFactoryImpl extends NativeWindowFactory { + private static final ToolkitLock nullToolkitLock = new NullToolkitLock(); + + public static ToolkitLock getNullToolkitLock() { + return nullToolkitLock; + } + + // This subclass of NativeWindowFactory handles the case of + // NativeWindows being passed in + protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException { + if (null == winObj) { + throw new IllegalArgumentException("winObj is null"); + } + if (winObj instanceof NativeWindow) { + // Use the NativeWindow directly + return (NativeWindow) winObj; + } + + if (null == config) { + throw new IllegalArgumentException("AbstractGraphicsConfiguration is null with a non NativeWindow object"); + } + + if (NativeWindowFactory.isAWTAvailable() && ReflectionUtil.instanceOf(winObj, AWTComponentClassName)) { + return getAWTNativeWindow(winObj, config); + } + + throw new IllegalArgumentException("Target window object type " + + winObj.getClass().getName() + " is unsupported; expected " + + "javax.media.nativewindow.NativeWindow or "+AWTComponentClassName); + } + + private Constructor nativeWindowConstructor = null; + + private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) { + if (nativeWindowConstructor == null) { + try { + String osType = getNativeWindowType(true); + String windowClassName = null; + + // We break compile-time dependencies on the AWT here to + // make it easier to run this code on mobile devices + + if (osType.equals(TYPE_WINDOWS)) { + windowClassName = "jogamp.nativewindow.jawt.windows.WindowsJAWTWindow"; + } else if (osType.equals(TYPE_MACOSX)) { + windowClassName = "jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow"; + } else if (osType.equals(TYPE_X11)) { + // Assume Linux, Solaris, etc. Should probably test for these explicitly. + windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow"; + } else { + throw new IllegalArgumentException("OS " + getNativeOSName(false) + " not yet supported"); + } + + nativeWindowConstructor = ReflectionUtil.getConstructor( + windowClassName, new Class[] { Object.class, AbstractGraphicsConfiguration.class }, + getClass().getClassLoader()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + try { + return (NativeWindow) nativeWindowConstructor.newInstance(new Object[] { winObj, config }); + } catch (Exception ie) { + throw new IllegalArgumentException(ie); + } + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java new file mode 100644 index 000000000..2056d205e --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java @@ -0,0 +1,55 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock} + * without any locking. Since there is no locking it all, + * it is intrinsically recursive. + */ +public class NullToolkitLock implements ToolkitLock { + + /** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */ + protected NullToolkitLock() { } + + public final void lock() { + if(TRACE_LOCK) { + String msg = "NullToolkitLock.lock()"; + System.err.println(msg); + // Throwable t = new Throwable(msg); + // t.printStackTrace(); + } + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); } + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java new file mode 100644 index 000000000..4c2b1c875 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java @@ -0,0 +1,70 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.ProxySurface; +import javax.media.nativewindow.SurfaceChangeable; + + +public class WrappedSurface extends ProxySurface implements SurfaceChangeable { + protected long surfaceHandle; + + public WrappedSurface(AbstractGraphicsConfiguration cfg) { + this(cfg, 0); + } + + public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle) { + super(cfg); + surfaceHandle=handle; + } + + protected final void invalidateImpl() { + surfaceHandle = 0; + } + + public long getSurfaceHandle() { + return surfaceHandle; + } + + public void setSurfaceHandle(long surfaceHandle) { + this.surfaceHandle=surfaceHandle; + } + + protected int lockSurfaceImpl() { + return LOCK_SUCCESS; + } + + protected void unlockSurfaceImpl() { + } + + public String toString() { + return "WrappedSurface[config " + config + ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) + ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) + ", size " + getWidth() + "x" + getHeight() + "]"; + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java new file mode 100644 index 000000000..834d8a703 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.awt; + +import java.awt.Window; +import java.awt.Component; +import java.awt.Container; +import java.awt.Frame; +import javax.swing.JFrame; +import javax.swing.WindowConstants; + +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.WindowClosingProtocol; +import javax.swing.MenuSelectionManager; + +public class AWTMisc { + + public static JFrame getJFrame(Component c) { + while (c != null && !(c instanceof JFrame)) { + c = c.getParent(); + } + return (JFrame) c; + } + + public static Frame getFrame(Component c) { + while (c != null && !(c instanceof Frame)) { + c = c.getParent(); + } + return (Frame) c; + } + + public static Window getWindow(Component c) { + while (c != null && !(c instanceof Window)) { + c = c.getParent(); + } + return (Window) c; + } + + public static Container getContainer(Component c) { + while (c != null && !(c instanceof Container)) { + c = c.getParent(); + } + return (Container) c; + } + + /** + * Issue this when your non AWT toolkit gains focus to clear AWT menu path + */ + public static void clearAWTMenus() { + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + + public static int AWT2NWClosingOperation(int awtClosingOperation) { + switch (awtClosingOperation) { + case WindowConstants.DISPOSE_ON_CLOSE: + case WindowConstants.EXIT_ON_CLOSE: + return WindowClosingProtocol.DISPOSE_ON_CLOSE; + case WindowConstants.DO_NOTHING_ON_CLOSE: + case WindowConstants.HIDE_ON_CLOSE: + return WindowClosingProtocol.DO_NOTHING_ON_CLOSE; + default: + throw new NativeWindowException("Unhandled AWT Closing Operation: " + awtClosingOperation); + } + } + + public static int getNWClosingOperation(Component c) { + JFrame jf = getJFrame(c); + int op = (null != jf) ? jf.getDefaultCloseOperation() : WindowConstants.DO_NOTHING_ON_CLOSE ; + return AWT2NWClosingOperation(op); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java new file mode 100644 index 000000000..1ac9e1709 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt; + +import javax.media.nativewindow.NativeWindowFactory; +import jogamp.nativewindow.NWJNILibLoader; + +import java.awt.Toolkit; +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class JAWTJNILibLoader extends NWJNILibLoader { + public static void loadAWTImpl() { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + // Make sure that awt.dll is loaded before loading jawt.dll. Otherwise + // a Dialog with "awt.dll not found" might pop up. + // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4481947. + Toolkit.getDefaultToolkit(); + + // Must pre-load JAWT on all non-Mac platforms to + // ensure references from jogl_awt shared object + // will succeed since JAWT shared object isn't in + // default library path + if ( ! NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false) ) ) { + try { + loadLibrary("jawt", null, true); + } catch (Throwable t) { + // It might be ok .. if it's already loaded + if(DEBUG) { + t.printStackTrace(); + } + } + } + return null; + } + }); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTToolkitLock.java new file mode 100644 index 000000000..37e34c01c --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTToolkitLock.java @@ -0,0 +1,54 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.jawt; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()}. + * <br> + * This strategy should only be used if AWT is using the underlying native windowing toolkit + * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call + * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets. + */ +public class JAWTToolkitLock implements ToolkitLock { + + /** Singleton via {@link JAWTUtil#getJAWTToolkitLock()} */ + protected JAWTToolkitLock() {} + + public final void lock() { + if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); } + JAWTUtil.lockToolkit(); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); } + JAWTUtil.unlockToolkit(); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java new file mode 100644 index 000000000..c1c97eece --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package jogamp.nativewindow.jawt; + +import jogamp.nativewindow.*; +import java.awt.EventQueue; + +import javax.media.nativewindow.*; + + +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; +import java.lang.reflect.*; +import java.security.*; +import java.util.ArrayList; +import java.util.Map; + +public class JAWTUtil { + protected static final boolean DEBUG = Debug.debug("JAWT"); + + // See whether we're running in headless mode + private static final boolean headlessMode; + + // Java2D magic .. + private static final Method isQueueFlusherThread; + private static final boolean j2dExist; + + private static final Method sunToolkitAWTLockMethod; + private static final Method sunToolkitAWTUnlockMethod; + private static final boolean hasSunToolkitAWTLock; + + private static final JAWTToolkitLock jawtToolkitLock; + + private static class PrivilegedDataBlob1 { + PrivilegedDataBlob1() { + ok = false; + } + Method sunToolkitAWTLockMethod; + Method sunToolkitAWTUnlockMethod; + boolean ok; + } + + static { + JAWTJNILibLoader.loadAWTImpl(); + JAWTJNILibLoader.loadNativeWindow("awt"); + + headlessMode = GraphicsEnvironment.isHeadless(); + + boolean ok = false; + Class jC = null; + Method m = null; + if (!headlessMode) { + try { + jC = Class.forName("jogamp.opengl.awt.Java2D"); + m = jC.getMethod("isQueueFlusherThread", (Class[])null); + ok = true; + } catch (Exception e) { + } + } + isQueueFlusherThread = m; + j2dExist = ok; + + PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + PrivilegedDataBlob1 d = new PrivilegedDataBlob1(); + try { + final Class sunToolkitClass = Class.forName("sun.awt.SunToolkit"); + d.sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{}); + d.sunToolkitAWTLockMethod.setAccessible(true); + d.sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{}); + d.sunToolkitAWTUnlockMethod.setAccessible(true); + d.ok=true; + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return d; + } + }); + sunToolkitAWTLockMethod = pdb1.sunToolkitAWTLockMethod; + sunToolkitAWTUnlockMethod = pdb1.sunToolkitAWTUnlockMethod; + + boolean _hasSunToolkitAWTLock = false; + if ( pdb1.ok ) { + try { + sunToolkitAWTLockMethod.invoke(null, (Object[])null); + sunToolkitAWTUnlockMethod.invoke(null, (Object[])null); + _hasSunToolkitAWTLock = true; + } catch (Exception e) { + } + } + hasSunToolkitAWTLock = _hasSunToolkitAWTLock; + // hasSunToolkitAWTLock = false; + + jawtToolkitLock = new JAWTToolkitLock(); + + // trigger native AWT toolkit / properties initialization + Map desktophints = null; + try { + if(EventQueue.isDispatchThread()) { + desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + } else { + final ArrayList desktophintsBucket = new ArrayList(1); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + if(null!=_desktophints) { + desktophintsBucket.add(_desktophints); + } + } + }); + desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ; + } + } catch (InterruptedException ex) { + ex.printStackTrace(); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + + if (DEBUG) { + System.err.println("JAWTUtil: Has sun.awt.SunToolkit.awtLock/awtUnlock " + hasSunToolkitAWTLock); + System.err.println("JAWTUtil: Has Java2D " + j2dExist); + System.err.println("JAWTUtil: Is headless " + headlessMode); + int hints = ( null != desktophints ) ? desktophints.size() : 0 ; + System.err.println("JAWTUtil: AWT Desktop hints " + hints); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public static boolean hasJava2D() { + return j2dExist; + } + + public static boolean isJava2DQueueFlusherThread() { + boolean b = false; + if(j2dExist) { + try { + b = ((Boolean)isQueueFlusherThread.invoke(null, (Object[])null)).booleanValue(); + } catch (Exception e) {} + } + return b; + } + + public static boolean isHeadlessMode() { + return headlessMode; + } + + /** + * Locks the AWT's global ReentrantLock.<br> + * + * JAWT's native Lock() function calls SunToolkit.awtLock(), + * which just uses AWT's global ReentrantLock.<br> + */ + public static void awtLock() { + if(hasSunToolkitAWTLock) { + try { + sunToolkitAWTLockMethod.invoke(null, (Object[])null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtLock failed", e); + } + } else { + JAWT.getJAWT().Lock(); + } + } + + /** + * Unlocks the AWT's global ReentrantLock.<br> + * + * JAWT's native Unlock() function calls SunToolkit.awtUnlock(), + * which just uses AWT's global ReentrantLock.<br> + */ + public static void awtUnlock() { + if(hasSunToolkitAWTLock) { + try { + sunToolkitAWTUnlockMethod.invoke(null, (Object[])null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtUnlock failed", e); + } + } else { + JAWT.getJAWT().Unlock(); + } + } + + public static void lockToolkit() throws NativeWindowException { + if(!headlessMode && !isJava2DQueueFlusherThread()) { + awtLock(); + } + } + + public static void unlockToolkit() { + if(!headlessMode && !isJava2DQueueFlusherThread()) { + awtUnlock(); + } + } + + public static JAWTToolkitLock getJAWTToolkitLock() { + return jawtToolkitLock; + } +} + diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java new file mode 100644 index 000000000..67f6fe4b8 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package jogamp.nativewindow.jawt; + +import com.jogamp.common.util.locks.RecursiveLock; + +import java.awt.Component; +import java.awt.Window; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; + +public abstract class JAWTWindow implements NativeWindow { + protected static final boolean DEBUG = JAWTUtil.DEBUG; + + // lifetime: forever + protected Component component; + protected AbstractGraphicsConfiguration config; + + // lifetime: valid after lock, forever until invalidate + protected long drawable; + protected Rectangle bounds; + + public JAWTWindow(Object comp, AbstractGraphicsConfiguration config) { + if (config == null) { + throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null"); + } + this.config = config; + init((Component)comp); + } + + private void init(Component windowObject) throws NativeWindowException { + invalidate(); + this.component = windowObject; + validateNative(); + } + protected abstract void validateNative() throws NativeWindowException; + + protected synchronized void invalidate() { + component = null; + drawable= 0; + bounds = new Rectangle(); + } + + protected final void updateBounds(JAWT_Rectangle jawtBounds) { + bounds.setX(jawtBounds.getX()); + bounds.setY(jawtBounds.getY()); + bounds.setWidth(jawtBounds.getWidth()); + bounds.setHeight(jawtBounds.getHeight()); + } + + /** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */ + public final Rectangle getBounds() { return bounds; } + + public final Component getAWTComponent() { + return component; + } + + // + // SurfaceUpdateListener + // + + public final void surfaceUpdated(Object updater, NativeSurface ns, long when) { + // nop + } + + // + // NativeSurface + // + + private RecursiveLock surfaceLock = new RecursiveLock(); + + protected abstract int lockSurfaceImpl() throws NativeWindowException; + + public final int lockSurface() throws NativeWindowException { + surfaceLock.lock(); + int res = surfaceLock.getRecursionCount() == 0 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; + + if ( LOCK_SURFACE_NOT_READY == res ) { + try { + final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + adevice.lock(); + try { + res = lockSurfaceImpl(); + } finally { + if (LOCK_SURFACE_NOT_READY >= res) { + adevice.unlock(); + } + } + } finally { + if (LOCK_SURFACE_NOT_READY >= res) { + surfaceLock.unlock(); + } + } + } + return res; + } + + protected abstract void unlockSurfaceImpl() throws NativeWindowException; + + public final void unlockSurface() { + surfaceLock.validateLocked(); + + if (surfaceLock.getRecursionCount() == 0) { + final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + try { + unlockSurfaceImpl(); + } finally { + adevice.unlock(); + } + } + surfaceLock.unlock(); + } + + public final boolean isSurfaceLockedByOtherThread() { + return surfaceLock.isLockedByOtherThread(); + } + + public final boolean isSurfaceLocked() { + return surfaceLock.isLocked(); + } + + public final Thread getSurfaceLockOwner() { + return surfaceLock.getOwner(); + } + + public final boolean surfaceSwap() { + return false; + } + + public final void surfaceUpdated(Object updater, NativeWindow window, long when) { } + + public final long getSurfaceHandle() { + return drawable; + } + public final AbstractGraphicsConfiguration getGraphicsConfiguration() { + return config; + } + + public final long getDisplayHandle() { + return config.getScreen().getDevice().getHandle(); + } + + public final int getScreenIndex() { + return config.getScreen().getIndex(); + } + + public final void setSize(int width, int height) { + component.setSize(width, height); + } + + public final int getWidth() { + return component.getWidth(); + } + + public final int getHeight() { + return component.getHeight(); + } + + // + // NativeWindow + // + + public synchronized void destroy() { + if(null!=component) { + if(component instanceof Window) { + ((Window)component).dispose(); + } + } + invalidate(); + } + + public final NativeWindow getParent() { + return null; + } + + public long getWindowHandle() { + return drawable; + } + + public final int getX() { + return component.getX(); + } + + public final int getY() { + return component.getY(); + } + + public Point getLocationOnScreen(Point storage) { + if( 0 != getWindowHandle() ) { + Point d; + // windowLock.lock(); + try { + d = getLocationOnScreenImpl(0, 0); + } finally { + // windowLock.unlock(); + } + if(null!=d) { + if(null!=storage) { + storage.translate(d.getX(),d.getY()); + return storage; + } + return d; + } + // fall through intended .. + } + + if(!Thread.holdsLock(component.getTreeLock())) { + return null; // avoid deadlock .. + } + java.awt.Point awtLOS = component.getLocationOnScreen(); + int dx = (int) ( awtLOS.getX() + .5 ) ; + int dy = (int) ( awtLOS.getY() + .5 ) ; + if(null!=storage) { + return storage.translate(dx, dy); + } + return new Point(dx, dy); + } + protected abstract Point getLocationOnScreenImpl(int x, int y); + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("JAWT-Window["+ + "windowHandle 0x"+Long.toHexString(getWindowHandle())+ + ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+ + ", bounds "+bounds); + if(null!=component) { + sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+ + ", visible "+component.isVisible()); + } else { + sb.append(", component NULL"); + } + sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+ + ",\n\tconfig "+config+ + ",\n\tawtComponent "+getAWTComponent()+"]"); + + return sb.toString(); + } + +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWT_PlatformInfo.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWT_PlatformInfo.java new file mode 100644 index 000000000..40d7b8032 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWT_PlatformInfo.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt; + +/** Marker class for all window system-specific JAWT data structures. */ + +public interface JAWT_PlatformInfo { +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java new file mode 100644 index 000000000..9c29bbd52 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt.macosx; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.Point; + +import jogamp.nativewindow.jawt.JAWT; +import jogamp.nativewindow.jawt.JAWTFactory; +import jogamp.nativewindow.jawt.JAWTWindow; +import jogamp.nativewindow.jawt.JAWT_DrawingSurface; +import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; + +public class MacOSXJAWTWindow extends JAWTWindow { + + public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) { + super(comp, config); + } + + protected void validateNative() throws NativeWindowException { + } + + protected int lockSurfaceImpl() throws NativeWindowException { + int ret = NativeWindow.LOCK_SUCCESS; + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + int res = ds.Lock(); + dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; + if (!dsLocked) { + unlockSurfaceImpl(); + throw new NativeWindowException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = NativeWindow.LOCK_SURFACE_CHANGED; + } + if (firstLock) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + dsi = ds.GetDrawingSurfaceInfo(); + return null; + } + }); + } else { + dsi = ds.GetDrawingSurfaceInfo(); + } + if (dsi == null) { + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + firstLock = false; + macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(); + if (macosxdsi == null) { + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + drawable = macosxdsi.getCocoaViewRef(); + + if (drawable == 0) { + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; + } else { + updateBounds(dsi.getBounds()); + } + return ret; + } + + protected void unlockSurfaceImpl() throws NativeWindowException { + if(null!=ds) { + if (null!=dsi) { + ds.FreeDrawingSurfaceInfo(dsi); + } + if (dsLocked) { + ds.Unlock(); + } + JAWT.getJAWT().FreeDrawingSurface(ds); + } + ds = null; + dsi = null; + macosxdsi = null; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return null; // FIXME + } + + // Variables for lockSurface/unlockSurface + private JAWT_DrawingSurface ds; + private boolean dsLocked; + private JAWT_DrawingSurfaceInfo dsi; + private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; + + // Workaround for instance of 4796548 + private boolean firstLock = true; + +} + diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java new file mode 100644 index 000000000..5ad22807f --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt.windows; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.awt.AWTGraphicsConfiguration; + +/** This class encapsulates the reflection routines necessary to peek + inside a few data structures in the AWT implementation on X11 for + the purposes of correctly enumerating the available visuals. */ + +public class Win32SunJDKReflection { + private static Class win32GraphicsDeviceClass; + private static Class win32GraphicsConfigClass; + private static Method win32GraphicsConfigGetConfigMethod; + private static Method win32GraphicsConfigGetVisualMethod; + private static boolean initted; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + win32GraphicsDeviceClass = Class.forName("sun.awt.Win32GraphicsDevice"); + win32GraphicsConfigClass = Class.forName("sun.awt.Win32GraphicsConfig"); + win32GraphicsConfigGetConfigMethod = win32GraphicsConfigClass.getDeclaredMethod("getConfig", new Class[] { win32GraphicsDeviceClass, int.class }); + win32GraphicsConfigGetConfigMethod.setAccessible(true); + win32GraphicsConfigGetVisualMethod = win32GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {}); + win32GraphicsConfigGetVisualMethod.setAccessible(true); + initted = true; + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + } + + public static GraphicsConfiguration graphicsConfigurationGet(GraphicsDevice device, int pfdID) { + if (!initted) { + return null; + } + + try { + return (GraphicsConfiguration) win32GraphicsConfigGetConfigMethod.invoke(null, new Object[] { device, new Integer(pfdID) }); + } catch (Exception e) { + return null; + } + } + + public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) { + try { + if (config instanceof AWTGraphicsConfiguration) { + return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration()); + } + return 0; + } catch (Exception e) { + return 0; + } + } + + public static int graphicsConfigurationGetPixelFormatID(GraphicsConfiguration config) { + if (!initted) { + return 0; + } + + try { + return ((Integer) win32GraphicsConfigGetVisualMethod.invoke(config, (Object[])null)).intValue(); + } catch (Exception e) { + return 0; + } + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java new file mode 100644 index 000000000..982b94888 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt.windows; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.Point; + +import jogamp.nativewindow.jawt.JAWT; +import jogamp.nativewindow.jawt.JAWTFactory; +import jogamp.nativewindow.jawt.JAWTWindow; +import jogamp.nativewindow.jawt.JAWT_DrawingSurface; +import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; +import jogamp.nativewindow.windows.GDI; + +public class WindowsJAWTWindow extends JAWTWindow { + + public WindowsJAWTWindow(Object comp, AbstractGraphicsConfiguration config) { + super(comp, config); + } + + protected void validateNative() throws NativeWindowException { + } + + @Override + protected synchronized void invalidate() { + super.invalidate(); + windowHandle = 0; + } + + protected int lockSurfaceImpl() throws NativeWindowException { + int ret = NativeWindow.LOCK_SUCCESS; + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + int res = ds.Lock(); + dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; + if (!dsLocked) { + unlockSurfaceImpl(); + throw new NativeWindowException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = LOCK_SURFACE_CHANGED; + } + dsi = ds.GetDrawingSurfaceInfo(); + if (dsi == null) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(); + if (win32dsi == null) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + windowHandle = win32dsi.getHandle(); + drawable = win32dsi.getHdc(); + if (windowHandle == 0 || drawable == 0) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } else { + updateBounds(dsi.getBounds()); + } + return ret; + } + + protected void unlockSurfaceImpl() throws NativeWindowException { + long startTime = 0; + if(null!=ds) { + if (null!=dsi) { + ds.FreeDrawingSurfaceInfo(dsi); + } + if (dsLocked) { + ds.Unlock(); + } + JAWT.getJAWT().FreeDrawingSurface(ds); + } + ds = null; + dsi = null; + win32dsi = null; + } + + @Override + public long getWindowHandle() { + return windowHandle; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); + } + + // Variables for lockSurface/unlockSurface + private JAWT_DrawingSurface ds; + private boolean dsLocked; + private JAWT_DrawingSurfaceInfo dsi; + private JAWT_Win32DrawingSurfaceInfo win32dsi; + + // lifetime: valid after lock, forever until invalidate + protected long windowHandle; +} + diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java new file mode 100644 index 000000000..5d4fa0dad --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java @@ -0,0 +1,60 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.jawt.x11; + +import jogamp.nativewindow.jawt.*; +import jogamp.nativewindow.x11.X11Util; +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}. + * <br> + * This strategy should only be used if AWT is using the underlying native windowing toolkit + * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call + * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets. + */ +public class X11JAWTToolkitLock implements ToolkitLock { + long displayHandle; + + public X11JAWTToolkitLock(long displayHandle) { + this.displayHandle = displayHandle; + } + + public final void lock() { + if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); } + JAWTUtil.lockToolkit(); + X11Util.XLockDisplay(displayHandle); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); } + X11Util.XUnlockDisplay(displayHandle); + JAWTUtil.unlockToolkit(); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java new file mode 100644 index 000000000..2319d6269 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package jogamp.nativewindow.jawt.x11; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.awt.AWTGraphicsDevice; +import javax.media.nativewindow.util.Point; + +import jogamp.nativewindow.jawt.JAWT; +import jogamp.nativewindow.jawt.JAWTFactory; +import jogamp.nativewindow.jawt.JAWTWindow; +import jogamp.nativewindow.jawt.JAWT_DrawingSurface; +import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; +import jogamp.nativewindow.x11.X11Util; + +public class X11JAWTWindow extends JAWTWindow { + + public X11JAWTWindow(Object comp, AbstractGraphicsConfiguration config) { + super(comp, config); + } + + protected void validateNative() throws NativeWindowException { + AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice(); + + if(awtDevice.getHandle() != 0) { + // subtype and handle set already, done + return; + } + + long displayHandle = 0; + + // first try a pre-existing attached native configuration, ie native X11GraphicsDevice + AbstractGraphicsConfiguration aconfig = (null!=config) ? config.getNativeGraphicsConfiguration() : null; + AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null; + AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null; // X11GraphicsDevice + if(null!=adevice) { + displayHandle = adevice.getHandle(); + } + + if(0 == displayHandle) { + displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice()); + } + if(0==displayHandle) { + throw new InternalError("X11JAWTWindow: No X11 Display handle available"); + } + awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle); + } + + protected int lockSurfaceImpl() throws NativeWindowException { + int ret = NativeWindow.LOCK_SUCCESS; + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + int res = ds.Lock(); + dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; + if (!dsLocked) { + unlockSurfaceImpl(); + throw new NativeWindowException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = LOCK_SURFACE_CHANGED; + } + dsi = ds.GetDrawingSurfaceInfo(); + if (dsi == null) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); + if (x11dsi == null) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } + drawable = x11dsi.getDrawable(); + if (drawable == 0) { + unlockSurfaceImpl(); + return LOCK_SURFACE_NOT_READY; + } else { + updateBounds(dsi.getBounds()); + } + return ret; + } + + protected void unlockSurfaceImpl() throws NativeWindowException { + if(null!=ds) { + if (null!=dsi) { + ds.FreeDrawingSurfaceInfo(dsi); + } + if (dsLocked) { + ds.Unlock(); + } + JAWT.getJAWT().FreeDrawingSurface(ds); + } + ds = null; + dsi = null; + x11dsi = null; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + } + + // Variables for lockSurface/unlockSurface + private JAWT_DrawingSurface ds; + private boolean dsLocked; + private JAWT_DrawingSurfaceInfo dsi; + private JAWT_X11DrawingSurfaceInfo x11dsi; + +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java new file mode 100644 index 000000000..b576b0c6b --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +package jogamp.nativewindow.jawt.x11; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.awt.AWTGraphicsConfiguration; + +/** This class encapsulates the reflection routines necessary to peek + inside a few data structures in the AWT implementation on X11 for + the purposes of correctly enumerating the available visuals. */ + +public class X11SunJDKReflection { + private static Class x11GraphicsDeviceClass; + private static Method x11GraphicsDeviceGetDisplayMethod; + private static Class x11GraphicsConfigClass; + private static Method x11GraphicsConfigGetVisualMethod; + private static boolean initted; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice"); + x11GraphicsDeviceGetDisplayMethod = x11GraphicsDeviceClass.getDeclaredMethod("getDisplay", new Class[] {}); + x11GraphicsDeviceGetDisplayMethod.setAccessible(true); + + x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig"); + x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {}); + x11GraphicsConfigGetVisualMethod.setAccessible(true); + initted = true; + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + } + + public static long graphicsDeviceGetDisplay(GraphicsDevice device) { + if (!initted) { + return 0; + } + + try { + return ((Long) x11GraphicsDeviceGetDisplayMethod.invoke(device, (Object[])null)).longValue(); + } catch (Exception e) { + return 0; + } + } + + public static int graphicsConfigurationGetVisualID(AbstractGraphicsConfiguration config) { + try { + if (config instanceof AWTGraphicsConfiguration) { + return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration()); + } + return 0; + } catch (Exception e) { + return 0; + } + } + + public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) { + if (!initted) { + return 0; + } + + try { + return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, (Object[])null)).intValue(); + } catch (Exception e) { + return 0; + } + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java new file mode 100644 index 000000000..d1f5efc88 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java @@ -0,0 +1,240 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.swt; + +import com.jogamp.common.os.Platform; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.eclipse.swt.graphics.GCData; +import org.eclipse.swt.widgets.Control; + +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.windows.WindowsGraphicsDevice; +import javax.media.nativewindow.x11.X11GraphicsDevice; +import com.jogamp.common.util.ReflectionUtil; +import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; + +public class SWTAccessor { + static final Field swt_control_handle; + static final boolean swt_uses_long_handles; + + // X11/GTK, Windows/GDI, .. + static final String str_handle = "handle"; + + // OSX/Cocoa + static final String str_view = "view"; // OSX + static final String str_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"; + + static { + Field f = null; + + if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) { + try { + f = Control.class.getField(str_handle); + } catch (Exception ex) { + throw new NativeWindowException(ex); + } + } + swt_control_handle = f; // maybe null ! + + boolean ulh; + if (null != swt_control_handle) { + ulh = swt_control_handle.getGenericType().toString().equals(long.class.toString()); + } else { + ulh = Platform.is64Bit(); + } + 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) { + 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 }); + } else { + m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { int.class, GCData.class }); + } + } catch (NoSuchMethodException ex) { + throw new NativeWindowException(ex); + } + swt_control_internal_dispose_GC = m; + + Class c=null; + Method m1=null, m2=null, m3=null, m4=null, m5=null; + Class handleType = swt_uses_long_handles ? long.class : int.class ; + if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) { + try { + c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader()); + m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType); + m2 = c.getDeclaredMethod(str_gtk_widget_unrealize, handleType); + m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType); + m4 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType); + m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType); + } catch (Exception ex) { throw new NativeWindowException(ex); } + } + OS_gtk_class = c; + 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; + } + + static Object getIntOrLong(long arg) { + if(swt_uses_long_handles) { + return new Long(arg); + } + return new Integer((int) arg); + } + + static void callStaticMethodL2V(Method m, 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) }); + 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 static boolean isUsingLongHandles() { + return swt_uses_long_handles; + } + + public static long getHandle(Control swtControl) { + long h = 0; + if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + 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) { + throw new NativeWindowException(ex); + } + } + + try { + h = swt_control_handle.getLong(swtControl); + } catch (Exception ex) { + throw new NativeWindowException(ex); + } + return h; + } + + public static void setRealized(Control swtControl, boolean realize) { + long handle = getHandle(swtControl); + + if(null != OS_gtk_class) { + if(realize) { + callStaticMethodL2V(OS_gtk_widget_realize, handle); + } else { + 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); + } + if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) { + return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + } + throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false)); + } + + 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); + } + if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) || + NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + return handle; + } + throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false)); + } + + public static long newGC(Control swtControl, GCData gcData) { + Object o = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC, new Object[] { gcData }); + if(o instanceof Number) { + return ((Number)o).longValue(); + } else { + throw new InternalError("SWT internal_new_GC did not return int or long but "+o.getClass()); + } + } + + public static void disposeGC(Control swtControl, long gc, GCData gcData) { + if(swt_uses_long_handles) { + ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Long(gc), gcData }); + } else { + ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Integer((int)gc), gcData }); + } + } + +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java new file mode 100644 index 000000000..68cf8af45 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java @@ -0,0 +1,87 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow.windows; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.NativeWindowException; + +import javax.media.nativewindow.ProxySurface; + +/** + * GDI Surface implementation which wraps an existing window handle + * allowing the use of HDC via lockSurface()/unlockSurface() protocol. + * The latter will get and release the HDC. + * The size via getWidth()/getHeight() is invalid. + */ +public class GDISurface extends ProxySurface { + protected long windowHandle; + protected long surfaceHandle; + + public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle) { + super(cfg); + if(0 == windowHandle) { + throw new NativeWindowException("Error hwnd 0, werr: "+GDI.GetLastError()); + } + this.windowHandle=windowHandle; + } + + protected final void invalidateImpl() { + windowHandle=0; + surfaceHandle=0; + } + + protected int lockSurfaceImpl() { + if (0 != surfaceHandle) { + throw new InternalError("surface not released"); + } + surfaceHandle = GDI.GetDC(windowHandle); + return (0 != surfaceHandle) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; + } + + protected void unlockSurfaceImpl() { + if (0 == surfaceHandle) { + throw new InternalError("surface not acquired"); + } + GDI.ReleaseDC(windowHandle, surfaceHandle); + surfaceHandle=0; + } + + public long getSurfaceHandle() { + return surfaceHandle; + } + + public String toString() { + return "GDISurface[config "+config+ + ", displayHandle 0x"+Long.toHexString(getDisplayHandle())+ + ", windowHandle 0x"+Long.toHexString(windowHandle)+ + ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+ + ", size "+getWidth()+"x"+getHeight()+"]"; + } + +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java new file mode 100644 index 000000000..afb3daf7c --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java @@ -0,0 +1,45 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow.windows; + +public class RegisteredClass { + long hInstance; + String className; + + RegisteredClass(long hInst, String name) { + hInstance = hInst; + className = name; + } + + public final long getHandle() { return hInstance; } + public final String getName() { return className; } + + @Override + public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+"]"; } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java new file mode 100644 index 000000000..15e0a67cb --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java @@ -0,0 +1,133 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow.windows; + +import jogamp.nativewindow.Debug; +import java.util.ArrayList; +import javax.media.nativewindow.NativeWindowException; + +public class RegisteredClassFactory { + static final boolean DEBUG = Debug.debug("RegisteredClass"); + private static ArrayList sharedClasses = new ArrayList(); + private String classBaseName; + long wndProc; + + private RegisteredClass sharedClass = null; + private int classIter = 0; + private int sharedRefCount = 0; + private Object sync = new Object(); + + /** + * Intended for a JVM shutdown hook, hence little synchronization + */ + public static void shutdownSharedClasses() { + synchronized(sharedClasses) { + for(int i=0; i<sharedClasses.size(); i++) { + RegisteredClass sc = (RegisteredClass) sharedClasses.get(i); + GDI.DestroyWindowClass(sc.getHandle(), sc.getName()); + if(DEBUG) { + System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc); + } + } + sharedClasses.clear(); + } + } + + public RegisteredClassFactory(String classBaseName, long wndProc) { + this.classBaseName = classBaseName; + this.wndProc = wndProc; + } + + public RegisteredClass getSharedClass() throws NativeWindowException { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + long hInstance = GDI.GetApplicationHandle(); + if( 0 == hInstance ) { + throw new NativeWindowException("Error: Null ModuleHandle for Application"); + } + String clazzName = null; + boolean registered = false; + while ( !registered && Integer.MAX_VALUE >= classIter ) { + // Retry with next clazz name, this could happen if more than one JVM is running + clazzName = classBaseName + classIter; + classIter++; + registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc); + } + if( !registered ) { + throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName); + } + sharedClass = new RegisteredClass(hInstance, clazzName); + synchronized(sharedClasses) { + sharedClasses.add(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass); + } + } else if ( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + sharedRefCount++; + } + return sharedClass; + } + + public void releaseSharedClass() { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + return; + } + sharedRefCount--; + if( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + if( 0 == sharedRefCount ) { + GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName()); + synchronized(sharedClasses) { + sharedClasses.remove(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass); + } + sharedClass = null; + sharedRefCount = 0; + classIter = 0; + } + } + } + + public int getSharedRefCount() { + return sharedRefCount; + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java new file mode 100644 index 000000000..b669bce75 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package jogamp.nativewindow.x11; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; + +public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) + throws IllegalArgumentException, NativeWindowException { + + if(!(screen instanceof X11GraphicsScreen)) { + throw new NativeWindowException("Only valid X11GraphicsScreen are allowed"); + } + return new X11GraphicsConfiguration((X11GraphicsScreen)screen, capsChosen, capsRequested, getXVisualInfo(screen, capsChosen)); + } + + public static XVisualInfo getXVisualInfo(AbstractGraphicsScreen screen, long visualID) + { + XVisualInfo xvi_temp = XVisualInfo.create(); + xvi_temp.setVisualid(visualID); + xvi_temp.setScreen(screen.getIndex()); + int num[] = { -1 }; + long display = screen.getDevice().getHandle(); + + XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); + + if(xvis==null || num[0]<1) { + return null; + } + + return XVisualInfo.create(xvis[0]); + } + + public static XVisualInfo getXVisualInfo(AbstractGraphicsScreen screen, CapabilitiesImmutable capabilities) + { + XVisualInfo xv = getXVisualInfoImpl(screen, capabilities, 4 /* TrueColor */); + if(null!=xv) return xv; + return getXVisualInfoImpl(screen, capabilities, 5 /* DirectColor */); + } + + private static XVisualInfo getXVisualInfoImpl(AbstractGraphicsScreen screen, CapabilitiesImmutable capabilities, int c_class) + { + XVisualInfo ret = null; + int[] num = { -1 }; + + XVisualInfo vinfo_template = XVisualInfo.create(); + vinfo_template.setScreen(screen.getIndex()); + vinfo_template.setC_class(c_class); + long display = screen.getDevice().getHandle(); + + XVisualInfo[] vinfos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); + XVisualInfo best=null; + int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits(); + for (int i = 0; vinfos!=null && i < num[0]; i++) { + if ( best == null || + best.getDepth() < vinfos[i].getDepth() ) + { + best = vinfos[i]; + if(rdepth <= best.getDepth()) + break; + } + } + if ( null!=best && ( rdepth <= best.getDepth() || 24 == best.getDepth()) ) { + ret = XVisualInfo.create(best); + } + best = null; + + return ret; + } +} + diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java new file mode 100644 index 000000000..fb0aff10d --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java @@ -0,0 +1,55 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.nativewindow.x11; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing {@link X11Util#XLockDisplay(long)}. + * <br> + * This strategy should not be used in case XInitThreads() is being used, + * or a higher level toolkit lock is required, ie AWT lock. + */ +public class X11ToolkitLock implements ToolkitLock { + long displayHandle; + + public X11ToolkitLock(long displayHandle) { + this.displayHandle = displayHandle; + } + + public final void lock() { + if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); } + X11Util.XLockDisplay(displayHandle); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); } + X11Util.XUnlockDisplay(displayHandle); + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java new file mode 100644 index 000000000..26da46319 --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package jogamp.nativewindow.x11; + +import com.jogamp.common.util.LongObjectHashMap; +import jogamp.nativewindow.Debug; +import jogamp.nativewindow.NWJNILibLoader; + +import javax.media.nativewindow.*; + +import java.nio.Buffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.security.AccessController; +import java.util.ArrayList; +import java.util.List; +import javax.media.nativewindow.util.Point; + +/** + * Contains a thread safe X11 utility to retrieve display connections. + */ +public class X11Util { + private static final boolean DEBUG = Debug.debug("X11Util"); + private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.getBooleanProperty("nativewindow.debug.X11Util.TraceDisplayLifecycle", true, AccessController.getContext()); + + private static volatile String nullDisplayName = null; + private static boolean isFirstX11ActionOnProcess = false; + private static boolean isInit = false; + + private static int setX11ErrorHandlerRecCount = 0; + private static Object setX11ErrorHandlerLock = new Object(); + + public static synchronized void initSingleton(boolean firstX11ActionOnProcess) { + if(!isInit) { + NWJNILibLoader.loadNativeWindow("x11"); + + /** + * Always issue XInitThreads() since we have independent + * off-thread created Display connections able to utilize multithreading, ie NEWT */ + initialize0( true ); + // initialize0( firstX11ActionOnProcess ); + isFirstX11ActionOnProcess = firstX11ActionOnProcess; + + if(DEBUG) { + System.out.println("X11Util.isFirstX11ActionOnProcess: "+isFirstX11ActionOnProcess); + } + isInit = true; + } + } + + public static void setX11ErrorHandler(boolean onoff, boolean quiet) { + synchronized(setX11ErrorHandlerLock) { + if(onoff) { + if(0==setX11ErrorHandlerRecCount) { + setX11ErrorHandler0(true, quiet); + } + setX11ErrorHandlerRecCount++; + } else { + if(0 >= setX11ErrorHandlerRecCount) { + throw new InternalError(); + } + setX11ErrorHandlerRecCount--; + if(0==setX11ErrorHandlerRecCount) { + setX11ErrorHandler0(false, false); + } + } + } + } + + public static boolean isFirstX11ActionOnProcess() { + return isFirstX11ActionOnProcess; + } + + public static void lockDefaultToolkit(long dpyHandle) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + if(!isFirstX11ActionOnProcess) { + X11Util.XLockDisplay(dpyHandle); + } + } + + public static void unlockDefaultToolkit(long dpyHandle) { + if(!isFirstX11ActionOnProcess) { + X11Util.XUnlockDisplay(dpyHandle); + } + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + + public static String getNullDisplayName() { + if(null==nullDisplayName) { // volatile: ok + synchronized(X11Util.class) { + if(null==nullDisplayName) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + long dpy = X11Lib.XOpenDisplay(null); + nullDisplayName = X11Lib.XDisplayString(dpy); + X11Lib.XCloseDisplay(dpy); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + if(DEBUG) { + System.out.println("X11 Display(NULL) <"+nullDisplayName+">"); + } + } + } + } + return nullDisplayName; + } + + private X11Util() {} + + // not exactly thread safe, but good enough for our purpose, + // which is to tag a NamedDisplay uncloseable after creation. + private static Object globalLock = new Object(); + private static LongObjectHashMap globalNamedDisplayMap = new LongObjectHashMap(); + private static List openDisplayList = new ArrayList(); + private static List pendingDisplayList = new ArrayList(); + + public static class NamedDisplay { + String name; + long handle; + int refCount; + boolean unCloseable; + Throwable creationStack; + + protected NamedDisplay(String name, long handle) { + this.name=name; + this.handle=handle; + this.refCount=1; + this.unCloseable=false; + if(DEBUG) { + this.creationStack=new Throwable("NamedDisplay Created at:"); + } else { + this.creationStack=null; + } + } + + public final String getName() { return name; } + public final long getHandle() { return handle; } + public final int getRefCount() { return refCount; } + + public final void setUncloseable(boolean v) { unCloseable = v; } + public final boolean isUncloseable() { return unCloseable; } + + public final Throwable getCreationStack() { return creationStack; } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public String toString() { + return "NamedX11Display["+name+", 0x"+Long.toHexString(handle)+", refCount "+refCount+", unCloseable "+unCloseable+"]"; + } + } + + /** Returns the number of unclosed X11 Displays. + * @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called. + */ + public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) { + int num=0; + if(DEBUG||verbose||pendingDisplayList.size() > 0) { + String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+ + ", open (no close attempt): "+globalNamedDisplayMap.size()+"/"+openDisplayList.size()+ + ", open (no close attempt and uncloseable): "+pendingDisplayList.size()+")" ; + if(DEBUG) { + Exception e = new Exception(msg); + e.printStackTrace(); + } else { + System.err.println(msg); + } + if( openDisplayList.size() > 0) { + X11Util.dumpOpenDisplayConnections(); + } + if( pendingDisplayList.size() > 0 ) { + X11Util.dumpPendingDisplayConnections(); + } + } + + synchronized(globalLock) { + if(realXCloseOpenAndPendingDisplays) { + closePendingDisplayConnections(); + } + openDisplayList.clear(); + pendingDisplayList.clear(); + globalNamedDisplayMap.clear(); + } + return num; + } + + /** + * Closing pending Display connections in reverse order. + * + * @return number of closed Display connections + */ + public static int closePendingDisplayConnections() { + int num=0; + synchronized(globalLock) { + if(DEBUG) { + System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size()); + } + for(int i=pendingDisplayList.size()-1; i>=0; i--) { + NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i); + if(DEBUG) { + System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy); + } + XCloseDisplay(ndpy.getHandle()); + num++; + } + } + return num; + } + + public static int getOpenDisplayConnectionNumber() { + synchronized(globalLock) { + return openDisplayList.size(); + } + } + + public static void dumpOpenDisplayConnections() { + synchronized(globalLock) { + System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size()); + for(int i=0; i<pendingDisplayList.size(); i++) { + NamedDisplay ndpy = (NamedDisplay) openDisplayList.get(i); + System.err.println("X11Util: ["+i+"]: "+ndpy); + if(null!=ndpy) { + Throwable t = ndpy.getCreationStack(); + if(null!=t) { + t.printStackTrace(); + } + } + } + } + } + + public static int getPendingDisplayConnectionNumber() { + synchronized(globalLock) { + return pendingDisplayList.size(); + } + } + + public static void dumpPendingDisplayConnections() { + synchronized(globalLock) { + System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size()); + for(int i=0; i<pendingDisplayList.size(); i++) { + NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i); + System.err.println("X11Util: ["+i+"]: "+ndpy); + if(null!=ndpy) { + Throwable t = ndpy.getCreationStack(); + if(null!=t) { + t.printStackTrace(); + } + } + } + } + } + + public static boolean markDisplayUncloseable(long handle) { + NamedDisplay ndpy; + synchronized(globalLock) { + ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + } + if( null != ndpy ) { + ndpy.setUncloseable(true); + return true; + } + return false; + } + + /** Returns this created named display. */ + public static long createDisplay(String name) { + name = validateDisplayName(name); + long dpy = XOpenDisplay(name); + if(0==dpy) { + throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection. Thread "+Thread.currentThread().getName()); + } + // if you like to debug and synchronize X11 commands .. + // setSynchronizeDisplay(dpy, true); + NamedDisplay namedDpy = new NamedDisplay(name, dpy); + synchronized(globalLock) { + globalNamedDisplayMap.put(dpy, namedDpy); + openDisplayList.add(namedDpy); + pendingDisplayList.add(namedDpy); + } + if(DEBUG) { + Exception e = new Exception("X11Util.Display: Created new "+namedDpy+". Thread "+Thread.currentThread().getName()); + e.printStackTrace(); + } + return namedDpy.getHandle(); + } + + public static void closeDisplay(long handle) { + NamedDisplay namedDpy; + + synchronized(globalLock) { + namedDpy = (NamedDisplay) globalNamedDisplayMap.remove(handle); + if(namedDpy!=null) { + if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); } + } + } + if(null==namedDpy) { + X11Util.dumpPendingDisplayConnections(); + throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped. Thread "+Thread.currentThread().getName()); + } + if(namedDpy.getHandle()!=handle) { + X11Util.dumpPendingDisplayConnections(); + throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") Mapping error: "+namedDpy+". Thread "+Thread.currentThread().getName()); + } + + if(DEBUG) { + Exception e = new Exception("X11Util.Display: Closing new "+namedDpy+". Thread "+Thread.currentThread().getName()); + e.printStackTrace(); + } + + if(!namedDpy.isUncloseable()) { + synchronized(globalLock) { + if(!pendingDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); } + } + XCloseDisplay(namedDpy.getHandle()); + } + } + + public static NamedDisplay getNamedDisplay(long handle) { + synchronized(globalLock) { + return (NamedDisplay) globalNamedDisplayMap.get(handle); + } + } + + /** + * @return If name is null, it returns the previous queried NULL display name, + * otherwise the name. */ + public static String validateDisplayName(String name) { + return ( null == name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) ? getNullDisplayName() : name ; + } + + public static String validateDisplayName(String name, long handle) { + if( ( null==name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) && 0!=handle) { + name = XDisplayString(handle); + } + return validateDisplayName(name); + } + + /******************************* + ** + ** Locked X11Lib wrapped functions + ** + *******************************/ + + public static long XOpenDisplay(String arg0) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + long handle = X11Lib.XOpenDisplay(arg0); + if(TRACE_DISPLAY_LIFECYCLE) { + Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle)); + t.printStackTrace(); + } + return handle; + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XCloseDisplay(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + if(TRACE_DISPLAY_LIFECYCLE) { + Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display)); + t.printStackTrace(); + } + return X11Lib.XCloseDisplay(display); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XFree(Buffer arg0) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return X11Lib.XFree(arg0); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XSync(long display, boolean discard) { + lockDefaultToolkit(display); + try { + return X11Lib.XSync(display, discard); + } finally { + unlockDefaultToolkit(display); + } + } + + public static void XSynchronize(long display, boolean onoff) { + lockDefaultToolkit(display); + try { + X11Lib.XSynchronize(display, onoff); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XineramaEnabled(long display) { + lockDefaultToolkit(display); + try { + return X11Lib.XineramaEnabled(display); + } finally { + unlockDefaultToolkit(display); + } + } + + public static int DefaultScreen(long display) { + lockDefaultToolkit(display); + try { + return X11Lib.DefaultScreen(display); + } finally { + unlockDefaultToolkit(display); + } + } + + public static long RootWindow(long display, int screen_number) { + lockDefaultToolkit(display); + try { + return X11Lib.RootWindow(display, screen_number); + } finally { + unlockDefaultToolkit(display); + } + } + + public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) { + lockDefaultToolkit(display); + try { + return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4); + } finally { + unlockDefaultToolkit(display); + } + } + + public static String XDisplayString(long display) { + lockDefaultToolkit(display); + try { + return X11Lib.XDisplayString(display); + } finally { + unlockDefaultToolkit(display); + } + } + + public static int XFlush(long display) { + lockDefaultToolkit(display); + try { + return X11Lib.XFlush(display); + } finally { + unlockDefaultToolkit(display); + } + } + + public static int XFreePixmap(long display, long arg1) { + lockDefaultToolkit(display); + try { + return X11Lib.XFreePixmap(display, arg1); + } finally { + unlockDefaultToolkit(display); + } + } + + public static long DefaultVisualID(long display, int screen) { + lockDefaultToolkit(display); + try { + return X11Lib.DefaultVisualID(display, screen); + } finally { + unlockDefaultToolkit(display); + } + } + + public static long CreateDummyWindow(long display, int screen_index, long visualID, int width, int height) { + lockDefaultToolkit(display); + try { + return X11Lib.CreateDummyWindow(display, screen_index, visualID, width, height); + } finally { + unlockDefaultToolkit(display); + } + } + + public static void DestroyDummyWindow(long display, long window) { + lockDefaultToolkit(display); + try { + X11Lib.DestroyDummyWindow(display, window); + } finally { + unlockDefaultToolkit(display); + } + } + + public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) { + lockDefaultToolkit(display); + try { + return X11Lib.GetRelativeLocation(display, screen_index, src_win, dest_win, src_x, src_y); + } finally { + unlockDefaultToolkit(display); + } + } + + public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) { + lockDefaultToolkit(display); + try { + return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array); + } finally { + unlockDefaultToolkit(display); + } + } + + public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) { + lockDefaultToolkit(display); + try { + return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset); + } finally { + unlockDefaultToolkit(display); + } + } + + public static void XLockDisplay(long handle) { + if(ToolkitLock.TRACE_LOCK) { + System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle)); + } + X11Lib.XLockDisplay(handle); + } + + public static void XUnlockDisplay(long handle) { + if(ToolkitLock.TRACE_LOCK) { + System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle)); + } + X11Lib.XUnlockDisplay(handle); + } + + private static native void initialize0(boolean firstUIActionOnProcess); + private static native void setX11ErrorHandler0(boolean onoff, boolean quiet); +} diff --git a/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c new file mode 100644 index 000000000..470f03a49 --- /dev/null +++ b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2003 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 + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * 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. + */ + +#include <jawt_md.h> + +#ifdef WIN32 + #define PLATFORM_DSI_SIZE sizeof(JAWT_Win32DrawingSurfaceInfo) +#elif defined(linux) || defined(__sun) || defined(__FreeBSD__) || defined(_HPUX) + #define PLATFORM_DSI_SIZE sizeof(JAWT_X11DrawingSurfaceInfo) +#elif defined(macosx) + #define PLATFORM_DSI_SIZE sizeof(JAWT_MacOSXDrawingSurfaceInfo) +#else + ERROR: port JAWT_DrawingSurfaceInfo.c to your platform +#endif + +JNIEXPORT jobject JNICALL +Java_jogamp_nativewindow_jawt_JAWT_1DrawingSurfaceInfo_platformInfo0(JNIEnv* env, jobject unused, jobject jthis0) { + JAWT_DrawingSurfaceInfo* dsi; + dsi = (*env)->GetDirectBufferAddress(env, jthis0); + if (dsi == NULL) { + (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), + "Argument \"jthis0\" was not a direct buffer"); + return NULL; + } + if (dsi->platformInfo == NULL) { + return NULL; + } + return (*env)->NewDirectByteBuffer(env, dsi->platformInfo, PLATFORM_DSI_SIZE); +} diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c new file mode 100644 index 000000000..e357045d6 --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.c @@ -0,0 +1,57 @@ + +#include "NativewindowCommon.h" + +static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buffer); + (*env)->FatalError(env, buffer); +} + +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); +} + +int NativewindowCommon_init(JNIEnv *env) { + if(NULL==runtimeExceptionClz) { + jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + NativewindowCommon_FatalError(env, "Nativewindow: can't find %s", ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + NativewindowCommon_FatalError(env, "Nativewindow: can't use %s", ClazzNameRuntimeException); + } + return 1; + } + return 0; +} + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h new file mode 100644 index 000000000..5dc5debef --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.h @@ -0,0 +1,15 @@ + +#ifndef NATIVEWINDOW_COMMON_H +#define NATIVEWINDOW_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +int NativewindowCommon_init(JNIEnv *env); + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...); +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); + +#endif diff --git a/src/nativewindow/native/windows/GDImisc.c b/src/nativewindow/native/windows/GDImisc.c new file mode 100644 index 000000000..9bead17ec --- /dev/null +++ b/src/nativewindow/native/windows/GDImisc.c @@ -0,0 +1,242 @@ +#include <jni.h> +#include <stdlib.h> +#include <assert.h> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef WIN32_LEAN_AND_MEAN + +#include <wingdi.h> +#include <stddef.h> + +#ifdef _WIN32 + #ifdef _MSC_VER + /* This typedef is apparently needed for Microsoft compilers before VC8, + and on Windows CE */ + #if (_MSC_VER < 1400) || defined(UNDER_CE) + #ifdef _WIN64 + typedef long long intptr_t; + #else + typedef int intptr_t; + #endif + #endif + #else + #include <inttypes.h> + #endif +#else + #include <inttypes.h> +#endif + +#include <stdio.h> + +#include "NativewindowCommon.h" +#include "jogamp_nativewindow_windows_GDI.h" + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + #define DBG_PRINT(args...) fprintf(stderr, args); +#else + #define DBG_PRINT(args...) +#endif + +static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; +static const char * const ClazzAnyCstrName = "<init>"; +static const char * const ClazzNamePointCstrSignature = "(II)V"; + +static jclass pointClz = NULL; +static jmethodID pointCstr = NULL; + +HINSTANCE GetApplicationHandle() { + return GetModuleHandle(NULL); +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.windows.GDI + * Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc) + * C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc); + */ +JNIEXPORT jboolean JNICALL +Java_jogamp_nativewindow_windows_GDI_CreateWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + WNDCLASS wc; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + ZeroMemory( &wc, sizeof( wc ) ); + if( GetClassInfo( hInstance, clazzName, &wc ) ) { + // registered already + res = JNI_TRUE; + } else { + // register now + ZeroMemory( &wc, sizeof( wc ) ); + wc.style = CS_HREDRAW | CS_VREDRAW ; + wc.lpfnWndProc = (WNDPROC) (intptr_t) wndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor( NULL, IDC_ARROW); + wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = clazzName; + res = ( 0 != RegisterClass( &wc ) ) ? JNI_TRUE : JNI_FALSE ; + } + +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.windows.GDI + * Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className) + * C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className); + */ +JNIEXPORT jboolean JNICALL +Java_jogamp_nativewindow_windows_GDI_DestroyWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + res = ( 0 != UnregisterClass( clazzName, hInstance ) ) ? JNI_TRUE : JNI_FALSE ; + +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; +} + + +/* Java->C glue code: + * Java package: jogamp.nativewindow.windows.GDI + * Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, java.lang.String windowName, int x, int y, int width, int height) + * C function: HANDLE CreateDummyWindow0(HANDLE hInstance, LPCSTR className, LPCSTR windowName, int x, int y, int width, int height); + */ +JNIEXPORT jlong JNICALL +Java_jogamp_nativewindow_windows_GDI_CreateDummyWindow0 + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* wndClassName = NULL; + const TCHAR* wndName = NULL; + DWORD dwExStyle; + DWORD dwStyle; + HWND hWnd; + +#ifdef UNICODE + wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName); + wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); +#else + wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL); + wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); +#endif + + dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dwStyle = WS_OVERLAPPEDWINDOW; + + hWnd = CreateWindowEx( dwExStyle, + wndClassName, + wndName, + dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + x, y, width, height, + NULL, NULL, hInstance, NULL ); + +#ifdef UNICODE + free((void*) wndClassName); + free((void*) wndName); +#else + (*env)->ReleaseStringUTFChars(env, jWndClassName, wndClassName); + (*env)->ReleaseStringUTFChars(env, jWndName, wndName); +#endif + + return (jlong) (intptr_t) hWnd; +} + + +/* + * Class: jogamp_nativewindow_windows_GDI + * Method: initIDs0 + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDI_initIDs0 + (JNIEnv *env, jclass clazz) +{ + if(NativewindowCommon_init(env)) { + jclass c = (*env)->FindClass(env, ClazzNamePoint); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't find %s", ClazzNamePoint); + } + pointClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==pointClz) { + NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't use %s", ClazzNamePoint); + } + pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); + if(NULL==pointCstr) { + NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't fetch %s.%s %s", + ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); + } + } + return JNI_TRUE; +} + +LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +/* + * Class: jogamp_nativewindow_windows_GDI + * Method: getDummyWndProc0 + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_windows_GDI_getDummyWndProc0 + (JNIEnv *env, jclass clazz) +{ + return (jlong) (intptr_t) DummyWndProc; +} + +/* + * Class: jogamp_nativewindow_windows_GDI + * Method: GetRelativeLocation0 + * Signature: (JJII)Ljavax/media/nativewindow/util/Point; + */ +JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDI_GetRelativeLocation0 + (JNIEnv *env, jclass unused, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y) +{ + HWND src_win = (HWND) (intptr_t) jsrc_win; + HWND dest_win = (HWND) (intptr_t) jdest_win; + POINT dest = { src_x, src_y } ; + int res; + + res = MapWindowPoints(src_win, dest_win, &dest, 1); + + DBG_PRINT("*** WindowsWindow: getRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n", + (void*)src_win, src_x, src_y, (void*)dest_win, (int)dest.x, (int)dest.y, res); + + return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest.x, (jint)dest.y); +} + diff --git a/src/nativewindow/native/x11/XineramaHelper.c b/src/nativewindow/native/x11/XineramaHelper.c new file mode 100644 index 000000000..899bbba55 --- /dev/null +++ b/src/nativewindow/native/x11/XineramaHelper.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +/* This file contains a helper routine to be called by Java code to + determine whether the Xinerama extension is in use and therefore to + treat the multiple AWT screens as one large screen. */ + +#include <inttypes.h> +#include <X11/Xlib.h> + +#ifdef __sun + +typedef Status XineramaGetInfoFunc(Display* display, int screen_number, + XRectangle* framebuffer_rects, unsigned char* framebuffer_hints, + int* num_framebuffers); +typedef Status XineramaGetCenterHintFunc(Display* display, int screen_number, + int* x, int* y); + +XineramaGetCenterHintFunc* XineramaSolarisCenterFunc = NULL; +#include <dlfcn.h> + +#else + +#include <X11/extensions/Xinerama.h> + +#endif + +Bool XineramaEnabled(Display* display) { +#ifdef __sun + +#define MAXFRAMEBUFFERS 16 + char* XinExtName = "XINERAMA"; + int32_t major_opcode, first_event, first_error; + Bool gotXinExt = False; + void* libHandle = 0; + unsigned char fbhints[MAXFRAMEBUFFERS]; + XRectangle fbrects[MAXFRAMEBUFFERS]; + int locNumScr = 0; + Bool usingXinerama = False; + + char* XineramaLibName= "libXext.so"; + char* XineramaGetInfoName = "XineramaGetInfo"; + char* XineramaGetCenterHintName = "XineramaGetCenterHint"; + XineramaGetInfoFunc* XineramaSolarisFunc = NULL; + + gotXinExt = XQueryExtension(display, XinExtName, &major_opcode, + &first_event, &first_error); + + if (gotXinExt) { + /* load library, load and run XineramaGetInfo */ + libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL); + if (libHandle != 0) { + XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName); + XineramaSolarisCenterFunc = + (XineramaGetCenterHintFunc*)dlsym(libHandle, + XineramaGetCenterHintName); + if (XineramaSolarisFunc != NULL) { + if ((*XineramaSolarisFunc)(display, 0, &fbrects[0], + &fbhints[0], &locNumScr) != 0) { + + usingXinerama = True; + } + } + dlclose(libHandle); + } + } + return usingXinerama; + +#else + + char* XinExtName = "XINERAMA"; + int32_t major_opcode, first_event, first_error; + Bool gotXinExt = False; + int32_t locNumScr = 0; + + XineramaScreenInfo *xinInfo; + + gotXinExt = XQueryExtension(display, XinExtName, &major_opcode, + &first_event, &first_error); + + if (gotXinExt) { + xinInfo = XineramaQueryScreens(display, &locNumScr); + if (xinInfo != NULL) { + return True; + } + } + return False; + +#endif +} + diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c new file mode 100644 index 000000000..1ced0fff4 --- /dev/null +++ b/src/nativewindow/native/x11/Xmisc.c @@ -0,0 +1,521 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> +#include <errno.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +/* Linux headers don't work properly */ +#define __USE_GNU +#include <dlfcn.h> +#undef __USE_GNU + +/* Current versions of Solaris don't expose the XF86 extensions, + although with the recent transition to Xorg this will probably + happen in an upcoming release */ +#if !defined(__sun) && !defined(_HPUX) +#include <X11/extensions/xf86vmode.h> +#else +/* Need to provide stubs for these */ +Bool XF86VidModeGetGammaRampSize( + Display *display, + int screen, + int* size) +{ + return False; +} + +Bool XF86VidModeGetGammaRamp( + Display *display, + int screen, + int size, + unsigned short *red_array, + unsigned short *green_array, + unsigned short *blue_array) { + return False; +} +Bool XF86VidModeSetGammaRamp( + Display *display, + int screen, + int size, + unsigned short *red_array, + unsigned short *green_array, + unsigned short *blue_array) { + return False; +} +#endif /* defined(__sun) || defined(_HPUX) */ + +/* HP-UX doesn't define RTLD_DEFAULT. */ +#if defined(_HPUX) && !defined(RTLD_DEFAULT) +#define RTLD_DEFAULT NULL +#endif + +#include "NativewindowCommon.h" +#include "jogamp_nativewindow_x11_X11Lib.h" + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + #define DBG_PRINT(args...) fprintf(stderr, args); +#else + #define DBG_PRINT(args...) +#endif + +/* Need to pull this in as we don't have a stub header for it */ +extern Bool XineramaEnabled(Display* display); + +static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; +static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; +static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; +static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer"; +static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; +static const char * const ClazzAnyCstrName = "<init>"; +static const char * const ClazzNamePointCstrSignature = "(II)V"; +static jclass clazzBuffers = NULL; +static jmethodID cstrBuffers = NULL; +static jclass clazzByteBuffer = NULL; +static jclass pointClz = NULL; +static jmethodID pointCstr = NULL; + +static void _initClazzAccess(JNIEnv *env) { + jclass c; + + if(!NativewindowCommon_init(env)) return; + + c = (*env)->FindClass(env, ClazzNameBuffers); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers); + } + clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==clazzBuffers) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers); + } + c = (*env)->FindClass(env, ClazzNameByteBuffer); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer); + } + clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer); + } + + cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, + ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); + if(NULL==cstrBuffers) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s", + ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); + } + + c = (*env)->FindClass(env, ClazzNamePoint); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint); + } + pointClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==pointClz) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint); + } + pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); + if(NULL==pointCstr) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s", + ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); + } +} + +static JNIEnv * x11ErrorHandlerJNIEnv = NULL; +static XErrorHandler origErrorHandler = NULL ; +static int errorHandlerBlocked = 0 ; +static int errorHandlerQuiet = 0 ; + +static int x11ErrorHandler(Display *dpy, XErrorEvent *e) +{ + if(!errorHandlerQuiet) { + fprintf(stderr, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno)); + } +#if 0 + // Since the X11 Error may happen anytime, a exception could mess up the JVM completely. + // Experienced this for remote displays issuing non supported commands, eg. glXCreateContextAttribsARB(..) + // + NativewindowCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", + dpy, e->error_code, strerror(errno)); +#endif + +#if 0 + if(NULL!=origErrorHandler) { + origErrorHandler(dpy, e); + } +#endif + + return 0; +} + +static void x11ErrorHandlerEnable(Display *dpy, int onoff, JNIEnv * env) { + if(errorHandlerBlocked) return; + + if(onoff) { + if(NULL==origErrorHandler) { + x11ErrorHandlerJNIEnv = env; + if(NULL!=dpy) { + XSync(dpy, False); + } + origErrorHandler = XSetErrorHandler(x11ErrorHandler); + } + } else { + if(NULL!=origErrorHandler) { + if(NULL!=dpy) { + XSync(dpy, False); + } + XSetErrorHandler(origErrorHandler); + origErrorHandler = NULL; + } + } +} + +static void x11ErrorHandlerEnableBlocking(JNIEnv * env, int onoff, int quiet) { + errorHandlerBlocked = 0 ; + x11ErrorHandlerEnable(NULL, onoff, env); + errorHandlerBlocked = onoff ; + errorHandlerQuiet = quiet; +} + + +static XIOErrorHandler origIOErrorHandler = NULL; + +static int x11IOErrorHandler(Display *dpy) +{ + fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, XDisplayName(NULL), strerror(errno)); + // NativewindowCommon_FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); + if(NULL!=origIOErrorHandler) { + origIOErrorHandler(dpy); + } + return 0; +} + +static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) { + if(onoff) { + if(NULL==origIOErrorHandler) { + x11ErrorHandlerJNIEnv = env; + origIOErrorHandler = XSetIOErrorHandler(x11IOErrorHandler); + } + } else { + XSetIOErrorHandler(origIOErrorHandler); + origIOErrorHandler = NULL; + } +} + +static int _initialized=0; + +JNIEXPORT void JNICALL +Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) { + if(0==_initialized) { + if( JNI_TRUE == firstUIActionOnProcess ) { + if( 0 == XInitThreads() ) { + fprintf(stderr, "Warning: XInitThreads() failed\n"); + } else { + fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n"); + } + } else { + fprintf(stderr, "Info: XInitThreads() _not_ called for concurrent Thread support\n"); + } + + _initClazzAccess(env); + x11IOErrorHandlerEnable(1, env); + _initialized=1; + } +} + +JNIEXPORT void JNICALL +Java_jogamp_nativewindow_x11_X11Util_setX11ErrorHandler0(JNIEnv *env, jclass _unused, jboolean onoff, jboolean quiet) { + x11ErrorHandlerEnableBlocking(env, ( JNI_TRUE == onoff ) ? 1 : 0, ( JNI_TRUE == quiet ) ? 1 : 0); +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.x11.X11Lib + * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3) + * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); + */ +JNIEXPORT jobject JNICALL +Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { + XVisualInfo * _ptr2 = NULL; + int * _ptr3 = NULL; + XVisualInfo * _res; + int count; + jobject jbyteSource; + jobject jbyteCopy; + if(0==arg0) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + } + if (arg2 != NULL) { + _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0); + } + if (arg3 != NULL) { + _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); + } + x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 1, env); + _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); + x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 0, env); + count = _ptr3[0]; + if (arg3 != NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); + } + if (_res == NULL) return NULL; + + jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo)); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); + + XFree(_res); + + return jbyteCopy; +} + +JNIEXPORT jlong JNICALL +Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) { + jlong r; + if(0==display) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + } + x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); + r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) ); + x11ErrorHandlerEnable((Display *) (intptr_t) display, 0, env); + return r; +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.x11.X11Lib + * Java method: void XLockDisplay(long display) + * C function: void XLockDisplay(Display * display); + */ +JNIEXPORT void JNICALL +Java_jogamp_nativewindow_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { + if(0==display) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + } + XLockDisplay((Display *) (intptr_t) display); +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.x11.X11Lib + * Java method: void XUnlockDisplay(long display) + * C function: void XUnlockDisplay(Display * display); + */ +JNIEXPORT void JNICALL +Java_jogamp_nativewindow_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { + if(0==display) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + } + XUnlockDisplay((Display *) (intptr_t) display); +} + +/* Java->C glue code: + * Java package: jogamp.nativewindow.x11.X11Lib + * Java method: int XCloseDisplay(long display) + * C function: int XCloseDisplay(Display * display); + */ +JNIEXPORT jint JNICALL +Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) { + int _res; + if(0==display) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + } + x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); + _res = XCloseDisplay((Display *) (intptr_t) display); + x11ErrorHandlerEnable(NULL, 0, env); + return _res; +} + +/* + * Class: jogamp_nativewindow_x11_X11Lib + * Method: CreateDummyWindow + * Signature: (JIJII)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow + (JNIEnv *env, jclass unused, jlong display, jint screen_index, jlong visualID, jint width, jint height) +{ + Display * dpy = (Display *)(intptr_t)display; + int scrn_idx = (int)screen_index; + Window windowParent = 0; + Window window = 0; + + XVisualInfo visualTemplate; + XVisualInfo *pVisualQuery = NULL; + Visual *visual = NULL; + int depth; + + XSetWindowAttributes xswa; + unsigned long attrMask; + int n; + + Screen* scrn; + + if(NULL==dpy) { + NativewindowCommon_FatalError(env, "invalid display connection.."); + return 0; + } + + if(visualID<0) { + NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); + return 0; + } + + x11ErrorHandlerEnable(dpy, 1, env); + + scrn = ScreenOfDisplay(dpy, scrn_idx); + + // try given VisualID on screen + memset(&visualTemplate, 0, sizeof(XVisualInfo)); + visualTemplate.screen = scrn_idx; + visualTemplate.visualid = (VisualID)visualID; + pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); + if(pVisualQuery!=NULL) { + visual = pVisualQuery->visual; + depth = pVisualQuery->depth; + visualID = (jlong)pVisualQuery->visualid; + XFree(pVisualQuery); + pVisualQuery=NULL; + } + DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); + + if (visual==NULL) + { + x11ErrorHandlerEnable(dpy, 0, env); + NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); + return 0; + } + + if(pVisualQuery!=NULL) { + XFree(pVisualQuery); + pVisualQuery=NULL; + } + + if(0==windowParent) { + windowParent = XRootWindowOfScreen(scrn); + } + + attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | + CWBorderPixel | CWColormap | CWOverrideRedirect ) ; + + memset(&xswa, 0, sizeof(xswa)); + xswa.override_redirect = False; // use the window manager, always + xswa.border_pixel = 0; + xswa.background_pixmap = None; + xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ + xswa.backing_planes=0; /* planes to be preserved if possible */ + xswa.backing_pixel=0; /* value to use in restoring planes */ + + xswa.colormap = XCreateColormap(dpy, + XRootWindow(dpy, scrn_idx), + visual, + AllocNone); + + window = XCreateWindow(dpy, + windowParent, + 0, 0, + width, height, + 0, // border width + depth, + InputOutput, + visual, + attrMask, + &xswa); + + XSync(dpy, False); + + XSelectInput(dpy, window, 0); // no events + XSync(dpy, False); + + x11ErrorHandlerEnable(dpy, 0, env); + + DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); + + return (jlong) window; +} + + +/* + * Class: jogamp_nativewindow_x11_X11Lib + * Method: DestroyDummyWindow + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow + (JNIEnv *env, jclass unused, jlong display, jlong window) +{ + Display * dpy = (Display *)(intptr_t)display; + Window w = (Window) window; + + if(NULL==dpy) { + NativewindowCommon_throwNewRuntimeException(env, "invalid display connection.."); + return; + } + + x11ErrorHandlerEnable(dpy, 1, env); + XUnmapWindow(dpy, w); + XSync(dpy, False); + XDestroyWindow(dpy, w); + x11ErrorHandlerEnable(dpy, 0, env); +} + +/* + * Class: jogamp_nativewindow_x11_X11Lib + * Method: GetRelativeLocation + * Signature: (JIJJII)Ljavax/media/nativewindow/util/Point; + */ +JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocation0 + (JNIEnv *env, jclass unused, jlong jdisplay, jint screen_index, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y) +{ + Display * dpy = (Display *) (intptr_t) jdisplay; + Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); + Window root = XRootWindowOfScreen(scrn); + Window src_win = (Window)jsrc_win; + Window dest_win = (Window)jdest_win; + int dest_x=-1; + int dest_y=-1; + Window child; + Bool res; + + if( 0 == jdest_win ) { dest_win = root; } + if( 0 == jsrc_win ) { src_win = root; } + + x11ErrorHandlerEnable(dpy, 1, env); + + res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child); + + x11ErrorHandlerEnable(dpy, 0, env); + + DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n", + (void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res); + + return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y); +} + |