diff options
Diffstat (limited to 'src/newt/classes')
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); |