aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-04 17:15:04 +0100
committerSven Gothel <[email protected]>2014-01-04 17:15:04 +0100
commitfcc0e7397bb6f3ceb1fe143667f8c59b5bf63874 (patch)
treefbb8225c6408cfe6bf17cccdfeafbc293d126e39 /src
parente3cf96249f4c722f8b2a7d0e052e19165cef171e (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')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java67
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java91
-rw-r--r--src/newt/classes/jogamp/newt/PointerIconImpl.java126
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java9
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java34
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java22
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java14
-rw-r--r--src/newt/native/MacWindow.m113
-rw-r--r--src/newt/native/NewtMacWindow.h86
-rw-r--r--src/newt/native/NewtMacWindow.m1017
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java28
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java53
15 files changed, 992 insertions, 694 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();
}
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 1be3a6ed5..eb5913706 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -347,30 +347,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPoint
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPointerIcon0
(JNIEnv *env, jobject unused, jlong handle)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSCursor * c = (NSCursor*) (intptr_t) handle ;
- if( NULL != c ) {
- if ( NO == [c isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "destroyPointerIcon0 NSCursor %p - is of invalid type\n", c);
- } else {
- DBG_PRINT( "destroyPointerIcon0 %p\n", c);
- [c release];
- }
+ if( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+ DBG_PRINT( "Not a NSCursor %p\n", c);
+ return;
}
- [pool release];
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
- (JNIEnv *env, jobject unused, jlong window, jlong handle)
-{
+ DBG_PRINT( "destroyPointerIcon0 %p\n", c);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
- NSCursor * c = (NSCursor*) (intptr_t) handle ;
- if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (1)\n", c);
- } else {
- [mWin setPointerIcon: c];
- }
+ [c release];
[pool release];
}
@@ -717,7 +701,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
NSRect rectView = NSMakeRect(0, 0, w, h);
NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ;
- DBG_PRINT( "createView0.X.%d - new view: %p\n", myView);
+ DBG_PRINT( "createView0.X - new view: %p\n", myView);
[pool release];
@@ -738,7 +722,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* myView = (NewtView*) (intptr_t) jview ;
- DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n",
+ DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n",
(void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen,
(int)styleMask, (int)bufferingType, myView);
(void)myView;
@@ -865,6 +849,7 @@ NS_ENDHANDLER
// Set the content view
changeContentView(env, jthis, parentView, myWindow, myView, NO);
+ [myWindow setInitialFirstResponder: myView];
DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n",
dbgIdx++, myWindow, myView, [myWindow isVisible]);
@@ -965,7 +950,6 @@ NS_ENDHANDLER
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
if( NULL == mWin ) {
DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n");
@@ -979,6 +963,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
DBG_PRINT( "windowClose.0 - Not a NEWT win - abort\n");
return;
}
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* mView = (NewtView *)[mWin contentView];
BOOL fullscreen = mWin->isFullscreenWindow;
BOOL destroyNotifySent, isNSView, isNewtView;
@@ -1093,6 +1078,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
#endif
DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+ [mWin setAcceptsMouseMovedEvents: YES];
[mWin makeFirstResponder: nil];
[mWin orderFrontRegardless];
[mWin makeKeyWindow];
@@ -1331,18 +1317,39 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
(JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
{
NSObject *nsObj = (NSObject*) ((intptr_t) win);
- NewtMacWindow * mWin = NULL;
-
- if( [nsObj isKindOfClass:[NewtMacWindow class]] ) {
- mWin = (NewtMacWindow*) nsObj;
- } else {
- NewtCommon_throwNewRuntimeException(env, "not NewtMacWindow %p\n", nsObj);
+ NewtMacWindow * mWin = (NewtMacWindow*) nsObj;
+ if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", nsObj);
+ return NULL;
}
-
NSPoint p0 = [mWin getLocationOnScreen: NSMakePoint(src_x, src_y)];
return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y);
}
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
+ (JNIEnv *env, jobject unused, jlong window, jlong handle)
+{
+ NSCursor *c = (NSCursor*) (intptr_t) handle ;
+ if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+ DBG_PRINT("Not a NSCursor %p\n", c);
+ return JNI_FALSE;
+ }
+ NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setPointerIcon: c];
+ [pool release];
+ return JNI_TRUE;
+}
+
/*
* Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: setPointerVisible0
@@ -1351,10 +1358,19 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO
- hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO
+ hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
[pool release];
return JNI_TRUE;
}
@@ -1367,9 +1383,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointe
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong window, jboolean confine)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
[pool release];
return JNI_TRUE;
}
@@ -1379,12 +1404,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePo
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
[pool release];
+ return JNI_TRUE;
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 2728c2201..daf75bec7 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -63,6 +63,14 @@
volatile NSTrackingRectTag ptrTrackingTag;
NSRect ptrRect;
+ NSCursor * myCursor;
+ BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
+
+ BOOL mouseConfined;
+ BOOL mouseInside;
+ BOOL mouseVisible;
+ BOOL cursorIsHidden;
+ NSPoint lastInsideMousePosition;
}
- (id)initWithFrame:(NSRect)frameRect;
@@ -83,9 +91,6 @@
- (void) setJavaWindowObject: (jobject) javaWindowObj;
- (jobject) getJavaWindowObject;
-- (void) rightMouseDown: (NSEvent*) theEvent;
-- (void) resetCursorRects;
-
- (void) setDestroyNotifySent: (BOOL) v;
- (BOOL) getDestroyNotifySent;
@@ -99,6 +104,41 @@
- (void) viewDidHide;
- (void) viewDidUnhide;
- (BOOL) acceptsFirstResponder;
+- (BOOL) becomeFirstResponder;
+- (BOOL) resignFirstResponder;
+
+- (void) removeCursorRects;
+- (void) addCursorRects;
+- (void) removeMyCursor;
+- (void) resetCursorRects;
+- (void) setPointerIcon: (NSCursor*)c;
+- (void) mouseEntered: (NSEvent*) theEvent;
+- (void) mouseExited: (NSEvent*) theEvent;
+- (BOOL) updateMouseInside;
+- (void) cursorHide:(BOOL)v enter:(int)enterState;
+- (void) setPointerIcon:(NSCursor*)c;
+- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus;
+- (BOOL) isMouseVisible;
+- (void) setMouseConfined:(BOOL)v;
+- (void) setMousePosition:(NSPoint)p;
+- (void) mouseMoved: (NSEvent*) theEvent;
+- (void) scrollWheel: (NSEvent*) theEvent;
+- (void) mouseDown: (NSEvent*) theEvent;
+- (void) mouseDragged: (NSEvent*) theEvent;
+- (void) mouseUp: (NSEvent*) theEvent;
+- (void) rightMouseDown: (NSEvent*) theEvent;
+- (void) rightMouseDragged: (NSEvent*) theEvent;
+- (void) rightMouseUp: (NSEvent*) theEvent;
+- (void) otherMouseDown: (NSEvent*) theEvent;
+- (void) otherMouseDragged: (NSEvent*) theEvent;
+- (void) otherMouseUp: (NSEvent*) theEvent;
+- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
+- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
+
+- (void) handleFlagsChanged:(NSUInteger) mods;
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
@end
@@ -108,14 +148,7 @@
@interface NewtMacWindow : NSWindow
#endif
{
- BOOL mouseConfined;
- BOOL mouseVisible;
- BOOL mouseInside;
- BOOL cursorIsHidden;
- NSCursor * customCursor;
BOOL realized;
- BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
- NSPoint lastInsideMousePosition;
@public
BOOL hasPresentationSwitch;
NSUInteger defaultPresentationOptions;
@@ -147,20 +180,14 @@
- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p;
- (NSSize) newtClientSize2TLSize: (NSSize) nsz;
- (NSPoint) getLocationOnScreen: (NSPoint) p;
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
-- (BOOL) isMouseInside;
-- (void) cursorHide:(BOOL)v enter:(int)enterState;
-- (void) setPointerIcon:(NSCursor*)c;
-- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus;
-- (void) setMouseConfined:(BOOL)v;
-- (void) setMousePosition:(NSPoint)p;
-
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
- (void) focusChanged: (BOOL) gained;
+- (void) keyDown: (NSEvent*) theEvent;
+- (void) keyUp: (NSEvent*) theEvent;
+- (void) flagsChanged: (NSEvent *) theEvent;
+- (BOOL) acceptsMouseMovedEvents;
+- (BOOL) acceptsFirstResponder;
- (BOOL) becomeFirstResponder;
- (BOOL) resignFirstResponder;
- (BOOL) canBecomeKeyWindow;
@@ -168,22 +195,7 @@
- (void) resignKeyWindow;
- (void) windowDidBecomeKey: (NSNotification *) notification;
- (void) windowDidResignKey: (NSNotification *) notification;
-- (void) keyDown: (NSEvent*) theEvent;
-- (void) keyUp: (NSEvent*) theEvent;
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
-- (void) flagsChanged: (NSEvent *) theEvent;
-- (void) mouseEntered: (NSEvent*) theEvent;
-- (void) mouseExited: (NSEvent*) theEvent;
-- (void) mouseMoved: (NSEvent*) theEvent;
-- (void) scrollWheel: (NSEvent*) theEvent;
-- (void) mouseDown: (NSEvent*) theEvent;
-- (void) mouseDragged: (NSEvent*) theEvent;
-- (void) mouseUp: (NSEvent*) theEvent;
-- (void) rightMouseDown: (NSEvent*) theEvent;
-- (void) rightMouseDragged: (NSEvent*) theEvent;
-- (void) rightMouseUp: (NSEvent*) theEvent;
-- (void) otherMouseDown: (NSEvent*) theEvent;
-- (void) otherMouseUp: (NSEvent*) theEvent;
+
- (void) windowDidResize: (NSNotification*) notification;
- (void) windowDidMove: (NSNotification*) notification;
- (BOOL) windowClosingImpl: (BOOL) force;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 96965b67a..5ccd9c658 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -86,6 +86,88 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
return (jfloat) delta;
}
+#define kVK_Shift 0x38
+#define kVK_Option 0x3A
+#define kVK_Control 0x3B
+#define kVK_Command 0x37
+
+static jint mods2JavaMods(NSUInteger mods)
+{
+ int javaMods = 0;
+ if (mods & NSShiftKeyMask) {
+ javaMods |= EVENT_SHIFT_MASK;
+ }
+ if (mods & NSControlKeyMask) {
+ javaMods |= EVENT_CTRL_MASK;
+ }
+ if (mods & NSCommandKeyMask) {
+ javaMods |= EVENT_META_MASK;
+ }
+ if (mods & NSAlternateKeyMask) {
+ javaMods |= EVENT_ALT_MASK;
+ }
+ return javaMods;
+}
+
+static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
+ UInt32 keysDown = 0;
+ UniChar chars[4];
+ UniCharCount realLength;
+
+ UCKeyTranslate(keyboardLayout, keyCode,
+ kUCKeyActionDisplay, 0,
+ LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
+ &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
+
+ return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
+
+static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
+ CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
+ const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+
+ CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL);
+ if ( NULL != codeToCharDict ) {
+ intptr_t i;
+ for (i = 0; i < 128; ++i) {
+ CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout);
+ if( NULL != string ) {
+ CFIndex stringLen = CFStringGetLength (string);
+ if ( 0 < stringLen ) {
+ UniChar character = CFStringGetCharacterAtIndex(string, 0);
+ DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character);
+ CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character);
+ }
+ CFRelease(string);
+ }
+ }
+ }
+ return codeToCharDict;
+}
+
+static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+
+static void CKCH_CreateDictionaries() {
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+ CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
+ CFRelease(currentKeyboard);
+}
+
+static UniChar CKCH_CharForKeyCode(jshort keyCode) {
+ UniChar rChar = 0;
+
+ if ( NULL != CKCH_USCodeToNNChar ) {
+ intptr_t code = (intptr_t) keyCode;
+ intptr_t character = 0;
+
+ if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) {
+ rChar = (UniChar) character;
+ DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar);
+ }
+ }
+ return rChar;
+}
+
static jmethodID enqueueMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
@@ -122,6 +204,16 @@ static jmethodID windowRepaintID = NULL;
pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive
ptrTrackingTag = 0;
+ myCursor = NULL;
+
+ modsDown[0] = NO; // shift
+ modsDown[1] = NO; // ctrl
+ modsDown[2] = NO; // alt
+ modsDown[3] = NO; // win
+ mouseConfined = NO;
+ mouseVisible = YES;
+ mouseInside = NO;
+ cursorIsHidden = NO;
DBG_PRINT("NewtView::create: %p (refcnt %d)\n", res, (int)[res retainCount]);
return res;
@@ -144,10 +236,9 @@ static jmethodID windowRepaintID = NULL;
if( 0 < softLockCount ) {
NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
- if(0 != ptrTrackingTag) {
- [self removeTrackingRect: ptrTrackingTag];
- ptrTrackingTag = 0;
- }
+ [self removeCursorRects];
+ [self removeMyCursor];
+
pthread_mutex_destroy(&softLockSync);
DBG_PRINT("NewtView::dealloc.X: %p\n", self);
[super dealloc];
@@ -182,26 +273,6 @@ static jmethodID windowRepaintID = NULL;
return javaWindowObject;
}
-- (void) rightMouseDown: (NSEvent*) theEvent
-{
- NSResponder* next = [self nextResponder];
- if (next != nil) {
- [next rightMouseDown: theEvent];
- }
-}
-
-- (void) resetCursorRects
-{
- [super resetCursorRects];
-
- if(0 != ptrTrackingTag) {
- [self removeTrackingRect: ptrTrackingTag];
- ptrTrackingTag = 0;
- }
- ptrRect = [self bounds];
- ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
-}
-
- (void) setDestroyNotifySent: (BOOL) v
{
destroyNotifySent = v;
@@ -337,67 +408,397 @@ static jmethodID windowRepaintID = NULL;
return YES;
}
-@end
+- (BOOL) becomeFirstResponder
+{
+ DBG_PRINT( "*************** View.becomeFirstResponder\n");
+ return [super becomeFirstResponder];
+}
-static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
- UInt32 keysDown = 0;
- UniChar chars[4];
- UniCharCount realLength;
+- (BOOL) resignFirstResponder
+{
+ DBG_PRINT( "*************** View.resignFirstResponder\n");
+ return [super resignFirstResponder];
+}
- UCKeyTranslate(keyboardLayout, keyCode,
- kUCKeyActionDisplay, 0,
- LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
- &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
+- (void) removeCursorRects
+{
+ if(0 != ptrTrackingTag) {
+ if(NULL != myCursor) {
+ [self removeCursorRect: ptrRect cursor: myCursor];
+ }
+ [self removeTrackingRect: ptrTrackingTag];
+ ptrTrackingTag = 0;
+ }
+}
- return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+- (void) addCursorRects
+{
+ ptrRect = [self bounds];
+ if(NULL != myCursor) {
+ [self addCursorRect: ptrRect cursor: myCursor];
+ }
+ ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
}
-static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
- CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
- const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+- (void) removeMyCursor
+{
+ if(NULL != myCursor) {
+ [myCursor release];
+ myCursor = NULL;
+ }
+}
- CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL);
- if ( NULL != codeToCharDict ) {
- intptr_t i;
- for (i = 0; i < 128; ++i) {
- CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout);
- if( NULL != string ) {
- CFIndex stringLen = CFStringGetLength (string);
- if ( 0 < stringLen ) {
- UniChar character = CFStringGetCharacterAtIndex(string, 0);
- DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character);
- CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character);
- }
- CFRelease(string);
- }
+- (void) resetCursorRects
+{
+ [super resetCursorRects];
+
+ [self removeCursorRects];
+ [self addCursorRects];
+}
+
+- (void) setPointerIcon: (NSCursor*)c
+{
+ DBG_PRINT( "setPointerIcon: %p -> %p, top %p, mouseInside %d\n", myCursor, c, [NSCursor currentCursor], (int)mouseInside);
+ if( c != myCursor ) {
+ [self removeCursorRects];
+ [self removeMyCursor];
+ myCursor = c;
+ if( NULL != myCursor ) {
+ [myCursor retain];
}
}
- return codeToCharDict;
+ NSWindow* nsWin = [self window];
+ if( NULL != nsWin ) {
+ [nsWin invalidateCursorRectsForView: self];
+ }
}
-static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+- (void) mouseEntered: (NSEvent*) theEvent
+{
+ DBG_PRINT( "mouseEntered: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]);
+ mouseInside = YES;
+ [self cursorHide: !mouseVisible enter: 1];
+ if(NO == mouseConfined) {
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED];
+ }
+ NSWindow* nsWin = [self window];
+ if( NULL != nsWin ) {
+ [nsWin makeFirstResponder: self];
+ }
+}
-static void CKCH_CreateDictionaries() {
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
- CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
- CFRelease(currentKeyboard);
+- (void) mouseExited: (NSEvent*) theEvent
+{
+ DBG_PRINT( "mouseExited: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]);
+ if(NO == mouseConfined) {
+ mouseInside = NO;
+ [self cursorHide: NO enter: -1];
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED];
+ [self resignFirstResponder];
+ } else {
+ [self setMousePosition: lastInsideMousePosition];
+ }
}
-static UniChar CKCH_CharForKeyCode(jshort keyCode) {
- UniChar rChar = 0;
+- (void) setMousePosition:(NSPoint)p
+{
+ NSWindow* nsWin = [self window];
+ if( NULL != nsWin ) {
+ NSScreen* screen = [nsWin screen];
+ NSRect screenRect = [screen frame];
- if ( NULL != CKCH_USCodeToNNChar ) {
- intptr_t code = (intptr_t) keyCode;
- intptr_t character = 0;
+ CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
+ CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
+ CGEventPost (kCGHIDEventTap, ev);
+ }
+}
- if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) {
- rChar = (UniChar) character;
- DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar);
+- (BOOL) updateMouseInside
+{
+ NSRect viewFrame = [self frame];
+ NSPoint l1 = [NSEvent mouseLocation];
+ NSPoint l0 = [self screenPos2NewtClientWinPos: l1];
+ mouseInside = viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) &&
+ viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ;
+ return mouseInside;
+}
+
+- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus
+{
+ mouseVisible = v;
+ [self updateMouseInside];
+ DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n",
+ mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus);
+ if(YES == focus && YES == mouseInside) {
+ [self cursorHide: !mouseVisible enter: 0];
+ }
+}
+- (BOOL) isMouseVisible
+{
+ return mouseVisible;
+}
+
+- (void) cursorHide:(BOOL)v enter:(int)enterState
+{
+ DBG_PRINT( "cursorHide: %d -> %d, enter %d; PointerIcon: %p, top %p\n",
+ cursorIsHidden, v, enterState, myCursor, [NSCursor currentCursor]);
+ if(v) {
+ if(!cursorIsHidden) {
+ [NSCursor hide];
+ cursorIsHidden = YES;
+ }
+ } else {
+ if(cursorIsHidden) {
+ [NSCursor unhide];
+ cursorIsHidden = NO;
}
}
- return rChar;
}
+- (void) setMouseConfined:(BOOL)v
+{
+ mouseConfined = v;
+ DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible);
+}
+
+- (void) mouseMoved: (NSEvent*) theEvent
+{
+ if( mouseInside ) {
+ NSCursor * currentCursor = [NSCursor currentCursor];
+ BOOL setCursor = NULL != myCursor && NO == cursorIsHidden && currentCursor != myCursor;
+ DBG_PRINT( "mouseMoved.set: %d; mouseInside %d, CursorHidden %d, PointerIcon: %p, top %p\n",
+ setCursor, mouseInside, cursorIsHidden, myCursor, currentCursor);
+ if( setCursor ) {
+ // FIXME: Workaround missing NSCursor update for 'fast moving' pointer
+ [myCursor set];
+ }
+ lastInsideMousePosition = [NSEvent mouseLocation];
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+ }
+}
+
+- (void) scrollWheel: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED];
+}
+
+- (void) mouseDown: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+}
+
+- (void) mouseDragged: (NSEvent*) theEvent
+{
+ lastInsideMousePosition = [NSEvent mouseLocation];
+ // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
+
+- (void) mouseUp: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+}
+
+- (void) rightMouseDown: (NSEvent*) theEvent
+{
+ NSResponder* next = [self nextResponder];
+ if (next != nil) {
+ [next rightMouseDown: theEvent];
+ }
+ // FIXME: ^^ OR [super rightMouseDown: theEvent] ?
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+}
+
+- (void) rightMouseDragged: (NSEvent*) theEvent
+{
+ lastInsideMousePosition = [NSEvent mouseLocation];
+ // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
+
+- (void) rightMouseUp: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+}
+
+- (void) otherMouseDown: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+}
+
+- (void) otherMouseDragged: (NSEvent*) theEvent
+{
+ lastInsideMousePosition = [NSEvent mouseLocation];
+ // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
+
+- (void) otherMouseUp: (NSEvent*) theEvent
+{
+ [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+}
+
+- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
+{
+ if (javaWindowObject == NULL) {
+ DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
+ return;
+ }
+ int shallBeDetached = 0;
+ JNIEnv* env;
+ if( NULL != jvmHandle ) {
+ env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ } else {
+ env = NULL;
+ }
+ if(NULL==env) {
+ DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ return;
+ }
+ jint javaMods[] = { 0 } ;
+ javaMods[0] = mods2JavaMods([event modifierFlags]);
+
+ // convert to 1-based button number (or use zero if no button is involved)
+ // TODO: detect mouse button when mouse wheel scrolled
+ jshort javaButtonNum = 0;
+ jfloat scrollDeltaY = 0.0f;
+ switch ([event type]) {
+ case NSScrollWheel: {
+ scrollDeltaY = GetDelta(event, javaMods);
+ javaButtonNum = 1;
+ break;
+ }
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSLeftMouseDragged:
+ javaButtonNum = 1;
+ break;
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSRightMouseDragged:
+ javaButtonNum = 3;
+ break;
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+ javaButtonNum = 2;
+ break;
+ }
+
+ if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
+ // ignore 0 increment wheel scroll events
+ return;
+ }
+ if (evType == EVENT_MOUSE_PRESSED) {
+ (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
+ }
+
+ NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
+
+ (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
+ evType, javaMods[0],
+ (jint) location.x, (jint) location.y,
+ javaButtonNum, scrollDeltaY);
+
+ /* if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ } */
+}
+
+- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p
+{
+ NSRect viewFrame = [self frame];
+
+ NSRect r;
+ r.origin.x = p.x;
+ r.origin.y = p.y;
+ r.size.width = 0;
+ r.size.height = 0;
+ // NSRect rS = [[self window] convertRectFromScreen: r]; // 10.7
+ NSPoint oS = [[self window] convertScreenToBase: r.origin];
+ oS.y = viewFrame.size.height - oS.y; // y-flip
+ return oS;
+}
+
+- (void) handleFlagsChanged:(NSUInteger) mods
+{
+ [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
+ [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
+ [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
+ [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
+}
+
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
+{
+ if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) {
+ modsDown[keyIdx] = YES;
+ [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED];
+ } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) {
+ modsDown[keyIdx] = NO;
+ [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED];
+ }
+}
+
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType
+{
+ jshort keyCode = (jshort) [event keyCode];
+ NSString* chars = [event charactersIgnoringModifiers];
+ NSUInteger mods = [event modifierFlags];
+ [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
+}
+
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType
+{
+ if (javaWindowObject == NULL) {
+ DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
+ return;
+ }
+ int shallBeDetached = 0;
+ JNIEnv* env;
+ if( NULL != jvmHandle ) {
+ env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ } else {
+ env = NULL;
+ }
+ if(NULL==env) {
+ DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ return;
+ }
+
+ int i;
+ int len = NULL != chars ? [chars length] : 0;
+ jint javaMods = mods2JavaMods(mods);
+
+ if(len > 0) {
+ // printable chars
+ for (i = 0; i < len; i++) {
+ // Note: the key code in the NSEvent does not map to anything we can use
+ UniChar keyChar = (UniChar) [chars characterAtIndex: i];
+ UniChar keySymChar = CKCH_CharForKeyCode(keyCode);
+
+ DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X, mods 0x%X/0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar,
+ (int)mods, (int)javaMods, (int)keySymChar);
+
+ (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+ evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
+ }
+ } else {
+ // non-printable chars
+ jchar keyChar = (jchar) 0;
+
+ DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
+
+ (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+ evType, javaMods, keyCode, keyChar, keyChar);
+ }
+
+ /* if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ } */
+}
+
+@end
+
@implementation NewtMacWindow
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
@@ -463,15 +864,6 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
cachedInsets[1] = 0; // r
cachedInsets[2] = 0; // t
cachedInsets[3] = 0; // b
- modsDown[0] = NO; // shift
- modsDown[1] = NO; // ctrl
- modsDown[2] = NO; // alt
- modsDown[3] = NO; // win
- mouseConfined = NO;
- mouseVisible = YES;
- mouseInside = NO;
- cursorIsHidden = NO;
- customCursor = NULL;
realized = YES;
DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n",
res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
@@ -633,311 +1025,82 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
return oS;
}
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p
-{
- NSView* view = [self contentView];
- NSRect viewFrame = [view frame];
-
- NSRect r;
- r.origin.x = p.x;
- r.origin.y = p.y;
- r.size.width = 0;
- r.size.height = 0;
- // NSRect rS = [win convertRectFromScreen: r]; // 10.7
- NSPoint oS = [self convertScreenToBase: r.origin];
- oS.y = viewFrame.size.height - oS.y; // y-flip
- return oS;
-}
-
-- (BOOL) isMouseInside
-{
- NSView* view = [self contentView];
- NSRect viewFrame = [view frame];
- NSPoint l1 = [NSEvent mouseLocation];
- NSPoint l0 = [self screenPos2NewtClientWinPos: l1];
- return viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) &&
- viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ;
-}
-
-- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus
-{
- mouseVisible = v;
- mouseInside = [self isMouseInside];
- DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n",
- mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus);
- if(YES == focus && YES == mouseInside) {
- [self cursorHide: !mouseVisible enter: 0];
- }
-}
-
-- (void) setPointerIcon:(NSCursor*)c
-{
- DBG_PRINT( "setPointerIcon: mouseInside cursor: %p -> %p (glob %p), mouseInside %d\n", customCursor, c, [NSCursor currentCursor], (int)mouseInside);
- if(YES == mouseInside) {
- if( NULL != c ) {
- DBG_PRINT( "setPointerIcon push: %p\n", c);
- [c push];
- } else if( NULL != customCursor ) {
- if ( NO == [customCursor isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (2)\n", customCursor);
- if( [NSCursor currentCursor] == customCursor ) {
- [NSCursor pop];
- }
- } else if( [NSCursor currentCursor] == customCursor ) {
- DBG_PRINT( "setPointerIcon pop: %p\n", customCursor);
- [customCursor pop];
- }
- }
- }
- customCursor = c;
-}
-
-- (void) cursorHide:(BOOL)v enter:(int)enterState
-{
- DBG_PRINT( "cursorHide: %d -> %d, enter %d\n", cursorIsHidden, v, enterState);
- if( NULL != customCursor ) {
- if ( NO == [customCursor isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (3)\n", customCursor);
- if( [NSCursor currentCursor] == customCursor ) {
- [NSCursor pop];
- }
- } else {
- if( 1 == enterState && [NSCursor currentCursor] != customCursor ) {
- DBG_PRINT( "cursorHide.PointerIcon push: %p\n", customCursor);
- [customCursor push];
- } else if( -1 == enterState && [NSCursor currentCursor] == customCursor ) {
- DBG_PRINT( "cursorHide.PointerIcon pop: %p\n", customCursor);
- [customCursor pop];
- }
- }
- }
- if(v) {
- if(!cursorIsHidden) {
- [NSCursor hide];
- cursorIsHidden = YES;
- }
- } else {
- if(cursorIsHidden) {
- [NSCursor unhide];
- cursorIsHidden = NO;
- }
- }
-}
-
-- (void) setMouseConfined:(BOOL)v
-{
- mouseConfined = v;
- DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible);
-}
-
-- (void) setMousePosition:(NSPoint)p
-{
- NSScreen* screen = [self screen];
- NSRect screenRect = [screen frame];
-
- CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
- CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
- CGEventPost (kCGHIDEventTap, ev);
-}
-
-static jint mods2JavaMods(NSUInteger mods)
-{
- int javaMods = 0;
- if (mods & NSShiftKeyMask) {
- javaMods |= EVENT_SHIFT_MASK;
- }
- if (mods & NSControlKeyMask) {
- javaMods |= EVENT_CTRL_MASK;
- }
- if (mods & NSCommandKeyMask) {
- javaMods |= EVENT_META_MASK;
- }
- if (mods & NSAlternateKeyMask) {
- javaMods |= EVENT_ALT_MASK;
- }
- return javaMods;
-}
-
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType
-{
- jshort keyCode = (jshort) [event keyCode];
- NSString* chars = [event charactersIgnoringModifiers];
- NSUInteger mods = [event modifierFlags];
- [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
-}
-
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType
+- (void) focusChanged: (BOOL) gained
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT( "focusChanged: gained %d\n", gained);
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return;
}
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
+ jobject javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject == NULL) {
- DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env;
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
} else {
env = NULL;
}
if(NULL==env) {
- DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env);
return;
}
- int i;
- int len = NULL != chars ? [chars length] : 0;
- jint javaMods = mods2JavaMods(mods);
-
- if(len > 0) {
- // printable chars
- for (i = 0; i < len; i++) {
- // Note: the key code in the NSEvent does not map to anything we can use
- UniChar keyChar = (UniChar) [chars characterAtIndex: i];
- UniChar keySymChar = CKCH_CharForKeyCode(keyCode);
-
- DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, (int)keySymChar);
-
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
- }
- } else {
- // non-printable chars
- jchar keyChar = (jchar) 0;
-
- DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
-
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyChar, keyChar);
- }
+ (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
/* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
} */
}
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
+- (void) keyDown: (NSEvent*) theEvent
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
- return;
- }
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
- if (javaWindowObject == NULL) {
- DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
- return;
- }
- int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env;
- if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
- } else {
- env = NULL;
- }
- if(NULL==env) {
- DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
- return;
- }
- jint javaMods[] = { 0 } ;
- javaMods[0] = mods2JavaMods([event modifierFlags]);
-
- // convert to 1-based button number (or use zero if no button is involved)
- // TODO: detect mouse button when mouse wheel scrolled
- jshort javaButtonNum = 0;
- jfloat scrollDeltaY = 0.0f;
- switch ([event type]) {
- case NSScrollWheel: {
- scrollDeltaY = GetDelta(event, javaMods);
- javaButtonNum = 1;
- break;
- }
- case NSLeftMouseDown:
- case NSLeftMouseUp:
- case NSLeftMouseDragged:
- javaButtonNum = 1;
- break;
- case NSRightMouseDown:
- case NSRightMouseUp:
- case NSRightMouseDragged:
- javaButtonNum = 3;
- break;
- case NSOtherMouseDown:
- case NSOtherMouseUp:
- case NSOtherMouseDragged:
- javaButtonNum = 2;
- break;
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
}
+}
- if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
- // ignore 0 increment wheel scroll events
- return;
- }
- if (evType == EVENT_MOUSE_PRESSED) {
- (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
+- (void) keyUp: (NSEvent*) theEvent
+{
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
}
-
- NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
-
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
- evType, javaMods[0],
- (jint) location.x, (jint) location.y,
- javaButtonNum, scrollDeltaY);
-
- /* if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- } */
}
-- (void) focusChanged: (BOOL) gained
+- (void) flagsChanged:(NSEvent *) theEvent
{
- DBG_PRINT( "focusChanged: gained %d\n", gained);
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
- return;
- }
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
- if (javaWindowObject == NULL) {
- DBG_PRINT("focusChanged: null javaWindowObject\n");
- return;
- }
- int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env;
- if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
- } else {
- env = NULL;
- }
- if(NULL==env) {
- DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env);
- return;
+ NSUInteger mods = [theEvent modifierFlags];
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView handleFlagsChanged: mods];
}
+}
- (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+- (BOOL) acceptsMouseMovedEvents
+{
+ return YES;
+}
- /* if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- } */
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
}
- (BOOL) becomeFirstResponder
{
- DBG_PRINT( "*************** becomeFirstResponder\n");
+ DBG_PRINT( "*************** Win.becomeFirstResponder\n");
return [super becomeFirstResponder];
}
- (BOOL) resignFirstResponder
{
- DBG_PRINT( "*************** resignFirstResponder\n");
+ DBG_PRINT( "*************** Win.resignFirstResponder\n");
return [super resignFirstResponder];
}
@@ -965,9 +1128,12 @@ static jint mods2JavaMods(NSUInteger mods)
- (void) windowDidBecomeKey: (NSNotification *) notification
{
DBG_PRINT( "*************** windowDidBecomeKey\n");
- mouseInside = [self isMouseInside];
- if(YES == mouseInside) {
- [self cursorHide: !mouseVisible enter: 0];
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ BOOL mouseInside = [newtView updateMouseInside];
+ if(YES == mouseInside) {
+ [newtView cursorHide: ![newtView isMouseVisible] enter: 1];
+ }
}
[self focusChanged: YES];
}
@@ -979,128 +1145,6 @@ static jint mods2JavaMods(NSUInteger mods)
[self focusChanged: NO];
}
-- (void) keyDown: (NSEvent*) theEvent
-{
- [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
-}
-
-- (void) keyUp: (NSEvent*) theEvent
-{
- [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
-}
-
-#define kVK_Shift 0x38
-#define kVK_Option 0x3A
-#define kVK_Control 0x3B
-#define kVK_Command 0x37
-
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
-{
- if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) {
- modsDown[keyIdx] = YES;
- [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED];
- } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) {
- modsDown[keyIdx] = NO;
- [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED];
- }
-}
-
-- (void) flagsChanged:(NSEvent *) theEvent
-{
- NSUInteger mods = [theEvent modifierFlags];
-
- // BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
-
- [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
- [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
- [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
- [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
-}
-
-- (void) mouseEntered: (NSEvent*) theEvent
-{
- DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible);
- mouseInside = YES;
- [self cursorHide: !mouseVisible enter: 1];
- if(NO == mouseConfined) {
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED];
- }
-}
-
-- (void) mouseExited: (NSEvent*) theEvent
-{
- DBG_PRINT( "mouseExited: confined %d, visible %d\n", mouseConfined, mouseVisible);
- if(NO == mouseConfined) {
- mouseInside = NO;
- [self cursorHide: NO enter: -1];
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED];
- } else {
- [self setMousePosition: lastInsideMousePosition];
- }
-}
-
-- (void) mouseMoved: (NSEvent*) theEvent
-{
- lastInsideMousePosition = [NSEvent mouseLocation];
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
-}
-
-- (void) scrollWheel: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED];
-}
-
-- (void) mouseDown: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
-}
-
-- (void) mouseDragged: (NSEvent*) theEvent
-{
- lastInsideMousePosition = [NSEvent mouseLocation];
- // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
-}
-
-- (void) mouseUp: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
-}
-
-- (void) rightMouseDown: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
-}
-
-- (void) rightMouseDragged: (NSEvent*) theEvent
-{
- lastInsideMousePosition = [NSEvent mouseLocation];
- // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
-}
-
-- (void) rightMouseUp: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
-}
-
-- (void) otherMouseDown: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
-}
-
-- (void) otherMouseDragged: (NSEvent*) theEvent
-{
- lastInsideMousePosition = [NSEvent mouseLocation];
- // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
-}
-
-- (void) otherMouseUp: (NSEvent*) theEvent
-{
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
-}
-
- (void)windowDidResize: (NSNotification*) notification
{
JNIEnv* env = NULL;
@@ -1108,14 +1152,13 @@ static jint mods2JavaMods(NSUInteger mods)
int shallBeDetached = 0;
JavaVM *jvmHandle = NULL;
- NSView* nsview = [self contentView];
- if( [nsview isKindOfClass:[NewtView class]] ) {
- NewtView* view = (NewtView *) nsview;
- javaWindowObject = [view getJavaWindowObject];
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject != NULL) {
- jvmHandle = [view getJVMHandle];
+ jvmHandle = [newtView getJVMHandle];
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
}
}
}
@@ -1139,21 +1182,20 @@ static jint mods2JavaMods(NSUInteger mods)
- (void)windowDidMove: (NSNotification*) notification
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return;
}
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
+ jobject javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject == NULL) {
DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env;
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
} else {
env = NULL;
}
@@ -1186,32 +1228,31 @@ static jint mods2JavaMods(NSUInteger mods)
jboolean closed = JNI_FALSE;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [self cursorHide: NO enter: -1];
-
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return NO;
}
- NewtView* view = (NewtView *) nsview;
- if( false == [view getDestroyNotifySent] ) {
- jobject javaWindowObject = [view getJavaWindowObject];
+ [newtView cursorHide: NO enter: -1];
+
+ if( false == [newtView getDestroyNotifySent] ) {
+ jobject javaWindowObject = [newtView getJavaWindowObject];
DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
DBG_PRINT("windowWillClose: null javaWindowObject\n");
return NO;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env = NULL;
NS_DURING
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
}
NS_HANDLER
jvmHandle = NULL;
env = NULL;
- [view setJVMHandle: NULL];
+ [newtView setJVMHandle: NULL];
DBG_PRINT("windowWillClose: JVMHandler Exception\n");
NS_ENDHANDLER
DBG_PRINT("windowWillClose: JVM %p JNIEnv %p\n", jvmHandle, env);
@@ -1219,11 +1260,11 @@ NS_ENDHANDLER
return NO;
}
- [view setDestroyNotifySent: true]; // earmark assumption of being closed
+ [newtView setDestroyNotifySent: true]; // earmark assumption of being closed
closed = (*env)->CallBooleanMethod(env, javaWindowObject, windowDestroyNotifyID, force ? JNI_TRUE : JNI_FALSE);
if(!force && !closed) {
// not closed on java side, not force -> clear flag
- [view setDestroyNotifySent: false];
+ [newtView setDestroyNotifySent: false];
}
/* if (shallBeDetached) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index efec961de..8cc676291 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -85,6 +85,7 @@ public class TestGearsES2NEWT extends UITestCase {
static boolean waitForKey = false;
static boolean mouseVisible = true;
static boolean mouseConfined = false;
+ static boolean setPointerIcon = false;
static boolean showFPS = false;
static int loops = 1;
static boolean loop_shutdown = false;
@@ -183,6 +184,10 @@ public class TestGearsES2NEWT extends UITestCase {
}
pointerIconOne = _pointerIconOne;
}
+ if( setPointerIcon ) {
+ glWindow.setPointerIcon(pointerIconOne);
+ System.err.println("Set PointerIcon: "+glWindow.getPointerIcon());
+ }
glWindow.addKeyListener(new KeyAdapter() {
@Override
@@ -216,16 +221,6 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("[set alwaysontop post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setExclusiveContextThread(t);
} }.start();
- } else if(e.getKeyChar()=='c') {
- new Thread() {
- public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
- System.err.println("[set pointer-icon pre]");
- final PointerIcon currentPI = glWindow.getPointerIcon();
- glWindow.setPointerIcon( currentPI == pointerIconOne ? null : pointerIconOne);
- System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
- glWindow.setExclusiveContextThread(t);
- } }.start();
} else if(e.getKeyChar()=='d') {
new Thread() {
public void run() {
@@ -245,6 +240,16 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("[set position post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
glWindow.setExclusiveContextThread(t);
} }.start();
+ } else if(e.getKeyChar()=='c') {
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set pointer-icon pre]");
+ final PointerIcon currentPI = glWindow.getPointerIcon();
+ glWindow.setPointerIcon( currentPI == pointerIconOne ? null : pointerIconOne);
+ System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
+ glWindow.setExclusiveContextThread(t);
+ } }.start();
} else if(e.getKeyChar()=='i') {
new Thread() {
public void run() {
@@ -482,6 +487,8 @@ public class TestGearsES2NEWT extends UITestCase {
mouseVisible = false;
} else if(args[i].equals("-mouseConfine")) {
mouseConfined = true;
+ } else if(args[i].equals("-pointerIcon")) {
+ setPointerIcon = true;
} else if(args[i].equals("-showFPS")) {
showFPS = true;
} else if(args[i].equals("-width")) {
@@ -537,6 +544,7 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("pmvDirect "+(!pmvUseBackingArray));
System.err.println("mouseVisible "+mouseVisible);
System.err.println("mouseConfined "+mouseConfined);
+ System.err.println("pointerIcon "+setPointerIcon);
System.err.println("loops "+loops);
System.err.println("loop shutdown "+loop_shutdown);
System.err.println("forceES2 "+forceES2);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
index 189645d3d..69874df6b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
@@ -31,6 +31,10 @@ import java.awt.Frame;
import javax.media.nativewindow.util.InsetsImmutable;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.Display.PointerIcon;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
@@ -42,6 +46,7 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
final NewtCanvasAWT newtCanvasAWT;
final GLWindow glWindow;
final QuitAdapter quitAdapter;
+ PointerIcon pointerIconTest = null;
public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow, QuitAdapter quitAdapter) {
this.frame = frame;
@@ -54,9 +59,7 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
if( !e.isPrintableKey() || e.isAutoRepeat() ) {
return;
}
- if( e.getKeySymbol() == KeyEvent.VK_I ) {
- System.err.println(glWindow);
- } else if( e.getKeySymbol() == KeyEvent.VK_L ) {
+ if( e.getKeySymbol() == KeyEvent.VK_L ) {
javax.media.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null);
javax.media.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
System.err.println("NewtCanvasAWT position: "+p0+", "+p1);
@@ -140,6 +143,50 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
quitAdapter.enable(true);
}
} }.start();
+ } else if(e.getKeySymbol() == KeyEvent.VK_C ) {
+ if( null == pointerIconTest ) {
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/jogamp-32x32.png" } );
+ final Display disp = glWindow.getScreen().getDisplay();
+ try {
+ pointerIconTest = disp.createPointerIcon(res, 16, 0);
+ } catch (Exception err) {
+ err.printStackTrace();
+ }
+ }
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set pointer-icon pre]");
+ final PointerIcon currentPI = glWindow.getPointerIcon();
+ glWindow.setPointerIcon( currentPI == pointerIconTest ? null : pointerIconTest);
+ System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
+ glWindow.setExclusiveContextThread(t);
+ } }.start();
+ } else if( e.getKeySymbol() == KeyEvent.VK_I ) {
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible());
+ glWindow.setPointerVisible(!glWindow.isPointerVisible());
+ System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible());
+ glWindow.setExclusiveContextThread(t);
+ } }.start();
+ } else if(e.getKeySymbol() == KeyEvent.VK_J ) {
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined());
+ glWindow.confinePointer(!glWindow.isPointerConfined());
+ System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined());
+ glWindow.setExclusiveContextThread(t);
+ } }.start();
+ } else if(e.getKeySymbol() == KeyEvent.VK_W ) {
+ new Thread() {
+ public void run() {
+ System.err.println("[set mouse pos pre]");
+ glWindow.warpPointer(glWindow.getWidth()/2, glWindow.getHeight()/2);
+ System.err.println("[set mouse pos post]");
+ } }.start();
}
}
} \ No newline at end of file