diff options
author | Sven Gothel <[email protected]> | 2014-01-04 17:15:04 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-01-04 17:15:04 +0100 |
commit | fcc0e7397bb6f3ceb1fe143667f8c59b5bf63874 (patch) | |
tree | fbb8225c6408cfe6bf17cccdfeafbc293d126e39 /src/newt/classes | |
parent | e3cf96249f4c722f8b2a7d0e052e19165cef171e (diff) |
Bug 935: NEWT PointerIcon: Refine Spec and Implementation / Fix OSX Crash and Issues
- Refine Display.PointerIcon: Complete type allowing re-creation
- Add associated Display reference
- Add used IOUtil.ClassResources reference
- Add isValid()/validate() methods for recreation
- Refine API doc
- Move Display.destroyPointerIcon(PointerIcon) -> PointerIcon.destroy()
- Move DisplayImpl.PointerIconImpl -> PointerIconImpl (own source file)
- Creation/Destruction and setting of PointerIcon happens on EDT
- DisplayImpl.shutdownAll() and Display.destroy() calls destroyAllPointerIconFromList
- WindowDriver.setPointerIconImpl: Validates PointerIconImpl (i.e. re-creates if required)
- Fix 'initial' window.setPointerIcon(..) before createNative(..),
tested w/ TestGearsES2NEWT
- OSX Native Code:
- Move mouse and pointer-state handling from NewtMacWindow -> NewtView class
to retain states (pointer handle, pointer visibility, etc) when reparenting.
Reparenting will move an exisiting NewtView into a new NewtMacWindow.
- Enable all mouse move events:
- NewtView::mouseEnter [nsWin makeFirstResponder: nsView];
- NewtView::mouseExited if( !mouseConfined ) { [nsView resignFirstResponder]; }
- NewtView::mouseMoved issued [myCurser set] if required, fixing
OSX issue not updating NSCursor properly.
- MacWindow:
- Test NewtMacWindow, NewtView and NSCursor handles before usage
- Fix DBG_PRINT(..) warnings
Diffstat (limited to 'src/newt/classes')
10 files changed, 272 insertions, 117 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index cf1099c85..8d1445f80 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -66,16 +66,60 @@ public abstract class Display { /** * Native PointerIcon handle. * <p> - * Instances can be created via {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int)} - * and released via {@link Display#destroyPointerIcon(PointerIcon)}. + * Instances can be created via {@link Display}'s {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(..)}. + * </p> + * <p> + * Instance is {@link #destroy()}'ed automatically if it's {@link #getDisplay() associated Display} is destroyed. + * </p> + * <p> + * Instance can be re-validated after destruction via {@link #validate()}. + * </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. * </p> * <p> * PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}. * </p> */ public static interface PointerIcon { + /** + * @return the associated Display + */ + Display getDisplay(); + + /** + * @return the single {@link IOUtil.ClassResources}. + */ + IOUtil.ClassResources getResource(); + + /** + * Returns true if valid, otherwise false. + * <p> + * A PointerIcon instance becomes invalid if it's {@link #getDisplay() associated Display} is destroyed. + * </p> + */ + boolean isValid(); + + /** + * Returns true if instance {@link #isValid()} or validation was successful, otherwise false. + * <p> + * Validation, i.e. recreation, is required if instance became invalid, see {@link #isValid()}. + * </p> + */ + boolean validate(); + + /** + * Destroys this instance. + * <p> + * Will be called automatically if it's {@link #getDisplay() associated Display} is destroyed. + * </p> + */ + void destroy(); + /** Returns the size, i.e. width and height. */ DimensionImmutable getSize(); + /** Returns the hotspot. */ PointImmutable getHotspot(); @@ -84,28 +128,23 @@ public abstract class Display { } /** - * Returns the created {@link PointerIcon} or <code>null</code> if not implemented on platform. + * 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 PNG resource + * @param pngResource single PNG resource, 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 IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}. * @throws MalformedURLException * @throws InterruptedException * @throws IOException * * @see PointerIcon - * @see #destroyPointerIcon(PointerIcon) * @see Window#setPointerIcon(PointerIcon) */ - - public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException; - - /** - * @param pi - * - * @see #createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) - */ - public abstract void destroyPointerIcon(PointerIcon pi); + public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws IllegalStateException, MalformedURLException, InterruptedException, IOException; /** * Manual trigger the native creation, if it is not done yet.<br> diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index dc3705daa..346c03b15 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -51,8 +51,6 @@ import java.util.ArrayList; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.PointImmutable; public abstract class DisplayImpl extends Display { private static int serialno = 1; @@ -68,49 +66,19 @@ public abstract class DisplayImpl extends Display { }); } - public static class PointerIconImpl implements PointerIcon { - public final long handle; - private final DimensionImmutable size; - private final PointImmutable hotspot; - public PointerIconImpl(final long handle, final DimensionImmutable size, final PointImmutable hotspot) { - this.handle=handle; - this.size = size; - this.hotspot = hotspot; - } - @Override - public final DimensionImmutable getSize() { - return size; - } - @Override - public final PointImmutable getHotspot() { - return hotspot; - } - @Override - public final String toString() { - return "PointerIcon[0x"+Long.toHexString(handle)+", "+size+", "+hotspot+"]"; - } - } - - private void addPointerIconToList(final PointerIcon pi) { - synchronized(pointerIconList) { - pointerIconList.add(pi); - } - } - private void delPointerIconFromList(final PointerIcon pi) { - synchronized(pointerIconList) { - pointerIconList.remove(pi); - } - } - private final ArrayList<PointerIcon> pointerIconList = new ArrayList<PointerIcon>(); + final ArrayList<PointerIconImpl> pointerIconList = new ArrayList<PointerIconImpl>(); /** Executed from EDT! */ private void destroyAllPointerIconFromList(final long dpy) { synchronized(pointerIconList) { - for( int i=0; i < pointerIconList.size(); i++ ) { - final PointerIcon item = pointerIconList.get(i); - if( null != item ) { - // destroy! - destroyPointerIconImpl(dpy, item); + final int count = pointerIconList.size(); + for( int i=0; i < count; i++ ) { + final PointerIconImpl item = pointerIconList.get(i); + if(DEBUG) { + System.err.println("destroyAllPointerIconFromList: dpy "+toHexString(dpy)+", # "+i+"/"+count+": "+item+" @ "+getThreadName()); + } + if( null != item && item.isValid() ) { + item.destroyOnEDT(dpy); } } pointerIconList.clear(); @@ -119,31 +87,37 @@ 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 { - final PointerIcon res = createPointerIconImpl(pngResource, hotX, hotY); - addPointerIconToList(res); - return res; - } - protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { - return null; + return createPointerIcon(false /* isTemp */, pngResource, hotX, hotY); } - - @Override - public final void destroyPointerIcon(final PointerIcon pi) { - delPointerIconFromList(pi); - runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { - @Override - public Object run(long dpy) { + PointerIcon createPointerIcon(final boolean isTemp, final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + if( !isNativeValid() ) { + throw new IllegalStateException("Display.createPointerIcon(1): Display invalid "+this); + } + final PointerIconImpl[] res = { null }; + runOnEDTIfAvail(true, new Runnable() { + public void run() { try { - destroyPointerIconImpl(dpy, pi); + if( !DisplayImpl.this.isNativeValid() ) { + throw new IllegalStateException("Display.createPointerIcon(2): Display invalid "+DisplayImpl.this); + } + res[0] = createPointerIconImpl(pngResource, hotX, hotY); } catch (Exception e) { e.printStackTrace(); } - return null; + } } ); + if( !isTemp ) { + 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! */ - protected void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { } + protected void destroyPointerIconImpl(final long displayHandle, long piHandle) { } /** Ensure static init has been run. */ /* pp */static void initSingleton() { } @@ -399,6 +373,7 @@ public abstract class DisplayImpl extends Display { @Override public void run() { if ( null != d.getGraphicsDevice() ) { + d.destroyAllPointerIconFromList(f_aDevice.getHandle()); d.closeNativeImpl(f_aDevice); } } diff --git a/src/newt/classes/jogamp/newt/PointerIconImpl.java b/src/newt/classes/jogamp/newt/PointerIconImpl.java new file mode 100644 index 000000000..e2388be67 --- /dev/null +++ b/src/newt/classes/jogamp/newt/PointerIconImpl.java @@ -0,0 +1,126 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.newt; + +import javax.media.nativewindow.util.DimensionImmutable; +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 DimensionImmutable size; + private final PointImmutable hotspot; + private long handle; + public PointerIconImpl(DisplayImpl display, ClassResources resource, final DimensionImmutable size, final PointImmutable hotspot, final long handle) { + this.display = display; + this.resource = resource; + this.size = size; + this.hotspot = hotspot; + this.handle=handle; + } + public synchronized final long getHandle() { return handle; } + public synchronized final long validatedHandle() { + synchronized(display.pointerIconList) { + if( !display.pointerIconList.contains(this) ) { + display.pointerIconList.add(this); + } + } + if( 0 == handle ) { + try { + final PointerIconImpl temp = (PointerIconImpl) display.createPointerIcon(true /* isTemp */, resource, hotspot.getX(), hotspot.getY()); + handle = temp.handle; + return handle; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } else { + return handle; + } + } + @Override + public final Display getDisplay() { return display; } + @Override + public final IOUtil.ClassResources getResource() { return resource; } + @Override + public synchronized final boolean isValid() { return 0 != handle; } + @Override + public synchronized final boolean validate() { + if( 0 == handle ) { + return 0 != validatedHandle(); + } + return true; + } + + @Override + public synchronized void destroy() { + if(DisplayImpl.DEBUG) { + System.err.println("PointerIcon.destroy: "+this+", "+display+", "+DisplayImpl.getThreadName()); + } + if( 0 != handle ) { + synchronized(display.pointerIconList) { + display.pointerIconList.remove(this); + } + display.runOnEDTIfAvail(false, new Runnable() { + public void run() { + if( display.isNativeValid() ) { + destroyOnEDT(display.getHandle()); + } + } } ); + } + } + + /** No checks, assume execution on EDT */ + synchronized void destroyOnEDT(final long dpy) { + final long h = handle; + handle = 0; + try { + display.destroyPointerIconImpl(dpy, h); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public final DimensionImmutable getSize() { + return size; + } + @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+"]"; + } +}
\ 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 d078caa3b..8d9fb8d7e 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -84,7 +84,6 @@ import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; import jogamp.nativewindow.SurfaceUpdatedHelper; -import jogamp.newt.DisplayImpl.PointerIconImpl; public abstract class WindowImpl implements Window, NEWTEventConsumer { @@ -440,7 +439,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer screen.addMonitorModeListener(monitorModeListenerImpl); setTitleImpl(title); if( null != pointerIcon ) { - setPointerIcon(pointerIcon); + setPointerIconImpl((PointerIconImpl)pointerIcon); } setPointerVisibleImpl(pointerVisible); confinePointerImpl(pointerConfined); @@ -1689,9 +1688,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final void setPointerIcon(final PointerIcon pi) { if( this.pointerIcon != pi ) { - setPointerIcon(pointerIcon); if( isNativeValid() ) { - setPointerIconImpl((PointerIconImpl)pi); + runOnEDTIfAvail(true, new Runnable() { + public void run() { + setPointerIconImpl((PointerIconImpl)pi); + } } ); } this.pointerIcon = pi; } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java index f0f0a955a..30583c48c 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java @@ -50,6 +50,7 @@ import com.jogamp.newt.NewtFactory; import jogamp.newt.DisplayImpl; import jogamp.newt.NEWTJNILibLoader; +import jogamp.newt.PointerIconImpl; import jogamp.newt.driver.PNGIcon; public class DisplayDriver extends DisplayImpl { @@ -112,21 +113,21 @@ public class DisplayDriver extends DisplayImpl { } @Override - protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + 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() ) { - return new PointerIconImpl( createPointerIcon0(data, width[0], height[0], hotX, hotY), - new Dimension(width[0], height[0]), new Point(hotX, hotY)); 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; } @Override - protected final void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { - destroyPointerIcon0(((PointerIconImpl)pi).handle); + protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) { + destroyPointerIcon0(piHandle); } public static void runNSApplication() { diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index a55fa915a..6f3c95570 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -45,8 +45,8 @@ import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import jogamp.nativewindow.macosx.OSXUtil; +import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; -import jogamp.newt.DisplayImpl.PointerIconImpl; import jogamp.newt.driver.DriverClearFocus; import jogamp.newt.driver.DriverUpdatePosition; @@ -394,17 +394,29 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl @Override protected void setPointerIconImpl(final PointerIconImpl pi) { - OSXUtil.RunOnMainThread(false, new Runnable() { - @Override - public void run() { - setPointerIcon0(getWindowHandle(), null != pi ? pi.handle : 0); - } } ); + if( !isOffscreenInstance ) { + final long piHandle = null != pi ? pi.validatedHandle() : 0; + OSXUtil.RunOnMainThread(true, new Runnable() { // waitUntildone due to PointerIconImpl's Lifecycle ! + @Override + public void run() { + if( !setPointerIcon0(getWindowHandle(), piHandle) ) { + throw new RuntimeException("Failed: "+pi+", "+WindowDriver.this); + } + } } ); + } // else may need offscreen solution ? FIXME } @Override protected boolean setPointerVisibleImpl(final boolean pointerVisible) { if( !isOffscreenInstance ) { - return setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible); + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + if( !setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible) ) { + throw new RuntimeException("Failed"); + } + } } ); + return true; // setPointerVisible0 always returns true .. } // else may need offscreen solution ? FIXME return false; } @@ -420,7 +432,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl @Override protected void warpPointerImpl(final int x, final int y) { if( !isOffscreenInstance ) { - warpPointer0(getWindowHandle(), x, y); + if( !warpPointer0(getWindowHandle(), x, y) ) { + throw new RuntimeException("Failed"); + } } // else may need offscreen solution ? FIXME } @@ -575,10 +589,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl /** Must be called on Main-Thread */ private native void setAlwaysOnTop0(long window, boolean atop); private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y); + private static native boolean setPointerIcon0(long windowHandle, long handle); private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible); private static native boolean confinePointer0(long windowHandle, boolean confine); - private static native void warpPointer0(long windowHandle, int x, int y); - private static native void setPointerIcon0(long windowHandle, long handle); + private static native boolean warpPointer0(long windowHandle, int x, int y); // Window styles private static final int NSBorderlessWindowMask = 0; diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java index 39b2efd15..1e9c78a5d 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java @@ -43,6 +43,7 @@ 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; @@ -104,21 +105,21 @@ public class DisplayDriver extends DisplayImpl { } @Override - protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + 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() ) { - return new PointerIconImpl( createBGRA8888Icon0(data, width[0], height[0], true, hotX, hotY), - new Dimension(width[0], height[0]), new Point(hotX, hotY)); 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; } @Override - protected final void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { - destroyIcon0(((PointerIconImpl)pi).handle); + protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) { + destroyIcon0(piHandle); } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index 764d4fdab..c8d7c65cc 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -38,8 +38,8 @@ import java.nio.ByteBuffer; import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDIUtil; +import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; -import jogamp.newt.DisplayImpl.PointerIconImpl; import jogamp.newt.driver.PNGIcon; import javax.media.nativewindow.AbstractGraphicsConfiguration; @@ -252,7 +252,7 @@ public class WindowDriver extends WindowImpl { @Override protected void setPointerIconImpl(final PointerIconImpl pi) { - setPointerIcon0(getWindowHandle(), null != pi ? pi.handle : 0); + setPointerIcon0(getWindowHandle(), null != pi ? pi.validatedHandle() : 0); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index c377e7f85..150337df4 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -51,6 +51,7 @@ 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 { @@ -131,32 +132,21 @@ public class DisplayDriver extends DisplayImpl { protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } @Override - protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + 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 = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Long>() { - @Override - public Long run(long dpy) { - long h = 0; - try { - h = createPointerIcon0(dpy, data, width[0], height[0], hotX, hotY); - } catch (Exception e) { - e.printStackTrace(); - } - return Long.valueOf(h); - } - }).longValue(); - return new PointerIconImpl(handle, new Dimension(width[0], height[0]), new Point(hotX, hotY)); + 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; } @Override - protected final void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { - destroyPointerIcon0(displayHandle, ((PointerIconImpl)pi).handle); + protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) { + destroyPointerIcon0(displayHandle, piHandle); } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 0ea2c5358..ad1744f2e 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -40,7 +40,7 @@ import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; import jogamp.newt.DisplayImpl; import jogamp.newt.DisplayImpl.DisplayRunnable; -import jogamp.newt.DisplayImpl.PointerIconImpl; +import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; import jogamp.newt.driver.PNGIcon; @@ -279,7 +279,7 @@ public class WindowDriver extends WindowImpl { @Override public Object run(long dpy) { try { - setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.handle : 0); + setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.validatedHandle() : 0); } catch (Exception e) { e.printStackTrace(); } @@ -293,7 +293,15 @@ public class WindowDriver extends WindowImpl { return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() { @Override public Boolean run(long dpy) { - return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible)); + final PointerIconImpl pi = (PointerIconImpl)getPointerIcon(); + final boolean res; + if( pointerVisible && null != pi ) { + setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.validatedHandle() : 0); + res = true; + } else { + res = setPointerVisible0(dpy, getWindowHandle(), pointerVisible); + } + return Boolean.valueOf(res); } }).booleanValue(); } |