aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-08 21:56:26 +0100
committerSven Gothel <[email protected]>2014-01-08 21:56:26 +0100
commitbd98b927b910d9421e63cf0dbc2b746eec019f80 (patch)
tree0cf29f02720abb656f97bc369b057350a6170226 /src/newt/classes
parentfe28bc125429b38cdcd016746081f4a6d521c6fd (diff)
Bug 935: NEWT PointerIcon: Utilize Toolkit Agnostic PixelFormat and Conversion Utilities (Allowing 'arbitrary' PointerIcon data input)
Commit fe28bc125429b38cdcd016746081f4a6d521c6fd added the notion of toolkit agnostic PixelFormat and conversion utilities, utilized and further tested by this patch. +++ - PointerIcon is a PixelRectangle and hence holds the decoded data. This allows on-the-fly conversion if required as well as recreation w/o PNG re-decoding. - Using array-backed PointerIcon data where possible, allowing better performance when converting PixelFormat etc. - NEWT Display adds 'createPointerIcon(final IOUtil.ClassResources pngResource...' method to support agnostic PointerIcon creation. - NEWT Display adds methods to allow users to avoid PixelFormat and Buffer NIO type forced conversion: - PixelFormat getNativePointerIconPixelFormat() - boolean getNativePointerIconForceDirectNIO() +++ PNGImage -> PNGPixelRect Deleted: com.jogamp.opengl.util.texture.spi.PNGImage Added: com.jogamp.opengl.util.PNGPixelRect (We hope nobody was using PNGImage directly since it was a service-plugin for TextureIO) PNGPixelRect is a PixelRectangle PNGPixelRect actually is implemented OpenGL agnostic, however - since our PNGJ support lives under package 'jogamp.opengl.util.pngj' it cannot be moved up (yet). PNGPixelRect now handles all PixelFormat for the target format and also added support for grayscale+alpha (2 channels). The latter is force-converted to RGB* - similar to paletted. Further more, PNGPixelRect allows simply passing an OutputStream to write the PNG data. Used by: TextureIO and NEWT +++ - OffscreenSurfaceLayer's setCursor(..) uses the agnostic PixelRectangle instead of a PNG resource. - AWTMisc uses the PixelRectangle to produce the AWT Cursor and converts it to the required format. Hence same pixels are used for NEWT and AWT pointer/cursor icon. - TestGearsES2Newt and NewtAWTReparentingKeyAdapter 'tests' iterate over 3 custom PointerIcon when pressed 'c'. - JOGLNewtAppletBase uses the new custom PointerIcon 'newt/data/crosshair-lumina-trans-32x32.png', which is included in NEWT (213 bytes only). -
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java119
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java4
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java156
-rw-r--r--src/newt/classes/jogamp/newt/PointerIconImpl.java63
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java8
-rw-r--r--src/newt/classes/jogamp/newt/driver/PNGIcon.java35
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java58
-rw-r--r--src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java92
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java50
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java38
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java20
11 files changed, 418 insertions, 225 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 8d1445f80..4b38fcca5 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -30,14 +30,14 @@ package com.jogamp.newt;
import java.io.IOException;
import java.lang.ref.WeakReference;
-import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormat;
import javax.media.nativewindow.util.PointImmutable;
import jogamp.newt.Debug;
@@ -47,6 +47,7 @@ import com.jogamp.newt.util.EDTUtil;
public abstract class Display {
public static final boolean DEBUG = Debug.debug("Display");
+ protected static final boolean DEBUG_POINTER_ICON = Debug.debug("Display.PointerIcon");
/** return precomputed hashCode from FQN {@link #getFQName()} */
@Override
@@ -66,7 +67,9 @@ public abstract class Display {
/**
* Native PointerIcon handle.
* <p>
- * Instances can be created via {@link Display}'s {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(..)}.
+ * Instances can be created via {@link Display}'s
+ * {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(pngResource, ..)}
+ * or {@link Display#createPointerIcon(PixelRectangle, int, int) createPointerIcon(pixelrect, ..)}.
* </p>
* <p>
* Instance is {@link #destroy()}'ed automatically if it's {@link #getDisplay() associated Display} is destroyed.
@@ -75,23 +78,65 @@ public abstract class Display {
* Instance can be re-validated after destruction via {@link #validate()}.
* </p>
* <p>
+ * {@link PointerIcon} must not be {@link #destroy() destroyed} while in use!
+ * </p>
+ * <p>
* {@link PointerIcon} may be {@link #destroy() destroyed} manually after use,
* i.e. when no {@link Window} {@link Window#setPointerIcon(PointerIcon) uses them} anymore.
+ * However, this is not required.
* </p>
* <p>
* PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}.
* </p>
*/
- public static interface PointerIcon {
+ public static interface PointerIcon extends PixelRectangle {
/**
- * @return the associated Display
+ * Always neatly packed, i.e. width * bytes_per_pixel.
+ * <p>
+ * {@inheritDoc}
+ * </p>
*/
- Display getDisplay();
+ @Override
+ int getStride();
+
+ /**
+ * Always false, i.e. origin is TOP-LEFT.
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ */
+ boolean isGLOriented();
+
+ /**
+ * Computes a hash code over:
+ * <ul>
+ * <li>display</li>
+ * <li>pixelformat</li>
+ * <li>size</li>
+ * <li>stride</li>
+ * <li>isGLOriented</li>
+ * <li>pixels</li>
+ * <li>hotspot</li>
+ * </ul>
+ * Dismissing the native handle!
+ * <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();
/**
- * @return the single {@link IOUtil.ClassResources}.
+ * @return the associated Display
*/
- IOUtil.ClassResources getResource();
+ Display getDisplay();
+
+ /** Returns the hotspot. */
+ PointImmutable getHotspot();
/**
* Returns true if valid, otherwise false.
@@ -116,35 +161,69 @@ public abstract class Display {
* </p>
*/
void destroy();
+ }
- /** Returns the size, i.e. width and height. */
- DimensionImmutable getSize();
+ /**
+ * Returns the native platform's {@link PointerIcon.PixelFormat} for pointer-icon pixel data.
+ * <p>
+ * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
+ * </p>
+ */
+ public abstract PixelFormat getNativePointerIconPixelFormat();
- /** Returns the hotspot. */
- PointImmutable getHotspot();
+ /**
+ * Returns the native platform's direct NIO buffer requirement pointer-icon pixel data.
+ * <p>
+ * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
+ * </p>
+ */
+ public abstract boolean getNativePointerIconForceDirectNIO();
- @Override
- String toString();
- }
+ /**
+ * Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
+ * <p>
+ * See {@link PointerIcon} for lifecycle semantics.
+ * </p>
+ *
+ * @param pngResource single PNG resource for the {@link PointerIcon}. Only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used.
+ * @param hotX pointer hotspot x-coord, origin is upper-left corner
+ * @param hotY pointer hotspot y-coord, origin is upper-left corner
+ *
+ * @throws IllegalArgumentException if pngResource is null or invalid
+ * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
+ * @throws IOException if the <code>pngResource</code> could not be {@link IOUtil.ClassResources#resolve(int) resolved}
+ * or via the PNG parser processing the input stream.
+ *
+ * @see PointerIcon
+ * @see Window#setPointerIcon(PointerIcon)
+ */
+ public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
+ throws IllegalArgumentException, IllegalStateException, IOException;
/**
* Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
* <p>
* See {@link PointerIcon} for lifecycle semantics.
* </p>
+ * <p>
+ * In case {@link #getNativePointerIconPixelFormat()} or {@link #getNativePointerIconForceDirectNIO()}
+ * is not matched by the given <code>pixelrect</code>, the <code>pixelrect</code> is converted
+ * into the required {@link PixelFormat} and NIO type.
+ * </p>
*
- * @param pngResource single PNG resource, only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used.
+ * @param pixelrect {@link PixelRectangle} source for the {@link PointerIcon}
* @param hotX pointer hotspot x-coord, origin is upper-left corner
* @param hotY pointer hotspot y-coord, origin is upper-left corner
+ *
+ * @throws IllegalArgumentException if pixelrect is null.
* @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
- * @throws MalformedURLException
- * @throws InterruptedException
- * @throws IOException
*
* @see PointerIcon
* @see Window#setPointerIcon(PointerIcon)
+ * @see #getNativePointerIconPixelFormat()
+ * @see #getNativePointerIconForceDirectNIO()
*/
- public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws IllegalStateException, MalformedURLException, InterruptedException, IOException;
+ public abstract PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY) throws IllegalArgumentException, IllegalStateException;
/**
* Manual trigger the native creation, if it is not done yet.<br>
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
index 7ffbc2e83..472672fd9 100644
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
@@ -235,10 +235,10 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
glWindow.setVisible(true);
glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
if( null == pointerIconTest ) {
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/jogamp-32x32.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/crosshair-lumina-trans-32x32.png" } );
final Display disp = glWindow.getScreen().getDisplay();
try {
- pointerIconTest = disp.createPointerIcon(res, 16, 0);
+ pointerIconTest = disp.createPointerIcon(res, 16, 16);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index 346c03b15..4c7169ec4 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -34,7 +34,9 @@
package jogamp.newt;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.NEWTEvent;
@@ -43,17 +45,25 @@ import com.jogamp.newt.event.NEWTEventConsumer;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
import java.io.IOException;
-import java.net.MalformedURLException;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.util.PixelFormatUtil;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
public abstract class DisplayImpl extends Display {
private static int serialno = 1;
+ private static final boolean pngUtilAvail;
static {
NativeWindowFactory.addCustomShutdownHook(true /* head */, new Runnable() {
@@ -64,8 +74,14 @@ public abstract class DisplayImpl extends Display {
DisplayImpl.shutdownAll();
}
});
+
+ final ClassLoader cl = DisplayImpl.class.getClassLoader();
+ pngUtilAvail = ReflectionUtil.isClassAvailable("jogamp.opengl.util.pngj.PngReader", cl) &&
+ ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.PNGPixelRect", cl);
}
+ public static final boolean isPNGUtilAvailable() { return pngUtilAvail; }
+
final ArrayList<PointerIconImpl> pointerIconList = new ArrayList<PointerIconImpl>();
/** Executed from EDT! */
@@ -86,13 +102,94 @@ public abstract class DisplayImpl extends Display {
}
@Override
- public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
- return createPointerIcon(false /* isTemp */, pngResource, hotX, hotY);
+ public PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; }
+ @Override
+ public boolean getNativePointerIconForceDirectNIO() { return false; }
+
+ @Override
+ public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
+ throws IllegalArgumentException, IllegalStateException, IOException
+ {
+ if( !isNativeValid() ) {
+ throw new IllegalStateException("Display.createPointerIcon(1): Display invalid "+this);
+ }
+ if( null == pngResource || 0 >= pngResource.resourceCount() ) {
+ throw new IllegalArgumentException("Null or invalid pngResource "+pngResource);
+ }
+ if( !pngUtilAvail ) {
+ return null;
+ }
+ final PointerIconImpl[] res = { null };
+ runOnEDTIfAvail(true, new Runnable() {
+ public void run() {
+ try {
+ if( !DisplayImpl.this.isNativeValid() ) {
+ throw new IllegalStateException("Display.createPointerIcon(2): Display invalid "+DisplayImpl.this);
+ }
+ final URLConnection urlConn = pngResource.resolve(0);
+ if( null == urlConn ) {
+ throw new IOException("Could not resolve "+pngResource.resourcePaths[0]);
+ }
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(),
+ getNativePointerIconPixelFormat(),
+ getNativePointerIconForceDirectNIO(),
+ 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ final long handle = createPointerIconImplChecked(image.getPixelformat(), image.getSize().getWidth(), image.getSize().getHeight(),
+ image.getPixels(), hotX, hotY);
+ final PointImmutable hotspot = new Point(hotX, hotY);
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconPNG.0: "+image+", handle: "+toHexString(handle)+", hot "+hotspot);
+ }
+ if( 0 != handle ) {
+ res[0] = new PointerIconImpl(DisplayImpl.this, image, hotspot, handle);
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconPNG.0: "+res[0]);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } } );
+ if( null != res[0] ) {
+ synchronized(pointerIconList) {
+ pointerIconList.add(res[0]);
+ }
+ }
+ return res[0];
}
- PointerIcon createPointerIcon(final boolean isTemp, final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
+
+ @Override
+ public final PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY)
+ throws IllegalArgumentException, IllegalStateException
+ {
if( !isNativeValid() ) {
throw new IllegalStateException("Display.createPointerIcon(1): Display invalid "+this);
}
+ if( null == pixelrect ) {
+ throw new IllegalArgumentException("Null or pixelrect");
+ }
+ final PixelRectangle fpixelrect;
+ if( getNativePointerIconPixelFormat() != pixelrect.getPixelformat() || pixelrect.isGLOriented() ) {
+ // conversion !
+ fpixelrect = PixelFormatUtil.convert32(pixelrect, getNativePointerIconPixelFormat(),
+ 0 /* ddestStride */, false /* isGLOriented */, getNativePointerIconForceDirectNIO() );
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconRES.0: Conversion-FMT "+pixelrect+" -> "+fpixelrect);
+ }
+ } else if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixelrect.getPixels()) ) {
+ // transfer to direct NIO
+ final ByteBuffer sBB = pixelrect.getPixels();
+ final ByteBuffer dBB = Buffers.newDirectByteBuffer(sBB.array(), sBB.arrayOffset());
+ fpixelrect = new PixelRectangle.GenericPixelRect(pixelrect.getPixelformat(), pixelrect.getSize(), pixelrect.getStride(), pixelrect.isGLOriented(), dBB);
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconRES.0: Conversion-NIO "+pixelrect+" -> "+fpixelrect);
+ }
+ } else {
+ fpixelrect = pixelrect;
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconRES.0: No conversion "+fpixelrect);
+ }
+ }
final PointerIconImpl[] res = { null };
runOnEDTIfAvail(true, new Runnable() {
public void run() {
@@ -100,22 +197,63 @@ public abstract class DisplayImpl extends Display {
if( !DisplayImpl.this.isNativeValid() ) {
throw new IllegalStateException("Display.createPointerIcon(2): Display invalid "+DisplayImpl.this);
}
- res[0] = createPointerIconImpl(pngResource, hotX, hotY);
+ if( null != fpixelrect ) {
+ final long handle = createPointerIconImplChecked(fpixelrect.getPixelformat(),
+ fpixelrect.getSize().getWidth(),
+ fpixelrect.getSize().getHeight(),
+ fpixelrect.getPixels(), hotX, hotY);
+ if( 0 != handle ) {
+ res[0] = new PointerIconImpl(DisplayImpl.this, fpixelrect, new Point(hotX, hotY), handle);
+ }
+ }
} catch (Exception e) {
e.printStackTrace();
}
} } );
- if( !isTemp ) {
+ if( null != res[0] ) {
synchronized(pointerIconList) {
pointerIconList.add(res[0]);
}
}
return res[0];
}
- /** Executed from EDT! */
- protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
- return null;
+
+ /**
+ * Executed from EDT!
+ *
+ * @param pixelformat the <code>pixels</code>'s format
+ * @param width the <code>pixels</code>'s width
+ * @param height the <code>pixels</code>'s height
+ * @param pixels the <code>pixels</code>
+ * @param hotX the PointerIcon's hot-spot x-coord
+ * @param hotY the PointerIcon's hot-spot x-coord
+ * @return if successful a valid handle (not null), otherwise null.
+ */
+ protected final long createPointerIconImplChecked(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+ if( getNativePointerIconPixelFormat() != pixelformat ) {
+ throw new IllegalArgumentException("Pixelformat no "+getNativePointerIconPixelFormat()+", but "+pixelformat);
+ }
+ if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixels) ) {
+ throw new IllegalArgumentException("pixel buffer is not direct "+pixels);
+ }
+ return createPointerIconImpl(pixelformat, width, height, pixels, hotX, hotY);
+ }
+
+ /**
+ * Executed from EDT!
+ *
+ * @param pixelformat the <code>pixels</code>'s format
+ * @param width the <code>pixels</code>'s width
+ * @param height the <code>pixels</code>'s height
+ * @param pixels the <code>pixels</code>
+ * @param hotX the PointerIcon's hot-spot x-coord
+ * @param hotY the PointerIcon's hot-spot x-coord
+ * @return if successful a valid handle (not null), otherwise null.
+ */
+ protected long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+ return 0;
}
+
/** Executed from EDT! */
protected void destroyPointerIconImpl(final long displayHandle, long piHandle) { }
diff --git a/src/newt/classes/jogamp/newt/PointerIconImpl.java b/src/newt/classes/jogamp/newt/PointerIconImpl.java
index e2388be67..7c8535f20 100644
--- a/src/newt/classes/jogamp/newt/PointerIconImpl.java
+++ b/src/newt/classes/jogamp/newt/PointerIconImpl.java
@@ -27,27 +27,63 @@
*/
package jogamp.newt;
+import java.nio.ByteBuffer;
+
import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelRectangle;
import javax.media.nativewindow.util.PointImmutable;
-import com.jogamp.common.util.IOUtil;
-import com.jogamp.common.util.IOUtil.ClassResources;
import com.jogamp.newt.Display;
import com.jogamp.newt.Display.PointerIcon;
public class PointerIconImpl implements PointerIcon {
private final DisplayImpl display;
- private final IOUtil.ClassResources resource;
+ private final PixelFormat pixelformat;
private final DimensionImmutable size;
+ private final ByteBuffer pixels;
private final PointImmutable hotspot;
private long handle;
- public PointerIconImpl(DisplayImpl display, ClassResources resource, final DimensionImmutable size, final PointImmutable hotspot, final long handle) {
+ private int hashCode = 0;
+ private volatile boolean hashCodeComputed = false;
+
+ public PointerIconImpl(final DisplayImpl display, final PixelFormat pixelformat, final DimensionImmutable size, final ByteBuffer pixels, final PointImmutable hotspot, final long handle) {
this.display = display;
- this.resource = resource;
+ this.pixelformat = pixelformat;
this.size = size;
+ this.pixels = pixels;
this.hotspot = hotspot;
+
this.handle=handle;
}
+ public PointerIconImpl(final DisplayImpl display, final PixelRectangle pixelrect, final PointImmutable hotspot, final long handle) {
+ this.display = display;
+ this.pixelformat = pixelrect.getPixelformat();
+ this.size = pixelrect.getSize();
+ this.pixels = pixelrect.getPixels();
+ this.hotspot = hotspot;
+ this.handle=handle;
+ }
+
+ @Override
+ public int hashCode() {
+ if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE
+ synchronized (this) {
+ if( !hashCodeComputed ) {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + display.getFQName().hashCode();
+ hash = ((hash << 5) - hash) + pixelformat.hashCode();
+ hash = ((hash << 5) - hash) + size.hashCode();
+ hash = ((hash << 5) - hash) + getStride();
+ hash = ((hash << 5) - hash) + ( isGLOriented() ? 1 : 0);
+ hash = ((hash << 5) - hash) + pixels.hashCode();
+ hashCode = ((hash << 5) - hash) + hotspot.hashCode();
+ }
+ }
+ }
+ return hashCode;
+ }
+
public synchronized final long getHandle() { return handle; }
public synchronized final long validatedHandle() {
synchronized(display.pointerIconList) {
@@ -57,8 +93,7 @@ public class PointerIconImpl implements PointerIcon {
}
if( 0 == handle ) {
try {
- final PointerIconImpl temp = (PointerIconImpl) display.createPointerIcon(true /* isTemp */, resource, hotspot.getX(), hotspot.getY());
- handle = temp.handle;
+ handle = display.createPointerIconImpl(pixelformat, size.getWidth(), size.getHeight(), pixels, hotspot.getX(), hotspot.getY());
return handle;
} catch (Exception e) {
e.printStackTrace();
@@ -71,7 +106,9 @@ public class PointerIconImpl implements PointerIcon {
@Override
public final Display getDisplay() { return display; }
@Override
- public final IOUtil.ClassResources getResource() { return resource; }
+ public final PixelFormat getPixelformat() { return pixelformat; }
+ @Override
+ public final ByteBuffer getPixels() { return pixels; }
@Override
public synchronized final boolean isValid() { return 0 != handle; }
@Override
@@ -116,11 +153,19 @@ public class PointerIconImpl implements PointerIcon {
return size;
}
@Override
+ public final int getStride() {
+ return size.getWidth() * pixelformat.bytesPerPixel();
+ }
+ @Override
+ public final boolean isGLOriented() {
+ return false;
+ }
+ @Override
public final PointImmutable getHotspot() {
return hotspot;
}
@Override
public final String toString() {
- return "PointerIcon["+DisplayImpl.toHexString(super.hashCode())+", "+display.getFQName()+", "+resource.resourcePaths[0]+", 0x"+Long.toHexString(handle)+", "+size+", "+hotspot+"]";
+ return "PointerIcon[obj 0x"+Integer.toHexString(super.hashCode())+", "+display.getFQName()+", 0x"+Long.toHexString(handle)+", "+pixelformat+", "+size+", "+hotspot+", pixels "+pixels+"]";
}
} \ No newline at end of file
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 50f30f04d..dc9affd63 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -53,6 +53,7 @@ import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.PixelRectangle;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
import javax.media.nativewindow.util.Rectangle;
@@ -61,7 +62,6 @@ import javax.media.nativewindow.util.RectangleImmutable;
import jogamp.nativewindow.SurfaceUpdatedHelper;
import com.jogamp.common.util.ArrayHashSet;
-import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.IntBitfield;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.locks.LockFactory;
@@ -1700,7 +1700,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/**
* Helper method to delegate {@link #setPointerVisibleImpl(boolean)} to
- * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}.
+ * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)}.
* <p>
* Note: JAWTWindow is an OffscreenLayerSurface.
* </p>
@@ -1755,7 +1755,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/**
* Helper method to delegate {@link #setPointerIconIntern(PointerIconImpl)} to
- * {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}.
+ * {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)}
* <p>
* Note: JAWTWindow is an OffscreenLayerSurface.
* </p>
@@ -1777,7 +1777,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent;
try {
if( null != pi ) {
- return ols.setCursor(pi.getResource(), pi.getHotspot());
+ return ols.setCursor(pi, pi.getHotspot());
} else {
return ols.setCursor(null, null); // default
}
diff --git a/src/newt/classes/jogamp/newt/driver/PNGIcon.java b/src/newt/classes/jogamp/newt/driver/PNGIcon.java
index ffa62978f..967acd413 100644
--- a/src/newt/classes/jogamp/newt/driver/PNGIcon.java
+++ b/src/newt/classes/jogamp/newt/driver/PNGIcon.java
@@ -32,6 +32,7 @@ import java.net.MalformedURLException;
import java.nio.ByteBuffer;
import jogamp.newt.Debug;
+import jogamp.newt.DisplayImpl;
import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.ReflectionUtil;
@@ -45,8 +46,7 @@ public class PNGIcon {
Debug.initSingleton();
final ClassLoader cl = PNGIcon.class.getClassLoader();
- avail = ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl) &&
- ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.texture.spi.PNGImage", cl);
+ avail = DisplayImpl.isPNGUtilAvailable() && ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl);
}
/** Returns true if PNG decoder is available. */
@@ -55,7 +55,11 @@ public class PNGIcon {
}
/**
- * Implemented for X11.
+ * Special implementation for X11 Window Icons
+ * <p>
+ * The returned byte buffer is a direct buffer!
+ * </p>
+ *
* @param resources
* @param data_size
* @param elem_bytesize
@@ -73,29 +77,4 @@ public class PNGIcon {
}
throw new UnsupportedOperationException(err0);
}
-
- /**
- * Implemented for Windows.
- * @param resources
- * @param toBGRA if true, arranges stores in BGRA888 order, otherwise RGBA888
- * @param width
- * @param height
- * @param data_size
- * @param resourcesIdx
- * @return pixels with origin at upper-left corner.
- * If storing RGBA8888, component R is located on the lowest 8-bit.
- * If storing BGRA8888, component B is located on the lowest 8-bit.
- * Component A is located on the highest 8-bit.
- *
- * @throws UnsupportedOperationException if not implemented
- * @throws InterruptedException
- * @throws IOException
- * @throws MalformedURLException
- */
- public static ByteBuffer singleToRGBAImage(IOUtil.ClassResources resources, int resourceIdx, boolean toBGRA, int[] width, int[] height, int[] data_size) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException {
- if( avail ) {
- return jogamp.newt.driver.opengl.JoglUtilPNGIcon.singleToRGBAImage(resources, resourceIdx, toBGRA, width, height, data_size);
- }
- throw new UnsupportedOperationException(err0);
- }
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index 30583c48c..d850a18af 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -34,28 +34,25 @@
package jogamp.newt.driver.macosx;
-import java.io.IOException;
-import java.net.MalformedURLException;
+import java.net.URLConnection;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PixelFormat;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.opengl.util.PNGPixelRect;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
-import jogamp.newt.PointerIconImpl;
-import jogamp.newt.driver.PNGIcon;
public class DisplayDriver extends DisplayImpl {
- private static final int defaultIconWidth, defaultIconHeight;
- private static final Buffer defaultIconData;
+ private static final PNGPixelRect defaultIconData;
static {
NEWTJNILibLoader.loadNEWT();
@@ -67,21 +64,23 @@ public class DisplayDriver extends DisplayImpl {
throw new NativeWindowException("Failed to initialize jmethodIDs");
}
{
- final int[] width = { 0 }, height = { 0 }, data_size = { 0 };
- Buffer data=null;
- if( PNGIcon.isAvailable() ) {
+ PNGPixelRect image=null;
+ if( DisplayImpl.isPNGUtilAvailable() ) {
try {
+ // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
- data = PNGIcon.singleToRGBAImage(iconRes, iconRes.resourceCount()-1, false /* toBGRA */, width, height, data_size);
+ final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
+ image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, true /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
} catch (Exception e) {
e.printStackTrace();
}
}
- defaultIconWidth = width[0];
- defaultIconHeight = height[0];
- defaultIconData = data;
+ defaultIconData = image;
if( null != defaultIconData ) {
- DisplayDriver.setAppIcon0(defaultIconData, defaultIconWidth, defaultIconHeight);
+ final Buffer pixels = defaultIconData.getPixels();
+ DisplayDriver.setAppIcon0(
+ pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */,
+ defaultIconData.getSize().getWidth(), defaultIconData.getSize().getHeight());
}
}
@@ -112,17 +111,20 @@ public class DisplayDriver extends DisplayImpl {
aDevice.close();
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
+ * </p>
+ */
@Override
- protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
- if( PNGIcon.isAvailable() ) {
- final int[] width = { 0 }, height = { 0 }, data_size = { 0 };
- if( null != pngResource && 0 < pngResource.resourceCount() ) {
- final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, true /* toBGRA */, width, height, data_size);
- return new PointerIconImpl( this, pngResource, new Dimension(width[0], height[0]),
- new Point(hotX, hotY), createPointerIcon0(data, width[0], height[0], hotX, hotY));
- }
- }
- return null;
+ public final boolean getNativePointerIconForceDirectNIO() { return true; }
+
+ @Override
+ protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+ return createPointerIcon0(
+ pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */,
+ width, height, hotX, hotY);
}
@Override
@@ -140,8 +142,8 @@ public class DisplayDriver extends DisplayImpl {
private static native boolean initNSApplication0();
private static native void runNSApplication0();
private static native void stopNSApplication0();
- /* pp */ static native void setAppIcon0(Object iconData, int iconWidth, int iconHeight);
- private static native long createPointerIcon0(Object iconData, int iconWidth, int iconHeight, int hotX, int hotY);
+ /* pp */ static native void setAppIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height);
+ private static native long createPointerIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY);
private static native long destroyPointerIcon0(long handle);
}
diff --git a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
index 216a0cb20..551929b8d 100644
--- a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
+++ b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
@@ -32,20 +32,22 @@ import java.net.MalformedURLException;
import java.net.URLConnection;
import java.nio.ByteBuffer;
+import javax.media.nativewindow.util.PixelFormat;
+
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.IOUtil;
-import com.jogamp.opengl.util.texture.spi.PNGImage;
+import com.jogamp.opengl.util.PNGPixelRect;
public class JoglUtilPNGIcon {
public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException {
- final PNGImage[] images = new PNGImage[resources.resourceCount()];
+ final PNGPixelRect[] images = new PNGPixelRect[resources.resourceCount()];
data_size[0] = 0;
for(int i=0; i<resources.resourceCount(); i++) {
final URLConnection urlConn = resources.resolve(i);
- final PNGImage image = PNGImage.read(urlConn.getInputStream());
- data_size[0] += 2 + image.getWidth() * image.getHeight();
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ data_size[0] += 2 + image.getSize().getWidth() * image.getSize().getHeight();
images[i] = image;
}
final boolean is64Bit = Platform.is64Bit();
@@ -53,31 +55,26 @@ public class JoglUtilPNGIcon {
final ByteBuffer buffer = Buffers.newDirectByteBuffer( data_size[0] * elem_bytesize[0] );
for(int i=0; i<images.length; i++) {
- final PNGImage image1 = images[i];
+ final PNGPixelRect image1 = images[i];
+ final int width = image1.getSize().getWidth();
+ final int height = image1.getSize().getHeight();
if( is64Bit ) {
- buffer.putLong(image1.getWidth());
- buffer.putLong(image1.getHeight());
+ buffer.putLong(width);
+ buffer.putLong(height);
} else {
- buffer.putInt(image1.getWidth());
- buffer.putInt(image1.getHeight());
+ buffer.putInt(width);
+ buffer.putInt(height);
}
- final ByteBuffer bb = image1.getData();
- final int bpp = image1.getBytesPerPixel();
- final int stride = image1.getWidth() * bpp;
- for(int y=0; y<image1.getHeight(); y++) {
- int bbOff = image1.isGLOriented() ? ( image1.getHeight() - 1 - y ) * stride : y * stride;
- for(int x=0; x<image1.getWidth(); x++) {
- // Source: R G B A
- // Dest: B G R A
+ final ByteBuffer bb = image1.getPixels();
+ final int stride = image1.getStride();
+ for(int y=0; y<height; y++) {
+ int bbOff = y * stride;
+ for(int x=0; x<width; x++) {
long pixel;
- pixel = ( 0xffL & bb.get(bbOff++) ) << 16; // R
+ pixel = ( 0xffL & bb.get(bbOff++) ); // B
pixel |= ( 0xffL & bb.get(bbOff++) ) << 8; // G
- pixel |= ( 0xffL & bb.get(bbOff++) ); // B
- if( 4 == bpp ) {
- pixel |= ( 0xffL & bb.get(bbOff++) ) << 24;
- } else {
- pixel |= 0x00000000ff000000L;
- }
+ pixel |= ( 0xffL & bb.get(bbOff++) ) << 16; // R
+ pixel |= ( 0xffL & bb.get(bbOff++) ) << 24; // A
if( is64Bit ) {
buffer.putLong(pixel);
} else {
@@ -89,51 +86,4 @@ public class JoglUtilPNGIcon {
buffer.rewind();
return buffer;
}
-
- public static ByteBuffer singleToRGBAImage(IOUtil.ClassResources resources, int resourceIdx, boolean toBGRA, int[] width, int[] height, int[] data_size) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException {
- width[0] = 0;
- height[0] = 0;
- data_size[0] = 0;
- final URLConnection urlConn = resources.resolve(resourceIdx);
- final PNGImage image = PNGImage.read(urlConn.getInputStream());
- width[0] = image.getWidth();
- height[0] = image.getHeight();
- data_size[0] = image.getWidth() * image.getHeight();
-
- final int elem_bytesize = 4; // BGRA
- final ByteBuffer buffer = Buffers.newDirectByteBuffer( data_size[0] * elem_bytesize );
-
- final ByteBuffer bb = image.getData();
- final int bpp = image.getBytesPerPixel();
- final int stride = image.getWidth() * bpp;
- for(int y=0; y<image.getHeight(); y++) {
- int bbOff = image.isGLOriented() ? ( image.getHeight() - 1 - y ) * stride : y * stride;
- for(int x=0; x<image.getWidth(); x++) {
- // Source: R G B A
- final byte r, g, b, a;
- r = bb.get(bbOff++); // R
- g = bb.get(bbOff++); // G
- b = bb.get(bbOff++); // B
- if( 4 == bpp ) {
- a = bb.get(bbOff++); // A
- } else {
- a = (byte)0xff; // A
- }
- if( toBGRA ) {
- // Dest: B G R A
- buffer.put(b);
- buffer.put(g);
- buffer.put(r);
- } else {
- // Dest: R G B A
- buffer.put(r);
- buffer.put(g);
- buffer.put(b);
- }
- buffer.put(a);
- }
- }
- buffer.rewind();
- return buffer;
- }
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index a4db50165..a30431788 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -34,8 +34,7 @@
package jogamp.newt.driver.windows;
-import java.io.IOException;
-import java.net.MalformedURLException;
+import java.net.URLConnection;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@@ -43,18 +42,16 @@ import jogamp.nativewindow.windows.RegisteredClass;
import jogamp.nativewindow.windows.RegisteredClassFactory;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
-import jogamp.newt.PointerIconImpl;
-import jogamp.newt.driver.PNGIcon;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PixelFormat;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.opengl.util.PNGPixelRect;
public class DisplayDriver extends DisplayImpl {
@@ -66,17 +63,18 @@ public class DisplayDriver extends DisplayImpl {
NEWTJNILibLoader.loadNEWT();
{
long[] _defaultIconHandle = { 0, 0 };
- if( PNGIcon.isAvailable() ) {
+ if( DisplayImpl.isPNGUtilAvailable() ) {
try {
- final int[] width = { 0 }, height = { 0 }, data_size = { 0 };
final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
{
- final ByteBuffer icon_data_small = PNGIcon.singleToRGBAImage(iconRes, 0, true /* toBGRA */, width, height, data_size);
- _defaultIconHandle[0] = DisplayDriver.createBGRA8888Icon0(icon_data_small, width[0], height[0], false, 0, 0);
+ final URLConnection urlConn = iconRes.resolve(0);
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ _defaultIconHandle[0] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
}
{
- final ByteBuffer icon_data_big = PNGIcon.singleToRGBAImage(iconRes, iconRes.resourceCount()-1, true /* toBGRA */, width, height, data_size);
- _defaultIconHandle[1] = DisplayDriver.createBGRA8888Icon0(icon_data_big, width[0], height[0], false, 0, 0);
+ final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ _defaultIconHandle[1] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
}
} catch (Exception e) {
e.printStackTrace();
@@ -127,16 +125,8 @@ public class DisplayDriver extends DisplayImpl {
}
@Override
- protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
- if( PNGIcon.isAvailable() ) {
- final int[] width = { 0 }, height = { 0 }, data_size = { 0 };
- if( null != pngResource && 0 < pngResource.resourceCount() ) {
- final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, true /* toBGRA */, width, height, data_size);
- return new PointerIconImpl( this, pngResource, new Dimension(width[0], height[0]),
- new Point(hotX, hotY), createBGRA8888Icon0(data, width[0], height[0], true, hotX, hotY));
- }
- }
- return null;
+ protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+ return createBGRA8888Icon0(pixels, width, height, true, hotX, hotY);
}
@Override
@@ -149,16 +139,18 @@ public class DisplayDriver extends DisplayImpl {
//
private static native void DispatchMessages0();
- static long createBGRA8888Icon0(Buffer data, int width, int height, boolean isCursor, int hotX, int hotY) {
- if( null == data ) {
+ static long createBGRA8888Icon0(Buffer pixels, int width, int height, boolean isCursor, int hotX, int hotY) {
+ if( null == pixels ) {
throw new IllegalArgumentException("data buffer/size");
}
- if( !Buffers.isDirect(data) ) {
- throw new IllegalArgumentException("data buffer is not direct "+data);
- }
- return createBGRA8888Icon0(data, Buffers.getDirectBufferByteOffset(data), width, height, isCursor, hotX, hotY);
+ final boolean pixels_is_direct = Buffers.isDirect(pixels);
+ return createBGRA8888Icon0(
+ pixels_is_direct ? pixels : Buffers.getArray(pixels),
+ pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels),
+ pixels_is_direct,
+ width, height, isCursor, hotX, hotY);
}
- private static native long createBGRA8888Icon0(Object data, int data_offset, int width, int height, boolean isCursor, int hotX, int hotY);
+ private static native long createBGRA8888Icon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, boolean isCursor, int hotX, int hotY);
private static native void destroyIcon0(long handle);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 150337df4..4d1388eec 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -34,25 +34,19 @@
package jogamp.newt.driver.x11;
-import java.io.IOException;
-import java.net.MalformedURLException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PixelFormat;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.util.IOUtil;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
-import jogamp.newt.PointerIconImpl;
-import jogamp.newt.driver.PNGIcon;
public class DisplayDriver extends DisplayImpl {
@@ -132,16 +126,11 @@ public class DisplayDriver extends DisplayImpl {
protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; }
@Override
- protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException {
- if( PNGIcon.isAvailable() ) {
- final int[] width = { 0 }, height = { 0 }, data_size = { 0 };
- if( null != pngResource && 0 < pngResource.resourceCount() ) {
- final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, false /* toBGRA */, width, height, data_size);
- final long handle = createPointerIcon0(getHandle(), data, width[0], height[0], hotX, hotY);
- return new PointerIconImpl(DisplayDriver.this, pngResource, new Dimension(width[0], height[0]), new Point(hotX, hotY), handle);
- }
- }
- return null;
+ public final PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.RGBA8888; }
+
+ @Override
+ protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+ return createPointerIcon(getHandle(), pixels, width, height, hotX, hotY);
}
@Override
@@ -166,13 +155,16 @@ public class DisplayDriver extends DisplayImpl {
private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now
- static long createPointerIcon0(long display, Buffer data, int width, int height, int hotX, int hotY) {
- if( !Buffers.isDirect(data) ) {
- throw new IllegalArgumentException("data buffer is not direct "+data);
- }
- return createPointerIcon0(display, data, Buffers.getDirectBufferByteOffset(data), width, height, hotX, hotY);
+ private static long createPointerIcon(long display, Buffer pixels, int width, int height, int hotX, int hotY) {
+ final boolean pixels_is_direct = Buffers.isDirect(pixels);
+ return createPointerIcon0(display,
+ pixels_is_direct ? pixels : Buffers.getArray(pixels),
+ pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels),
+ pixels_is_direct,
+ width, height, hotX, hotY);
}
- private static native long createPointerIcon0(long display, Object data, int data_offset, int width, int height, int hotX, int hotY);
+ private static native long createPointerIcon0(long display, Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY);
+
static native void destroyPointerIcon0(long display, long handle);
/** X11 Window delete atom marker used on EDT */
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index ad1744f2e..0eda37eac 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -50,6 +50,7 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.NewtFactory;
@@ -74,6 +75,7 @@ public class WindowDriver extends WindowImpl {
Buffer _icon_data=null;
if( PNGIcon.isAvailable() ) {
try {
+ // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
final int[] data_size = { 0 }, elem_bytesize = { 0 };
_icon_data = PNGIcon.arrayToX11BGRAImages(NewtFactory.getWindowIcons(), data_size, elem_bytesize);
_icon_data_size = data_size[0];
@@ -124,7 +126,7 @@ public class WindowDriver extends WindowImpl {
( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
edtDevice.lock();
try {
- setWindowHandle(CreateWindow0(getParentWindowHandle(),
+ setWindowHandle(CreateWindow(getParentWindowHandle(),
edtDevice.getHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
getX(), getY(), getWidth(), getHeight(), autoPosition(), flags,
@@ -430,10 +432,24 @@ public class WindowDriver extends WindowImpl {
protected static native boolean initIDs0();
+ private long CreateWindow(long parentWindowHandle, long display, int screen_index,
+ int visualID, long javaObjectAtom, long windowDeleteAtom,
+ int x, int y, int width, int height, boolean autoPosition, int flags,
+ int pixelDataSize, Buffer pixels) {
+ // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
+ if( !Buffers.isDirect(pixels) ) {
+ throw new IllegalArgumentException("data buffer is not direct "+pixels);
+ }
+ return CreateWindow0(parentWindowHandle, display, screen_index,
+ visualID, javaObjectAtom, windowDeleteAtom,
+ x, y, width, height, autoPosition, flags,
+ pixelDataSize,
+ pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */);
+ }
private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
int visualID, long javaObjectAtom, long windowDeleteAtom,
int x, int y, int width, int height, boolean autoPosition, int flags,
- int iconDataSize, Object iconData);
+ int pixelDataSize, Object pixels, int pixels_byte_offset, boolean pixels_is_direct);
private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle*/ ); // XKB disabled for now
private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle,
long windowDeleteAtom, int x, int y, int width, int height, int flags);