From 78b4918b207e16b967e8335fb8ec1b31c706c507 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 2 Feb 2015 02:38:55 +0100
Subject: Bug 682 - Relocating javax.media.opengl.* -> com.jogamp.opengl.*
 (Part 2)

Relocation javax.media.nativewindow.* -> com.jogamp.nativewindow.*
Relocation javax.media.opengl.* -> com.jogamp.opengl.*
---
 .../AbstractGraphicsConfiguration.java             |  81 +++
 .../nativewindow/AbstractGraphicsDevice.java       | 166 +++++
 .../nativewindow/AbstractGraphicsScreen.java       |  57 ++
 .../com/jogamp/nativewindow/Capabilities.java      | 414 ++++++++++++
 .../jogamp/nativewindow/CapabilitiesChooser.java   |  70 ++
 .../jogamp/nativewindow/CapabilitiesImmutable.java | 139 ++++
 .../nativewindow/DefaultCapabilitiesChooser.java   | 172 +++++
 .../nativewindow/DefaultGraphicsConfiguration.java | 134 ++++
 .../jogamp/nativewindow/DefaultGraphicsDevice.java | 253 +++++++
 .../jogamp/nativewindow/DefaultGraphicsScreen.java |  71 ++
 .../nativewindow/GraphicsConfigurationFactory.java | 435 ++++++++++++
 .../com/jogamp/nativewindow/MutableSurface.java    |  44 ++
 .../com/jogamp/nativewindow/NativeSurface.java     | 238 +++++++
 .../jogamp/nativewindow/NativeSurfaceHolder.java   |  41 ++
 .../com/jogamp/nativewindow/NativeWindow.java      | 204 ++++++
 .../jogamp/nativewindow/NativeWindowException.java |  68 ++
 .../jogamp/nativewindow/NativeWindowFactory.java   | 716 ++++++++++++++++++++
 .../jogamp/nativewindow/OffscreenLayerOption.java  |  61 ++
 .../jogamp/nativewindow/OffscreenLayerSurface.java |  86 +++
 .../com/jogamp/nativewindow/ProxySurface.java      | 135 ++++
 .../com/jogamp/nativewindow/ScalableSurface.java   | 107 +++
 .../nativewindow/SurfaceUpdatedListener.java       |  51 ++
 .../com/jogamp/nativewindow/ToolkitLock.java       |  78 +++
 .../jogamp/nativewindow/UpstreamSurfaceHook.java   |  66 ++
 .../com/jogamp/nativewindow/VisualIDHolder.java    | 136 ++++
 .../jogamp/nativewindow/WindowClosingProtocol.java |  73 ++
 .../classes/com/jogamp/nativewindow/package.html   | 101 +++
 .../com/jogamp/nativewindow/util/Dimension.java    | 128 ++++
 .../nativewindow/util/DimensionImmutable.java      |  68 ++
 .../com/jogamp/nativewindow/util/Insets.java       | 136 ++++
 .../jogamp/nativewindow/util/InsetsImmutable.java  |  71 ++
 .../com/jogamp/nativewindow/util/PixelFormat.java  | 739 +++++++++++++++++++++
 .../jogamp/nativewindow/util/PixelFormatUtil.java  | 600 +++++++++++++++++
 .../jogamp/nativewindow/util/PixelRectangle.java   | 194 ++++++
 .../com/jogamp/nativewindow/util/Point.java        | 190 ++++++
 .../jogamp/nativewindow/util/PointImmutable.java   |  63 ++
 .../com/jogamp/nativewindow/util/Rectangle.java    | 237 +++++++
 .../nativewindow/util/RectangleImmutable.java      |  87 +++
 .../com/jogamp/nativewindow/util/SurfaceSize.java  | 113 ++++
 39 files changed, 6823 insertions(+)
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsConfiguration.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsDevice.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsScreen.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/Capabilities.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesChooser.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesImmutable.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DefaultCapabilitiesChooser.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsConfiguration.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/MutableSurface.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/NativeSurface.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/NativeSurfaceHolder.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/NativeWindow.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerOption.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerSurface.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/ProxySurface.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/ScalableSurface.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/SurfaceUpdatedListener.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/ToolkitLock.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHook.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/WindowClosingProtocol.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/package.html
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/Dimension.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/DimensionImmutable.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/Insets.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/InsetsImmutable.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/PixelRectangle.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/PointImmutable.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/Rectangle.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/RectangleImmutable.java
 create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/util/SurfaceSize.java

(limited to 'src/nativewindow/classes/com/jogamp')

diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsConfiguration.java
new file mode 100644
index 000000000..684f1f86a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsConfiguration.java
@@ -0,0 +1,81 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+/** A marker interface describing a graphics configuration, visual, or
+    pixel format in a toolkit-independent manner. */
+public interface AbstractGraphicsConfiguration extends VisualIDHolder, Cloneable {
+    public Object clone();
+
+    /**
+     * Return the screen this graphics configuration is valid for
+     */
+    public AbstractGraphicsScreen getScreen();
+
+    /**
+     * Return the capabilities reflecting this graphics configuration,
+     * which may differ from the capabilities used to choose this configuration.
+     *
+     * @return An immutable instance of the Capabilities to avoid mutation by
+     * the user.
+     */
+    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 multiple screen environment.
+     *
+     * @return An immutable instance of the Capabilities to avoid mutation by
+     * the user.
+     */
+    public CapabilitiesImmutable getRequestedCapabilities();
+
+    /**
+     * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+     * this method shall return the native {@link AbstractGraphicsConfiguration},
+     * otherwise this instance.
+     * @see NativeSurface#getGraphicsConfiguration()
+     */
+    public AbstractGraphicsConfiguration getNativeGraphicsConfiguration();
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsDevice.java
new file mode 100644
index 000000000..7b630b1ea
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsDevice.java
@@ -0,0 +1,166 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import jogamp.nativewindow.Debug;
+
+/** A interface describing a graphics device in a
+    toolkit-independent manner.
+ */
+public interface AbstractGraphicsDevice extends Cloneable {
+    public static final boolean DEBUG = Debug.debug("GraphicsDevice");
+
+    /** 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;
+
+    public Object clone();
+
+    /**
+     * 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 object of this device using {@link #getType() type},
+     * {@link #getConnection() connection} and {@link #getUnitID() unitID} as it's key components.
+     * <p>
+     * The unique ID does not reflect the instance of the device, hence the handle is not included.
+     * The unique ID may be used as a key for semantic device mapping.
+     * </p>
+     * <p>
+     * The returned string object reference is unique using {@link String#intern()}
+     * and hence can be used as a key itself.
+     * </p>
+     */
+    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 com.jogamp.nativewindow.ToolkitLock#lock()}.
+     * The lock implementation must be recursive.
+     */
+    public void lock();
+
+    /**
+     * Optionally unlocking the device, utilizing eg {@link com.jogamp.nativewindow.ToolkitLock#unlock()}.
+     * The lock implementation must be recursive.
+     *
+     * @throws RuntimeException in case the lock is not acquired by this thread.
+     */
+    public void unlock();
+
+    /**
+     * @throws RuntimeException if current thread does not hold the lock
+     */
+    public void validateLocked() throws RuntimeException;
+
+    /**
+     * Optionally [re]opening the device if handle is <code>null</code>.
+     * <p>
+     * The default implementation is a <code>NOP</code>.
+     * </p>
+     * <p>
+     * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
+     * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice}
+     * issue the native open operation in case handle is <code>null</code>.
+     * </p>
+     *
+     * @return true if the handle was <code>null</code> and opening was successful, otherwise false.
+     */
+    public boolean open();
+
+    /**
+     * Optionally closing the device if handle is not <code>null</code>.
+     * <p>
+     * The default implementation {@link ToolkitLock#dispose() dispose} it's {@link ToolkitLock} and sets the handle to <code>null</code>.
+     * </p>
+     * <p>
+     * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
+     * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice}
+     * issue the native close operation or skip it depending on the {@link #isHandleOwner() handles's ownership}.
+     * </p>
+     *
+     * @return true if the handle was not <code>null</code> and closing was successful, otherwise false.
+     */
+    public boolean close();
+
+    /**
+     * @return <code>true</code> if instance owns the handle to issue {@link #close()}, otherwise <code>false</code>.
+     */
+    public boolean isHandleOwner();
+
+    public void clearHandleOwner();
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsScreen.java
new file mode 100644
index 000000000..7767cf9e4
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/AbstractGraphicsScreen.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+/** A interface describing a graphics screen in a
+    toolkit-independent manner.
+ */
+
+public interface AbstractGraphicsScreen extends Cloneable {
+    public Object clone();
+
+    /**
+     * 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/com/jogamp/nativewindow/Capabilities.java b/src/nativewindow/classes/com/jogamp/nativewindow/Capabilities.java
new file mode 100644
index 000000000..fa172b201
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/Capabilities.java
@@ -0,0 +1,414 @@
+/*
+ * 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 com.jogamp.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 {
+  protected final static String na_str = "----" ;
+
+  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 = 0;
+  private int     transparentValueGreen = 0;
+  private int     transparentValueBlue = 0;
+  private int     transparentValueAlpha = 0;
+
+  // Switch for on- or offscreen
+  private boolean onscreen  = true;
+
+  // offscreen bitmap mode
+  private boolean isBitmap  = false;
+
+  /** Creates a Capabilities object. All attributes are in a default
+      state.
+    */
+  public Capabilities() {}
+
+  @Override
+  public Object cloneMutable() {
+    return clone();
+  }
+
+  @Override
+  public Object clone() {
+    try {
+      return super.clone();
+    } catch (final CloneNotSupportedException e) {
+      throw new NativeWindowException(e);
+    }
+  }
+
+  /**
+   * Copies all {@link Capabilities} values
+   * from <code>source</code> into this instance.
+   * @return this instance
+   */
+  public Capabilities copyFrom(final CapabilitiesImmutable other) {
+    redBits = other.getRedBits();
+    greenBits = other.getGreenBits();
+    blueBits = other.getBlueBits();
+    alphaBits = other.getAlphaBits();
+    backgroundOpaque = other.isBackgroundOpaque();
+    onscreen = other.isOnscreen();
+    isBitmap = other.isBitmap();
+    transparentValueRed = other.getTransparentRedValue();
+    transparentValueGreen = other.getTransparentGreenValue();
+    transparentValueBlue = other.getTransparentBlueValue();
+    transparentValueAlpha = other.getTransparentAlphaValue();
+    return this;
+  }
+
+  @Override
+  public int hashCode() {
+    // 31 * x == (x << 5) - x
+    int hash = 31 + this.redBits;
+    hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
+    hash = ((hash << 5) - hash) + ( this.isBitmap ? 1 : 0 );
+    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;
+    return hash;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if(this == obj)  { return true; }
+    if(!(obj instanceof CapabilitiesImmutable)) {
+        return false;
+    }
+    final CapabilitiesImmutable other = (CapabilitiesImmutable)obj;
+    boolean res = other.getRedBits()==redBits &&
+                  other.getGreenBits()==greenBits &&
+                  other.getBlueBits()==blueBits &&
+                  other.getAlphaBits()==alphaBits &&
+                  other.isBackgroundOpaque()==backgroundOpaque &&
+                  other.isOnscreen()==onscreen &&
+                  other.isBitmap()==isBitmap;
+    if(res && !backgroundOpaque) {
+     res = other.getTransparentRedValue()==transparentValueRed &&
+           other.getTransparentGreenValue()==transparentValueGreen &&
+           other.getTransparentBlueValue()==transparentValueBlue &&
+           other.getTransparentAlphaValue()==transparentValueAlpha;
+    }
+
+    return res;
+  }
+
+  /**
+   * Comparing RGBA values only
+   **/
+  @Override
+  public int compareTo(final CapabilitiesImmutable caps) {
+    /**
+    if ( ! ( o instanceof CapabilitiesImmutable ) ) {
+        Class<?> c = (null != o) ? o.getClass() : null ;
+        throw new ClassCastException("Not a CapabilitiesImmutable object, but " + c);
+    }
+    final CapabilitiesImmutable caps = (CapabilitiesImmutable) o; */
+
+    final int rgba = redBits * greenBits * blueBits * ( alphaBits + 1 );
+
+    final int xrgba = caps.getRedBits() * caps.getGreenBits() * caps.getBlueBits() * ( caps.getAlphaBits() + 1 );
+
+    if(rgba > xrgba) {
+        return 1;
+    } else if(rgba < xrgba) {
+        return -1;
+    }
+
+    return 0; // they are equal: RGBA
+  }
+
+  @Override
+  public int getVisualID(final VIDType type) throws NativeWindowException {
+      switch(type) {
+          case INTRINSIC:
+          case NATIVE:
+              return VisualIDHolder.VID_UNDEFINED;
+          default:
+              throw new NativeWindowException("Invalid type <"+type+">");
+      }
+  }
+
+  @Override
+  public final 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(final int redBits) {
+    this.redBits = redBits;
+  }
+
+  @Override
+  public final 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(final int greenBits) {
+    this.greenBits = greenBits;
+  }
+
+  @Override
+  public final 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(final int blueBits) {
+    this.blueBits = blueBits;
+  }
+
+  @Override
+  public final 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.
+   * <p>
+   * <b>Note:</b> If alpha bits are <code>zero</code>, they are set to <code>one</code>
+   * by {@link #setBackgroundOpaque(boolean)} and it's OpenGL specialization <code>GLCapabilities::setSampleBuffers(boolean)</code>.<br/>
+   * Ensure to call this method after the above to ensure a <code>zero</code> value.</br>
+   * The above automated settings takes into account, that the user calls this method to <i>request</i> alpha bits,
+   * not to <i>reflect</i> a current state. Nevertheless if this is the case - call it at last.
+   * </p>
+   */
+  public void setAlphaBits(final int alphaBits) {
+    this.alphaBits = alphaBits;
+  }
+
+  /**
+   * Sets whether the surface shall be opaque or translucent.
+   * <p>
+   * Platform implementations may need an alpha component in the surface (eg. Windows),
+   * or expect pre-multiplied alpha values (eg. X11/XRender).<br>
+   * To unify the experience, this method also invokes {@link #setAlphaBits(int) setAlphaBits(1)}
+   * if {@link #getAlphaBits()} == 0.<br>
+   * Please note that in case alpha is required on the platform the
+   * clear color shall have an alpha lower than 1.0 to allow anything shining through.
+   * </p>
+   * <p>
+   * Mind that translucency may cause a performance penalty
+   * due to the composite work required by the window manager.
+   * </p>
+   */
+  public void setBackgroundOpaque(final boolean opaque) {
+      backgroundOpaque = opaque;
+      if(!opaque && getAlphaBits()==0) {
+          setAlphaBits(1);
+      }
+  }
+
+  @Override
+  public final boolean isBackgroundOpaque() {
+    return backgroundOpaque;
+  }
+
+  /**
+   * Sets whether the surface shall be on- or offscreen.
+   * <p>
+   * Defaults to true.
+   * </p>
+   * <p>
+   * If requesting an offscreen surface without further selection of it's mode,
+   * e.g. FBO, Pbuffer or {@link #setBitmap(boolean) bitmap},
+   * the implementation will choose the best available offscreen mode.
+   * </p>
+   * @param onscreen
+   */
+  public void setOnscreen(final boolean onscreen) {
+    this.onscreen=onscreen;
+  }
+
+  @Override
+  public final boolean isOnscreen() {
+    return onscreen;
+  }
+
+  /**
+   * Requesting offscreen bitmap mode.
+   * <p>
+   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
+   * </p>
+   * <p>
+   * Defaults to false.
+   * </p>
+   * <p>
+   * Requesting offscreen bitmap mode disables the offscreen auto selection.
+   * </p>
+   */
+  public void setBitmap(final boolean enable) {
+    if(enable) {
+      setOnscreen(false);
+    }
+    isBitmap = enable;
+  }
+
+  @Override
+  public boolean isBitmap() {
+    return isBitmap;
+  }
+
+  @Override
+  public final int getTransparentRedValue() { return transparentValueRed; }
+
+  @Override
+  public final int getTransparentGreenValue() { return transparentValueGreen; }
+
+  @Override
+  public final int getTransparentBlueValue() { return transparentValueBlue; }
+
+  @Override
+  public final 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(final 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(final 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(final 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(final int transValueAlpha) { transparentValueAlpha=transValueAlpha; }
+
+  @Override
+  public StringBuilder toString(final StringBuilder sink) {
+      return toString(sink, true);
+  }
+
+  /** Returns a textual representation of this Capabilities
+      object. */
+  @Override
+  public String toString() {
+    final StringBuilder msg = new StringBuilder();
+    msg.append("Caps[");
+    toString(msg);
+    msg.append("]");
+    return msg.toString();
+  }
+
+  /** Return a textual representation of this object's on/off screen state. Use the given StringBuilder [optional]. */
+  protected StringBuilder onoffScreenToString(StringBuilder sink) {
+    if(null == sink) {
+        sink = new StringBuilder();
+    }
+    if(onscreen) {
+        sink.append("on-scr");
+    } else {
+        sink.append("offscr[");
+    }
+    if(isBitmap) {
+        sink.append("bitmap");
+    } else if(onscreen) {
+        sink.append(".");        // no additional off-screen modes besides on-screen
+    } else {
+        sink.append("auto-cfg"); // auto-config off-screen mode
+    }
+    sink.append("]");
+
+    return sink;
+  }
+
+  /** Element separator */
+  protected static final String ESEP = "/";
+  /** Component separator */
+  protected static final String CSEP = ", ";
+
+  protected StringBuilder toString(StringBuilder sink, final boolean withOnOffScreen) {
+    if(null == sink) {
+        sink = new StringBuilder();
+    }
+    sink.append("rgba ").append(redBits).append(ESEP).append(greenBits).append(ESEP).append(blueBits).append(ESEP).append(alphaBits);
+    if(backgroundOpaque) {
+        sink.append(", opaque");
+    } else {
+        sink.append(", trans-rgba 0x").append(toHexString(transparentValueRed)).append(ESEP).append(toHexString(transparentValueGreen)).append(ESEP).append(toHexString(transparentValueBlue)).append(ESEP).append(toHexString(transparentValueAlpha));
+    }
+    if(withOnOffScreen) {
+        sink.append(CSEP);
+        onoffScreenToString(sink);
+    }
+    return sink;
+  }
+
+  protected final String toHexString(final int val) { return Integer.toHexString(val); }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesChooser.java b/src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesChooser.java
new file mode 100644
index 000000000..c33ff5a3f
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/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 com.jogamp.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<? extends CapabilitiesImmutable> available,
+                                int windowSystemRecommendedChoice);
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesImmutable.java
new file mode 100644
index 000000000..780d537b8
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/CapabilitiesImmutable.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 com.jogamp.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 com.jogamp.nativewindow.Capabilities
+ */
+public interface CapabilitiesImmutable extends VisualIDHolder, WriteCloneable, Comparable<CapabilitiesImmutable> {
+
+    /**
+     * Returns the number of bits 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 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 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 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();
+
+    /**
+     * Returns whether an opaque or translucent surface is requested, supported or chosen.
+     * <p>
+     * Default is true, i.e. opaque.
+     * </p>
+     */
+    boolean isBackgroundOpaque();
+
+    /**
+     * Returns whether an on- or offscreen surface is requested, available or chosen.
+     * <p>
+     * Default is true, i.e. onscreen.
+     * </p>
+     * <p>
+     * Mind that an capabilities intance w/ <i>available</i> semantics
+     * may show onscreen, but also the offscreen modes FBO, Pbuffer or {@link #setBitmap(boolean) bitmap}.
+     * This is valid, since one native configuration maybe used for either functionality.
+     * </p>
+     */
+    boolean isOnscreen();
+
+    /**
+     * Returns whether bitmap offscreen mode is requested, available or chosen.
+     * <p>
+     * Default is false.
+     * </p>
+     * <p>
+     * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+     * </p>
+     */
+    boolean isBitmap();
+
+    /**
+     * 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();
+
+    /** 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 StringBuilder [optional]. */
+    StringBuilder toString(StringBuilder sink);
+
+    /** Returns a textual representation of this object. */
+    @Override
+    String toString();
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultCapabilitiesChooser.java
new file mode 100644
index 000000000..33c3f8458
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultCapabilitiesChooser.java
@@ -0,0 +1,172 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import java.util.List;
+
+import com.jogamp.common.util.PropertyAccess;
+
+import jogamp.nativewindow.Debug;
+
+/** <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;
+
+  static {
+      Debug.initSingleton();
+      DEBUG = PropertyAccess.isPropertyDefined("nativewindow.debug.CapabilitiesChooser", true);
+  }
+
+  private final static int NO_SCORE = -9999999;
+  private final static int COLOR_MISMATCH_PENALTY_SCALE     = 36;
+
+  @Override
+  public int chooseCapabilities(final CapabilitiesImmutable desired,
+                                final List<? extends 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
+    final int[] scores = new int[availnum];
+    for (int i = 0; i < availnum; i++) {
+      scores[i] = NO_SCORE;
+    }
+    // Compute score for each
+    for (int i = 0; i < availnum; i++) {
+      final CapabilitiesImmutable cur = available.get(i);
+      if (cur == null) {
+        continue;
+      }
+      if (desired.isOnscreen() && !cur.isOnscreen()) {
+        continue; // requested onscreen, but n/a
+      }
+
+      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++) {
+      final 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(final int score) {
+    if (score < 0) {
+      return -1;
+    }
+    return 1;
+  }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsConfiguration.java
new file mode 100644
index 000000000..d20a6824d
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsConfiguration.java
@@ -0,0 +1,134 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import jogamp.nativewindow.Debug;
+
+public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphicsConfiguration {
+    protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+    private AbstractGraphicsScreen screen;
+    protected CapabilitiesImmutable capabilitiesChosen;
+    protected CapabilitiesImmutable capabilitiesRequested;
+
+    public DefaultGraphicsConfiguration(final AbstractGraphicsScreen screen,
+                                        final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested) {
+        if(null == screen) {
+            throw new IllegalArgumentException("Null screen");
+        }
+        if(null == capsChosen) {
+            throw new IllegalArgumentException("Null chosen caps");
+        }
+        if(null == capsRequested) {
+            throw new IllegalArgumentException("Null requested caps");
+        }
+        this.screen = screen;
+        this.capabilitiesChosen = capsChosen;
+        this.capabilitiesRequested = capsRequested;
+    }
+
+    @Override
+    public Object clone() {
+        try {
+          return super.clone();
+        } catch (final CloneNotSupportedException e) {
+          throw new NativeWindowException(e);
+        }
+    }
+
+    @Override
+    final public AbstractGraphicsScreen getScreen() {
+        return screen;
+    }
+
+    @Override
+    final public CapabilitiesImmutable getChosenCapabilities() {
+        return capabilitiesChosen;
+    }
+
+    @Override
+    final public CapabilitiesImmutable getRequestedCapabilities() {
+        return capabilitiesRequested;
+    }
+
+    @Override
+    public AbstractGraphicsConfiguration getNativeGraphicsConfiguration() {
+        return this;
+    }
+
+    @Override
+    final public int getVisualID(final VIDType type) throws NativeWindowException {
+        return capabilitiesChosen.getVisualID(type);
+    }
+
+    /**
+     * Set the capabilities to a new value.
+     *
+     * <p>
+     * The use case for setting the Capabilities at a later time is
+     * a change or re-validation of capabilities.
+     * </p>
+     * @see com.jogamp.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
+     */
+    protected void setChosenCapabilities(final CapabilitiesImmutable capsChosen) {
+        this.capabilitiesChosen = capsChosen;
+    }
+
+    /**
+     * Set a new screen.
+     *
+     * <p>
+     * the use case for setting a new screen at a later time is
+     * a change of the graphics device in a multi-screen environment.
+     * </p>
+     */
+    protected void setScreen(final AbstractGraphicsScreen screen) {
+        this.screen = screen;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[" + screen +
+                                       ",\n\tchosen    " + capabilitiesChosen+
+                                       ",\n\trequested " + capabilitiesRequested+
+                                       "]";
+    }
+
+    public static String toHexString(final int val) {
+        return "0x"+Integer.toHexString(val);
+    }
+
+    public static String toHexString(final long val) {
+        return "0x"+Long.toHexString(val);
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
new file mode 100644
index 000000000..070b6bb28
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
@@ -0,0 +1,253 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import jogamp.nativewindow.NativeWindowFactoryImpl;
+
+public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice {
+    private static final String separator = "_";
+    private final String type;
+    protected final String connection;
+    protected final int unitID;
+    protected final String uniqueID;
+    protected long handle;
+    protected ToolkitLock toolkitLock;
+
+    /**
+     * Create an instance with the system default {@link ToolkitLock},
+     * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.
+     * @param type
+     */
+    public DefaultGraphicsDevice(final String type, final String connection, final int unitID) {
+        this(type, connection, unitID, 0, NativeWindowFactory.getDefaultToolkitLock(type));
+    }
+
+    /**
+     * Create an instance with the system default {@link ToolkitLock}.
+     * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+     * @param type
+     * @param handle
+     */
+    public DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle) {
+        this(type, connection, unitID, handle, NativeWindowFactory.getDefaultToolkitLock(type, handle));
+    }
+
+    /**
+     * Create an instance with the given {@link ToolkitLock} instance, or <i>null</i> {@link ToolkitLock} if null.
+     * @param type
+     * @param handle
+     * @param locker if null, a non blocking <i>null</i> lock is used.
+     */
+    public DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle, final ToolkitLock locker) {
+        this.type = type;
+        this.connection = connection;
+        this.unitID = unitID;
+        this.uniqueID = getUniqueID(type, connection, unitID);
+        this.handle = handle;
+        this.toolkitLock = null != locker ? locker : NativeWindowFactoryImpl.getNullToolkitLock();
+    }
+
+    @Override
+    public Object clone() {
+        try {
+          return super.clone();
+        } catch (final CloneNotSupportedException e) {
+          throw new NativeWindowException(e);
+        }
+    }
+
+    @Override
+    public final String getType() {
+        return type;
+    }
+
+    @Override
+    public final String getConnection() {
+        return connection;
+    }
+
+    @Override
+    public final int getUnitID() {
+        return unitID;
+    }
+
+    @Override
+    public final String getUniqueID() {
+      return uniqueID;
+    }
+
+    @Override
+    public final long getHandle() {
+        return handle;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+     * </p>
+     *
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock)
+     */
+    @Override
+    public final void lock() {
+        toolkitLock.lock();
+    }
+
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        toolkitLock.validateLocked();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+     * </p>
+     *
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock)
+     */
+    @Override
+    public final void unlock() {
+        toolkitLock.unlock();
+    }
+
+    @Override
+    public boolean open() {
+        return false;
+    }
+
+    @Override
+    public boolean close() {
+        toolkitLock.dispose();
+        if(0 != handle) {
+            handle = 0;
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isHandleOwner() {
+        return false;
+    }
+
+    @Override
+    public void clearHandleOwner() {
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", owner "+isHandleOwner()+", "+toolkitLock+"]";
+    }
+
+    /**
+     * Set the native handle of the underlying native device
+     * and return the previous one.
+     */
+    protected final long setHandle(final long newHandle) {
+        final long oldHandle = handle;
+        handle = newHandle;
+        return oldHandle;
+    }
+
+    protected Object getHandleOwnership() {
+        return null;
+    }
+    protected Object setHandleOwnership(final Object newOwnership) {
+        return null;
+    }
+
+    public static final void swapDeviceHandleAndOwnership(final DefaultGraphicsDevice aDevice1, final DefaultGraphicsDevice aDevice2) {
+        aDevice1.lock();
+        try {
+            aDevice2.lock();
+            try {
+                final long aDevice1Handle = aDevice1.getHandle();
+                final long aDevice2Handle = aDevice2.setHandle(aDevice1Handle);
+                aDevice1.setHandle(aDevice2Handle);
+                final Object aOwnership1 = aDevice1.getHandleOwnership();
+                final Object aOwnership2 = aDevice2.setHandleOwnership(aOwnership1);
+                aDevice1.setHandleOwnership(aOwnership2);
+            } finally {
+                aDevice2.unlock();
+            }
+        } finally {
+            aDevice1.unlock();
+        }
+    }
+
+    /**
+     * Set the internal ToolkitLock, which is used within the
+     * {@link #lock()} and {@link #unlock()} implementation.
+     *
+     * <p>
+     * The current ToolkitLock is being locked/unlocked while swapping the reference,
+     * ensuring no concurrent access can occur during the swap.
+     * </p>
+     *
+     * @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used
+     * @return the previous ToolkitLock instance
+     */
+    protected ToolkitLock setToolkitLock(final ToolkitLock locker) {
+        final ToolkitLock _toolkitLock = toolkitLock;
+        _toolkitLock.lock();
+        try {
+            toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+        } finally {
+            _toolkitLock.unlock();
+        }
+        return _toolkitLock;
+    }
+
+    /**
+     * @return the used ToolkitLock
+     *
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock)
+     */
+    public final ToolkitLock getToolkitLock() {
+         return toolkitLock;
+    }
+
+   /**
+    * Returns a unique String object using {@link String#intern()} for the given arguments,
+    * which object reference itself can be used as a key.
+    */
+    private static String getUniqueID(final String type, final String connection, final int unitID) {
+      return (type + separator + connection + separator + unitID).intern();
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
new file mode 100644
index 000000000..63c79af55
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
@@ -0,0 +1,71 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+public class DefaultGraphicsScreen implements Cloneable, AbstractGraphicsScreen {
+    private final AbstractGraphicsDevice device;
+    private final int idx;
+
+    public DefaultGraphicsScreen(final AbstractGraphicsDevice device, final int idx) {
+        this.device = device;
+        this.idx = idx;
+    }
+
+    public static AbstractGraphicsScreen createDefault(final String type) {
+        return new DefaultGraphicsScreen(new DefaultGraphicsDevice(type, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT), 0);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+          return super.clone();
+        } catch (final CloneNotSupportedException e) {
+          throw new NativeWindowException(e);
+        }
+    }
+
+    @Override
+    public AbstractGraphicsDevice getDevice() {
+        return device;
+    }
+
+    @Override
+    public int getIndex() {
+      return idx;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"["+device+", idx "+idx+"]";
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
new file mode 100644
index 000000000..929af054e
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
@@ -0,0 +1,435 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.ReflectionUtil;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.DefaultGraphicsConfigurationFactoryImpl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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;
+
+    private static class DeviceCapsType {
+        public final Class<?> deviceType;
+        public final Class<?> capsType;
+        private final int hash32;
+
+        public DeviceCapsType(final Class<?> deviceType, final Class<?> capsType) {
+            this.deviceType = deviceType;
+            this.capsType = capsType;
+
+            // 31 * x == (x << 5) - x
+            int hash32 = 31 + deviceType.hashCode();
+            hash32 = ((hash32 << 5) - hash32) + capsType.hashCode();
+            this.hash32 = hash32;
+        }
+
+        @Override
+        public final int hashCode() {
+            return hash32;
+        }
+
+        @Override
+        public final boolean equals(final Object obj) {
+            if(this == obj)  { return true; }
+            if (obj instanceof DeviceCapsType) {
+                final DeviceCapsType dct = (DeviceCapsType)obj;
+                return deviceType == dct.deviceType && capsType == dct.capsType;
+            }
+            return false;
+        }
+
+        @Override
+        public final String toString() {
+            return "DeviceCapsType["+deviceType.getName()+", "+capsType.getName()+"]";
+        }
+
+    }
+
+    private static final Map<DeviceCapsType, GraphicsConfigurationFactory> registeredFactories;
+    private static final DeviceCapsType defaultDeviceCapsType;
+    static boolean initialized = false;
+
+    static {
+        DEBUG = Debug.debug("GraphicsConfiguration");
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName()+" - Info: GraphicsConfigurationFactory.<init>");
+            // Thread.dumpStack();
+        }
+        registeredFactories = Collections.synchronizedMap(new HashMap<DeviceCapsType, GraphicsConfigurationFactory>());
+        defaultDeviceCapsType = new DeviceCapsType(AbstractGraphicsDevice.class, CapabilitiesImmutable.class);
+    }
+
+    public static synchronized void initSingleton() {
+        if(!initialized) {
+            initialized = true;
+
+            if(DEBUG) {
+                System.err.println(Thread.currentThread().getName()+" - GraphicsConfigurationFactory.initSingleton()");
+            }
+
+            // 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(defaultDeviceCapsType.deviceType, defaultDeviceCapsType.capsType, new DefaultGraphicsConfigurationFactoryImpl());
+
+            if (NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+                try {
+                    ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
+                                                    "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+                } catch (final Exception e) {
+                    throw new RuntimeException(e);
+                }
+                if(NativeWindowFactory.isAWTAvailable()) {
+                    try {
+                        ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.awt.X11AWTGraphicsConfigurationFactory",
+                                                        "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+                    } catch (final Exception e) { /* n/a */ }
+                }
+            }
+        }
+    }
+
+    public static synchronized void shutdown() {
+        if(initialized) {
+            initialized = false;
+            if(DEBUG) {
+                System.err.println(Thread.currentThread().getName()+" - GraphicsConfigurationFactory.shutdown()");
+            }
+            registeredFactories.clear();
+        }
+    }
+
+    protected static String getThreadName() {
+        return Thread.currentThread().getName();
+    }
+
+    protected static String toHexString(final int val) {
+        return "0x" + Integer.toHexString(val);
+    }
+
+    protected static String toHexString(final long val) {
+        return "0x" + Long.toHexString(val);
+    }
+
+    /** Creates a new NativeWindowFactory instance. End users do not
+        need to call this method. */
+    protected GraphicsConfigurationFactory() {
+    }
+
+    /**
+     * Returns the graphics configuration factory for use with the
+     * given device and capability.
+     *
+     * @see #getFactory(Class, Class)
+     */
+    public static GraphicsConfigurationFactory getFactory(final AbstractGraphicsDevice device, final CapabilitiesImmutable caps) {
+        if (device == null) {
+            throw new IllegalArgumentException("null device");
+        }
+        if (caps == null) {
+            throw new IllegalArgumentException("null caps");
+        }
+        return getFactory(device.getClass(), caps.getClass());
+    }
+
+    /**
+     * Returns the graphics configuration factory for use with the
+     * given device and capability class.
+     * <p>
+     * Note: Registered device types maybe classes or interfaces, where capabilities types are interfaces only.
+     * </p>
+     *
+     * <p>
+     * Pseudo code for finding a suitable factory is:
+     * <pre>
+        For-All devT := getTopDownDeviceTypes(deviceType)
+            For-All capsT := getTopDownCapabilitiesTypes(capabilitiesType)
+               f = factory.get(devT, capsT);
+               if(f) { return f; }
+            end
+        end
+     * </pre>
+     * </p>
+     *
+     * @param deviceType the minimum capabilities class type accepted, must implement or extend {@link AbstractGraphicsDevice}
+     * @param capabilitiesType the minimum capabilities class type accepted, must implement or extend {@link CapabilitiesImmutable}
+     *
+     * @throws IllegalArgumentException if the deviceType does not implement {@link AbstractGraphicsDevice} or
+     *                                  capabilitiesType does not implement {@link CapabilitiesImmutable}
+     */
+    public static GraphicsConfigurationFactory getFactory(final Class<?> deviceType, final Class<?> capabilitiesType)
+        throws IllegalArgumentException, NativeWindowException
+    {
+        if (!(defaultDeviceCapsType.deviceType.isAssignableFrom(deviceType))) {
+            throw new IllegalArgumentException("Given class must implement AbstractGraphicsDevice");
+        }
+        if (!(defaultDeviceCapsType.capsType.isAssignableFrom(capabilitiesType))) {
+            throw new IllegalArgumentException("Given capabilities class must implement CapabilitiesImmutable");
+        }
+        if(DEBUG) {
+            ExceptionUtils.dumpStack(System.err);
+            System.err.println("GraphicsConfigurationFactory.getFactory: "+deviceType.getName()+", "+capabilitiesType.getName());
+            dumpFactories();
+        }
+
+        final List<Class<?>> deviceTypes = getAllAssignableClassesFrom(defaultDeviceCapsType.deviceType, deviceType, false);
+        if(DEBUG) {
+            System.err.println("GraphicsConfigurationFactory.getFactory() deviceTypes: " + deviceTypes);
+        }
+        final List<Class<?>> capabilitiesTypes = getAllAssignableClassesFrom(defaultDeviceCapsType.capsType, capabilitiesType, true);
+        if(DEBUG) {
+            System.err.println("GraphicsConfigurationFactory.getFactory() capabilitiesTypes: " + capabilitiesTypes);
+        }
+        for(int j=0; j<deviceTypes.size(); j++) {
+            final Class<?> interfaceDevice = deviceTypes.get(j);
+            for(int i=0; i<capabilitiesTypes.size(); i++) {
+                final Class<?> interfaceCaps = capabilitiesTypes.get(i);
+                final DeviceCapsType dct = new DeviceCapsType(interfaceDevice, interfaceCaps);
+                final GraphicsConfigurationFactory factory = registeredFactories.get(dct);
+                if (factory != null) {
+                    if(DEBUG) {
+                        System.err.println("GraphicsConfigurationFactory.getFactory() found "+dct+" -> "+factory);
+                    }
+                    return factory;
+                }
+            }
+        }
+        // Return the default
+        final GraphicsConfigurationFactory factory = registeredFactories.get(defaultDeviceCapsType);
+        if(DEBUG) {
+            System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+defaultDeviceCapsType+" -> "+factory);
+        }
+        return factory;
+    }
+    private static ArrayList<Class<?>> getAllAssignableClassesFrom(final Class<?> superClassOrInterface, final Class<?> fromClass, final boolean interfacesOnly) {
+        // Using a todo list avoiding a recursive loop!
+        final ArrayList<Class<?>> inspectClasses  = new ArrayList<Class<?>>();
+        final ArrayList<Class<?>> resolvedInterfaces = new ArrayList<Class<?>>();
+        inspectClasses.add(fromClass);
+        for(int j=0; j<inspectClasses.size(); j++) {
+            final Class<?> clazz = inspectClasses.get(j);
+            getAllAssignableClassesFrom(superClassOrInterface, clazz, interfacesOnly, resolvedInterfaces, inspectClasses);
+        }
+        return resolvedInterfaces;
+    }
+    private static void getAllAssignableClassesFrom(final Class<?> superClassOrInterface, final Class<?> fromClass, final boolean interfacesOnly, final List<Class<?>> resolvedInterfaces, final List<Class<?>> inspectClasses) {
+        final ArrayList<Class<?>> types = new ArrayList<Class<?>>();
+        if( superClassOrInterface.isAssignableFrom(fromClass) && !resolvedInterfaces.contains(fromClass)) {
+            if( !interfacesOnly || fromClass.isInterface() ) {
+                types.add(fromClass);
+            }
+        }
+        types.addAll(Arrays.asList(fromClass.getInterfaces()));
+
+        for(int i=0; i<types.size(); i++) {
+            final Class<?> iface = types.get(i);
+            if( superClassOrInterface.isAssignableFrom(iface) && !resolvedInterfaces.contains(iface) ) {
+                resolvedInterfaces.add(iface);
+                if( !superClassOrInterface.equals(iface) && !inspectClasses.contains(iface) ) {
+                    inspectClasses.add(iface); // safe add to todo list, avoiding a recursive nature
+                }
+            }
+        }
+        final Class<?> parentClass = fromClass.getSuperclass();
+        if( null != parentClass && superClassOrInterface.isAssignableFrom(parentClass) && !inspectClasses.contains(parentClass) ) {
+            inspectClasses.add(parentClass); // safe add to todo list, avoiding a recursive nature
+        }
+    }
+    private static void dumpFactories() {
+        final Set<DeviceCapsType> dcts = registeredFactories.keySet();
+        int i=0;
+        for(final Iterator<DeviceCapsType> iter = dcts.iterator(); iter.hasNext(); ) {
+            final DeviceCapsType dct = iter.next();
+            System.err.println("Factory #"+i+": "+dct+" -> "+registeredFactories.get(dct));
+            i++;
+        }
+    }
+
+    /**
+     * Registers a GraphicsConfigurationFactory handling
+     * the given graphics device and capability class.
+     * <p>
+     * This does not need to be called by end users, only implementors of new
+     * GraphicsConfigurationFactory subclasses.
+     * </p>
+     *
+     * <p>
+     * Note: Registered device types maybe classes or interfaces, where capabilities types are interfaces only.
+     * </p>
+     *
+     * <p>See {@link #getFactory(Class, Class)} for a description of the find algorithm.</p>
+     *
+     * @param deviceType the minimum capabilities class type accepted, must implement or extend interface {@link AbstractGraphicsDevice}
+     * @param capabilitiesType the minimum capabilities class type accepted, must extend interface {@link CapabilitiesImmutable}
+     * @return the previous registered factory, or null if none
+     * @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
+     */
+    protected static GraphicsConfigurationFactory registerFactory(final Class<?> abstractGraphicsDeviceImplementor, final Class<?> capabilitiesType, final GraphicsConfigurationFactory factory)
+        throws IllegalArgumentException
+    {
+        if (!(defaultDeviceCapsType.deviceType.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
+            throw new IllegalArgumentException("Given device class must implement AbstractGraphicsDevice");
+        }
+        if (!(defaultDeviceCapsType.capsType.isAssignableFrom(capabilitiesType))) {
+            throw new IllegalArgumentException("Given capabilities class must implement CapabilitiesImmutable");
+        }
+        final DeviceCapsType dct = new DeviceCapsType(abstractGraphicsDeviceImplementor, capabilitiesType);
+        final GraphicsConfigurationFactory prevFactory;
+        if(null == factory) {
+            prevFactory = registeredFactories.remove(dct);
+            if(DEBUG) {
+                System.err.println("GraphicsConfigurationFactory.registerFactory() remove "+dct+
+                                   ", deleting: "+prevFactory);
+            }
+        } else {
+            prevFactory = registeredFactories.put(dct, factory);
+            if(DEBUG) {
+                System.err.println("GraphicsConfigurationFactory.registerFactory() put "+dct+" -> "+factory+
+                                   ", overridding: "+prevFactory);
+            }
+        }
+        return prevFactory;
+    }
+
+    /**
+     * <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
+     * com.jogamp.nativewindow.awt.AWTGraphicsDevice AWTGraphicsDevice} objects and returns {@link
+     * com.jogamp.nativewindow.awt.AWTGraphicsConfiguration AWTGraphicsConfiguration} objects. On
+     * X11 platforms where the AWT is not in use, it also accepts
+     * {@link com.jogamp.nativewindow.x11.X11GraphicsDevice
+     * X11GraphicsDevice} objects and returns {@link
+     * com.jogamp.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
+     * @param nativeVisualID if not {@link VisualIDHolder#VID_UNDEFINED} it reflects a pre-chosen visualID of the native platform's windowing system.
+     * @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 com.jogamp.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
+     * @see com.jogamp.nativewindow.DefaultGraphicsConfiguration#setChosenCapabilities(Capabilities caps)
+     */
+    public final AbstractGraphicsConfiguration
+        chooseGraphicsConfiguration(final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
+                                    final CapabilitiesChooser chooser,
+                                    final AbstractGraphicsScreen screen, final int nativeVisualID)
+        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");
+        }
+        final AbstractGraphicsDevice device =  screen.getDevice();
+        if(null==device) {
+            throw new NativeWindowException("Screen's Device is null");
+        }
+        device.lock();
+        try {
+            return chooseGraphicsConfigurationImpl(capsChosen, capsRequested, chooser, screen, nativeVisualID);
+        } finally {
+            device.unlock();
+        }
+    }
+
+    protected abstract AbstractGraphicsConfiguration
+        chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+                                        CapabilitiesChooser chooser, AbstractGraphicsScreen screen, int nativeVisualID)
+        throws IllegalArgumentException, NativeWindowException;
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/MutableSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/MutableSurface.java
new file mode 100644
index 000000000..7686f270b
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/MutableSurface.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2012 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;
+
+/**
+ * Provides a {@link NativeSurface} with a mutable <code>surfaceHandle</code>
+ * via {@link #setSurfaceHandle(long)}.
+ *
+ * @see NativeSurface
+ */
+public interface MutableSurface extends NativeSurface {
+
+    /**
+     * Sets the surface handle which is created outside of this implementation.
+     */
+    public void setSurfaceHandle(long surfaceHandle);
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeSurface.java
new file mode 100644
index 000000000..ce0699c56
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeSurface.java
@@ -0,0 +1,238 @@
+/**
+ * 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;
+
+/**
+ * Provides low-level information required for
+ * hardware-accelerated rendering using a surface in a platform-independent manner.
+ * <p>
+ * All values of this interface are represented in pixel units, if not stated otherwise.
+ * See {@link NativeWindow}.
+ * </p>
+ * <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, {@value}. */
+  public static final int LOCK_SURFACE_UNLOCKED = 0;
+
+  /** Returned by {@link #lockSurface()} if the surface is not ready to be locked, {@value}. */
+  public static final int LOCK_SURFACE_NOT_READY = 1;
+
+  /** Returned by {@link #lockSurface()} if the surface is locked, but has changed, {@value}. */
+  public static final int LOCK_SURFACE_CHANGED = 2;
+
+  /** Returned by {@link #lockSurface()} if the surface is locked, and is unchanged, {@value}. */
+  public static final int LOCK_SUCCESS = 3;
+
+  /**
+   * Lock the surface of this native window.
+   * <p>
+   * The surface handle shall be valid after a successfull call,
+   * ie return a value other than {@link #LOCK_SURFACE_UNLOCKED} and {@link #LOCK_SURFACE_NOT_READY},
+   * which is
+   * <pre>
+   *    boolean ok = LOCK_SURFACE_NOT_READY < lockSurface();
+   * </pre>
+   * </p>
+   * <p>
+   * The caller may need to take care of the result {@link #LOCK_SURFACE_CHANGED},
+   * where the surface handle is valid but has changed.
+   * </p>
+   * <p>
+   * This call is blocking until the surface has been locked
+   * or a timeout is reached. The latter will throw a runtime exception.
+   * </p>
+   * <p>
+   * This call allows recursion from the same thread.
+   * </p>
+   * <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>
+   * <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
+   * @throws NativeWindowException if native locking failed, maybe platform related
+   *
+   * @see com.jogamp.common.util.locks.RecursiveLock
+   */
+  public int lockSurface() throws NativeWindowException, RuntimeException;
+
+  /**
+   * 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>
+   *
+   * The implementation shall be fail safe, i.e. tolerant in case the native resources
+   * are already released / unlocked. In this case the implementation shall simply ignore the call.
+   *
+   * @see #lockSurface
+   * @see com.jogamp.common.util.locks.RecursiveLock
+   */
+  public void unlockSurface();
+
+  /**
+   * Query if surface is locked by another thread, i.e. not the current one.
+   * <br>
+   * Convenient shortcut for:
+   * <pre>
+   *   final Thread o = getSurfaceLockOwner();
+   *   if( null != o && Thread.currentThread() != o ) { .. }
+   * </pre>
+   */
+  public boolean isSurfaceLockedByOtherThread();
+
+  /**
+   * 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 if double buffering is enabled.
+   * <p>
+   * The implementation may itself apply the swapping,
+   * in which case true shall be returned.
+   * </p>
+   *
+   * @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();
+
+  /** Appends the given {@link SurfaceUpdatedListener} to the end of the list. */
+  public void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+  /**
+   * Inserts the given {@link SurfaceUpdatedListener} at the
+   * specified position in the list.<br>
+   *
+   * @param index Position where the listener will be inserted.
+   * Should be within (0 <= index && index <= size()).
+   * An index value of -1 is interpreted as the end of the list, size().
+   * @param l The listener object to be inserted
+   * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+   */
+  public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
+
+  /** Remove the specified {@link SurfaceUpdatedListener} from the list. */
+  public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+  /**
+   * Returns the handle to the surface for this NativeSurface. <P>
+   *
+   * 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 width of the client area excluding insets (window decorations) in pixel units.
+   * @return width of the client area in pixel units
+   * @see NativeWindow#getWidth()
+   * @see #convertToWindowUnits(int[])
+   */
+  public int getSurfaceWidth();
+
+  /**
+   * Returns the height of the client area excluding insets (window decorations) in pixel units.
+   * @return height of the client area in pixel units
+   * @see NativeWindow#getHeight()
+   * @see #convertToWindowUnits(int[])
+   */
+  public int getSurfaceHeight();
+
+  /**
+   * Converts the given pixel units into window units <i>in place</i>.
+   * @param pixelUnitsAndResult int[2] storage holding the pixel units for the x- and y-coord to convert
+   *                             and the resulting values.
+   * @return result int[2] storage pixelUnitsAndResult for chaining holding the converted values
+   * @see ScalableSurface
+   */
+  public int[] convertToWindowUnits(final int[] pixelUnitsAndResult);
+
+  /**
+   * Converts the given window units into pixel units <i>in place</i>.
+   * @param windowUnitsAndResult int[2] storage holding the window units for the x- and y-coord to convert
+   *                             and the resulting values.
+   * @return result int[2] storage windowUnitsAndResult for chaining holding the converted values
+   * @see ScalableSurface
+   */
+  public int[] convertToPixelUnits(final int[] windowUnitsAndResult);
+
+  /**
+   * Returns the graphics configuration corresponding to this window.
+   * <p>
+   * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+   * this method shall return the native {@link AbstractGraphicsConfiguration} via {@link AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()}.
+   * </p>
+   * @see AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()
+   * @see com.jogamp.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/com/jogamp/nativewindow/NativeSurfaceHolder.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeSurfaceHolder.java
new file mode 100644
index 000000000..667f5d8af
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeSurfaceHolder.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2014 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;
+
+/**
+ * Accessor interface for implementing classes with ownership of a {@link NativeSurface}
+ * via an <i>is-a</i> or <i>has-a</i> relation.
+ */
+public interface NativeSurfaceHolder {
+  /**
+   * Returns the associated {@link NativeSurface} of this {@link NativeSurfaceHolder}.
+   */
+  public NativeSurface getNativeSurface();
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindow.java
new file mode 100644
index 000000000..1a2d212da
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindow.java
@@ -0,0 +1,204 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import com.jogamp.nativewindow.util.InsetsImmutable;
+import com.jogamp.nativewindow.util.Point;
+
+/**
+ * Extend the {@link NativeSurface} interface with windowing
+ * information such as {@link #getWindowHandle() window-handle},
+ * {@link #getWidth() window-size} and {@link #getX() window-position}.
+ * <p>
+ * All values of this interface are represented in window units, if not stated otherwise.
+ * See {@link NativeSurface}.
+ * </p>
+ *
+ * <a name="coordinateSystem"><h5>Coordinate System</h5></a>
+ * <p>
+ *  <ul>
+ *      <li>Abstract screen space has it's origin in the top-left corner, and may not be at 0/0.</li>
+ *      <li>Window origin is in it's top-left corner, see {@link #getX()} and {@link #getY()}. </li>
+ *      <li>Window client-area excludes {@link #getInsets() insets}, i.e. window decoration.</li>
+ *      <li>Window origin is relative to it's parent window if exist, or the screen position (top-level).</li>
+ *  </ul>
+ * </p>
+ * <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, NativeSurfaceHolder {
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * Returns this instance, which <i>is-a</i> {@link NativeSurface}.
+   * </p>
+   */
+  @Override
+  public NativeSurface getNativeSurface();
+
+  /**
+   * Destroys this window incl. releasing all 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 insets defined as the width and height of the window decoration
+   * on the left, right, top and bottom in window units.
+   * <p>
+   * Insets are zero if the window is undecorated, including child windows.
+   * </p>
+   *
+   * <p>
+   * Insets are available only after the native window has been created,
+   * ie. the native window has been made visible.<br>
+   *
+   * The top-level window area's top-left corner is located at
+   * <pre>
+   *   {@link #getX()} - getInsets().{@link InsetsImmutable#getLeftWidth() getLeftWidth()}
+   *   {@link #getY()} - getInsets().{@link InsetsImmutable#getTopHeight() getTopHeight()}
+   * </pre>
+   *
+   * The top-level window size is
+   * <pre>
+   *   {@link #getWidth()}  + getInsets().{@link InsetsImmutable#getTotalWidth() getTotalWidth()}
+   *   {@link #getHeight()} + getInsets().{@link InsetsImmutable#getTotalHeight() getTotalHeight()}
+   * </pre>
+   *
+   * @return insets
+   */
+  public InsetsImmutable getInsets();
+
+  /** Returns the current x position of this window, relative to it's parent. */
+
+  /**
+   * Returns the x position of the top-left corner
+   * of the client area relative to it's parent in window units.
+   * <p>
+   * If no parent exist (top-level window), this coordinate equals the screen coordinate.
+   * </p>
+   * <p>
+   * Since the position reflects the client area, it does not include the insets.
+   * </p>
+   * <p>
+   * See <a href="#coordinateSystem"> Coordinate System</a>.
+   * </p>
+   * @see #getInsets()
+   * @see #getLocationOnScreen(Point)
+   */
+  public int getX();
+
+  /**
+   * Returns the current y position of the top-left corner
+   * of the client area relative to it's parent in window units.
+   * <p>
+   * If no parent exist (top-level window), this coordinate equals the screen coordinate.
+   * </p>
+   * <p>
+   * Since the position reflects the client area, it does not include the insets.
+   * </p>
+   * <p>
+   * See <a href="#coordinateSystem"> Coordinate System</a>.
+   * </p>
+   * @see #getInsets()
+   * @see #getLocationOnScreen(Point)
+   */
+  public int getY();
+
+  /**
+   * Returns the width of the client area excluding insets (window decorations) in window units.
+   * @return width of the client area in window units
+   * @see NativeSurface#getSurfaceWidth()
+   */
+  public int getWidth();
+
+  /**
+   * Returns the height of the client area excluding insets (window decorations) in window units.
+   * @return height of the client area in window units
+   * @see NativeSurface#getSurfaceHeight()
+   */
+  public int getHeight();
+
+  /**
+   * Returns the window's top-left client-area position in the screen.
+   * <p>
+   * If {@link Point} is not <code>null</code>, it is translated about the resulting screen position
+   * and returned.
+   * </p>
+   * <p>
+   * See <a href="#coordinateSystem"> Coordinate System</a>.
+   * </p>
+   * <p>
+   * Since the position reflects the client area, it does not include the insets.
+   * </p>
+   * @param point Optional {@link Point} storage.
+   *              If not null, <code>null</code>, it is translated about the resulting screen position
+   *              and returned.
+   * @see #getX()
+   * @see #getY()
+   * @see #getInsets()
+   */
+  public Point getLocationOnScreen(Point point);
+
+  /** Returns true if this native window owns the focus, otherwise false. */
+  boolean hasFocus();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java
new file mode 100644
index 000000000..8f841e7ea
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/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 com.jogamp.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(final String message) {
+    super(message);
+  }
+
+  /** Constructs a NativeWindowException object with the specified detail
+      message and root cause. */
+  public NativeWindowException(final String message, final Throwable cause) {
+    super(message, cause);
+  }
+
+  /** Constructs a NativeWindowException object with the specified root
+      cause. */
+  public NativeWindowException(final Throwable cause) {
+    super(cause);
+  }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
new file mode 100644
index 000000000..cba3a9214
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
@@ -0,0 +1,716 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.jogamp.nativewindow.util.PointImmutable;
+
+import jogamp.common.os.PlatformPropsImpl;
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NativeWindowFactoryImpl;
+import jogamp.nativewindow.ToolkitProperties;
+import jogamp.nativewindow.ResourceToolkitLock;
+import jogamp.nativewindow.WrappedWindow;
+import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.windows.GDIUtil;
+import jogamp.nativewindow.x11.X11Lib;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.PropertyAccess;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
+import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
+import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+
+/** 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)}. String is canonical via {@link String#intern()}.*/
+    public static final String TYPE_EGL = ".egl".intern();
+
+    /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_WINDOWS = ".windows".intern();
+
+    /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_X11 = ".x11".intern();
+
+    /** Broadcom VC IV/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_BCM_VC_IV = ".bcm.vc.iv".intern();
+
+    /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+    public static final String TYPE_ANDROID = ".android".intern();
+
+    /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_MACOSX = ".macosx".intern();
+
+    /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_AWT = ".awt".intern();
+
+    /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_DEFAULT = ".default".intern();
+
+    private static final String nativeWindowingTypePure;   // canonical String via String.intern()
+    private static final String nativeWindowingTypeCustom; // canonical String via String.intern()
+
+    private static NativeWindowFactory defaultFactory;
+    private static Map<Class<?>, NativeWindowFactory> registeredFactories;
+
+    private static Class<?> nativeWindowClass;
+    private static boolean isAWTAvailable;
+
+    private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
+    /** {@link jogamp.nativewindow.x11.X11Util} implements {@link ToolkitProperties}. */
+    private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+    /** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
+    private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+    /** {@link jogamp.nativewindow.windows.GDIUtil} implements {@link ToolkitProperties}. */
+    private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
+
+    private static ToolkitLock jawtUtilJAWTToolkitLock;
+
+    private static boolean requiresToolkitLock;
+    private static boolean desktopHasThreadingIssues;
+
+    // Shutdown hook mechanism for the factory
+    private static volatile boolean isJVMShuttingDown = false;
+    private static final List<Runnable> customShutdownHooks = new ArrayList<Runnable>();
+
+    /** Creates a new NativeWindowFactory instance. End users do not
+        need to call this method. */
+    protected NativeWindowFactory() {
+    }
+
+    private static final boolean guessBroadcomVCIV() {
+        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            private final File vcliblocation = new File(
+                    "/opt/vc/lib/libbcm_host.so");
+                @Override
+                public Boolean run() {
+                    if ( vcliblocation.isFile() ) {
+                        return Boolean.TRUE;
+                    }
+                    return Boolean.FALSE;
+                }
+        } ).booleanValue();
+    }
+
+    private static String _getNativeWindowingType() {
+        switch(PlatformPropsImpl.OS_TYPE) {
+            case ANDROID:
+              return TYPE_ANDROID;
+            case MACOS:
+              return TYPE_MACOSX;
+            case WINDOWS:
+              return TYPE_WINDOWS;
+            case OPENKODE:
+              return TYPE_EGL;
+
+            case LINUX:
+            case FREEBSD:
+            case SUNOS:
+            case HPUX:
+            default:
+              if( guessBroadcomVCIV() ) {
+                return TYPE_BCM_VC_IV;
+              }
+              return TYPE_X11;
+        }
+    }
+
+    static {
+        final boolean[] _DEBUG = new boolean[] { false };
+        final String[] _tmp = new String[] { null };
+
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            @Override
+            public Object run() {
+                Platform.initSingleton(); // last resort ..
+                _DEBUG[0] = Debug.debug("NativeWindow");
+                _tmp[0] = PropertyAccess.getProperty("nativewindow.ws.name", true);
+                Runtime.getRuntime().addShutdownHook(
+                    new Thread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    NativeWindowFactory.shutdown(true);
+                                } }, "NativeWindowFactory_ShutdownHook" ) ) ;
+                return null;
+            } } ) ;
+
+        DEBUG = _DEBUG[0];
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName()+" - Info: NativeWindowFactory.<init>");
+            // Thread.dumpStack();
+        }
+
+        // Gather the windowing TK first
+        nativeWindowingTypePure = _getNativeWindowingType();
+        if(null==_tmp[0] || _tmp[0].length()==0) {
+            nativeWindowingTypeCustom = nativeWindowingTypePure;
+        } else {
+            nativeWindowingTypeCustom = _tmp[0].intern(); // canonical representation
+        }
+    }
+
+    private static boolean initialized = false;
+
+    private static void initSingletonNativeImpl(final ClassLoader cl) {
+        final String clazzName;
+        if( TYPE_X11 == nativeWindowingTypePure ) {
+            clazzName = X11UtilClassName;
+        } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
+            clazzName = GDIClassName;
+        } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
+            clazzName = OSXUtilClassName;
+        } else {
+            clazzName = null;
+        }
+        if( null != clazzName ) {
+            ReflectionUtil.callStaticMethod(clazzName, "initSingleton", null, null, cl );
+
+            final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
+            requiresToolkitLock = res1.booleanValue();
+            final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "hasThreadingIssues", null, null, cl);
+            desktopHasThreadingIssues = res2.booleanValue();
+        } else {
+            requiresToolkitLock = false;
+            desktopHasThreadingIssues = false;
+        }
+    }
+
+    /** Returns true if the JVM is shutting down, otherwise false. */
+    public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
+
+    /**
+     * Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory instance.
+     *
+     * @param head if true add runnable at the start, otherwise at the end
+     * @param runnable runnable to be added.
+     */
+    public static void addCustomShutdownHook(final boolean head, final Runnable runnable) {
+        synchronized( customShutdownHooks ) {
+            if( !customShutdownHooks.contains( runnable ) ) {
+                if( head ) {
+                    customShutdownHooks.add(0, runnable);
+                } else {
+                    customShutdownHooks.add( runnable );
+                }
+            }
+        }
+    }
+
+    /**
+     * Cleanup resources at JVM shutdown
+     */
+    public static synchronized void shutdown(final boolean _isJVMShuttingDown) {
+        isJVMShuttingDown = _isJVMShuttingDown;
+        if(DEBUG) {
+            System.err.println("NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown+", on thread "+Thread.currentThread().getName());
+        }
+        synchronized(customShutdownHooks) {
+            final int cshCount = customShutdownHooks.size();
+            for(int i=0; i < cshCount; i++) {
+                try {
+                    if( DEBUG ) {
+                        System.err.println("NativeWindowFactory.shutdown - customShutdownHook #"+(i+1)+"/"+cshCount);
+                    }
+                    customShutdownHooks.get(i).run();
+                } catch(final Throwable t) {
+                    System.err.println("NativeWindowFactory.shutdown: Caught "+t.getClass().getName()+" during customShutdownHook #"+(i+1)+"/"+cshCount);
+                    if( DEBUG ) {
+                        t.printStackTrace();
+                    }
+                }
+            }
+            customShutdownHooks.clear();
+        }
+        if(DEBUG) {
+            System.err.println("NativeWindowFactory.shutdown(): Post customShutdownHook");
+        }
+
+        if(initialized) {
+            initialized = false;
+            if(null != registeredFactories) {
+                registeredFactories.clear();
+                registeredFactories = null;
+            }
+            GraphicsConfigurationFactory.shutdown();
+        }
+
+        shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+        // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
+        }
+    }
+
+    private static void shutdownNativeImpl(final ClassLoader cl) {
+        final String clazzName;
+        if( TYPE_X11 == nativeWindowingTypePure ) {
+            clazzName = X11UtilClassName;
+        } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
+            clazzName = GDIClassName;
+        } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
+            clazzName = OSXUtilClassName;
+        } else {
+            clazzName = null;
+        }
+        if( null != clazzName ) {
+            ReflectionUtil.callStaticMethod(clazzName, "shutdown", null, null, cl );
+        }
+    }
+
+    /** Returns true if {@link #initSingleton()} has been called w/o subsequent {@link #shutdown(boolean)}. */
+    public static synchronized boolean isInitialized() { return initialized; }
+
+    /**
+     * Static one time initialization of this factory.<br>
+     * This initialization method <b>must be called</b> once by the program or utilizing modules!
+     */
+    public static synchronized void initSingleton() {
+        if(!initialized) {
+            initialized = true;
+
+            if(DEBUG) {
+                System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton()");
+            }
+
+            final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
+
+            isAWTAvailable = false; // may be set to true below
+
+            if( Platform.AWT_AVAILABLE &&
+                ReflectionUtil.isClassAvailable("com.jogamp.nativewindow.awt.AWTGraphicsDevice", cl) ) {
+
+                final Method[] jawtUtilMethods = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
+                    @Override
+                    public Method[] run() {
+                        try {
+                            final Class<?> _jawtUtilClass = Class.forName(JAWTUtilClassName, true, NativeWindowFactory.class.getClassLoader());
+                            final Method jawtUtilIsHeadlessMethod = _jawtUtilClass.getDeclaredMethod("isHeadlessMode", (Class[])null);
+                            jawtUtilIsHeadlessMethod.setAccessible(true);
+                            final Method jawtUtilInitMethod = _jawtUtilClass.getDeclaredMethod("initSingleton", (Class[])null);
+                            jawtUtilInitMethod.setAccessible(true);
+                            final Method jawtUtilGetJAWTToolkitLockMethod = _jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{});
+                            jawtUtilGetJAWTToolkitLockMethod.setAccessible(true);
+                            return new Method[] { jawtUtilInitMethod, jawtUtilIsHeadlessMethod, jawtUtilGetJAWTToolkitLockMethod };
+                        } catch (final Exception e) {
+                            if(DEBUG) {
+                                e.printStackTrace();
+                            }
+                        }
+                        return null;
+                    }
+                });
+                if(null != jawtUtilMethods) {
+                    final Method jawtUtilInitMethod = jawtUtilMethods[0];
+                    final Method jawtUtilIsHeadlessMethod = jawtUtilMethods[1];
+                    final Method jawtUtilGetJAWTToolkitLockMethod = jawtUtilMethods[2];
+
+                    ReflectionUtil.callMethod(null, jawtUtilInitMethod);
+
+                    Object resO = ReflectionUtil.callMethod(null, jawtUtilIsHeadlessMethod);
+                    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);
+                    } else {
+                        throw new RuntimeException("JAWTUtil.isHeadlessMode() didn't return a Boolean");
+                    }
+                    resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitLockMethod);
+                    if(resO instanceof ToolkitLock) {
+                        jawtUtilJAWTToolkitLock = (ToolkitLock) resO;
+                    } else {
+                        throw new RuntimeException("JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock");
+                    }
+                }
+            }
+
+            // X11 initialization after possible AWT initialization
+            // This is performed post AWT initialization, allowing AWT to complete the same,
+            // which may have been triggered before NativeWindow initialization.
+            // This way behavior is more uniforms across configurations (Applet/RCP, applications, ..).
+            initSingletonNativeImpl(cl);
+
+            registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>());
+
+            // register our default factory -> NativeWindow
+            final NativeWindowFactory factory = new NativeWindowFactoryImpl();
+            nativeWindowClass = com.jogamp.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(ReflectionUtil.AWTNames.ComponentClass, false, cl), factory);
+            }
+
+            if(DEBUG) {
+                System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", desktopHasThreadingIssues "+desktopHasThreadingIssues);
+                System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
+            }
+
+            GraphicsConfigurationFactory.initSingleton();
+        }
+    }
+
+    /** @return true if the underlying toolkit requires locking, otherwise false. */
+    public static boolean requiresToolkitLock() {
+        return requiresToolkitLock;
+    }
+
+    /** @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 window type, e.g. {@link #TYPE_X11}, which is canonical via {@link String#intern()}.
+     *        Hence {@link String#equals(Object)} and <code>==</code> produce the same result.
+     */
+    public static String getNativeWindowType(final 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_EGL == type) {
+            return new
+        } else if(TYPE_X11 == type) {
+        } else if(TYPE_WINDOWS == type) {
+        } else if(TYPE_MACOSX == type)) {
+        } else if(TYPE_AWT == type) {
+        } else if(TYPE_DEFAULT == type) {
+        }
+    } */
+
+    /** Sets the default NativeWindowFactory. */
+    public static void setDefaultFactory(final NativeWindowFactory factory) {
+        defaultFactory = factory;
+    }
+
+    /** Gets the default NativeWindowFactory. */
+    public static NativeWindowFactory getDefaultFactory() {
+        return defaultFactory;
+    }
+
+    /**
+     * Returns the AWT {@link ToolkitLock} (JAWT based) if {@link #isAWTAvailable}, otherwise null.
+     * <p>
+     * The JAWT based {@link ToolkitLock} also locks the global lock,
+     * which matters if the latter is required.
+     * </p>
+     */
+    public static ToolkitLock getAWTToolkitLock() {
+        return jawtUtilJAWTToolkitLock;
+    }
+
+    public static ToolkitLock getNullToolkitLock() {
+        return NativeWindowFactoryImpl.getNullToolkitLock();
+    }
+
+    /**
+     * Provides the system default {@link ToolkitLock} for the default system windowing type.
+     * @see #getNativeWindowType(boolean)
+     * @see #getDefaultToolkitLock(java.lang.String)
+     */
+    public static ToolkitLock getDefaultToolkitLock() {
+        return getDefaultToolkitLock(nativeWindowingTypePure);
+    }
+
+    /**
+     * Provides the default {@link ToolkitLock} for <code>type</code>.
+     * <ul>
+     *   <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+     *   <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+     *   <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
+     * </ul>
+     */
+    public static ToolkitLock getDefaultToolkitLock(final String type) {
+        if( requiresToolkitLock ) {
+            if( TYPE_AWT == type && isAWTAvailable() ) { // uses .intern()!
+                return getAWTToolkitLock();
+            }
+            return ResourceToolkitLock.create();
+        }
+        return NativeWindowFactoryImpl.getNullToolkitLock();
+    }
+
+    /**
+     * Provides the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
+     * <ul>
+     *   <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+     *   <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+     *   <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
+     * </ul>
+     */
+    public static ToolkitLock getDefaultToolkitLock(final String type, final long deviceHandle) {
+        if( requiresToolkitLock ) {
+            if( TYPE_AWT == type && isAWTAvailable() ) { // uses .intern()!
+                return getAWTToolkitLock();
+            }
+            return ResourceToolkitLock.create();
+        }
+        return NativeWindowFactoryImpl.getNullToolkitLock();
+    }
+
+    /**
+     * @param device
+     * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen
+     * @return newly created AbstractGraphicsScreen matching device's native type
+     */
+    public static AbstractGraphicsScreen createScreen(final AbstractGraphicsDevice device, int screen) {
+        final String type = device.getType();
+        if( TYPE_X11 == type ) {
+            final X11GraphicsDevice x11Device = (X11GraphicsDevice)device;
+            if(0 > screen) {
+                screen = x11Device.getDefaultScreen();
+            }
+            return new X11GraphicsScreen(x11Device, screen);
+        }
+        if(0 > screen) {
+            screen = 0; // FIXME: Needs native API utilization
+        }
+        if( TYPE_AWT == type ) {
+            final AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) device;
+            return new AWTGraphicsScreen(awtDevice);
+        }
+        return new DefaultGraphicsScreen(device, screen);
+    }
+
+    /** 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(final Class<?> windowClass) throws IllegalArgumentException {
+        if (nativeWindowClass.isAssignableFrom(windowClass)) {
+            return registeredFactories.get(nativeWindowClass);
+        }
+        Class<?> clazz = windowClass;
+        while (clazz != null) {
+            final NativeWindowFactory factory = 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(final Class<?> windowClass, final 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 com.jogamp.opengl.GLDrawableFactory com.jogamp.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 com.jogamp.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 com.jogamp.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
+    */
+    public static NativeWindow getNativeWindow(final Object winObj, final 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;
+
+    /**
+     * Returns the {@link OffscreenLayerSurface} instance of this {@link NativeSurface}.
+     * <p>
+     * In case this surface is a {@link NativeWindow}, we traverse from the given surface
+     * up to root until an implementation of {@link OffscreenLayerSurface} is found.
+     * In case <code>ifEnabled</code> is true, the surface must also implement {@link OffscreenLayerOption}
+     * where {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()} is <code>true</code>.
+     * </p>
+     *
+     * @param surface The surface to query.
+     * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()}.
+     * @return
+     */
+    public static OffscreenLayerSurface getOffscreenLayerSurface(final NativeSurface surface, final boolean ifEnabled) {
+        if(surface instanceof OffscreenLayerSurface &&
+           ( !ifEnabled || surface instanceof OffscreenLayerOption ) ) {
+            final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface;
+            return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+        }
+        if(surface instanceof NativeWindow) {
+            NativeWindow nw = ((NativeWindow) surface).getParent();
+            while(null != nw) {
+                if(nw instanceof OffscreenLayerSurface &&
+                   ( !ifEnabled || nw instanceof OffscreenLayerOption ) ) {
+                    final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw;
+                    return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+                }
+                nw = nw.getParent();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if the given visualID is valid for further processing, i.e. OpenGL usage,
+     * otherwise return false.
+     * <p>
+     * On certain platforms, i.e. X11, a valid visualID is required at window creation.
+     * Other platforms may determine it later on, e.g. OSX and Windows. </p>
+     * <p>
+     * If the visualID is {@link VisualIDHolder#VID_UNDEFINED} and the platform requires it
+     * at creation time (see above), it is not valid for further processing.
+     * </p>
+     */
+    public static boolean isNativeVisualIDValidForProcessing(final int visualID) {
+        return NativeWindowFactory.TYPE_X11 != NativeWindowFactory.getNativeWindowType(false) ||
+               VisualIDHolder.VID_UNDEFINED != visualID ;
+    }
+
+    /**
+     * Creates a native device type, following {@link #getNativeWindowType(boolean) getNativeWindowType(true)}.
+     * <p>
+     * The device will be opened if <code>own</code> is true, otherwise no native handle will ever be acquired.
+     * </p>
+     */
+    public static AbstractGraphicsDevice createDevice(final String displayConnection, final boolean own) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(true);
+        if( NativeWindowFactory.TYPE_X11 == nwt ) {
+            if( own ) {
+                return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT, null /* ToolkitLock */);
+            } else {
+                return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
+            }
+        } else if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+            return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        } else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+            return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+        /**
+         * FIXME: Needs service provider interface (SPI) for TK dependent implementation
+        } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) {
+        } else if( NativeWindowFactory.TYPE_ANDROID== nwt ) {
+        } else if( NativeWindowFactory.TYPE_EGL == nwt ) {
+        } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) {
+        } else if( NativeWindowFactory.TYPE_AWT == nwt ) {
+        */
+        }
+        throw new UnsupportedOperationException("n/a for windowing system: "+nwt);
+    }
+
+    /**
+     * Creates a wrapped {@link NativeWindow} with given native handles and {@link AbstractGraphicsScreen}.
+     * <p>
+     * The given {@link UpstreamWindowHookMutableSizePos} maybe used to reflect resizes and repositioning of the native window.
+     * </p>
+     * <p>
+     * The {@link AbstractGraphicsScreen} may be created via {@link #createScreen(AbstractGraphicsDevice, int)}.
+     * </p>
+     * <p>
+     * The {@link AbstractGraphicsScreen} may have an underlying open {@link AbstractGraphicsDevice}
+     * or a simple <i>dummy</i> instance, see {@link #createDevice(String, boolean)}.
+     * </p>
+     */
+    public static NativeWindow createWrappedWindow(final AbstractGraphicsScreen aScreen, final long surfaceHandle, final long windowHandle,
+                                                   final UpstreamWindowHookMutableSizePos hook) {
+        final CapabilitiesImmutable caps = new Capabilities();
+        final AbstractGraphicsConfiguration config = new DefaultGraphicsConfiguration(aScreen, caps, caps);
+        return new WrappedWindow(config, surfaceHandle, hook, true, windowHandle);
+    }
+
+    /**
+     * @param nw
+     * @return top-left client-area position in window units
+     */
+    public static PointImmutable getLocationOnScreen(final NativeWindow nw) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(true);
+        if( NativeWindowFactory.TYPE_X11 == nwt ) {
+            return X11Lib.GetRelativeLocation(nw.getDisplayHandle(), nw.getScreenIndex(), nw.getWindowHandle(), 0, 0, 0);
+        } else if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+            return GDIUtil.GetRelativeLocation(nw.getWindowHandle(), 0, 0, 0);
+        } else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+            return OSXUtil.GetLocationOnScreen(nw.getWindowHandle(), 0, 0);
+        /**
+         * FIXME: Needs service provider interface (SPI) for TK dependent implementation
+        } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) {
+        } else if( NativeWindowFactory.TYPE_ANDROID== nwt ) {
+        } else if( NativeWindowFactory.TYPE_EGL == nwt ) {
+        } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) {
+        } else if( NativeWindowFactory.TYPE_AWT == nwt ) {
+            */
+        }
+        throw new UnsupportedOperationException("n/a for windowing system: "+nwt);
+    }
+
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerOption.java b/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerOption.java
new file mode 100644
index 000000000..2e9f2c172
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerOption.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.nativewindow;
+
+/**
+ * Handling requests for using an {@link OffscreenLayerSurface}
+ * within the implementation.
+ */
+public interface OffscreenLayerOption {
+    /**
+     * Request an offscreen layer, if supported.
+     * <p>
+     * Shall be called before the first {@link NativeWindow#lockSurface()},
+     * and hence before realization.
+     * </p>
+     *
+     * @see #getShallUseOffscreenLayer()
+     * @see #isOffscreenLayerSurfaceEnabled()
+     */
+    public void setShallUseOffscreenLayer(boolean v);
+
+    /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */
+    public boolean getShallUseOffscreenLayer();
+
+    /**
+     * Returns true if this instance uses an offscreen layer, otherwise false.
+     * <p>
+     * This instance is an offscreen layer, if {@link #setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+     * has been called before it's realization and first lock and the underlying implementation supports it.
+     * </p>
+     * The return value is undefined before issuing the first {@link NativeWindow#lockSurface()}.
+     *
+     * @see #setShallUseOffscreenLayer(boolean)
+     */
+    public boolean isOffscreenLayerSurfaceEnabled();
+}
\ No newline at end of file
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerSurface.java
new file mode 100644
index 000000000..abba2c126
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/OffscreenLayerSurface.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.nativewindow;
+
+import com.jogamp.nativewindow.util.PixelRectangle;
+import com.jogamp.nativewindow.util.PointImmutable;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+
+/**
+ * Interface specifying the offscreen layer surface protocol.
+ */
+public interface OffscreenLayerSurface {
+  /**
+   * Attach the offscreen layer to this offscreen layer surface.
+   * <p>
+   * Implementation may realize all required resources at this point.
+   * </p>
+   *
+   * @see #isOffscreenLayerSurfaceEnabled()
+   * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+   */
+  public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+
+  /**
+   * Detaches a previously attached offscreen layer from this offscreen layer surface.
+   * @see #attachSurfaceLayer(long)
+   * @see #isOffscreenLayerSurfaceEnabled()
+   * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+   *                               or no surface layer is attached.
+   */
+  public void detachSurfaceLayer() throws NativeWindowException;
+
+  /** Returns the attached surface layer or null if none is attached. */
+  public long getAttachedSurfaceLayer();
+
+  /** Returns true if a surface layer is attached, otherwise false. */
+  public boolean isSurfaceLayerAttached();
+
+  /** Sets the capabilities of this instance, allowing upstream API's to refine it, i.e. OpenGL related settings. */
+  public void setChosenCapabilities(CapabilitiesImmutable caps);
+
+  /** Returns the recursive lock object of this surface, which synchronizes multithreaded access. */
+  public RecursiveLock getLock();
+
+  /**
+   * Optional method setting cursor in the corresponding on-screen surface/window, if exists.
+   *
+   * @param pixelrect cursor pixels, maybe null for default cursor
+   * @param hotSpot maybe null for default cursor
+   * @return true if successful, i.e. on-screen surface/window w/ cursor capabilities exists. Otherwise false.
+   */
+  public boolean setCursor(PixelRectangle pixelrect, PointImmutable hotSpot);
+
+  /**
+   * Optional method hiding the cursor in the corresponding on-screen surface/window, if exists.
+   *
+   * @return true if successful, i.e. on-screen surface/window w/ cursor capabilities exists. Otherwise false.
+   */
+  public boolean hideCursor();
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/ProxySurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/ProxySurface.java
new file mode 100644
index 000000000..7b36531dc
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/ProxySurface.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright 2012 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 jogamp.nativewindow.Debug;
+
+/**
+ * Provides a mutable {@link NativeSurface}, i.e. {@link MutableSurface}, while allowing an
+ * {@link UpstreamSurfaceHook} to influence the lifecycle and information.
+ *
+ * @see UpstreamSurfaceHook
+ * @see MutableSurface
+ * @see NativeSurface
+ */
+public interface ProxySurface extends MutableSurface {
+    public static final boolean DEBUG = Debug.debug("ProxySurface");
+
+    /**
+     * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's surface handle
+     * @see #addUpstreamOptionBits(int)
+     * @see #clearUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
+     */
+    public static final int OPT_PROXY_OWNS_UPSTREAM_SURFACE = 1 << 6;
+
+    /**
+     * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's {@link AbstractGraphicsDevice}.
+     * @see #addUpstreamOptionBits(int)
+     * @see #clearUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
+     */
+    public static final int OPT_PROXY_OWNS_UPSTREAM_DEVICE = 1 << 7;
+
+    /**
+     * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
+     * @see #addUpstreamOptionBits(int)
+     * @see #clearUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
+     */
+    public static final int OPT_UPSTREAM_WINDOW_INVISIBLE = 1 << 8;
+
+    /**
+     * Implementation specific bitvalue stating the upstream's {@link NativeSurface}'s zero handle is valid.
+     * @see #addUpstreamOptionBits(int)
+     * @see #clearUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
+     */
+    public static final int OPT_UPSTREAM_SURFACELESS = 1 << 9;
+
+    /** Allow redefining the AbstractGraphicsConfiguration */
+    public void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg);
+
+    /**
+     * Returns the optional upstream {@link NativeSurface} if used by implementation, otherwise <code>null</code>.
+     * <p>
+     * The upstream {@link NativeSurface} is retrieved via {@link #getUpstreamSurfaceHook() the UpstreamSurfaceHook},
+     * i.e.  {@link UpstreamSurfaceHook#getUpstreamSurface()}.
+     * </p>
+     * <p>
+     * One example is the JOGL EGLWrappedSurface, which might be backed up by a
+     * native platform NativeSurface (X11, WGL, CGL, ..).
+     * </p>
+     */
+    public NativeSurface getUpstreamSurface();
+
+    /** Returns the {@link UpstreamSurfaceHook} if {@link #setUpstreamSurfaceHook(UpstreamSurfaceHook) set}, otherwise <code>null</code>. */
+    public UpstreamSurfaceHook getUpstreamSurfaceHook();
+
+    /**
+     * Overrides the {@link UpstreamSurfaceHook}.
+     */
+    public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook);
+
+    /**
+     * Enables or disables the {@link UpstreamSurfaceHook} lifecycle functions
+     * {@link UpstreamSurfaceHook#create(ProxySurface)} and {@link UpstreamSurfaceHook#destroy(ProxySurface)}.
+     * <p>
+     * Use this for small code blocks where the native resources shall not change,
+     * i.e. resizing a derived (OpenGL) drawable.
+     * </p>
+     */
+    public void enableUpstreamSurfaceHookLifecycle(boolean enable);
+
+    /**
+     * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
+     */
+    public void createNotify();
+
+    /**
+     * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all proxy surface/window handles shall be cleared.
+     */
+    public void destroyNotify();
+
+    public StringBuilder getUpstreamOptionBits(StringBuilder sink);
+    public int getUpstreamOptionBits();
+
+    /** Returns <code>true</code> if the give bit-mask <code>v</code> is set in this instance upstream-option-bits, otherwise <code>false</code>.*/
+    public boolean containsUpstreamOptionBits(int v);
+
+    /** Add the given bit-mask to this instance upstream-option-bits using bit-or w/ <code>v</code>.*/
+    public void addUpstreamOptionBits(int v);
+
+    /** Clear the given bit-mask from this instance upstream-option-bits using bit-and w/ <code>~v</code>*/
+    public void clearUpstreamOptionBits(int v);
+
+    public StringBuilder toString(StringBuilder sink);
+    @Override
+    public String toString();
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/ScalableSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/ScalableSurface.java
new file mode 100644
index 000000000..eea9e4bed
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/ScalableSurface.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2014 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;
+
+/**
+ * Adding mutable surface pixel scale property to implementing class, usually to a {@link NativeSurface} implementation,
+ * see {@link #setSurfaceScale(float[])}.
+ */
+public interface ScalableSurface {
+  /** Setting surface-pixel-scale of {@value}, results in same pixel- and window-units. */
+  public static final float IDENTITY_PIXELSCALE = 1f;
+  /** Setting surface-pixel-scale of {@value}, results in maximum platform dependent pixel-scale, i.e. pixel-units >> window-units where available. */
+  public static final float AUTOMAX_PIXELSCALE = 0f;
+
+  /**
+   * Request a pixel scale in x- and y-direction for the associated {@link NativeSurface},
+   * where {@code size_in_pixel_units = pixel_scale * size_in_window_units}.
+   * <p>
+   * Default pixel scale request for both directions is {@link #AUTOMAX_PIXELSCALE}.
+   * </p>
+   * <p>
+   * In case platform only supports uniform pixel scale, i.e. one scale for both directions,
+   * either {@link #AUTOMAX_PIXELSCALE} or the maximum requested pixel scale component is used.
+   * </p>
+   * <p>
+   * The <i>requested</i> pixel scale will be validated against platform limits before native scale-setup,
+   * i.e. clipped to {@link #IDENTITY_PIXELSCALE} if not supported or clipped to the platform maximum.
+   * It can be queried via {@link #getRequestedSurfaceScale(float[])}.
+   * </p>
+   * <p>
+   * The actual <i>realized</i> pixel scale values of the {@link NativeSurface}
+   * can be queried via {@link #getCurrentSurfaceScale(float[])} or
+   * computed via <code>surface.{@link NativeSurface#convertToPixelUnits(int[]) convertToPixelUnits}(new int[] { 1, 1 })</code>
+   * </p>
+   * @param pixelScale <i>requested</i> surface pixel scale float[2] values for x- and y-direction.
+   * @return {@code true} if the {@link #getCurrentSurfaceScale(float[]) current pixel scale} has changed, otherwise {@code false}.
+   * @see #getRequestedSurfaceScale(float[])
+   */
+  public boolean setSurfaceScale(final float[] pixelScale);
+
+  /**
+   * Returns the {@link #setSurfaceScale(float[]) requested} pixel scale of the associated {@link NativeSurface}.
+   *
+   * @param result float[2] storage for the result
+   * @return the passed storage containing the current pixelScale for chaining
+   * @see #setSurfaceScale(float[])
+   */
+  public float[] getRequestedSurfaceScale(final float[] result);
+
+  /**
+   * Returns the current pixel scale of the associated {@link NativeSurface}.
+   *
+   * @param result float[2] storage for the result
+   * @return the passed storage containing the current pixelScale for chaining
+   */
+  public float[] getCurrentSurfaceScale(final float[] result);
+
+  /**
+   * Returns the minimum pixel scale of the associated {@link NativeSurface}.
+   * @param result float[2] storage for the result
+   * @return the passed storage containing the minimum pixelScale for chaining
+   */
+  public float[] getMinimumSurfaceScale(final float[] result);
+
+  /**
+   * Returns the maximum pixel scale of the associated {@link NativeSurface}.
+   * <p>
+   * The maximum pixel scale maybe used to determine the proper <i>dpi</i>
+   * value of the monitor displaying this {@link NativeSurface}.
+   * <pre>
+   *    surfacePpMM = monitorPpMM * currentSurfaceScale / nativeSurfaceScale,
+   *    with PpMM == pixel per millimeter
+   * </pre>
+   * </p>
+   *
+   * @param result float[2] storage for the result
+   * @return the passed storage containing the maximum pixelScale for chaining
+   */
+  public float[] getMaximumSurfaceScale(final float[] result);
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/SurfaceUpdatedListener.java b/src/nativewindow/classes/com/jogamp/nativewindow/SurfaceUpdatedListener.java
new file mode 100644
index 000000000..37e4bd0c9
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/SurfaceUpdatedListener.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.jogamp.nativewindow;
+
+/**
+ * Clients may add their SurfaceUpdateListener implementation to a {@link com.jogamp.nativewindow.NativeSurface}
+ * allowing to get notified after the surface has been updated, eg. after a swap buffer operation.
+ */
+public interface SurfaceUpdatedListener {
+    /** Notification of a surface update event, eg. after a swap buffer operation.
+     *
+     * @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/com/jogamp/nativewindow/ToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/ToolkitLock.java
new file mode 100644
index 000000000..eef11adb7
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/ToolkitLock.java
@@ -0,0 +1,78 @@
+/**
+ * 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 jogamp.nativewindow.Debug;
+
+/**
+ * Marker for a singleton global recursive blocking lock implementation,
+ * optionally locking a native windowing toolkit as well.
+ * <p>
+ * Toolkit locks are created solely via {@link NativeWindowFactory}.
+ * </p>
+ * <p>
+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
+ */
+public interface ToolkitLock {
+    public static final boolean DEBUG = Debug.debug("ToolkitLock");
+    public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
+
+    /**
+     * Blocking until the lock is acquired by this Thread or a timeout is reached.
+     * <p>
+     * Timeout is implementation specific, if used at all.
+     * </p>
+     *
+     * @throws RuntimeException in case of a timeout
+     */
+    public void lock();
+
+    /**
+     * Release the lock.
+     *
+     * @throws RuntimeException in case the lock is not acquired by this thread.
+     */
+    public void unlock();
+
+    /**
+     * @throws RuntimeException if current thread does not hold the lock
+     */
+    public void validateLocked() throws RuntimeException;
+
+    /**
+     * Dispose this instance.
+     * <p>
+     * Shall be called when instance is no more required.
+     * </p>
+     * This allows implementations sharing a lock via resources
+     * to decrease the reference counter.
+     */
+    public void dispose();
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHook.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHook.java
new file mode 100644
index 000000000..5e9b8d293
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHook.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2012 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;
+
+/**
+ * Interface allowing upstream caller to pass lifecycle actions and size info
+ * to a {@link ProxySurface} instance.
+ */
+public interface UpstreamSurfaceHook {
+    /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+    public void create(ProxySurface s);
+    /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+    public void destroy(ProxySurface s);
+
+    /**
+     * Returns the optional upstream {@link NativeSurface} if used by implementation, otherwise <code>null</code>.
+     * <p>
+     * One example is the JOGL EGLWrappedSurface, which might be backed up by a
+     * native platform NativeSurface (X11, WGL, CGL, ..).
+     * </p>
+     */
+    public NativeSurface getUpstreamSurface();
+
+    /** Returns the width of the upstream surface in pixels, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+    public int getSurfaceWidth(ProxySurface s);
+    /** Returns the height of the upstream surface in pixels, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+    public int getSurfaceHeight(ProxySurface s);
+
+    /**
+     * {@link UpstreamSurfaceHook} w/ mutable size, allowing it's {@link ProxySurface} user to resize.
+     */
+    public interface MutableSize extends UpstreamSurfaceHook {
+        /**
+         * Resizes the upstream surface.
+         * @param width new width in pixel units
+         * @param height new height in pixel units
+         */
+        public void setSurfaceSize(int width, int height);
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java b/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
new file mode 100644
index 000000000..69bfe50f8
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright 2012 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 java.util.Comparator;
+
+/**
+ * Visual ID holder interface.
+ * <p>
+ * Allows queries of different types of native visual IDs,
+ * see {@link #getVisualID(int)}.
+ * </p>
+ */
+public interface VisualIDHolder {
+
+    public enum VIDType {
+        // Generic Values
+        INTRINSIC(0), NATIVE(1),
+        // EGL Values
+        EGL_CONFIG(10),
+        // X11 Values
+        X11_XVISUAL(20), X11_FBCONFIG(21),
+        // Windows Values
+        WIN32_PFD(30);
+
+        public final int id;
+
+        VIDType(final int id){
+            this.id = id;
+        }
+    }
+
+    /**
+     * Returns the native visual ID of the given <code>type</code>
+     * if supported, or {@link #VID_UNDEFINED} if not supported.
+     * <p>
+     * Depending on the native windowing system, <code>type</code> is handled as follows:
+     * <ul>
+     *   <li>X11 throws NativeWindowException on <code>EGL_CONFIG</code>, <code>WIN32_PFD</code>
+     *     <ul>
+     *       <li><code>INTRINSIC</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>NATIVE</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>X11_XVISUAL</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>X11_FBCONFIG</code>: <code>VID_UNDEFINED</code></li>
+     *     </ul></li>
+     *   <li>X11/GL throws NativeWindowException on <code>EGL_CONFIG</code>, <code>WIN32_PFD</code>
+     *     <ul>
+     *       <li><code>INTRINSIC</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>NATIVE</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>X11_XVISUAL</code>: <i>X11 XVisual ID</i></li>
+     *       <li><code>X11_FBCONFIG</code>: <i>X11 FBConfig ID</i> or <code>VID_UNDEFINED</code></li>
+     *     </ul></li>
+     *   <li>Windows/GL throws NativeWindowException on <code>EGL_CONFIG</code>, <code>X11_XVISUAL</code>, <code>X11_FBCONFIG</code>
+     *     <ul>
+     *       <li><code>INTRINSIC</code>: <i>Win32 PIXELFORMATDESCRIPTOR ID</i></li>
+     *       <li><code>NATIVE</code>: <i>Win32 PIXELFORMATDESCRIPTOR ID</i></li>
+     *       <li><code>WIN32_PFD</code>: <i>Win32 PIXELFORMATDESCRIPTOR ID</i></li>
+     *     </ul></li>
+     *   <li>EGL/GL throws NativeWindowException on <code>X11_XVISUAL</code>, <code>X11_FBCONFIG</code>, <code>WIN32_PFD</code>
+     *     <ul>
+     *       <li><code>INTRINSIC</code>: <i>EGL Config ID</i></li>
+     *       <li><code>NATIVE</code>: <i>EGL NativeVisual ID</i> (<i>X11 XVisual ID</i>, <i>Win32 PIXELFORMATDESCRIPTOR ID</i>, ...)</li>
+     *       <li><code>EGL_CONFIG</code>: <i>EGL Config ID</i></li>
+     *     </ul></li>
+     * </ul>
+     * </p>
+     * Note: <code>INTRINSIC</code> and <code>NATIVE</code> are always handled,
+     *       but may result in {@link #VID_UNDEFINED}. The latter is true if
+     *       the native value are actually undefined or the corresponding object is not
+     *       mapped to a native visual object.
+     *
+     * @throws NativeWindowException if <code>type</code> is neither
+     *         <code>INTRINSIC</code> nor <code>NATIVE</code>
+     *         and does not match the native implementation.
+     */
+    int getVisualID(VIDType type) throws NativeWindowException ;
+
+    /**
+     * {@link #getVisualID(VIDType)} result indicating an undefined value,
+     * which could be cause by an unsupported query.
+     * <p>
+     * We assume the const value <code>0</code> doesn't reflect a valid native visual ID
+     * and is interpreted as <i>no value</i> on all platforms.
+     * This is currently true for Android, X11 and Windows.
+     * </p>
+     */
+    static final int VID_UNDEFINED = 0;
+
+    /** Comparing {@link VIDType#NATIVE} */
+    public static class VIDComparator implements Comparator<VisualIDHolder> {
+        private final VIDType type;
+
+        public VIDComparator(final VIDType type) {
+            this.type = type;
+        }
+
+        @Override
+        public int compare(final VisualIDHolder vid1, final VisualIDHolder vid2) {
+            final int id1 = vid1.getVisualID(type);
+            final int id2 = vid2.getVisualID(type);
+
+            if(id1 > id2) {
+                return 1;
+            } else if(id1 < id2) {
+                return -1;
+            }
+            return 0;
+        }
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WindowClosingProtocol.java b/src/nativewindow/classes/com/jogamp/nativewindow/WindowClosingProtocol.java
new file mode 100644
index 000000000..f4f8a02e1
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/WindowClosingProtocol.java
@@ -0,0 +1,73 @@
+/**
+ * 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;
+
+/**
+ * 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 WindowClosingMode#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 WindowClosingMode#DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.</p>
+ */
+public interface WindowClosingProtocol {
+
+    /**
+     * Window closing mode if triggered by toolkit close operation.
+     */
+    public enum WindowClosingMode {
+        /**
+         * Do nothing on native window close operation.<br>
+         * This is the default behavior within an AWT environment.
+         */
+        DO_NOTHING_ON_CLOSE,
+
+        /**
+         * Dispose resources on native window close operation.<br>
+         * This is the default behavior in case no underlying toolkit defines otherwise.
+         */
+        DISPOSE_ON_CLOSE;
+    }
+
+
+    /**
+     * @return the current close operation value
+     * @see WindowClosingMode#DISPOSE_ON_CLOSE
+     * @see WindowClosingMode#DO_NOTHING_ON_CLOSE
+     */
+    WindowClosingMode getDefaultCloseOperation();
+
+    /**
+     * @param op the new close operation value
+     * @return the previous close operation value
+     * @see WindowClosingMode#DISPOSE_ON_CLOSE
+     * @see WindowClosingMode#DO_NOTHING_ON_CLOSE
+     */
+    WindowClosingMode setDefaultCloseOperation(WindowClosingMode op);
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/package.html b/src/nativewindow/classes/com/jogamp/nativewindow/package.html
new file mode 100644
index 000000000..1fe52eea4
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/package.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>NativeWindow Specification Overview</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:
+  <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:
+  <ul>
+    <li>{@link com.jogamp.nativewindow.AbstractGraphicsDevice AbstractGraphicsDevice},
+        <p>Shall return the new string identifier with {@link com.jogamp.nativewindow.AbstractGraphicsDevice#getType() getType()}</p></li>
+    <li>{@link com.jogamp.nativewindow.AbstractGraphicsScreen AbstractGraphicsScreen}</li>
+    <li>{@link com.jogamp.nativewindow.AbstractGraphicsConfiguration AbstractGraphicsConfiguration}</li>
+  </ul>
+  <p>The implementor has to provide the following:</p>
+  <ul>
+    <li> The specialisation of the abstract class {@link com.jogamp.nativewindow.NativeWindowFactory NativeWindowFactory}
+         <p>shall be registered with {@link com.jogamp.nativewindow.NativeWindowFactory#registerFactory NativeWindowFactory.registerFactory(..)}.</p></li>
+
+    <li> The specialisation of the abstract class {@link com.jogamp.nativewindow.GraphicsConfigurationFactory GraphicsConfigurationFactory}
+         <p>shall be registered with {@link com.jogamp.nativewindow.GraphicsConfigurationFactory#registerFactory GraphicsConfigurationFactory.registerFactory(..)}.</p></li>
+  </ul>
+  <p>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 com.jogamp.nativewindow.NativeSurface NativeSurface}.</p>
+  <p>{@link com.jogamp.nativewindow.NativeWindow NativeWindow} specializes the NativeSurface.</p>
+  <p>However, an implementation of this protocol (e.g. {@link com.jogamp.newt}) may support the creation.</p>
+   
+<h3>Dependencies</h3>
+  This binding has dependencies to the following:
+  <ul>
+    <li> Either of the following Java implementations:
+    <ul>
+        <li> <a href="http://docs.oracle.com/javase/6/docs/api/">Java SE 1.6 or later</a> </li>
+        <li> A mobile JavaVM with language 1.6 support, ie:
+            <ul>
+                <li> <a href="http://developer.android.com/reference/packages.html">Android API Level 9 (Version 2.3)</a> </li>
+                <li> <a href="http://jamvm.sourceforge.net/">JamVM</a> </li>
+            </ul>
+            with
+            <ul>
+                <li> <a href="http://docs.oracle.com/javase/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:
+<ul>
+    <li>The <b>com.jogamp.nativewindow</b> package
+    <p>This package contains Java bindings for a native windowing system.</p>
+    <p>Subsequent packages contain marker type classes, containing native characteristics of the windowing system.</p>
+    <ul>
+        <li>The <b>com.jogamp.nativewindow.awt</b> package
+        <p>This sub package contains classes to cover the native characteristics of the AWT windowing system.</p></li>
+
+        <li>The <b>com.jogamp.nativewindow.x11</b> package
+        <p>This sub package contains classes to cover the native characteristics of the X11 windowing system.</p></li>
+
+        <li>The <b>com.jogamp.nativewindow.windows</b> package
+        <p>This sub package contains classes to cover the native characteristics of the Windows windowing system.</p></li>
+
+        <li>The <b>com.jogamp.nativewindow.macosx</b> package
+        <p>This sub package contains classes to cover the native characteristics of the MacOSX windowing system.</p></li>
+
+        <li>The <b>com.jogamp.nativewindow.egl</b> package
+        <p>This sub package contains classes to cover the native characteristics of the EGL/OpenKODE windowing system.</p></li>
+  </ul></li>
+</ul>
+
+<h3>Factory Model</h3>
+<p>Running on a platform with a supported windowing system, the factory model shall be used
+to instantiate a native window, see {@link com.jogamp.nativewindow.NativeWindowFactory NativeWindowFactory}.</p>
+
+<h3>Revision History</h3>
+   
+<ul>
+<li> Early Draft Review, June 2009</li>
+<li> 2.0.0 Maintenance Release, February 2011</li>
+<li> 2.0.2 Major Release, July 18th 2013</li>
+</ul>
+  <br>
+  <br>
+ <br>
+</body>
+</html>
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/Dimension.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/Dimension.java
new file mode 100644
index 000000000..28c5dd90e
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/Dimension.java
@@ -0,0 +1,128 @@
+/**
+ * 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 com.jogamp.nativewindow.util;
+
+public class Dimension implements Cloneable, DimensionImmutable {
+    int width;
+    int height;
+
+    public Dimension() {
+        this(0, 0);
+    }
+
+    public Dimension(final int[] size) {
+        this(size[0], size[1]);
+    }
+
+    public Dimension(final int width, final 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;
+    }
+
+    @Override
+    public Object cloneMutable() {
+      return clone();
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException ex) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public final int getWidth() { return width; }
+    @Override
+    public final int getHeight() { return height; }
+
+    public final void set(final int width, final int height) {
+        this.width = width;
+        this.height = height;
+    }
+    public final void setWidth(final int width) {
+        this.width = width;
+    }
+    public final void setHeight(final int height) {
+        this.height = height;
+    }
+    public final Dimension scale(final int s) {
+        width *= s;
+        height *= s;
+        return this;
+    }
+    public final Dimension add(final Dimension pd) {
+        width += pd.width ;
+        height += pd.height ;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return width + " x " + height;
+    }
+
+    @Override
+    public int compareTo(final DimensionImmutable d) {
+        final int tsq = width*height;
+        final int xsq = d.getWidth()*d.getHeight();
+
+        if(tsq > xsq) {
+            return 1;
+        } else if(tsq < xsq) {
+            return -1;
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if(this == obj)  { return true; }
+        if (obj instanceof Dimension) {
+            final Dimension p = (Dimension)obj;
+            return height == p.height &&
+                   width == p.width ;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        // 31 * x == (x << 5) - x
+        final int hash = 31 + width;
+        return ((hash << 5) - hash) + height;
+    }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/DimensionImmutable.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/DimensionImmutable.java
new file mode 100644
index 000000000..6de77a716
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/DimensionImmutable.java
@@ -0,0 +1,68 @@
+/**
+ * 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 com.jogamp.nativewindow.util;
+
+import com.jogamp.common.type.WriteCloneable;
+
+/** 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 DimensionImmutable extends WriteCloneable, Comparable<DimensionImmutable> {
+
+    int getHeight();
+
+    int getWidth();
+
+    /**
+     * <p>
+     * Compares square of size.
+     * </p>
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(final DimensionImmutable d);
+
+    /**
+     * 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>.
+     */
+    @Override
+    boolean equals(Object obj);
+
+    @Override
+    int hashCode();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/Insets.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/Insets.java
new file mode 100644
index 000000000..205e18346
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/Insets.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.nativewindow.util;
+
+/**
+ * Mutable insets representing rectangular window decoration insets on all four edges
+ * in window units.
+ */
+public class Insets implements Cloneable, InsetsImmutable {
+    static final InsetsImmutable zeroInsets = new Insets();
+    public static final InsetsImmutable getZero() { return zeroInsets; }
+
+    private int l, r, t, b;
+
+    public Insets() {
+        this(0, 0, 0, 0);
+    }
+
+    public Insets(final int left, final int right, final int top, final int bottom) {
+        this.l=left;
+        this.r=right;
+        this.t=top;
+        this.b=bottom;
+    }
+
+    @Override
+    public Object cloneMutable() {
+      return clone();
+    }
+
+    @Override
+    protected Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException ex) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public final int getLeftWidth() { return l; }
+    @Override
+    public final int getRightWidth() { return r; }
+    @Override
+    public final int getTotalWidth() { return l + r; }
+    @Override
+    public final int getTopHeight() { return t; }
+    @Override
+    public final int getBottomHeight() { return b; }
+    @Override
+    public final int getTotalHeight() { return t + b; }
+
+    /**
+     * Set the inset values of this instance in window units.
+     * @param left left inset width in window units.
+     * @param right right inset width in window units.
+     * @param top top inset width in window units.
+     * @param bottom bottom inset width in window units.
+     */
+    public final void set(final int left, final int right, final int top, final int bottom) {
+        l = left; r = right; t = top; b = bottom;
+    }
+    /**
+     * Set the left inset value of this instance in window units.
+     * @param left left inset width in window units.
+     */
+    public final void setLeftWidth(final int left) { l = left; }
+    /**
+     * Set the right inset value of this instance in window units.
+     * @param right right inset width in window units.
+     */
+    public final void setRightWidth(final int right) { r = right; }
+    /**
+     * Set the top inset value of this instance in window units.
+     * @param top top inset width in window units.
+     */
+    public final void setTopHeight(final int top) { t = top; }
+    /**
+     * Set the bottom inset value of this instance in window units.
+     * @param bottom bottom inset width in window units.
+     */
+    public final void setBottomHeight(final int bottom) { b = bottom; }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if(this == obj)  { return true; }
+        if (obj instanceof Insets) {
+            final Insets insets = (Insets)obj;
+            return (r == insets.r) && (l == insets.l) &&
+                   (b == insets.b) && (t == insets.t);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        final int sum1 = l + b;
+        final int sum2 = t + r;
+        final int val1 = sum1 * (sum1 + 1)/2 + l;
+        final int val2 = sum2 * (sum2 + 1)/2 + r;
+        final int sum3 = val1 + val2;
+        return sum3 * (sum3 + 1)/2 + val2;
+    }
+
+    @Override
+    public String toString() {
+        return "[ l "+l+", r "+r+" - t "+t+", b "+b+" - "+getTotalWidth()+"x"+getTotalHeight()+"]";
+    }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/InsetsImmutable.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/InsetsImmutable.java
new file mode 100644
index 000000000..e626a507e
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/InsetsImmutable.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.nativewindow.util;
+
+import com.jogamp.common.type.WriteCloneable;
+
+/**
+ * Immutable insets representing rectangular window decoration insets on all four edges
+ * in window units.
+ */
+public interface InsetsImmutable extends WriteCloneable {
+
+    /** @return left inset width in window units. */
+    int getLeftWidth();
+
+    /** @return right inset width in window units. */
+    int getRightWidth();
+
+    /** @return total width in window units, ie. <code>left_width + right_width</code> */
+    int getTotalWidth();
+
+    /** @return top inset height in window units. */
+    int getTopHeight();
+
+    /** @return bottom inset height in window units. */
+    int getBottomHeight();
+
+    /** @return total height in window units, ie. <code>top_height + bottom_height</code> */
+    int getTotalHeight();
+
+    /**
+     * Checks whether two rect objects are equal. Two instances
+     * of <code>Insets</code> are equal if the four integer values
+     * of the fields <code>left</code>, <code>right</code>,
+     * <code>top</code>, and <code>bottom</code> are all equal.
+     * @return      <code>true</code> if the two Insets are equal;
+     * otherwise <code>false</code>.
+     */
+    @Override
+    boolean equals(Object obj);
+
+    @Override
+    int hashCode();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java
new file mode 100644
index 000000000..8b1e91564
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java
@@ -0,0 +1,739 @@
+/**
+ * Copyright (c) 2014 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.util;
+
+import java.util.Arrays;
+
+import com.jogamp.common.util.IntBitfield;
+
+/**
+ * Basic pixel formats
+ * <p>
+ * Notation follows OpenGL notation, i.e.
+ * name consist of all it's component names
+ * followed by their bit size.
+ * </p>
+ * <p>
+ * Order of component names is from lowest-bit to highest-bit.
+ * </p>
+ * <p>
+ * In case component-size is 1 byte (e.g. OpenGL data-type GL_UNSIGNED_BYTE),
+ * component names are ordered from lowest-byte to highest-byte.
+ * Note that OpenGL applies special interpretation if
+ * data-type is e.g. GL_UNSIGNED_8_8_8_8_REV or GL_UNSIGNED_8_8_8_8_REV.
+ * </p>
+ * <p>
+ * PixelFormat can be converted to OpenGL GLPixelAttributes
+ * via
+ * <pre>
+ *  GLPixelAttributes glpa = GLPixelAttributes.convert(PixelFormat pixFmt, GLProfile glp);
+ * </pre>
+ * </p>
+ * <p>
+ * See OpenGL Specification 4.3 - February 14, 2013, Core Profile,
+ * Section 8.4.4 Transfer of Pixel Rectangles, p. 161-174.
+ * </ul>
+ *
+ * </p>
+ */
+public enum PixelFormat {
+    /**
+     * Stride is 8 bits, 8 bits per pixel, 1 component of 8 bits.
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_ALPHA (< GL3), GL_RED (>= GL3), data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>none</i></li>
+     * </ul>
+     * </p>
+     */
+    LUMINANCE(new CType[]{ CType.Y }, 1, 8, 8),
+
+    /**
+     * Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
+     * <p>
+     * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>R: 0x1F <<  0</li>
+     *   <li>G: 0x3F <<  5</li>
+     *   <li>B: 0x1F << 11</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5_REV</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    RGB565(new CType[]{ CType.R, CType.G, CType.B },
+           new int[]{   0x1F,    0x3F,    0x1F },
+           new int[]{   0,       5,       5+6 },
+           16 ),
+
+    /**
+     * Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
+     * <p>
+     * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>B: 0x1F <<  0</li>
+     *   <li>G: 0x3F <<  5</li>
+     *   <li>R: 0x1F << 11</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    BGR565(new CType[]{ CType.B, CType.G, CType.R},
+           new int[]{   0x1F,    0x3F,    0x1F },
+           new int[]{   0,       5,       5+6 },
+           16 ),
+
+    /**
+     * Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
+     * <p>
+     * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>R: 0x1F <<  0</li>
+     *   <li>G: 0x1F <<  5</li>
+     *   <li>B: 0x1F << 10</li>
+     *   <li>A: 0x01 << 15</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_1_5_5_5_REV</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    RGBA5551(new CType[]{ CType.R, CType.G, CType.B, CType.A},
+             new int[]{   0x1F,    0x1F,    0x1F,    0x01 },
+             new int[]{   0,          5,    5+5,     5+5+5 },
+             16 ),
+
+    /**
+     * Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
+     * <p>
+     * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>A: 0x01 <<  0</li>
+     *   <li>B: 0x1F <<  1</li>
+     *   <li>G: 0x1F <<  6</li>
+     *   <li>R: 0x1F << 11</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_5_5_5_1</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    ABGR1555(new CType[]{ CType.A, CType.B, CType.G, CType.R },
+             new int[]{   0x01,    0x1F,    0x1F,    0x1F },
+             new int[]{   0,       1,       1+5,     1+5+5 },
+             16 ),
+
+    /**
+     * Stride 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>R: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>B: 0xFF << 16</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    RGB888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 24),
+
+    /**
+     * Stride is 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>B: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>R: 0xFF << 16</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGR (>= GL2), data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_3BYTE_BGR TYPE_3BYTE_BGR}</li>
+     * </ul>
+     * </p>
+     */
+    BGR888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 24),
+
+    /**
+     * Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>R: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>B: 0xFF << 16</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE, with alpha discarded!</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_BGR TYPE_INT_BGR}</li>
+     * </ul>
+     * </p>
+     */
+    RGBx8888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 32),
+
+    /**
+     * Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>B: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>R: 0xFF << 16</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE - with alpha discarded!</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_RGB TYPE_INT_RGB}</li>
+     * </ul>
+     * </p>
+     */
+    BGRx8888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 32),
+
+    /**
+     * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>R: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>B: 0xFF << 16</li>
+     *   <li>A: 0xFF << 24</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>None</i></li>
+     *   <li>PointerIcon: OSX (NSBitmapImageRep)</li>
+     *   <li>Window Icon: OSX (NSBitmapImageRep)</li>
+     *   <li>PNGJ: Scanlines</li>
+     * </ul>
+     * </p>
+     */
+    RGBA8888(new CType[]{ CType.R, CType.G, CType.B, CType.A }, 4, 8, 32),
+
+    /**
+     * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>A: 0xFF <<  0</li>
+     *   <li>B: 0xFF <<  8</li>
+     *   <li>G: 0xFF << 16</li>
+     *   <li>R: 0xFF << 24</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_4BYTE_ABGR TYPE_4BYTE_ABGR}</li>
+     * </ul>
+     * </p>
+     */
+    ABGR8888(new CType[]{ CType.A, CType.B, CType.G, CType.R }, 4, 8, 32),
+
+    /**
+     * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>A: 0xFF <<  0</li>
+     *   <li>R: 0xFF <<  8</li>
+     *   <li>G: 0xFF << 16</li>
+     *   <li>B: 0xFF << 24</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    ARGB8888(new CType[]{ CType.A, CType.R, CType.G, CType.B }, 4, 8, 32),
+
+    /**
+     * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
+     * <p>
+     * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
+     * are interleaved in the order Low to High:
+     * <ol>
+     *   <li>B: 0xFF <<  0</li>
+     *   <li>G: 0xFF <<  8</li>
+     *   <li>R: 0xFF << 16</li>
+     *   <li>A: 0xFF << 24</li>
+     * </ol>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}</li>
+     *   <li>PointerIcon: X11 (XCURSOR), Win32, AWT</li>
+     *   <li>Window Icon: X11, Win32</li>
+     * </ul>
+     * </p>
+     */
+    BGRA8888(new CType[]{ CType.B, CType.G, CType.R, CType.A }, 4, 8, 32);
+
+    /** Unique {@link Composition Pixel Composition}, i.e. layout of its components. */
+    public final Composition comp;
+
+    /**
+     * @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
+     * @param componentCount number of components
+     * @param bpc bits per component
+     * @param bitStride stride bits to next pixel
+     */
+    private PixelFormat(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
+        this.comp = new PackedComposition(componentOrder, componentCount, bpc, bitStride);
+    }
+
+    /**
+     * @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
+     * @param componentMask bit-mask of of all components, see {@link Composition##componentBitMask()}.
+     * @param componentBitShift bit-shift of all components, see {@link Composition##componentBitMask()}.
+     * @param bitStride stride bits to next pixel
+     */
+    private PixelFormat(final CType[] componentOrder, final int[] componentMask, final int[] componentBitShift, final int bitStride) {
+        this.comp = new PackedComposition(componentOrder, componentMask, componentBitShift, bitStride);
+    }
+
+    /**
+     * Returns the unique matching {@link PixelFormat} of the given {@link Composition}
+     * or {@code null} if none is available.
+     */
+    public static PixelFormat valueOf(final Composition comp) {
+        final PixelFormat[] all = PixelFormat.values();
+        for(int i=all.length-1; i>=0; i--) {
+            final PixelFormat pf = all[i];
+            if( comp.hashCode() == pf.comp.hashCode() && comp.equals(pf.comp) ) {
+                return pf;
+            }
+        }
+        return null;
+    }
+
+    /** Component types */
+    public static enum CType {
+        /** Red component */
+        R,
+        /** Green component */
+        G,
+        /** Blue component */
+        B,
+        /** Alpha component */
+        A,
+        /** Luminance component, e.g. grayscale or Y of YUV */
+        Y,
+        /** U component of YUV */
+        U,
+        /** V component of YUV */
+        V;
+    }
+
+    /**
+     * Pixel composition, i.e. layout of its components.
+     */
+    public static interface Composition {
+        /** {@value} */
+        public static final int UNDEF = -1;
+
+        /**
+         * Returns {@code true} if all components are of same bit-size, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
+         * otherwise {@code false}, e.g. {@link PixelFormat#RGBA5551 RGBA5551}
+         */
+        boolean isUniform();
+
+        /**
+         * Returns {@code true} if all components are packed, i.e. interleaved, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
+         * otherwise {@code false}.
+         */
+        boolean isInterleaved();
+
+        /** Number of components per pixel, e.g. 3 for {@link PixelFormat#RGBx8888 RGBx8888}. */
+        int componenCount();
+        /** Number of bits per pixel, e.g. 24 bits for {@link PixelFormat#RGBx8888 RGBx8888}. */
+        int bitsPerPixel();
+        /**
+         * Bit distance between pixels.
+         * <p>
+         * For packed pixels e.g. 32 bits for {@link PixelFormat#RGBx8888 RGBx8888}.
+         * </p>
+         */
+        int bitStride();
+        /** Number of bytes per pixel, i.e. packed {@link #bitStride()} in bytes, e.g. 4 for {@link PixelFormat#RGBx8888 RGBx8888}. */
+        int bytesPerPixel();
+        /**
+         * Returns the {@link CType Component type} order of all components, see {@link #componentBitMask()}.
+         */
+        CType[] componentOrder();
+        /**
+         * Returns the index of given {@link CType} within {@link #componentOrder()}, -1 if not exists.
+         */
+        int find(final PixelFormat.CType s);
+        /**
+         * Returns the un-shifted bit-mask of all components.
+         * <p>
+         * Components mask is returned in the order Low-Index to High-Index, e.g.:
+         * <ul>
+         *   <li>{@link PixelFormat#RGB565 RGB565}: 0: R 0x1F, 1: G 0x3F, 2: B 0x1F</li>
+         *   <li>{@link PixelFormat#RGBA5551 RGBA5551}: 0: R 0x1F, 1: G 0x1F, 2: B 0x1F, 3: A 0x01</li>
+         *   <li>{@link PixelFormat#RGBA8888 RGBA8888}: 0: R 0xFF, 1: G 0xFF, 2: B 0xFF, 3: A 0xFF</li>
+         * </ul>
+         * </p>
+         * <p>
+         */
+        int[] componentBitMask();
+        /**
+         * Returns the number of bits of all components, see {@link #componentBitMask()}.
+         */
+        int[] componentBitCount();
+        /**
+         * Returns the bit-shift of all components, see {@link #componentBitMask()}.
+         */
+        int[] componentBitShift();
+
+        /**
+         * Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 32bit.
+         * @param shifted complete pixel encoded into on 32bit integer
+         * @param cIdx the desired component index
+         * @return the decoded component value
+         */
+        int decodeSingleI32(final int shifted, final int cIdx);
+        /**
+         * Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 64bit.
+         * @param shifted complete pixel encoded into on 64bit integer
+         * @param cIdx the desired component index
+         * @return the decoded component value
+         */
+        int decodeSingleI64(final long shifted, final int cIdx);
+
+        int encodeSingleI32(final int norm, final int cIdx);
+        long encodeSingleI64(final int norm, final int cIdx);
+
+        int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32);
+        int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32);
+
+        int encodeSingleI8(final byte normalI8, final int cIdx);
+        int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8);
+        int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8);
+
+        float toFloat(final int i32, final int cIdx, final boolean i32Shifted);
+        int fromFloat(final float f, final int cIdx, final boolean shiftResult);
+
+        int defaultValue(final int cIdx, final boolean shiftResult);
+
+        /**
+         * Returns cached immutable hash value, see {@link Object#hashCode()}.
+         */
+        int hashCode();
+        /**
+         * Returns {@link Object#equals(Object)}
+         */
+        boolean equals(final Object o);
+
+        /**
+         * Returns {@link Object#toString()}.
+         */
+        String toString();
+    }
+
+    /**
+     * Packed pixel composition, see {@link Composition}.
+     * <p>
+     * Components are interleaved, i.e. packed.
+     * </p>
+     */
+    public static class PackedComposition implements Composition {
+        private final CType[] compOrder;
+        private final int[] compMask;
+        private final int[] compBitCount;
+        private final int[] compBitShift;
+        private final int bitsPerPixel;
+        private final int bitStride;
+        private final boolean uniform;
+        private final int hashCode;
+
+        public final String toString() {
+            return String.format("PackedComp[order %s, stride %d, bpp %d, uni %b, comp %d: %s]",
+                    Arrays.toString(compOrder), bitStride, bitsPerPixel, uniform,
+                    compMask.length, toHexString(compBitCount, compMask, compBitShift));
+        }
+
+        /**
+         * @param componentOrder {@link CType Component type} order of all components, see {@link #componentBitMask()}.
+         * @param componentCount number of components
+         * @param bpc bits per component
+         * @param bitStride stride bits to next pixel
+         */
+        public PackedComposition(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
+            this.compOrder = componentOrder;
+            this.compMask = new int[componentCount];
+            this.compBitShift = new int[componentCount];
+            this.compBitCount = new int[componentCount];
+            final int compMask = ( 1 << bpc ) - 1;
+            for(int i=0; i<componentCount; i++) {
+                this.compMask[i] = compMask;
+                this.compBitShift[i] = bpc * i;
+                this.compBitCount[i] = bpc;
+            }
+            this.uniform = true;
+            this.bitsPerPixel = bpc * componentCount;
+            this.bitStride = bitStride;
+            if( this.bitStride < this.bitsPerPixel ) {
+                throw new IllegalArgumentException(String.format("bit-stride %d < bitsPerPixel %d", this.bitStride, this.bitsPerPixel));
+            }
+            this.hashCode = hashCodeImpl();
+        }
+
+        /**
+         * @param componentOrder {@link CType Component type} order of all components, see {@link #componentBitMask()}.
+         * @param componentMask bit-mask of of all components, see {@link #componentBitMask()}.
+         * @param componentBitShift bit-shift of all components, see {@link #componentBitMask()}.
+         * @param bitStride stride bits to next pixel
+         */
+        public PackedComposition(final CType[] componentOrder, final int[] componentMask, final int[] componentBitShift, final int bitStride) {
+            this.compOrder = componentOrder;
+            this.compMask = componentMask;
+            this.compBitShift = componentBitShift;
+            this.compBitCount = new int[componentMask.length];
+            int bpp = 0;
+            boolean uniform = true;
+            for(int i = componentMask.length-1; i>=0; i--) {
+                final int cmask = componentMask[i];
+                final int bitCount = IntBitfield.getBitCount(cmask);
+                bpp += bitCount;
+                this.compBitCount[i] = bitCount;
+                if( i > 0 && uniform ) {
+                    uniform = componentMask[i-1] == cmask;
+                }
+            }
+            this.uniform = uniform;
+            this.bitsPerPixel = bpp;
+            this.bitStride = bitStride;
+            if( this.bitStride < this.bitsPerPixel ) {
+                throw new IllegalArgumentException(String.format("bit-stride %d < bitsPerPixel %d", this.bitStride, this.bitsPerPixel));
+            }
+            this.hashCode = hashCodeImpl();
+        }
+
+        @Override
+        public final boolean isUniform() { return uniform; }
+        /**
+         * {@inheritDoc}
+         * <p>
+         * Instances of {@link PackedComposition} returns {@code true}.
+         * </p>
+         */
+        @Override
+        public final boolean isInterleaved() { return true; }
+        @Override
+        public final int componenCount() { return compMask.length; }
+        @Override
+        public final int bitsPerPixel() { return bitsPerPixel; }
+        @Override
+        public final int bitStride() { return bitStride; }
+        @Override
+        public final int bytesPerPixel() { return (7+bitStride)/8; }
+        @Override
+        public final CType[] componentOrder() { return compOrder; }
+        @Override
+        public final int find(final PixelFormat.CType s) { return PixelFormatUtil.find(s, compOrder, false /* mapRGB2Y */); }
+        @Override
+        public final int[] componentBitMask() { return compMask; }
+        @Override
+        public final int[] componentBitCount() { return compBitCount; }
+        @Override
+        public final int[] componentBitShift() { return compBitShift; }
+
+        @Override
+        public final int decodeSingleI32(final int shifted, final int cIdx) {
+            return ( shifted >>> compBitShift[cIdx] ) & compMask[cIdx];
+        }
+        @Override
+        public final int decodeSingleI64(final long shifted, final int cIdx) {
+            return ( (int)( 0xffffffffL & ( shifted >>> compBitShift[cIdx] ) ) ) & compMask[cIdx];
+        }
+        @Override
+        public final int encodeSingleI32(final int norm, final int cIdx) {
+            return ( norm & compMask[cIdx] ) << compBitShift[cIdx] ;
+        }
+        @Override
+        public final long encodeSingleI64(final int norm, final int cIdx) {
+            return ( 0xffffffffL & ( norm & compMask[cIdx] ) ) << compBitShift[cIdx] ;
+        }
+        @Override
+        public final int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32) {
+            return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
+                   ( c2NormI32 & compMask[1] ) << compBitShift[1] |
+                   ( c3NormI32 & compMask[2] ) << compBitShift[2] ;
+        }
+        @Override
+        public final int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32) {
+            return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
+                   ( c2NormI32 & compMask[1] ) << compBitShift[1] |
+                   ( c3NormI32 & compMask[2] ) << compBitShift[2] |
+                   ( c4NormI32 & compMask[3] ) << compBitShift[3] ;
+        }
+        @Override
+        public final int encodeSingleI8(final byte normI8, final int cIdx) {
+            return ( normI8 & compMask[cIdx] ) << compBitShift[cIdx] ;
+        }
+        @Override
+        public final int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8) {
+            return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
+                   ( c2NormI8 & compMask[1] ) << compBitShift[1] |
+                   ( c3NormI8 & compMask[2] ) << compBitShift[2] ;
+        }
+        @Override
+        public final int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8) {
+            return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
+                   ( c2NormI8 & compMask[1] ) << compBitShift[1] |
+                   ( c3NormI8 & compMask[2] ) << compBitShift[2] |
+                   ( c4NormI8 & compMask[3] ) << compBitShift[3] ;
+        }
+
+        @Override
+        public final float toFloat(final int i32, final int cIdx, final boolean i32Shifted) {
+            if( i32Shifted ) {
+                return ( ( i32 >>> compBitShift[cIdx] ) & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
+            } else {
+                return (   i32                          & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
+            }
+        }
+        @Override
+        public final int fromFloat(final float f, final int cIdx, final boolean shiftResult) {
+            final int v = (int)(f * compMask[cIdx] + 0.5f);
+            return shiftResult ? v << compBitShift[cIdx] : v;
+        }
+
+        @Override
+        public final int defaultValue(final int cIdx, final boolean shiftResult) {
+            final int v = ( CType.A == compOrder[cIdx] || CType.Y == compOrder[cIdx] )
+                          ? compMask[cIdx] : 0;
+            return shiftResult ? v << compBitShift[cIdx] : v;
+        }
+
+        @Override
+        public final int hashCode() { return hashCode; }
+        private final int hashCodeImpl() {
+            // 31 * x == (x << 5) - x
+            int hash = 31 + bitStride;
+            hash = ((hash << 5) - hash) + bitsPerPixel;
+            hash = ((hash << 5) - hash) + compMask.length;
+            for(int i=compOrder.length-1; i>=0; i--) {
+                hash = ((hash << 5) - hash) + compOrder[i].ordinal();
+            }
+            for(int i=compMask.length-1; i>=0; i--) {
+                hash = ((hash << 5) - hash) + compMask[i];
+            }
+            for(int i=compBitShift.length-1; i>=0; i--) {
+                hash = ((hash << 5) - hash) + compBitShift[i];
+            }
+            return hash;
+        }
+
+        @Override
+        public final boolean equals(final Object obj) {
+            if(this == obj)  { return true; }
+            if( obj instanceof PackedComposition ) {
+                final PackedComposition other = (PackedComposition) obj;
+                return bitStride == other.bitStride &&
+                       bitsPerPixel == other.bitsPerPixel &&
+                       Arrays.equals(compOrder, other.compOrder) &&
+                       Arrays.equals(compMask, other.compMask) &&
+                       Arrays.equals(compBitShift, other.compBitShift);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private static String toHexString(final int[] bitCount, final int[] mask, final int[] shift) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        final int l = mask.length;
+        for(int i=0; i < l; i++) {
+            if(i > 0) {
+                sb.append(", ");
+            }
+            sb.append(bitCount[i]).append(": ").
+            append("0x").append(Integer.toHexString(mask[i])).append(" << ").append(shift[i]);
+        }
+        return sb.append("]").toString();
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java
new file mode 100644
index 000000000..180f02d72
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java
@@ -0,0 +1,600 @@
+/**
+ * Copyright (c) 2014 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.util;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.Bitstream;
+
+/**
+ * Pixel Rectangle Utilities.
+ * <p>
+ * All conversion methods are endian independent.
+ * </p>
+ */
+public class PixelFormatUtil {
+    private static boolean DEBUG = false;
+
+    public static class ComponentMap {
+        /**
+         * Contains the source index for each destination index,
+         * length is {@link Composition#componenCount()} of destination.
+         */
+        final int[] dst2src;
+        /**
+         * Contains the destination index for each source index,
+         * length is {@link Composition#componenCount()} of source.
+         */
+        final int[] src2dst;
+
+        /**
+         * Contains the source index of RGBA components.
+         */
+        final int[] srcRGBA;
+        final boolean hasSrcRGB;
+
+        public ComponentMap(final PixelFormat.Composition src, final PixelFormat.Composition dst) {
+            final int sCompCount = src.componenCount();
+            final int dCompCount = dst.componenCount();
+            final PixelFormat.CType[] sCompOrder = src.componentOrder();
+            final PixelFormat.CType[] dCompOrder = dst.componentOrder();
+
+            dst2src = new int[dCompCount];
+            for(int dIdx=0; dIdx<dCompCount; dIdx++) {
+                dst2src[dIdx] = PixelFormatUtil.find(dCompOrder[dIdx], sCompOrder, true);
+            }
+            src2dst = new int[sCompCount];
+            for(int sIdx=0; sIdx<sCompCount; sIdx++) {
+                src2dst[sIdx] = PixelFormatUtil.find(sCompOrder[sIdx], dCompOrder, true);
+            }
+            srcRGBA = new int[4];
+            srcRGBA[0] = PixelFormatUtil.find(PixelFormat.CType.R, sCompOrder, false);
+            srcRGBA[1] = PixelFormatUtil.find(PixelFormat.CType.G, sCompOrder, false);
+            srcRGBA[2] = PixelFormatUtil.find(PixelFormat.CType.B, sCompOrder, false);
+            srcRGBA[3] = PixelFormatUtil.find(PixelFormat.CType.A, sCompOrder, false);
+            hasSrcRGB = 0 <= srcRGBA[0] && 0 <= srcRGBA[1] && 0 <= srcRGBA[2];
+        }
+    }
+
+    public static final int find(final PixelFormat.CType s,
+                                 final PixelFormat.CType[] pool, final boolean mapRGB2Y) {
+        int i=pool.length-1;
+        while( i >= 0 && pool[i] != s) { i--; }
+
+        if( 0 > i && mapRGB2Y && 1 == pool.length && pool[0] == PixelFormat.CType.Y &&
+            ( PixelFormat.CType.R == s ||
+              PixelFormat.CType.G == s ||
+              PixelFormat.CType.B == s ) )
+        {
+            // Special case, fallback for RGB mapping -> LUMINANCE/Y
+            return 0;
+        } else {
+            return i;
+        }
+    }
+
+    /**
+     * Returns shifted bytes from the given {@code data} at given {@code offset}
+     * of maximal 4 {@code bytesPerPixel}.
+     * @param bytesPerPixel number of bytes per pixel to fetch, a maximum of 4 are allowed
+     * @param data byte buffer covering complete pixel at position {@code offset}
+     * @param offset byte offset of pixel {@code data} start
+     * @return the shifted 32bit integer value of the pixel
+     */
+    public static int getShiftedI32(final int bytesPerPixel, final byte[] data, final int offset) {
+        if( bytesPerPixel <= 4 ) {
+            int shiftedI32 = 0;
+            for(int i=0; i<bytesPerPixel; i++) {
+                shiftedI32 |= ( 0xff & data[offset+i] ) << 8*i;
+            }
+            return shiftedI32;
+        } else {
+            throw new UnsupportedOperationException(bytesPerPixel+" bytesPerPixel too big, i.e. > 4");
+        }
+    }
+    /**
+     * Returns shifted bytes from the given {@code data} at given {@code offset}
+     * of maximal 8 {@code bytesPerPixel}.
+     * @param bytesPerPixel number of bytes per pixel to fetch, a maximum of 4 are allowed
+     * @param data byte buffer covering complete pixel at position {@code offset}
+     * @param offset byte offset of pixel {@code data} start
+     * @return the shifted 64bit integer value of the pixel
+     */
+    public static long getShiftedI64(final int bytesPerPixel, final byte[] data, final int offset) {
+        if( bytesPerPixel <= 8 ) {
+            long shiftedI64 = 0;
+            for(int i=0; i<bytesPerPixel; i++) {
+                shiftedI64 |= ( 0xff & data[offset+i] ) << 8*i;
+            }
+            return shiftedI64;
+        } else {
+            throw new UnsupportedOperationException(bytesPerPixel+" bytesPerPixel too big, i.e. > 8");
+        }
+    }
+    /**
+     * Returns shifted bytes from the given {@code data} at current position
+     * of maximal 4 {@code bytesPerPixel}.
+     * @param bytesPerPixel number of bytes per pixel to fetch, a maximum of 4 are allowed
+     * @param data byte buffer covering complete pixel at position {@code offset}
+     * @param retainDataPos if true, absolute {@link ByteBuffer#get(int)} is used and the {@code data} position stays unchanged.
+     *                      Otherwise relative {@link ByteBuffer#get()} is used and the {@code data} position changes.
+     * @return the shifted 32bit integer value of the pixel
+     */
+    public static int getShiftedI32(final int bytesPerPixel, final ByteBuffer data, final boolean retainDataPos) {
+        if( bytesPerPixel <= 4 ) {
+            int shiftedI32 = 0;
+            if( retainDataPos ) {
+                final int offset = data.position();
+                for(int i=0; i<bytesPerPixel; i++) {
+                    shiftedI32 |= ( 0xff & data.get(offset+i) ) << 8*i;
+                }
+            } else {
+                for(int i=0; i<bytesPerPixel; i++) {
+                    shiftedI32 |= ( 0xff & data.get() ) << 8*i;
+                }
+            }
+            return shiftedI32;
+        } else {
+            throw new UnsupportedOperationException(bytesPerPixel+" bytesPerPixel too big, i.e. > 4");
+        }
+    }
+    /**
+     * Returns shifted bytes from the given {@code data} at current position
+     * of maximal 8 {@code bytesPerPixel}.
+     * @param bytesPerPixel number of bytes per pixel to fetch, a maximum of 4 are allowed
+     * @param data byte buffer covering complete pixel at position {@code offset}
+     * @param retainDataPos if true, absolute {@link ByteBuffer#get(int)} is used and the {@code data} position stays unchanged.
+     *                      Otherwise relative {@link ByteBuffer#get()} is used and the {@code data} position changes.
+     * @return the shifted 64bit integer value of the pixel
+     */
+    public static long getShiftedI64(final int bytesPerPixel, final ByteBuffer data, final boolean retainDataPos) {
+        if( bytesPerPixel <= 8 ) {
+            long shiftedI64 = 0;
+            if( retainDataPos ) {
+                final int offset = data.position();
+                for(int i=0; i<bytesPerPixel; i++) {
+                    shiftedI64 |= ( 0xff & data.get(offset+i) ) << 8*i;
+                }
+            } else {
+                for(int i=0; i<bytesPerPixel; i++) {
+                    shiftedI64 |= ( 0xff & data.get() ) << 8*i;
+                }
+            }
+            return shiftedI64;
+        } else {
+            throw new UnsupportedOperationException(bytesPerPixel+" bytesPerPixel too big, i.e. > 8");
+        }
+    }
+
+    /**
+     * Returns the {@link PixelFormat} with reversed components of <code>fmt</code>.
+     * If no reversed  {@link PixelFormat} is available, returns <code>fmt</code>.
+     */
+    public static PixelFormat getReversed(final PixelFormat fmt) {
+        switch(fmt) {
+            case RGB565:
+                return PixelFormat.BGR565;
+            case BGR565:
+                return PixelFormat.RGB565;
+            case RGBA5551:
+                return PixelFormat.ABGR1555;
+            case ABGR1555:
+                return PixelFormat.RGBA5551;
+            case RGB888:
+                return PixelFormat.BGR888;
+            case BGR888:
+                return PixelFormat.RGB888;
+            case RGBA8888:
+                return PixelFormat.ABGR8888;
+            case ABGR8888:
+                return PixelFormat.RGBA8888;
+            case ARGB8888:
+                return PixelFormat.BGRA8888;
+            case BGRA8888:
+                return PixelFormat.ABGR8888;
+            default:
+                return fmt;
+        }
+    }
+
+    public static int convertToInt32(final PixelFormat dst_fmt, final byte r, final byte g, final byte b, final byte a) {
+        switch(dst_fmt) {
+            case LUMINANCE: {
+                final byte l = ( byte) ( ( ( ( 0xff & r ) + ( 0xff & g ) + ( 0xff & b ) ) / 3 ) * a );
+                return ( 0xff     ) << 24 | ( 0xff & l ) << 16 | ( 0xff & l ) << 8 | ( 0xff & l );
+            }
+            case RGB888:
+                return ( 0xff     ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+            case BGR888:
+                return ( 0xff     ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+            case RGBA8888:
+                return ( 0xff & a ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+            case ABGR8888:
+                return ( 0xff & r ) << 24 | ( 0xff & g ) << 16 | ( 0xff & b ) << 8 | ( 0xff & a );
+            case ARGB8888:
+                return ( 0xff & b ) << 24 | ( 0xff & g ) << 16 | ( 0xff & r ) << 8 | ( 0xff & a );
+            case BGRA8888:
+                return ( 0xff & a ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+            default:
+                throw new InternalError("Unhandled format "+dst_fmt);
+        }
+    }
+
+    public static int convertToInt32(final PixelFormat dst_fmt, final PixelFormat src_fmt, final ByteBuffer src, int srcOff) {
+        final byte r, g, b, a;
+        switch(src_fmt) {
+            case LUMINANCE:
+                r  = src.get(srcOff++); // R
+                g  = r;                 // G
+                b  = r;                 // B
+                a  = (byte) 0xff;       // A
+                break;
+            case RGB888:
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                a  = (byte) 0xff;       // A
+                break;
+            case BGR888:
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                a  = (byte) 0xff;       // A
+                break;
+            case RGBA8888:
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                a  = src.get(srcOff++); // A
+                break;
+            case ABGR8888:
+                a  = src.get(srcOff++); // A
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                break;
+            case ARGB8888:
+                a  = src.get(srcOff++); // A
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                break;
+            case BGRA8888:
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                a  = src.get(srcOff++); // A
+                break;
+            default:
+                throw new InternalError("Unhandled format "+src_fmt);
+        }
+        return convertToInt32(dst_fmt, r, g, b, a);
+    }
+
+    public static int convertToInt32(final PixelFormat dest_fmt, final PixelFormat src_fmt, final int src_pixel) {
+        final byte r, g, b, a;
+        switch(src_fmt) {
+            case LUMINANCE:
+                r  = (byte) ( src_pixel       );  // R
+                g  = r;                           // G
+                b  = r;                           // B
+                a  = (byte) 0xff;                 // A
+                break;
+            case RGB888:
+                r  = (byte) ( src_pixel        ); // R
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                b  = (byte) ( src_pixel >>> 16 ); // B
+                a  = (byte) 0xff;                 // A
+                break;
+            case BGR888:
+                b  = (byte) ( src_pixel        ); // B
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                r  = (byte) ( src_pixel >>> 16 ); // R
+                a  = (byte) 0xff;                 // A
+                break;
+            case RGBA8888:
+                r  = (byte) ( src_pixel        ); // R
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                b  = (byte) ( src_pixel >>> 16 ); // B
+                a  = (byte) ( src_pixel >>> 24 ); // A
+                break;
+            case ABGR8888:
+                a  = (byte) ( src_pixel        ); // A
+                b  = (byte) ( src_pixel >>>  8 ); // B
+                g  = (byte) ( src_pixel >>> 16 ); // G
+                r  = (byte) ( src_pixel >>> 24 ); // R
+                break;
+            case ARGB8888:
+                a  = (byte) ( src_pixel        ); // A
+                r  = (byte) ( src_pixel >>>  8 ); // R
+                g  = (byte) ( src_pixel >>> 16 ); // G
+                b  = (byte) ( src_pixel >>> 24 ); // B
+                break;
+            case BGRA8888:
+                b  = (byte) ( src_pixel        ); // B
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                r  = (byte) ( src_pixel >>> 16 ); // R
+                a  = (byte) ( src_pixel >>> 24 ); // A
+                break;
+            default:
+                throw new InternalError("Unhandled format "+src_fmt);
+        }
+        return convertToInt32(dest_fmt, r, g, b, a);
+    }
+
+    public static PixelRectangle convert(final PixelRectangle src,
+                                         final PixelFormat destFmt, final int ddestStride, final boolean isGLOriented,
+                                         final boolean destIsDirect) {
+        final int width = src.getSize().getWidth();
+        final int height = src.getSize().getHeight();
+        final int bpp = destFmt.comp.bytesPerPixel();
+        final int destStride;
+        if( 0 != ddestStride ) {
+            destStride = ddestStride;
+        } else {
+            destStride = bpp * width;
+        }
+        final int capacity = destStride*height;
+        final ByteBuffer destBB = destIsDirect ? Buffers.newDirectByteBuffer(capacity) : ByteBuffer.allocate(capacity).order(src.getPixels().order());
+        convert(src, destBB, destFmt, isGLOriented, destStride);
+        return new PixelRectangle.GenericPixelRect(destFmt, src.getSize(), destStride, isGLOriented, destBB);
+    }
+
+    /**
+     * @param src
+     * @param dst_bb  {@link ByteBuffer} sink
+     * @param dst_fmt destination {@link PixelFormat}
+     * @param dst_glOriented if true, the source memory is laid out in OpenGL's coordinate system, <i>origin at bottom left</i>,
+     *                       otherwise <i>origin at top left</i>.
+     * @param dst_lineStride line stride in byte-size for destination, i.e. byte count from one line to the next.
+     *                       Must be >= {@link PixelFormat.Composition#bytesPerPixel() dst_fmt.comp.bytesPerPixel()} * width
+     *                       or {@code zero} for default stride.
+     *
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException if {@code src_lineStride} or {@code dst_lineStride} is invalid
+     */
+    public static void convert(final PixelRectangle src,
+                               final ByteBuffer dst_bb, final PixelFormat dst_fmt, final boolean dst_glOriented, final int dst_lineStride)
+           throws IllegalStateException
+    {
+        convert(src.getSize().getWidth(), src.getSize().getHeight(),
+                src.getPixels(), src.getPixelformat(), src.isGLOriented(), src.getStride(),
+                dst_bb, dst_fmt, dst_glOriented, dst_lineStride);
+    }
+
+
+    /**
+     * @param width width of the to be converted pixel rectangle
+     * @param height height of the to be converted pixel rectangle
+     * @param src_bb  {@link ByteBuffer} source
+     * @param src_fmt source {@link PixelFormat}
+     * @param src_glOriented if true, the source memory is laid out in OpenGL's coordinate system, <i>origin at bottom left</i>,
+     *                       otherwise <i>origin at top left</i>.
+     * @param src_lineStride line stride in byte-size for source, i.e. byte count from one line to the next.
+     *                       Must be >= {@link PixelFormat.Composition#bytesPerPixel() src_fmt.comp.bytesPerPixel()} * width
+     *                       or {@code zero} for default stride.
+     * @param dst_bb  {@link ByteBuffer} sink
+     * @param dst_fmt destination {@link PixelFormat}
+     * @param dst_glOriented if true, the source memory is laid out in OpenGL's coordinate system, <i>origin at bottom left</i>,
+     *                       otherwise <i>origin at top left</i>.
+     * @param dst_lineStride line stride in byte-size for destination, i.e. byte count from one line to the next.
+     *                       Must be >= {@link PixelFormat.Composition#bytesPerPixel() dst_fmt.comp.bytesPerPixel()} * width
+     *                       or {@code zero} for default stride.
+     *
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException if {@code src_lineStride} or {@code dst_lineStride} is invalid
+     */
+    public static void convert(final int width, final int height,
+                               final ByteBuffer src_bb, final PixelFormat src_fmt, final boolean src_glOriented, int src_lineStride,
+                               final ByteBuffer dst_bb, final PixelFormat dst_fmt, final boolean dst_glOriented, int dst_lineStride
+                              ) throws IllegalStateException, IllegalArgumentException {
+        final PixelFormat.Composition src_comp = src_fmt.comp;
+        final PixelFormat.Composition dst_comp = dst_fmt.comp;
+        final int src_bpp = src_comp.bytesPerPixel();
+        final int dst_bpp = dst_comp.bytesPerPixel();
+
+        if( 0 != src_lineStride ) {
+            if( src_lineStride < src_bpp * width ) {
+                throw new IllegalArgumentException(String.format("Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
+                        "source", src_lineStride, src_bpp, width));
+            }
+        } else {
+            src_lineStride = src_bpp * width;
+        }
+        if( 0 != dst_lineStride ) {
+            if( dst_lineStride < dst_bpp * width ) {
+                throw new IllegalArgumentException(String.format("Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
+                        "destination", dst_lineStride, dst_bpp, width));
+            }
+        } else {
+            dst_lineStride = dst_bpp * width;
+        }
+
+        // final int src_comp_bitStride = src_comp.bitStride();
+        final int dst_comp_bitStride = dst_comp.bitStride();
+        final boolean vert_flip = src_glOriented != dst_glOriented;
+        final boolean fast_copy = src_comp.equals(dst_comp) && 0 == dst_comp_bitStride%8;
+        if( DEBUG ) {
+            System.err.println("XXX: size "+width+"x"+height+", fast_copy "+fast_copy);
+            System.err.println("XXX: SRC fmt "+src_fmt+", "+src_comp+", stride "+src_lineStride+", isGLOrient "+src_glOriented);
+            System.err.println("XXX: DST fmt "+dst_fmt+", "+dst_comp+", stride "+dst_lineStride+", isGLOrient "+dst_glOriented);
+        }
+
+        if( fast_copy ) {
+            // Fast copy
+            for(int y=0; y<height; y++) {
+                int src_off = vert_flip ? ( height - 1 - y ) * src_lineStride : y * src_lineStride;
+                int dst_off = dst_lineStride*y;
+                for(int x=0; x<width; x++) {
+                    dst_bb.put(dst_off+0, src_bb.get(src_off+0)); // 1
+                    if( 2 <= dst_bpp ) {
+                        dst_bb.put(dst_off+1, src_bb.get(src_off+1)); // 2
+                        if( 3 <= dst_bpp ) {
+                            dst_bb.put(dst_off+2, src_bb.get(src_off+2)); // 3
+                            if( 4 <= dst_bpp ) {
+                                dst_bb.put(dst_off+3, src_bb.get(src_off+3)); // 4
+                            }
+                        }
+                    }
+                    src_off += src_bpp;
+                    dst_off += dst_bpp;
+                }
+            }
+        } else {
+            // Conversion
+            final ComponentMap cmap = new ComponentMap(src_fmt.comp, dst_fmt.comp);
+
+            final Bitstream.ByteBufferStream srcBBS = new Bitstream.ByteBufferStream(src_bb);
+            final Bitstream<ByteBuffer> srcBitStream = new Bitstream<ByteBuffer>(srcBBS, false /* outputMode */);
+            srcBitStream.setThrowIOExceptionOnEOF(true);
+
+            final Bitstream.ByteBufferStream dstBBS = new Bitstream.ByteBufferStream(dst_bb);
+            final Bitstream<ByteBuffer> dstBitStream = new Bitstream<ByteBuffer>(dstBBS, true /* outputMode */);
+            dstBitStream.setThrowIOExceptionOnEOF(true);
+
+            if( DEBUG ) {
+                System.err.println("XXX: cmap.dst2src "+Arrays.toString(cmap.dst2src));
+                System.err.println("XXX: cmap.src2dst "+Arrays.toString(cmap.src2dst));
+                System.err.println("XXX: cmap.srcRGBA "+Arrays.toString(cmap.srcRGBA));
+                System.err.println("XXX: srcBitStream "+srcBitStream);
+                System.err.println("XXX: dstBitStream "+dstBitStream);
+            }
+            try {
+                for(int y=0; y<height; y++) {
+                    final int src_off = vert_flip ? ( height - 1 - y ) * src_lineStride * 8 : y * src_lineStride * 8;
+                    // final int dst_off = dst_lineStride*8*y;
+                    srcBitStream.position(src_off);
+                    for(int x=0; x<width; x++) {
+                        convert(cmap, dst_comp, dstBitStream, src_comp, srcBitStream);
+                    }
+                    // srcBitStream.skip(( src_lineStride * 8 ) - ( src_comp_bitStride * width ));
+                    dstBitStream.skip(( dst_lineStride * 8 ) - ( dst_comp_bitStride * width ));
+                }
+            } catch(final IOException ioe) {
+                throw new RuntimeException(ioe);
+            }
+            if( DEBUG ) {
+                System.err.println("XXX: srcBitStream "+srcBitStream);
+                System.err.println("XXX: dstBitStream "+dstBitStream);
+            }
+        }
+    }
+
+    public static void convert(final ComponentMap cmap,
+                               final PixelFormat.Composition dstComp,
+                               final Bitstream<ByteBuffer> dstBitStream,
+                               final PixelFormat.Composition srcComp,
+                               final Bitstream<ByteBuffer> srcBitStream) throws IllegalStateException, IOException {
+        final int sCompCount = srcComp.componenCount();
+        final int dCompCount = dstComp.componenCount();
+        final int[] sc = new int[sCompCount];
+        final int[] dcDef = new int[dCompCount];
+        final int[] srcCompBitCount = srcComp.componentBitCount();
+        final int[] srcCompBitMask = srcComp.componentBitMask();
+        final int[] dstCompBitCount = dstComp.componentBitCount();
+
+        // Fill w/ source values
+        for(int sIdx=0; sIdx<sCompCount; sIdx++) {
+            sc[sIdx] = srcBitStream.readBits31(srcCompBitCount[sIdx]) & srcCompBitMask[sIdx];
+        }
+        srcBitStream.skip(srcComp.bitStride() - srcComp.bitsPerPixel());
+
+        // Cache missing defaults
+        for(int i=0; i<dCompCount; i++) {
+            dcDef[i] = dstComp.defaultValue(i, false);
+        }
+
+        if( 1 == dCompCount &&
+            PixelFormat.CType.Y == dstComp.componentOrder()[0] &&
+            cmap.hasSrcRGB
+          )
+        {
+            // RGB[A] -> Y conversion
+            final int r = sc[cmap.srcRGBA[0]];
+            final int g = sc[cmap.srcRGBA[1]];
+            final int b = sc[cmap.srcRGBA[2]];
+            final float rF = srcComp.toFloat(r, cmap.srcRGBA[0], false);
+            final float gF = srcComp.toFloat(g, cmap.srcRGBA[1], false);
+            final float bF = srcComp.toFloat(b, cmap.srcRGBA[2], false);
+            final int a;
+            final float aF;
+            /** if( 0 <= cmap.srcRGBA[3] ) { // disable premultiplied-alpha
+                a = sc[cmap.srcRGBA[3]];
+                aF = srcComp.toFloat(a, false, cmap.srcRGBA[3]);
+            } else */ {
+                a = 1;
+                aF = 1f;
+            }
+            final float lF = ( rF + gF + bF ) * aF / 3f;
+            final int v = dstComp.fromFloat(lF, 0, false);
+
+            dstBitStream.writeBits31(dstCompBitCount[0], v);
+            dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
+            if( DEBUG ) {
+                if( srcBitStream.position() <= 8*4 ) {
+                    System.err.printf("convert: rgb[a] -> Y: rgb 0x%02X 0x%02X 0x%02X 0x%02X -> %f %f %f %f"+
+                            " -> %f -> dstC 0 0x%08X (%d bits: %s)%n",
+                            r, g, b, a,
+                            rF, gF, bF, aF,
+                            lF, v, dstCompBitCount[0], Bitstream.toBinString(true, v, dstCompBitCount[0])
+                            );
+                }
+            }
+            return;
+        }
+
+        for(int dIdx=0; dIdx<dCompCount; dIdx++) {
+            int sIdx;
+            if( 0 <= ( sIdx = cmap.dst2src[dIdx] ) ) {
+                final float f = srcComp.toFloat(sc[sIdx], sIdx, false);
+                final int v = dstComp.fromFloat(f, dIdx, false);
+                dstBitStream.writeBits31(dstCompBitCount[dIdx], v);
+                if( DEBUG ) {
+                    if( srcBitStream.position() <= 8*4 ) {
+                        System.err.printf("convert: srcC %d: 0x%08X -> %f -> dstC %d 0x%08X (%d bits: %s)%n",
+                                sIdx, sc[sIdx], f, dIdx, v, dstCompBitCount[dIdx], Bitstream.toBinString(true, v, dstCompBitCount[dIdx]));
+                    }
+                }
+            } else {
+                dstBitStream.writeBits31(dstCompBitCount[dIdx], dcDef[dIdx]);
+                if( DEBUG ) {
+                    if( srcBitStream.position() <= 8*4 ) {
+                        System.err.printf("convert: srcC %d: undef -> dstC %d 0x%08X (%d bits: %s)%n",
+                                sIdx, dIdx, dcDef[dIdx], dstCompBitCount[dIdx], Bitstream.toBinString(true, dcDef[dIdx], dstCompBitCount[dIdx]));
+                    }
+                }
+            }
+        }
+        dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
+        return;
+    }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelRectangle.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelRectangle.java
new file mode 100644
index 000000000..f58ba0ce2
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelRectangle.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2014 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.util;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Pixel Rectangle identified by it's {@link #hashCode()}.
+ * <p>
+ * The {@link #getPixels()} are assumed to be immutable.
+ * </p>
+ */
+public interface PixelRectangle {
+    /**
+     * <p>
+     * Computes a hash code over:
+     * <ul>
+     *   <li>pixelformat</li>
+     *   <li>size</li>
+     *   <li>stride</li>
+     *   <li>isGLOriented</li>
+     *   <li>pixels</li>
+     * </ul>
+     * </p>
+     * <p>
+     * The hashCode shall be computed only once with first call
+     * and stored for later retrieval to enhance performance.
+     * </p>
+     * <p>
+     * {@inheritDoc}
+     * </p>
+     */
+    @Override
+    int hashCode();
+
+    /** Returns the {@link PixelFormat}. */
+    PixelFormat getPixelformat();
+
+    /** Returns the size, i.e. width and height. */
+    DimensionImmutable getSize();
+
+    /**
+     * Returns stride in byte-size, i.e. byte count from one line to the next.
+     * <p>
+     * Must be >= {@link #getPixelformat()}.{@link PixelFormat#bytesPerPixel() bytesPerPixel()} * {@link #getSize()}.{@link DimensionImmutable#getWidth() getWidth()}.
+     * </p>
+     */
+    int getStride();
+
+    /**
+     * Returns <code>true</code> if the memory is laid out in
+     * OpenGL's coordinate system, <i>origin at bottom left</i>.
+     * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
+     */
+    public boolean isGLOriented();
+
+    /** Returns the pixels. */
+    ByteBuffer getPixels();
+
+    @Override
+    String toString();
+
+    /**
+     * Generic PixelRectangle implementation
+     */
+    public static class GenericPixelRect implements PixelRectangle {
+        protected final PixelFormat pixelformat;
+        protected final DimensionImmutable size;
+        protected final int strideInBytes;
+        protected final boolean isGLOriented;
+        protected final ByteBuffer pixels;
+        private int hashCode = 0;
+        private volatile boolean hashCodeComputed = false;
+
+        /**
+         *
+         * @param pixelformat
+         * @param size
+         * @param strideInBytes stride in byte-size, i.e. byte count from one line to the next.
+         *                      If not zero, value must be >= <code>width * bytes-per-pixel</code>.
+         *                      If zero, stride is set to <code>width * bytes-per-pixel</code>.
+         * @param isGLOriented
+         * @param pixels
+         * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+         * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+         */
+        public GenericPixelRect(final PixelFormat pixelformat, final DimensionImmutable size, int strideInBytes, final boolean isGLOriented, final ByteBuffer pixels)
+                throws IllegalArgumentException, IndexOutOfBoundsException
+        {
+            if( 0 != strideInBytes ) {
+                if( strideInBytes < pixelformat.comp.bytesPerPixel() * size.getWidth()) {
+                    throw new IllegalArgumentException("Invalid stride "+strideInBytes+", must be greater than bytesPerPixel "+pixelformat.comp.bytesPerPixel()+" * width "+size.getWidth());
+                }
+            } else {
+                strideInBytes = pixelformat.comp.bytesPerPixel() * size.getWidth();
+            }
+            final int reqBytes = strideInBytes * size.getHeight();
+            if( pixels.limit() < reqBytes ) {
+                throw new IndexOutOfBoundsException("Dest buffer has insufficient bytes left, needs "+reqBytes+": "+pixels);
+            }
+            this.pixelformat = pixelformat;
+            this.size = size;
+            this.strideInBytes = strideInBytes;
+            this.isGLOriented = isGLOriented;
+            this.pixels = pixels;
+        }
+
+        /**
+         * Copy ctor validating src.
+         * @param src
+         * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+         * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+         */
+        public GenericPixelRect(final PixelRectangle src)
+                throws IllegalArgumentException, IndexOutOfBoundsException
+        {
+            this(src.getPixelformat(), src.getSize(), src.getStride(), src.isGLOriented(), src.getPixels());
+        }
+
+        @Override
+        public int hashCode() {
+            if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE
+                synchronized (this) {
+                    if( !hashCodeComputed ) {
+                        // 31 * x == (x << 5) - x
+                        int hash = pixelformat.comp.hashCode();
+                        hash = ((hash << 5) - hash) + size.hashCode();
+                        hash = ((hash << 5) - hash) + strideInBytes;
+                        hash = ((hash << 5) - hash) + ( isGLOriented ? 1 : 0);
+                        hashCode = ((hash << 5) - hash) + pixels.hashCode();
+                        hashCodeComputed = true;
+                    }
+                }
+            }
+            return hashCode;
+        }
+
+        @Override
+        public PixelFormat getPixelformat() {
+            return pixelformat;
+        }
+
+        @Override
+        public DimensionImmutable getSize() {
+            return size;
+        }
+
+        @Override
+        public int getStride() {
+            return strideInBytes;
+        }
+
+        @Override
+        public boolean isGLOriented() {
+            return isGLOriented;
+        }
+
+        @Override
+        public ByteBuffer getPixels() {
+            return pixels;
+        }
+
+        @Override
+        public final String toString() {
+            return "PixelRect[obj 0x"+Integer.toHexString(super.hashCode())+", "+pixelformat+", "+size+", stride "+strideInBytes+", isGLOrient "+isGLOriented+", pixels "+pixels+"]";
+        }
+    }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
new file mode 100644
index 000000000..fc5465bbf
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
@@ -0,0 +1,190 @@
+/**
+ * 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 com.jogamp.nativewindow.util;
+
+public class Point implements Cloneable, PointImmutable {
+    int x;
+    int y;
+
+    public Point(final int x, final int y) {
+        this.x=x;
+        this.y=y;
+    }
+
+    public Point() {
+        this(0, 0);
+    }
+
+    @Override
+    public Object cloneMutable() {
+      return clone();
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException ex) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int compareTo(final PointImmutable d) {
+        final int sq = x*y;
+        final int xsq = d.getX()*d.getY();
+
+        if(sq > xsq) {
+            return 1;
+        } else if(sq < xsq) {
+            return -1;
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if(this == obj)  { return true; }
+        if (obj instanceof Point) {
+            final Point p = (Point)obj;
+            return y == p.y && x == p.x;
+        }
+        return false;
+    }
+
+    @Override
+    public final int getX() {
+        return x;
+    }
+
+    @Override
+    public final int getY() {
+        return y;
+    }
+
+    @Override
+    public int hashCode() {
+        // 31 * x == (x << 5) - x
+        int hash = 31 + x;
+        hash = ((hash << 5) - hash) + y;
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return x + " / " + y;
+    }
+
+    public final void set(final int x, final int y) { this.x = x; this.y = y; }
+    public final void setX(final int x) { this.x = x; }
+    public final void setY(final int y) { this.y = y; }
+
+    /**
+     * Translate this instance's x- and y-components,
+     * i.e. add the values of the given delta point to them.
+     * @param pd delta point
+     * @return this instance for scaling
+     */
+    public final Point translate(final Point pd) {
+        x += pd.x ;
+        y += pd.y ;
+        return this;
+    }
+
+    /**
+     * Translate this instance's x- and y-components,
+     * i.e. add the given deltas to them.
+     * @param dx delta for x
+     * @param dy delta for y
+     * @return this instance for scaling
+     */
+    public final Point translate(final int dx, final int dy) {
+        x += dx ;
+        y += dy ;
+        return this;
+    }
+
+    /**
+     * Scale this instance's x- and y-components,
+     * i.e. multiply them by the given scale factors.
+     * @param sx scale factor for x
+     * @param sy scale factor for y
+     * @return this instance for scaling
+     */
+    public final Point scale(final int sx, final int sy) {
+        x *= sx ;
+        y *= sy ;
+        return this;
+    }
+
+    /**
+     * Scale this instance's x- and y-components,
+     * i.e. multiply them by the given scale factors.
+     * <p>
+     * The product is rounded back to integer.
+     * </p>
+     * @param sx scale factor for x
+     * @param sy scale factor for y
+     * @return this instance for scaling
+     */
+    public final Point scale(final float sx, final float sy) {
+        x = (int)(x * sx + 0.5f);
+        y = (int)(y * sy + 0.5f);
+        return this;
+    }
+
+    /**
+     * Inverse scale this instance's x- and y-components,
+     * i.e. divide them by the given scale factors.
+     * @param sx inverse scale factor for x
+     * @param sy inverse scale factor for y
+     * @return this instance for scaling
+     */
+    public final Point scaleInv(final int sx, final int sy) {
+        x /= sx ;
+        y /= sy ;
+        return this;
+    }
+    /**
+     * Inverse scale this instance's x- and y-components,
+     * i.e. divide them by the given scale factors.
+     * <p>
+     * The product is rounded back to integer.
+     * </p>
+     * @param sx inverse scale factor for x
+     * @param sy inverse scale factor for y
+     * @return this instance for scaling
+     */
+    public final Point scaleInv(final float sx, final float sy) {
+        x = (int)(x / sx + 0.5f);
+        y = (int)(y / sy + 0.5f);
+        return this;
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PointImmutable.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PointImmutable.java
new file mode 100644
index 000000000..59372f67d
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PointImmutable.java
@@ -0,0 +1,63 @@
+/**
+ * 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 com.jogamp.nativewindow.util;
+
+import com.jogamp.common.type.WriteCloneable;
+
+/** Immutable Point interface */
+public interface PointImmutable extends WriteCloneable, Comparable<PointImmutable> {
+
+    int getX();
+
+    int getY();
+
+    /**
+     * <p>
+     * Compares the square of the position.
+     * </p>
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(final PointImmutable d);
+
+    /**
+     * 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>.
+     */
+    @Override
+    public boolean equals(Object obj);
+
+    @Override
+    public int hashCode();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/Rectangle.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/Rectangle.java
new file mode 100644
index 000000000..33a1955e8
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/Rectangle.java
@@ -0,0 +1,237 @@
+/**
+ * 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.util;
+
+import java.util.List;
+
+public class Rectangle implements Cloneable, RectangleImmutable {
+    int x;
+    int y;
+    int width;
+    int height;
+
+    public Rectangle() {
+        this(0, 0, 0, 0);
+    }
+
+    public Rectangle(final int x, final int y, final int width, final int height) {
+        this.x=x;
+        this.y=y;
+        this.width=width;
+        this.height=height;
+    }
+
+    @Override
+    public Object cloneMutable() {
+      return clone();
+    }
+
+    @Override
+    protected Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException ex) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public final int getX() { return x; }
+    @Override
+    public final int getY() { return y; }
+    @Override
+    public final int getWidth() { return width; }
+    @Override
+    public final int getHeight() { return height; }
+
+    public final void set(final int x, final int y, final int width, final int height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+    }
+    public final void set(final Rectangle s) {
+        this.x = s.x;
+        this.y = s.y;
+        this.width = s.width;
+        this.height = s.height;
+    }
+    public final void setX(final int x) { this.x = x; }
+    public final void setY(final int y) { this.y = y; }
+    public final void setWidth(final int width) { this.width = width; }
+    public final void setHeight(final int height) { this.height = height; }
+
+    @Override
+    public final RectangleImmutable union(final RectangleImmutable r) {
+        return union(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight());
+    }
+    @Override
+    public final RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2) {
+        final int x1 = Math.min(x, rx1);
+        final int y1 = Math.min(y, ry1);
+        final int x2 = Math.max(x + width, rx2);
+        final int y2 = Math.max(y + height, ry2);
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+    /**
+     * Calculates the union of the given rectangles, stores it in this instance and returns this instance.
+     * @param rectangles given list of rectangles
+     * @return this instance holding the union of given rectangles.
+     */
+    public final Rectangle union(final List<RectangleImmutable> rectangles) {
+        int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE;
+        int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE;
+        for(int i=rectangles.size()-1; i>=0; i--) {
+            final RectangleImmutable vp = rectangles.get(i);
+            x1 = Math.min(x1, vp.getX());
+            x2 = Math.max(x2, vp.getX() + vp.getWidth());
+            y1 = Math.min(y1, vp.getY());
+            y2 = Math.max(y2, vp.getY() + vp.getHeight());
+        }
+        set(x1, y1, x2 - x1, y2 - y1);
+        return this;
+    }
+
+    @Override
+    public final RectangleImmutable intersection(final RectangleImmutable r) {
+        return intersection(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight());
+    }
+    @Override
+    public final RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2) {
+        final int x1 = Math.max(x, rx1);
+        final int y1 = Math.max(y, ry1);
+        final int x2 = Math.min(x + width, rx2);
+        final int y2 = Math.min(y + height, ry2);
+        final int ix, iy, iwidth, iheight;
+        if( x2 < x1 ) {
+            ix = 0;
+            iwidth = 0;
+        } else {
+            ix = x1;
+            iwidth = x2 - x1;
+        }
+        if( y2 < y1 ) {
+            iy = 0;
+            iheight = 0;
+        } else {
+            iy = y1;
+            iheight = y2 - y1;
+        }
+        return new Rectangle (ix, iy, iwidth, iheight);
+    }
+    @Override
+    public final float coverage(final RectangleImmutable r) {
+        final RectangleImmutable isect = intersection(r);
+        final float sqI = isect.getWidth()*isect.getHeight();
+        final float sqT = width*height;
+        return sqI / sqT;
+    }
+
+    /**
+     * Scale this instance's components,
+     * i.e. multiply them by the given scale factors.
+     * @param sx scale factor for x
+     * @param sy scale factor for y
+     * @return this instance for scaling
+     */
+    public final Rectangle scale(final int sx, final int sy) {
+        x *= sx ;
+        y *= sy ;
+        width *= sx ;
+        height *= sy ;
+        return this;
+    }
+
+    /**
+     * Inverse scale this instance's components,
+     * i.e. divide them by the given scale factors.
+     * @param sx inverse scale factor for x
+     * @param sy inverse scale factor for y
+     * @return this instance for scaling
+     */
+    public final Rectangle scaleInv(final int sx, final int sy) {
+        x /= sx ;
+        y /= sy ;
+        width /= sx ;
+        height /= sy ;
+        return this;
+    }
+
+    @Override
+    public int compareTo(final RectangleImmutable d) {
+        {
+            final int sq = width*height;
+            final int xsq = d.getWidth()*d.getHeight();
+
+            if(sq > xsq) {
+                return 1;
+            } else if(sq < xsq) {
+                return -1;
+            }
+        }
+        {
+            final int sq = x*y;
+            final int xsq = d.getX()*d.getY();
+
+            if(sq > xsq) {
+                return 1;
+            } else if(sq < xsq) {
+                return -1;
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if(this == obj)  { return true; }
+        if (obj instanceof Rectangle) {
+            final Rectangle rect = (Rectangle)obj;
+            return (y == rect.y) && (x == rect.x) &&
+                   (height == rect.height) && (width == rect.width);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        final int sum1 = x + height;
+        final int sum2 = width + y;
+        final int val1 = sum1 * (sum1 + 1)/2 + x;
+        final int val2 = sum2 * (sum2 + 1)/2 + y;
+        final int sum3 = val1 + val2;
+        return sum3 * (sum3 + 1)/2 + val2;
+    }
+
+    @Override
+    public String toString() {
+        return "[ "+x+" / "+y+"  "+width+" x "+height+" ]";
+    }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/RectangleImmutable.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/RectangleImmutable.java
new file mode 100644
index 000000000..ff2209598
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/RectangleImmutable.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 com.jogamp.nativewindow.util;
+
+import com.jogamp.common.type.WriteCloneable;
+
+/** Immutable Rectangle interface */
+public interface RectangleImmutable extends WriteCloneable, Comparable<RectangleImmutable> {
+
+    int getHeight();
+
+    int getWidth();
+
+    int getX();
+
+    int getY();
+
+    /** Returns the union of this rectangle and the given rectangle. */
+    RectangleImmutable union(final RectangleImmutable r);
+    /** Returns the union of this rectangleand the given coordinates. */
+    RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2);
+    /** Returns the intersection of this rectangleand the given rectangle. */
+    RectangleImmutable intersection(RectangleImmutable r);
+    /** Returns the intersection of this rectangleand the given coordinates. */
+    RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2);
+    /**
+     * Returns the coverage of given rectangle w/ this this one, i.e. between <code>0.0</code> and <code>1.0</code>.
+     * <p>
+     * Coverage is computed by:
+     * <pre>
+     *    isect = this.intersection(r);
+     *    coverage = area( isect ) / area( this ) ;
+     * </pre>
+     * </p>
+     */
+    float coverage(RectangleImmutable r);
+
+    /**
+     * <p>
+     * Compares square of size 1st, if equal the square of position.
+     * </p>
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(final RectangleImmutable d);
+
+    /**
+     * 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>.
+     */
+    @Override
+    boolean equals(Object obj);
+
+    @Override
+    int hashCode();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/SurfaceSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/SurfaceSize.java
new file mode 100644
index 000000000..b9e6ded95
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/SurfaceSize.java
@@ -0,0 +1,113 @@
+/**
+ * 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 com.jogamp.nativewindow.util;
+
+/**
+ * Immutable SurfaceSize Class, consisting of it's read only components:<br>
+ * <ul>
+ *  <li>{@link com.jogamp.nativewindow.util.DimensionImmutable size in pixels}</li>
+ *  <li><code>bits per pixel</code></li>
+ * </ul>
+ */
+public class SurfaceSize implements Comparable<SurfaceSize> {
+    final DimensionImmutable resolution;
+    final int bitsPerPixel;
+
+    public SurfaceSize(final DimensionImmutable resolution, final int bitsPerPixel) {
+        if(null==resolution || bitsPerPixel<=0) {
+            throw new IllegalArgumentException("resolution must be set and bitsPerPixel greater 0");
+        }
+        this.resolution=resolution;
+        this.bitsPerPixel=bitsPerPixel;
+    }
+
+    /** Returns the resolution in pixel units */
+    public final DimensionImmutable getResolution() {
+        return resolution;
+    }
+
+    public final int getBitsPerPixel() {
+        return bitsPerPixel;
+    }
+
+    @Override
+    public final String toString() {
+        return "[ "+resolution+" pixels x "+bitsPerPixel+" bpp ]";
+    }
+
+    /**
+     * <p>
+     * Compares {@link DimensionImmutable#compareTo(DimensionImmutable) resolution} 1st, if equal the bitsPerPixel.
+     * </p>
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(final SurfaceSize ssz) {
+        final int rres = resolution.compareTo(ssz.getResolution());
+        if( 0 != rres ) {
+            return rres;
+        }
+        final int xbpp = ssz.getBitsPerPixel();
+        if(bitsPerPixel > xbpp) {
+            return 1;
+        } else if(bitsPerPixel < xbpp) {
+            return -1;
+        }
+        return 0;
+    }
+
+    /**
+     * 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>.
+     */
+    @Override
+    public final boolean equals(final Object obj) {
+        if(this == obj)  { return true; }
+        if (obj instanceof SurfaceSize) {
+            final SurfaceSize p = (SurfaceSize)obj;
+            return getResolution().equals(p.getResolution()) &&
+                   getBitsPerPixel() == p.getBitsPerPixel();
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        // 31 * x == (x << 5) - x
+        int hash = getResolution().hashCode();
+        hash = ((hash << 5) - hash) + getBitsPerPixel();
+        return hash;
+    }
+}
+
-- 
cgit v1.2.3