From 0f97d9292cc7ff97f61f68b69c5a375cc023a5af Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 8 Jul 2019 05:10:02 +0200
Subject: NEWT iOS: Support Multi-Touch Events, PixelScale, ..

Note: Two subsequent commit will add some required change in the
native UIWindow/UIView creation methods to actually make the NEWT view being displayed ;-)

The demo 'com.jogamp.opengl.demos.ios.Hello' demonstrated a standard NEWT application
running on iOS.
Previous NativeWindow wrap-around demo is preserved in 'com.jogamp.opengl.demos.ios.Hello1'.

Tested on ipad 11'inch arm64 and x86_64 simulation:
- Using GearsES2 demo
- PixelScale 1f, 2f and 0f - last two using max pixel scale
- Touch w/ GearsES2 works:
-- 1 finger rotate
-- 2 finger drag
-- 2 finger pinch-zoom gesture detection
---
 src/demos/com/jogamp/opengl/demos/ios/Hello.java   | 137 +++--
 src/demos/com/jogamp/opengl/demos/ios/Hello1.java  | 234 +++++++
 .../jogamp/nativewindow/NativeWindowFactory.java   |   2 +-
 src/nativewindow/native/ios/IOSmisc.m              |   1 +
 .../jogamp/newt/driver/ios/WindowDriver.java       |  18 +-
 src/newt/native/IOSNewtUIWindow.h                  |  88 ++-
 src/newt/native/IOSNewtUIWindow.m                  | 684 +++++++++++++--------
 src/newt/native/IOSWindow.m                        | 380 ++++--------
 src/newt/native/MacWindow.m                        |   5 -
 src/newt/native/MouseEvent.h                       |   6 +
 src/newt/native/NewtCommon.c                       |   5 +
 src/newt/native/NewtCommon.h                       |   2 +
 .../demos/es2/newt/TestGearsES2SimpleNEWT.java     |   2 +-
 13 files changed, 977 insertions(+), 587 deletions(-)
 create mode 100644 src/demos/com/jogamp/opengl/demos/ios/Hello1.java

(limited to 'src')

diff --git a/src/demos/com/jogamp/opengl/demos/ios/Hello.java b/src/demos/com/jogamp/opengl/demos/ios/Hello.java
index 9982d7d1f..378868bea 100644
--- a/src/demos/com/jogamp/opengl/demos/ios/Hello.java
+++ b/src/demos/com/jogamp/opengl/demos/ios/Hello.java
@@ -29,26 +29,20 @@ package com.jogamp.opengl.demos.ios;
 
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.common.util.VersionUtil;
-import com.jogamp.nativewindow.AbstractGraphicsScreen;
-import com.jogamp.nativewindow.MutableGraphicsConfiguration;
-import com.jogamp.nativewindow.NativeWindowFactory;
-import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
-
+import com.jogamp.nativewindow.ScalableSurface;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.common.GlueGenVersion;
 import com.jogamp.opengl.JoglVersion;
 import com.jogamp.opengl.demos.es2.RedSquareES2;
 import com.jogamp.opengl.util.Animator;
-import com.jogamp.opengl.util.AnimatorBase;
 
-import jogamp.nativewindow.WrappedWindow;
 import jogamp.nativewindow.ios.IOSUtil;
-import jogamp.opengl.GLDrawableFactoryImpl;
 
-import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.GLAutoDrawable;
 import com.jogamp.opengl.GLCapabilities;
-import com.jogamp.opengl.GLCapabilitiesImmutable;
-import com.jogamp.opengl.GLDrawable;
-import com.jogamp.opengl.GLDrawableFactory;
 import com.jogamp.opengl.GLEventListener;
 import com.jogamp.opengl.GLProfile;
 
@@ -60,8 +54,17 @@ public class Hello {
         } catch (final NumberFormatException nfe) {}
         return def;
     }
+    private static float parseFloat(final String s, final float def) {
+        try {
+            return Float.parseFloat(s);
+        } catch (final NumberFormatException nfe) {}
+        return def;
+    }
 
     public static void main(final String[] args) {
+        final float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
+
+        int secondsDuration = 10; // 10s
         int width = 832, height = 480; // ipad pro 11: 2388x1668 px (scale: 2)
         int fboDepthBits = -1; // CAEAGLLayer fails with depth 16 + 24 in Simulation; -1 means don't change
         boolean exitJVM = false;
@@ -77,6 +80,11 @@ public class Hello {
                 height = parseInt(args[++i], height);
             } else if(args[i].equals("-fboDepthBits") && i+1<args.length) {
                 fboDepthBits = parseInt(args[++i], fboDepthBits);
+            } else if(args[i].equals("-pixelScale") && i+1<args.length) {
+                reqSurfacePixelScale[0] = parseFloat(args[++i], reqSurfacePixelScale[0]);
+                reqSurfacePixelScale[1] = reqSurfacePixelScale[0];
+            } else if(args[i].equals("-seconds") && i+1<args.length) {
+                secondsDuration = parseInt(args[++i], secondsDuration);
             } else {
                 System.err.println("ignoring arg["+i+"]: "+args[i]);
             }
@@ -115,8 +123,7 @@ public class Hello {
         System.err.println("mark-04");
         System.err.println("");
 
-        GLAutoDrawableDelegate glad = null;
-        final long uiWindow = IOSUtil.CreateUIWindow(0, 0, width, height);
+        GLWindow glWindow = null;
         try {
             // 1) Config ..
             final GLProfile glp = GLProfile.getGL2ES2();
@@ -125,39 +132,44 @@ public class Hello {
                 reqCaps.setDepthBits(fboDepthBits);
             }
             System.out.println("Requested GL Caps: "+reqCaps);
-            final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(glp);
-
-            // 2) Create native window and wrap it around out NativeWindow structure
-            final long uiView = IOSUtil.GetUIView(uiWindow, true);
-            final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView);
-            System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow));
-            System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView));
-            System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer));
-            System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+
-                               ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer));
-            final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(NativeWindowFactory.createDevice(null, true /* own */), -1);
-            final UpstreamWindowHookMutableSizePos hook = new UpstreamWindowHookMutableSizePos(0, 0, width, height, width, height);
-            final MutableGraphicsConfiguration config = new MutableGraphicsConfiguration(aScreen, reqCaps, reqCaps);
-            final WrappedWindow nativeWindow = new WrappedWindow(config, uiView, hook, true, uiWindow);
-
-            // 3) Create a GLDrawable ..
-            final GLDrawable drawable = factory.createGLDrawable(nativeWindow);
-            drawable.setRealized(true);
-            // final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(aScreen.getDevice(), reqCaps, null, width, height);
-            glad = new GLAutoDrawableDelegate(drawable, null, nativeWindow, false, null) {
-                    @Override
-                    protected void destroyImplInLock() {
-                        super.destroyImplInLock();  // destroys drawable/context
-                        nativeWindow.destroy(); // destroys the actual window, incl. the device
-                        IOSUtil.DestroyUIWindow(uiWindow);
+
+            // 2) Create newt native window
+            final Display dpy = NewtFactory.createDisplay(null);
+            final Screen screen = NewtFactory.createScreen(dpy, 0);
+            glWindow = GLWindow.create(screen, reqCaps);
+            glWindow.setSurfaceScale(reqSurfacePixelScale);
+            final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]);
+            glWindow.setSize(width, height);
+            glWindow.setPosition(0, 0);
+            final GLEventListener tracker = new GLEventListener() {
+                void printInfo(final String prefix, final GLAutoDrawable d, final String postfix) {
+                    System.out.print(prefix+": drawable "+d.getSurfaceWidth()+"x"+d.getSurfaceHeight());
+                    if(null != postfix) {
+                        System.out.println(" - "+postfix);
+                    } else {
+                        System.out.println();
                     }
-                };
-            glad.display(); // force native context creation
+                }
+                @Override
+                public void init(final GLAutoDrawable drawable) {
+                    printInfo("GLEvent::Init", drawable, null);
+                }
 
-            // Check caps of GLDrawable after realization
-            final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
-            System.out.println("Choosen   GL Caps: "+chosenCaps);
+                @Override
+                public void dispose(final GLAutoDrawable drawable) {
+                    printInfo("GLEvent::Dispose", drawable, null);
+                }
+
+                @Override
+                public void display(final GLAutoDrawable drawable) {
+                }
 
+                @Override
+                public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+                    printInfo("GLEvent::Reshape", drawable, "reshape["+x+"/"+y+" "+width+"x"+height+"]");
+                }
+            };
+            glWindow.addGLEventListener(tracker);
             GLEventListener demo = null;
             {
                 try {
@@ -170,15 +182,36 @@ public class Hello {
                 }
             }
             System.out.println("Choosen demo "+demo.getClass().getName());
-            glad.addGLEventListener(demo);
+            glWindow.addGLEventListener(demo);
+            glWindow.setVisible(true); // force native context creation
+
+            // Check caps of GLDrawable after realization
+            System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
+            System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
+            System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+"[wu] "+glWindow.getWidth()+"x"+glWindow.getHeight()+"[wu] "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+"[px], "+glWindow.getInsets());
+
+            final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]);
+            System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
+                               valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
+                               hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
+            {
+                final long uiWindow = glWindow.getWindowHandle();
+                final long uiView = IOSUtil.GetUIView(uiWindow, true);
+                final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView);
+                System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow));
+                System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView));
+                System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer));
+                System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+
+                                   ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer));
+            }
 
             final Animator animator = new Animator();
             // animator.setExclusiveContext(exclusiveContext);
             animator.setUpdateFPSFrames(60, System.err);
-            animator.add(glad);
+            animator.add(glWindow);
             animator.start();
 
-            for(int i=0; i<10; i++) { // 10s
+            for(int i=0; i<secondsDuration; i++) {
                 try {
                     Thread.sleep(1000);
                 } catch (final InterruptedException e) {
@@ -188,13 +221,17 @@ public class Hello {
             animator.stop();
 
         } finally {
-            if( null != glad ) {
-                glad.destroy();
+            System.err.println("");
+            System.err.println("mark-05");
+            System.err.println("");
+
+            if( null != glWindow ) {
+                glWindow.destroy();
             }
         }
 
         System.err.println("");
-        System.err.println("mark-05");
+        System.err.println("mark-06");
         System.err.println("");
 
         if( exitJVM ) {
diff --git a/src/demos/com/jogamp/opengl/demos/ios/Hello1.java b/src/demos/com/jogamp/opengl/demos/ios/Hello1.java
new file mode 100644
index 000000000..e0c3be871
--- /dev/null
+++ b/src/demos/com/jogamp/opengl/demos/ios/Hello1.java
@@ -0,0 +1,234 @@
+/**
+ * Copyright 2019 Gothel Software e.K. 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 Gothel Software e.K. ``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 Gothel Software e.K. 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 Gothel Software e.K.
+ */
+package com.jogamp.opengl.demos.ios;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
+
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.AnimatorBase;
+
+import jogamp.nativewindow.WrappedWindow;
+import jogamp.nativewindow.ios.IOSUtil;
+import jogamp.opengl.GLDrawableFactoryImpl;
+
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLDrawable;
+import com.jogamp.opengl.GLDrawableFactory;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLProfile;
+
+public class Hello1 {
+
+    private static int parseInt(final String s, final int def) {
+        try {
+            return Integer.parseInt(s);
+        } catch (final NumberFormatException nfe) {}
+        return def;
+    }
+
+    public static void main(final String[] args) {
+        int width = 832, height = 480; // ipad pro 11: 2388x1668 px (scale: 2)
+        int fboDepthBits = -1; // CAEAGLLayer fails with depth 16 + 24 in Simulation; -1 means don't change
+        boolean exitJVM = false;
+        String demoName = "com.jogamp.opengl.demos.es2.GearsES2";
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-exit")) {
+                exitJVM = true;
+            } else if(args[i].equals("-demo") && i+1<args.length) {
+                demoName = args[++i];
+            } else if(args[i].equals("-width") && i+1<args.length) {
+                width = parseInt(args[++i], width);
+            } else if(args[i].equals("-height") && i+1<args.length) {
+                height = parseInt(args[++i], height);
+            } else if(args[i].equals("-fboDepthBits") && i+1<args.length) {
+                fboDepthBits = parseInt(args[++i], fboDepthBits);
+            } else {
+                System.err.println("ignoring arg["+i+"]: "+args[i]);
+            }
+        }
+        System.out.println("Hello JogAmp World: exitJVM "+exitJVM+", size "+width+"x"+height+", fboDepthBits "+fboDepthBits+", demo "+demoName);
+        System.out.println("os.name: <"+System.getProperty("os.name")+">");
+        System.out.println("os.version: <"+System.getProperty("os.version")+">");
+        System.out.println("os.arch: <"+System.getProperty("os.arch")+">");
+        System.out.println("java.vendor: <"+System.getProperty("java.vendor")+">");
+        System.out.println("java.vendor.url: <"+System.getProperty("java.vendor.url")+">");
+        System.out.println("java.version: <"+System.getProperty("java.version")+">");
+        System.out.println("java.vm.name: <"+System.getProperty("java.vm.name")+">");
+        System.out.println("java.runtime.name: <"+System.getProperty("java.runtime.name")+">");
+        System.out.println("");
+        System.out.println(VersionUtil.getPlatformInfo());
+        System.out.println("");
+        System.out.println("Version Info:");
+        System.out.println(GlueGenVersion.getInstance());
+        System.out.println("");
+        System.out.println("Full Manifest:");
+        System.out.println(GlueGenVersion.getInstance().getFullManifestInfo(null));
+
+        System.out.println("");
+        System.err.println("mark-01");
+        System.err.println("");
+        System.err.println(JoglVersion.getInstance());
+        System.err.println("");
+        System.err.println("mark-02");
+        System.err.println("");
+        GLProfile.initSingleton();
+        System.err.println("");
+        System.err.println("mark-03");
+        System.out.println("");
+        System.out.println(JoglVersion.getDefaultOpenGLInfo(GLProfile.getDefaultDevice(), null, true));
+        System.out.println("");
+        System.err.println("mark-04");
+        System.err.println("");
+
+        GLAutoDrawableDelegate glad = null;
+        final long uiWindow = IOSUtil.CreateUIWindow(0, 0, width, height);
+        try {
+            // 1) Config ..
+            final GLProfile glp = GLProfile.getGL2ES2();
+            final GLCapabilities reqCaps = new GLCapabilities(glp);
+            if( 0 <= fboDepthBits) {
+                reqCaps.setDepthBits(fboDepthBits);
+            }
+            System.out.println("Requested GL Caps: "+reqCaps);
+            final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(glp);
+
+            // 2) Create native window and wrap it around out NativeWindow structure
+            final long uiView = IOSUtil.GetUIView(uiWindow, true);
+            final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView);
+            System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow));
+            System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView));
+            System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer));
+            System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+
+                               ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer));
+            final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(NativeWindowFactory.createDevice(null, true /* own */), -1);
+            final UpstreamWindowHookMutableSizePos hook = new UpstreamWindowHookMutableSizePos(0, 0, width, height, width, height);
+            final MutableGraphicsConfiguration config = new MutableGraphicsConfiguration(aScreen, reqCaps, reqCaps);
+            final WrappedWindow nativeWindow = new WrappedWindow(config, uiView, hook, true, uiWindow);
+
+            // 3) Create a GLDrawable ..
+            final GLDrawable drawable = factory.createGLDrawable(nativeWindow);
+            drawable.setRealized(true);
+            // final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(aScreen.getDevice(), reqCaps, null, width, height);
+            glad = new GLAutoDrawableDelegate(drawable, null, nativeWindow, false, null) {
+                    @Override
+                    protected void destroyImplInLock() {
+                        super.destroyImplInLock();  // destroys drawable/context
+                        nativeWindow.destroy(); // destroys the actual window, incl. the device
+                        IOSUtil.DestroyUIWindow(uiWindow);
+                    }
+                };
+            final GLEventListener tracker = new GLEventListener() {
+                void printInfo(final String prefix, final GLAutoDrawable d, final String postfix) {
+                    System.out.print(prefix+": drawable "+d.getSurfaceWidth()+"x"+d.getSurfaceHeight());
+                    if(null != postfix) {
+                        System.out.println(" - "+postfix);
+                    } else {
+                        System.out.println();
+                    }
+                }
+                @Override
+                public void init(final GLAutoDrawable drawable) {
+                    printInfo("GLEvent::Init", drawable, null);
+                }
+
+                @Override
+                public void dispose(final GLAutoDrawable drawable) {
+                    printInfo("GLEvent::Dispose", drawable, null);
+                }
+
+                @Override
+                public void display(final GLAutoDrawable drawable) {
+                }
+
+                @Override
+                public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+                    printInfo("GLEvent::Reshape", drawable, "reshape["+x+"/"+y+" "+width+"x"+height+"]");
+                }
+            };
+            glad.addGLEventListener(tracker);
+            glad.display(); // force native context creation
+
+            // Check caps of GLDrawable after realization
+            final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+            System.out.println("Choosen   GL Caps: "+chosenCaps);
+
+            GLEventListener demo = null;
+            {
+                try {
+                    demo = (GLEventListener) ReflectionUtil.createInstance(demoName, Hello1.class.getClassLoader());
+                } catch( final Exception e ) {
+                    System.err.println(e.getMessage()+" using: <"+demoName+">");
+                }
+                if( null == demo ) {
+                    demo = new RedSquareES2();
+                }
+            }
+            System.out.println("Choosen demo "+demo.getClass().getName());
+            glad.addGLEventListener(demo);
+
+            final Animator animator = new Animator();
+            // animator.setExclusiveContext(exclusiveContext);
+            animator.setUpdateFPSFrames(60, System.err);
+            animator.add(glad);
+            animator.start();
+
+            for(int i=0; i<10; i++) { // 10s
+                try {
+                    Thread.sleep(1000);
+                } catch (final InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+            animator.stop();
+
+        } finally {
+            if( null != glad ) {
+                glad.destroy();
+            }
+        }
+
+        System.err.println("");
+        System.err.println("mark-05");
+        System.err.println("");
+
+        if( exitJVM ) {
+            System.exit(0);
+        }
+    }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
index 8e00d318c..63063bef7 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
@@ -103,7 +103,7 @@ public abstract class NativeWindowFactory {
     public static final String TYPE_MACOSX = ".macosx";
 
     /** iOS type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
-    public static final String TYPE_IOS = ".iOS";
+    public static final String TYPE_IOS = ".ios";
 
     /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
     public static final String TYPE_AWT = ".awt";
diff --git a/src/nativewindow/native/ios/IOSmisc.m b/src/nativewindow/native/ios/IOSmisc.m
index 70cff4c06..1983143df 100644
--- a/src/nativewindow/native/ios/IOSmisc.m
+++ b/src/nativewindow/native/ios/IOSmisc.m
@@ -367,6 +367,7 @@ NS_DURING
     if(NULL != subviews) {
         for(int i=0; i<[subviews count]; i++) {
             UIView* sub = [subviews objectAtIndex: i];
+            [sub removeFromSuperview];
             [sub setHidden: YES];
             [sub release];
         }
diff --git a/src/newt/classes/jogamp/newt/driver/ios/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/ios/WindowDriver.java
index 79c35c310..5469f74b1 100644
--- a/src/newt/classes/jogamp/newt/driver/ios/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/ios/WindowDriver.java
@@ -617,6 +617,21 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
                            SurfaceScaleUtils.scale(y, getPixelScaleY()), button, rotationXYZ, rotationScale);
     }
 
+    public final void sendTouchScreenEvent(final short eventType, final int modifiers,
+                                           final int[] pActionIdx, final short[] pNames,
+                                           final int[] pTypesI, final int[] pX, final int[] pY, final float[] pPressure, final float maxPressure) {
+        final int pCount = pNames.length;
+        final MouseEvent.PointerType[] pTypes = new MouseEvent.PointerType[pCount];
+        for(int i=0; i<pCount; i++) {
+           pTypes[i] = MouseEvent.PointerType.valueOf(pTypesI[i]);
+        }
+        for(int i=0; i<pActionIdx.length; i++) {
+            doPointerEvent(false /*enqueue*/, false /*wait*/,
+                           pTypes, eventType, modifiers, pActionIdx[i], true /*normalPNames*/, pNames,
+                           pX, pY, pPressure, maxPressure, new float[] { 0f, 0f, 0f} /*rotationXYZ*/, 1f/*rotationScale*/);
+        }
+    }
+
     @Override
     public final void sendKeyEvent(final short eventType, final int modifiers, final short keyCode, final short keySym, final char keyChar) {
         throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
@@ -765,7 +780,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
     }
 
     protected static native boolean initIDs0();
-    private native long createView0(int x, int y, int w, int h);
+    private native long createView0(int x, int y, int w, int h, float reqPixelScale);
     private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view);
     /** Must be called on Main-Thread */
     private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, float reqPixelScale,
@@ -787,7 +802,6 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
     private native void close0(long window);
     /** Must be called on Main-Thread */
     private native void setTitle0(long window, String title);
-    private native long contentView0(long window);
     /** Must be called on Main-Thread */
     private native void changeContentView0(long parentWindowOrView, long window, long view);
     /** Must be called on Main-Thread */
diff --git a/src/newt/native/IOSNewtUIWindow.h b/src/newt/native/IOSNewtUIWindow.h
index 27ca7f3c7..a335ac4ee 100644
--- a/src/newt/native/IOSNewtUIWindow.h
+++ b/src/newt/native/IOSNewtUIWindow.h
@@ -31,6 +31,7 @@
 #import <pthread.h>
 #import "jni.h"
 
+#include "CAEAGLLayered.h"
 #include "NewtCommon.h"
 
 // #define VERBOSE_ON 1
@@ -44,7 +45,30 @@
 
 // #define DBG_LIFECYCLE 1
 
-@interface NewtUIView : UIView
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NamedUITouch : NSObject
+{
+    @public
+    short name;
+    UITouch *touch;
+
+    @protected
+}
+
+- (id)initWithName:(UITouch*)t name:(short)n;
+
+- (void) dealloc;
+
+/** Ensure NSPointerFunctionsObjectPointerPersonality for NSArray */
+- (BOOL)isEqual:(id)object;
+
+/** Ensure NSPointerFunctionsObjectPointerPersonality for NSArray */
+- (NSUInteger)hash;
+
+@end
+
+@interface NewtUIView : CAEAGLUIView
 {
     jobject javaWindowObject;
 
@@ -52,6 +76,9 @@
     volatile int softLockCount;
     pthread_mutex_t softLockSync;
 
+    NSMapTable<UITouch*, NamedUITouch*>* activeTouchMap;
+    NSMutableArray<NamedUITouch*>* activeTouches;
+    short nextTouchName;
     BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
 }
 
@@ -64,7 +91,7 @@
 
 /* Register or deregister (NULL) the java Window object, 
    ie, if NULL, no events are send */
-- (void) setJavaWindowObject: (jobject) javaWindowObj;
+- (void) setJavaWindowObject: (nullable jobject) javaWindowObj;
 - (jobject) getJavaWindowObject;
 
 - (void) setDestroyNotifySent: (BOOL) v;
@@ -74,33 +101,34 @@
 - (BOOL) softUnlock;
 
 - (void) drawRect:(CGRect)dirtyRect;
-- (BOOL) acceptsFirstResponder;
 - (BOOL) becomeFirstResponder;
 - (BOOL) resignFirstResponder;
 
-- (void) sendMouseEvent: (UIEvent*) event eventType: (jshort) evType;
-- (CGPoint) screenPos2NewtClientWinPos: (CGPoint) p;
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
+- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
+- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
+- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
+- (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches;
+- (void)sendTouchEvent: (NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 
+                        eventState:(int)eventState newtEventType:(short)newtEventType;
 
-- (void) handleFlagsChanged:(NSUInteger) mods;
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
-- (void) sendKeyEvent: (UIEvent*) event eventType: (jshort) evType;
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
+- (CGPoint) screenPos2NewtClientWinPos: (CGPoint) p;
 
 @end
 
 @interface NewtUIWindow : UIWindow
 {
+@protected
     BOOL realized;
-    jboolean withinLiveResize;
+    BOOL useAutoMaxPixelScale;
+    BOOL withinLiveResize;
+    NewtUIView* contentNewtUIView;
 @public
-    BOOL hasPresentationSwitch;
-    NSUInteger defaultPresentationOptions;
-    NSUInteger fullscreenPresentationOptions;
     BOOL isFullscreenWindow;
     int cachedInsets[4]; // l, r, t, b
 }
 
-+ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz;
++ (BOOL) initNatives: (_Nonnull JNIEnv* _Nonnull) env forClass: (jobject) clazz;
 
 - (id) initWithFrame: (CGRect) contentRect
        styleMask: (NSUInteger) windowStyle
@@ -111,13 +139,18 @@
 - (void) release;
 #endif
 - (void) dealloc;
+- (void) setContentNewtUIView: (nullable NewtUIView*)v;
+- (NewtUIView*) getContentNewtUIView;
 - (void) setRealized: (BOOL)v;
 - (BOOL) isRealized;
 
 - (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom;
 
-- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin;
-- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer;
+- (void) setPixelScale: (CGFloat)reqPixelScale defer:(BOOL)defer;
+- (void) updatePixelScale: (BOOL) defer;
+
+- (void) updateInsets: (_Nullable JNIEnv* _Nullable) env jwin: (nullable jobject) javaWin;
+- (void) updateSizePosInsets: (_Nullable JNIEnv* _Nullable) env jwin: (nullable jobject) javaWin defer: (jboolean)defer;
 - (void) attachToParent: (UIWindow*) parent;
 - (void) detachFromParent: (UIWindow*) parent;
 
@@ -126,27 +159,24 @@
 - (CGPoint) getLocationOnScreen: (CGPoint) p;
 
 - (void) focusChanged: (BOOL) gained;
+- (void) visibilityChanged: (BOOL) visible;
 
-- (void) flagsChanged: (UIEvent *) theEvent;
-- (BOOL) acceptsMouseMovedEvents;
-- (BOOL) acceptsFirstResponder;
+- (BOOL) canBecomeFirstResponder;
 - (BOOL) becomeFirstResponder;
+- (BOOL) canResignFirstResponder;
 - (BOOL) resignFirstResponder;
-- (BOOL) canBecomeKeyWindow;
+
 - (void) becomeKeyWindow;
 - (void) resignKeyWindow;
-- (void) windowDidBecomeKey: (NSNotification *) notification;
-- (void) windowDidResignKey: (NSNotification *) notification;
 
-- (void) windowWillStartLiveResize: (NSNotification *) notification;
-- (void) windowDidEndLiveResize: (NSNotification *) notification;
-- (CGSize) windowWillResize: (UIWindow *)sender toSize:(CGSize)frameSize;
-- (void) windowDidResize: (NSNotification*) notification;
-- (void) sendResizeEvent;
+- (void) becameVisible: (NSNotification*)notice;
+- (void) becameHidden: (NSNotification*)notice;
 
+- (void) sendResizeEvent;
 - (void) windowDidMove: (NSNotification*) notification;
 - (BOOL) windowClosingImpl: (BOOL) force;
-- (BOOL) windowShouldClose: (id) sender;
-- (void) windowWillClose: (NSNotification*) notification;
 
 @end
+
+NS_ASSUME_NONNULL_END
+
diff --git a/src/newt/native/IOSNewtUIWindow.m b/src/newt/native/IOSNewtUIWindow.m
index 6c5031efc..c20dad1a8 100644
--- a/src/newt/native/IOSNewtUIWindow.m
+++ b/src/newt/native/IOSNewtUIWindow.m
@@ -37,8 +37,9 @@
 
 #define PRINTF(...) NSLog(@ __VA_ARGS__)
 
-static jmethodID enqueueMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
+#define IOS_TOUCH_COUNT 10
+
+static jmethodID sendTouchScreenEventID = NULL;
 static jmethodID requestFocusID = NULL;
 
 static jmethodID insetsChangedID   = NULL;
@@ -57,11 +58,58 @@ static jmethodID windowRepaintID = NULL;
 //     AWT-AppKit
 //     AWT-EventQueue-0
 
+@implementation NamedUITouch
+
+- (id)initWithName:(UITouch*)t name:(short)n
+{
+    self->name = n;
+    self->touch = [t retain];
+    return self;
+}
+- (void) dealloc
+{
+    [touch release]; 
+    [super dealloc];
+}
+
+- (BOOL)isEqual:(id)object
+{
+    // Ensure NSPointerFunctionsObjectPointerPersonality for NSArray
+    return self == object;
+}
+- (NSUInteger)hash
+{
+    // Ensure NSPointerFunctionsObjectPointerPersonality for NSArray
+    //
+    // When building 32-bit applications, NSUInteger is a 32-bit unsigned integer. 
+    // A 64-bit application treats NSUInteger as a 64-bit unsigned integer
+    // https://developer.apple.com/documentation/objectivec/nsuinteger?language=objc
+    return (NSUInteger)self;
+}
+
+@end
+
 @implementation NewtUIView
 
 - (id)initWithFrame:(CGRect)frameRect
 {
     id res = [super initWithFrame:frameRect];
+    CAEAGLLayer* l = (CAEAGLLayer*)[self layer];
+    [l setOpaque: YES];
+    l.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: /* defaults */
+                           [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
+    [self setMultipleTouchEnabled: YES]; // NEWT supports multitouch ..
+    [self setExclusiveTouch: YES]; // NEWT touches shall keep with NEWT
+    [self setUserInteractionEnabled: YES]; // Default ..
+
+    // NSMapTable<UITouch*, NamedUITouch*>* activeTouchMap;
+    // NSHashTable<NamedUITouch*>* activeTouches;
+    activeTouchMap = [[NSMapTable alloc] initWithKeyOptions:NSMapTableStrongMemory|NSMapTableObjectPointerPersonality
+                                         valueOptions:NSMapTableStrongMemory|NSMapTableObjectPointerPersonality
+                                         capacity:IOS_TOUCH_COUNT];
+    activeTouches = [[NSMutableArray alloc] initWithCapacity:IOS_TOUCH_COUNT];
+    nextTouchName = 0;
+
     javaWindowObject = NULL;
 
     destroyNotifySent = NO;
@@ -77,10 +125,10 @@ static jmethodID windowRepaintID = NULL;
     modsDown[2] = NO; // alt
     modsDown[3] = NO; // win
 
-    DBG_PRINT("NewtUIView::create: %p (refcnt %d)\n", res, (int)[res retainCount]);
+    DBG_PRINT("NewtUIView::create: %p/%p, CAEAGLLayer %p (pixelScale %f, isCAEAGLLayer %d) (res refcnt %d)\n", 
+        res, self, l, [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]], (int)[res retainCount]);
     return res;
 }
-
 #ifdef DBG_LIFECYCLE
 - (void) release
 {
@@ -91,13 +139,17 @@ static jmethodID windowRepaintID = NULL;
 
 - (void) dealloc
 {
-    DBG_PRINT("NewtUIView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag);
+    DBG_PRINT("NewtUIView::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
 #ifdef DBG_LIFECYCLE
     NSLog(@"%@",[NSThread callStackSymbols]);
 #endif
     if( 0 < softLockCount ) {
         NSLog(@"NewtUIView::dealloc: softLock still hold @ dealloc!\n");
     }
+    [activeTouchMap removeAllObjects];
+    [activeTouchMap release];
+    [activeTouches removeAllObjects];
+    [activeTouches release];
 
     pthread_mutex_destroy(&softLockSync);
     DBG_PRINT("NewtUIView::dealloc.X: %p\n", self);
@@ -126,21 +178,20 @@ static jmethodID windowRepaintID = NULL;
 
 - (BOOL) softLock
 {
-    // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self());
     int err;
     if( 0 != ( err = pthread_mutex_lock(&softLockSync) ) ) {
         NSLog(@"NewtUIView::softLock failed: errCode %d - %@", err, [NSThread callStackSymbols]);
         return NO;
     }
     softLockCount++;
-    // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self());
+    // DBG_PRINT("*************** softLock: %p count %d\n", (void*)pthread_self(), softLockCount);
     return 0 < softLockCount;
 }
 
 - (BOOL) softUnlock
 {
-    // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self());
     softLockCount--;
+    // DBG_PRINT("*************** softUnlock: %p count %d\n", (void*)pthread_self(), softLockCount);
     int err;
     if( 0 != ( err = pthread_mutex_unlock(&softLockSync) ) ) {
         softLockCount++;
@@ -152,7 +203,7 @@ static jmethodID windowRepaintID = NULL;
 
 - (void) drawRect:(CGRect)dirtyRect
 {
-    DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n", 
+    DBG_PRINT("*************** drawRect: dirtyRect: %p %lf/%lf %lfx%lf\n", 
         javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height);
 
     if(NULL==javaWindowObject) {
@@ -176,11 +227,6 @@ static jmethodID windowRepaintID = NULL;
     // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (BOOL) acceptsFirstResponder 
-{
-    return YES;
-}
-
 - (BOOL) becomeFirstResponder
 {
     DBG_PRINT( "*************** View.becomeFirstResponder\n");
@@ -193,153 +239,210 @@ static jmethodID windowRepaintID = NULL;
     return [super resignFirstResponder];
 }
 
-- (void) sendMouseEvent: (UIEvent*) event eventType: (jshort) evType
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
 {
-    if (javaWindowObject == NULL) {
-        DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
-        return;
-    }
-    int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
-    if(NULL==env) {
-        DBG_PRINT("sendMouseEvent: null JNIEnv\n");
-        return;
-    }
-    jint javaMods[] = { 0 } ;
-    javaMods[0] = 0; // TODO 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 = 1;
-    jfloat scrollDeltaY = 0.0f;
-    /**
-    switch ([event type]) {
-        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;
-        default:
-            javaButtonNum = 0;
-            break;
-    } */
-    CGPoint location = CGPointMake(0,0); // TODO [self screenPos2NewtClientWinPos: [UIEvent mouseLocation]];
-
-    (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
-                           evType, javaMods[0],
-                           (jint) location.x, (jint) location.y,
-                           javaButtonNum, scrollDeltaY);
-
-    // detaching thread not required - daemon
-    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
+    [self sendTouchEvent: touches withEvent:event eventState:1 newtEventType:(short)EVENT_MOUSE_PRESSED];
 }
-
-- (CGPoint) screenPos2NewtClientWinPos: (CGPoint) p
+- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
 {
-    CGRect viewFrame = [self frame];
-
-    CGRect r;
-    r.origin.x = p.x;
-    r.origin.y = p.y;
-    r.size.width = 0;
-    r.size.height = 0;
-    // CGRect rS = [[self window] convertRectFromScreen: r]; // 10.7
-    CGPoint oS = r.origin; // TODO [[self window] convertScreenToBase: r.origin];
-    oS.y = viewFrame.size.height - oS.y; // y-flip
-    return oS;
+    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+    [self sendTouchEvent: touches withEvent:event eventState:0 newtEventType:(short)EVENT_MOUSE_MOVED];
 }
-
-- (void) handleFlagsChanged:(NSUInteger) mods
+- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
 {
-    // TODO [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
-    // TODO [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
-    // TODO [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
-    // TODO [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
+    [self sendTouchEvent: touches withEvent:event eventState:-1 newtEventType:(short)EVENT_MOUSE_RELEASED];
 }
-
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
+- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
 {
-    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];
-    }
+    [self sendTouchEvent: touches withEvent:event eventState:-1 newtEventType:(short)EVENT_MOUSE_RELEASED];
 }
-
-- (void) sendKeyEvent: (UIEvent*) event eventType: (jshort) evType
+- (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches
 {
-    jshort keyCode = 0; // TODO (jshort) [event keyCode];
-    NSString* chars = NULL; // TODO [event charactersIgnoringModifiers];
-    NSUInteger mods = 0; // TODO [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)sendTouchEvent: (NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 
+                        eventState:(int)eventState newtEventType:(short)newtEventType
 {
     if (javaWindowObject == NULL) {
-        DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
+        DBG_PRINT("sendTouchEvent: null javaWindowObject\n");
         return;
     }
     int shallBeDetached = 0;
     JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
-        DBG_PRINT("sendKeyEvent: null JNIEnv\n");
+        DBG_PRINT("sendTouchEvent: null JNIEnv\n");
         return;
     }
+    jint newtEventModifiers = 0; // FIXME?
+    jint touchTypes[IOS_TOUCH_COUNT];
+    jshort pointerNames[IOS_TOUCH_COUNT];
+    jint x[IOS_TOUCH_COUNT];
+    jint y[IOS_TOUCH_COUNT];
+    jfloat pressure[IOS_TOUCH_COUNT];
+    jint actionIdx[IOS_TOUCH_COUNT];
+    int activeTouchesNewIdx = -1;
+
+    DBG_PRINT( "sendTouchEvent.0: Window %p, state %d, newtType %d, touches %d, activeTouches %d, nextTouchName %d\n", 
+        (void*)javaWindowObject, eventState, (int)newtEventType, (int)[touches count], (int)[activeTouches count], nextTouchName);
+
+    // merge new touches into activeTouchMap (unify) and 
+    // add to end of activeTouches array 
+    {
+        NSEnumerator<UITouch*>* touchesEnum = [touches objectEnumerator];
+        UITouch * t;
+        while( (t = [touchesEnum nextObject]) ) {
+            NamedUITouch *nt = (NamedUITouch*)[activeTouchMap objectForKey: t];
+            if( nil == nt ) {
+                if( 1 != eventState ) {
+                    // Ooops, not 'touchesBegan' but UITouch not mapped!
+                    NewtCommon_throwNewRuntimeException(env, "Internal Error: touch event (window %p) state %d, newtType %d not mapped", 
+                        (void*)javaWindowObject, eventState, (int)newtEventType);
+                }
+                if( IOS_TOUCH_COUNT > [activeTouches count] ) {
+                    nt = [[NamedUITouch alloc] initWithName:t name:nextTouchName++];
+                    [activeTouchMap setObject:nt forKey:t];
+                    [activeTouches addObject: nt];
+                    if( 0 > activeTouchesNewIdx ) {
+                        activeTouchesNewIdx = [activeTouches count] - 1;
+                    }
+                }
+            }
+        }
+    }
+#ifdef VERBOSE_ON
+    {
+        int activeTouchesNewCount = activeTouchesNewIdx < 0 ? 0 : [activeTouches count] - activeTouchesNewIdx;
+        DBG_PRINT( "sendTouchEvent.1: Window %p, state %d, newtType %d, touches %d, activeTouches %d, nextTouchName %d, newActiveTouches %d\n", 
+        (void*)javaWindowObject, eventState, (int)newtEventType, (int)[touches count], (int)[activeTouches count], nextTouchName, activeTouchesNewCount);
+    }
+#endif /* VERBOSE_ON */
+
+    int cnt, actionCnt;
+    for(cnt=0, actionCnt=0; cnt<[activeTouches count]; cnt++) {
+        NamedUITouch *nt = [activeTouches objectAtIndex: cnt];
+        switch( [nt->touch type] ) {
+            case UITouchTypeDirect:
+            case UITouchTypeIndirect: /* ??? */
+                touchTypes[cnt] = POINTER_TYPE_TOUCHSCREEN;
+                break;
+            case UITouchTypePencil:
+                touchTypes[cnt] = POINTER_TYPE_PEN;
+                break;
+            default:
+                touchTypes[cnt] = POINTER_TYPE_UNDEF;
+                break;
+        }
+        CGPoint loc = [nt->touch preciseLocationInView: self]; // [touch locationInView: self];
+        x[cnt] = (jint)(loc.x);
+        y[cnt] = (jint)(loc.y);
+        pressure[cnt] = (jfloat)(nt->touch.force);
+        pointerNames[cnt] = nt->name;
+        if( [touches member: nt->touch] ) {
+            actionIdx[actionCnt++] = cnt;
+            DBG_PRINT( "sendTouchEvent.2: Window %p, action-touchid[%d]: name %d, idx %d, ptr: %d/%d\n",
+                (void*)javaWindowObject, (actionCnt-1), nt->name, cnt, x[cnt], y[cnt]);
+        } else {
+            DBG_PRINT( "sendTouchEvent.2: Window %p, action-touchid[-1]: name %d, idx %d, ptr: %d/%d\n",
+                (void*)javaWindowObject, nt->name, cnt, x[cnt], y[cnt]);
+        }
+    }
+    if( 0 >= actionCnt || actionCnt != [touches count]) {
+        NewtCommon_throwNewRuntimeException(env, "Internal Error: touch event (window %p) %d actionIds not matching %d/%d touches", 
+            (void*)javaWindowObject, actionCnt, (int)[touches count], cnt);
+    }
+    if( -1 == eventState ) {
+        NSEnumerator<UITouch*>* touchesEnum = [touches objectEnumerator];
+        UITouch * t;
+        while( (t = [touchesEnum nextObject]) ) {
+            NamedUITouch *nt = (NamedUITouch*)[activeTouchMap objectForKey: t];
+            if( nil == nt ) {
+                // Ooops, 'touchesEnded' but UITouch not mapped!
+                NewtCommon_throwNewRuntimeException(env, "Internal Error: touch event (window %p) state %d, newtType %d not mapped", 
+                    (void*)javaWindowObject, eventState, (int)newtEventType);
+            }
+            [activeTouchMap removeObjectForKey: t];
+            [activeTouches removeObject: nt];
+        }
+        if( 0 == [activeTouches count] ) {
+            // all finger released ..
+            nextTouchName = 0;
+        }
+    }
+    DBG_PRINT( "sendTouchEvent.3: Window %p, state %d, newtType %d, touches %d, activeTouches %d, nextTouchName %d\n", 
+        (void*)javaWindowObject, eventState, (int)newtEventType, (int)[touches count], (int)[activeTouches count], nextTouchName);
 
-    int i;
-    int len = NULL != chars ? [chars length] : 0;
-    jint javaMods = 0; // TODO mods2JavaMods(mods);
+    jintArray jActionIdx = (*env)->NewIntArray(env, actionCnt);
+    if (jActionIdx == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (names) of size %d", actionCnt);
+    }
+    (*env)->SetIntArrayRegion(env, jActionIdx, 0, actionCnt, actionIdx);
 
-    if(len > 0) {
-        // printable chars
-        for (i = 0; i < len; i++) {
-            // Note: the key code in the UIEvent does not map to anything we can use
-            UniChar keyChar = (UniChar) [chars characterAtIndex: i];
-            UniChar keySymChar = 0; // TODO CKCH_CharForKeyCode(keyCode);
+    jshortArray jNames = (*env)->NewShortArray(env, cnt);
+    if (jNames == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate short array (names) of size %d", cnt);
+    }
+    (*env)->SetShortArrayRegion(env, jNames, 0, cnt, pointerNames);
 
-            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);
+    jintArray jTouchTypes = (*env)->NewIntArray(env, cnt);
+    if (jTouchTypes == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (TouchTypes) of size %d", cnt);
+    }
+    (*env)->SetIntArrayRegion(env, jTouchTypes, 0, cnt, touchTypes);
 
-            (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
-                                   evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
-        }
-    } else {
-        // non-printable chars
-        jchar keyChar = (jchar) 0;
+    jintArray jX = (*env)->NewIntArray(env, cnt);
+    if (jX == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (x) of size %d", cnt);
+    }
+    (*env)->SetIntArrayRegion(env, jX, 0, cnt, x);
 
-        DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
+    jintArray jY = (*env)->NewIntArray(env, cnt);
+    if (jY == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (y) of size %d", cnt);
+    }
+    (*env)->SetIntArrayRegion(env, jY, 0, cnt, y);
 
-        (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
-                               evType, javaMods, keyCode, keyChar, keyChar);
+    jfloatArray jPressure = (*env)->NewFloatArray(env, cnt);
+    if (jPressure == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate float array (pressure) of size %d", cnt);
     }
+    (*env)->SetFloatArrayRegion(env, jPressure, 0, cnt, pressure);
+
+    /** 
+     * Pressure (force) "1.0 represents the force of an average touch (predetermined by the system, not user-specific".
+     * So we pass 2.0f as the maxPressure value.
+     */
+    (*env)->CallVoidMethod(env, javaWindowObject, sendTouchScreenEventID,
+            (jshort)newtEventType, (jint)newtEventModifiers, 
+            jActionIdx, jNames, jTouchTypes, jX, jY, jPressure, (jfloat)2.0f); 
 
     // detaching thread not required - daemon
     // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
+- (CGPoint) screenPos2NewtClientWinPos: (CGPoint) p
+{
+    CGRect viewFrame = [self frame];
+
+    CGRect r;
+    r.origin.x = p.x;
+    r.origin.y = p.y;
+    r.size.width = 0;
+    r.size.height = 0;
+    // CGRect rS = [[self window] convertRectFromScreen: r]; // 10.7
+    CGPoint oS = r.origin; // TODO [[self window] convertScreenToBase: r.origin];
+    oS.y = viewFrame.size.height - oS.y; // y-flip
+    return oS;
+}
+
 @end
 
 @implementation NewtUIWindow
 
 + (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
 {
-    enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
-    enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
+    sendTouchScreenEventID = (*env)->GetMethodID(env, clazz, "sendTouchScreenEvent", "(SI[I[S[I[I[I[FF)V");
     sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
-    updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V");
+    updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFFFZ)V");
     visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
     insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
     sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
@@ -348,7 +451,7 @@ static jmethodID windowRepaintID = NULL;
     windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
     windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
     requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
-    if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && 
+    if (sendTouchScreenEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && 
         insetsChangedID && sizeScreenPosInsetsChangedID &&
         screenPositionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
     {
@@ -364,43 +467,9 @@ static jmethodID windowRepaintID = NULL;
        defer: (BOOL) deferCreation
        isFullscreenWindow:(BOOL)isfs
 {
-    /**
-    id res = [super initWithContentRect: contentRect
-                    styleMask: windowStyle
-                    backing: bufferingType
-                    defer: deferCreation];
-     */
     id res = [super initWithFrame: contentRect];
-    // OSX 10.6
-    /** TODO
-    if ( [NSApp respondsToSelector:@selector(currentSystemPresentationOptions)] &&
-         [NSApp respondsToSelector:@selector(setPresentationOptions:)] ) {
-        hasPresentationSwitch = YES;
-        defaultPresentationOptions = [NSApp currentSystemPresentationOptions];
-        fullscreenPresentationOptions = 
-                // NSApplicationPresentationDefault|
-                // NSApplicationPresentationAutoHideDock|
-                NSApplicationPresentationHideDock|
-                // NSApplicationPresentationAutoHideMenuBar|
-                NSApplicationPresentationHideMenuBar|
-                NSApplicationPresentationDisableAppleMenu|
-                // NSApplicationPresentationDisableProcessSwitching|
-                // NSApplicationPresentationDisableSessionTermination|
-                NSApplicationPresentationDisableHideApplication|
-                // NSApplicationPresentationDisableMenuBarTransparency|
-                // NSApplicationPresentationFullScreen| // OSX 10.7
-                0 ;
-    } else {
-    */
-        hasPresentationSwitch = NO;
-        defaultPresentationOptions = 0;
-        fullscreenPresentationOptions = 0; 
-    // }
-
+    self.rootViewController = [[[UIViewController alloc] initWithNibName:nil bundle:nil] autorelease];
     isFullscreenWindow = NO; // TODO isfs;
-    // Why is this necessary? Without it we don't get any of the
-    // delegate methods like resizing and window movement.
-    // TODO [self setDelegate: self];
 
     cachedInsets[0] = 0; // l
     cachedInsets[1] = 0; // r
@@ -409,8 +478,19 @@ static jmethodID windowRepaintID = NULL;
 
     realized = YES;
     withinLiveResize = JNI_FALSE;
-    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]);
+    contentNewtUIView = NULL;
+
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                          selector:@selector(becameVisible:)
+                                          name:UIWindowDidBecomeVisibleNotification
+                                          object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                          selector:@selector(becameHidden:)
+                                          name:UIWindowDidBecomeHiddenNotification
+                                          object:nil];
+
+    DBG_PRINT("NewtWindow::create: %p, realized %d, (refcnt %d)\n", 
+        res, realized, (int)[res retainCount]);
     return res;
 }
 
@@ -430,16 +510,36 @@ static jmethodID windowRepaintID = NULL;
     NSLog(@"%@",[NSThread callStackSymbols]);
 #endif
 
-    /**
-    NewtUIView* mView = (NewtUIView *)self; // TODO [self contentView];
-    if( NULL != mView ) {
-        [mView release];
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+    if( NULL != contentNewtUIView ) {
+        [contentNewtUIView removeFromSuperview];
+        [contentNewtUIView release];
+        contentNewtUIView=NULL;
     }
-    */
     [super dealloc];
     DBG_PRINT("NewtWindow::dealloc.X: %p\n", self);
 }
 
+- (void) setContentNewtUIView: (NewtUIView*)v
+{
+    DBG_PRINT( "NewtWindow::setContentNewtUIView.0: view %p -> %p\n", contentNewtUIView, v);
+    if( NULL != contentNewtUIView ) {
+        [contentNewtUIView removeFromSuperview];
+        [contentNewtUIView release];
+        contentNewtUIView=NULL;
+    }
+    contentNewtUIView = v;
+    if( NULL != contentNewtUIView ) {
+        [contentNewtUIView retain];
+        [self addSubview: contentNewtUIView];
+    }
+}
+- (NewtUIView*) getContentNewtUIView
+{
+    return contentNewtUIView;
+}
+
 - (void) setRealized: (BOOL)v
 {
     realized = v;
@@ -465,6 +565,110 @@ static jmethodID windowRepaintID = NULL;
     } */
 }
 
+- (void) updatePixelScale: (BOOL) defer
+{
+    NewtUIView* newtView = contentNewtUIView;
+    DBG_PRINT( "updatePixelScale view %p, autoMaxPixelScale %d, defer %d\n", 
+        newtView, useAutoMaxPixelScale, defer);
+    if( NULL == newtView ) {
+        return;
+    }
+    jobject javaWindowObject = [newtView getJavaWindowObject];
+    if ( NULL == javaWindowObject ) {
+        DBG_PRINT("updatePixelScale: null javaWindowObject\n");
+        return;
+    }
+    int shallBeDetached = 0;
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+    if(NULL==env) {
+        DBG_PRINT("updatePixelScale: null JNIEnv\n");
+        return;
+    }
+
+    CGFloat oldPixelScaleV = [newtView contentScaleFactor];
+    CGFloat oldPixelScaleL = [[newtView layer] contentsScale];
+    UIScreen* _screen = [self screen];
+    CGFloat maxPixelScale = [_screen scale];
+    CGFloat pixelScale;
+    BOOL changeScale;
+    if ( useAutoMaxPixelScale ) {
+        pixelScale = maxPixelScale;
+        changeScale = pixelScale != oldPixelScaleV || pixelScale != oldPixelScaleL;
+    } else {
+        pixelScale = oldPixelScaleV;
+        changeScale = NO;
+    }
+    DBG_PRINT("updatePixelScale: PixelScale: autoMaxPixelScale %d, max %f, view %f, layer %f -> %f (change %d)\n", 
+        useAutoMaxPixelScale, (float)maxPixelScale, (float)oldPixelScaleV, (float)oldPixelScaleL, (float)pixelScale, changeScale);
+    if( changeScale ) {
+        [newtView setContentScaleFactor: pixelScale];
+        [[newtView layer] setContentsScale: pixelScale];
+    }
+    (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, defer?JNI_TRUE:JNI_FALSE, 
+                          (jfloat)oldPixelScaleV, (jfloat)pixelScale, (jfloat)maxPixelScale, (jboolean)changeScale);
+
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
+}
+- (void) setPixelScale: (CGFloat)reqPixelScale defer:(BOOL)defer
+{
+    NewtUIView* newtView = contentNewtUIView;
+    useAutoMaxPixelScale = NewtCommon_isFloatZero(reqPixelScale);
+    DBG_PRINT( "setPixelScale view %p, reqPixelScale %f, autoMaxPixelScale %d, defer %d\n", 
+        newtView, reqPixelScale, useAutoMaxPixelScale, defer);
+    if( NULL == newtView ) {
+        return;
+    }
+    jobject javaWindowObject = [newtView getJavaWindowObject];
+    if ( NULL == javaWindowObject ) {
+        DBG_PRINT("setPixelScale: null javaWindowObject\n");
+        return;
+    }
+    int shallBeDetached = 0;
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+    if(NULL==env) {
+        DBG_PRINT("setPixelScale: null JNIEnv\n");
+        return;
+    }
+
+    CGFloat oldPixelScaleV = [newtView contentScaleFactor];
+    CGFloat oldPixelScaleL = [[newtView layer] contentsScale];
+    UIScreen* _screen = [self screen];
+    {
+         CGRect _bounds = [_screen bounds];
+         CGRect _nativeBounds = [_screen nativeBounds];
+         CGFloat _scale = [_screen scale];
+         CGFloat _nativeScale = [_screen nativeScale];
+         DBG_PRINT("setPixelScale: screen %p[native %f/%f %fx%f scale %f; logical %f/%f %fx%f scale %f]\n",
+            _screen,
+            _nativeBounds.origin.x, _nativeBounds.origin.y, _nativeBounds.size.width, _nativeBounds.size.height, _nativeScale,
+            _bounds.origin.x, _bounds.origin.y, _bounds.size.width, _bounds.size.height, _scale);
+    }
+    CGFloat maxPixelScale = [_screen scale];
+    CGFloat pixelScale;
+    BOOL changeScale;
+    if ( useAutoMaxPixelScale || maxPixelScale < reqPixelScale ) {
+        pixelScale = maxPixelScale;
+    } else if( 0 > reqPixelScale ) {
+        pixelScale = 1.0f;
+    } else {
+        pixelScale = reqPixelScale;
+    }
+    changeScale = pixelScale != oldPixelScaleV || pixelScale != oldPixelScaleL;
+    DBG_PRINT("setPixelScale: PixelScale: autoMaxPixelScale %d, max %f, view %f, layer %f, req %f -> %f (change %d)\n", 
+        useAutoMaxPixelScale, (float)maxPixelScale, (float)oldPixelScaleV, (float)oldPixelScaleL, (float)reqPixelScale, (float)pixelScale, changeScale);
+
+    if( changeScale ) {
+        [newtView setContentScaleFactor: pixelScale];
+        [[newtView layer] setContentsScale: pixelScale];
+    }
+    (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, defer?JNI_TRUE:JNI_FALSE, 
+                          (jfloat)oldPixelScaleV, (jfloat)pixelScale, (jfloat)maxPixelScale, (jboolean)changeScale);
+
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
+}
+
 - (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin
 {
     /**
@@ -498,8 +702,8 @@ static jmethodID windowRepaintID = NULL;
 
     CGRect frameRect = [self frame];
 
-    UIScreen* screen = [self screen];
-    CGPoint pS = [self convertPoint: frameRect.origin toCoordinateSpace: screen.fixedCoordinateSpace];
+    UIScreen* _screen = [self screen];
+    CGPoint pS = [self convertPoint: frameRect.origin toCoordinateSpace: _screen.fixedCoordinateSpace];
 
     DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) frameRect.size.width, (jint) frameRect.size.height, (jint)withinLiveResize);
     DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) pS.x, (jint) pS.y);
@@ -518,26 +722,27 @@ static jmethodID windowRepaintID = NULL;
 
 - (void) attachToParent: (UIWindow*) parent
 {
-    /** TODO 
     DBG_PRINT( "attachToParent.1\n");
-    [parent addChildWindow: self ordered: UIWindowAbove];
-    DBG_PRINT( "attachToParent.2\n");
-    [self setParentWindow: parent];
+    [parent addSubview: self];
+    // [self setwindowLevel: [parent windowLevel]+1.0f];
+    // NSWindow: [parent addChildWindow: self ordered: UIWindowAbove];
+    // NSWindow: [self setParentWindow: parent];
     DBG_PRINT( "attachToParent.X\n");
-    */
 }
 
 - (void) detachFromParent: (UIWindow*) parent
 {
-    /** TODO 
     DBG_PRINT( "detachFromParent.1\n");
+    [self removeFromSuperview];
+    /**
+    // NSWindow:
     [self setParentWindow: nil];
     if(NULL != parent) {
         DBG_PRINT( "detachFromParent.2\n");
         [parent removeChildWindow: self];
     }
-    DBG_PRINT( "detachFromParent.X\n");
     */
+    DBG_PRINT( "detachFromParent.X\n");
 }
 
 /**
@@ -561,8 +766,8 @@ static jmethodID windowRepaintID = NULL;
  */
 - (CGPoint) getLocationOnScreen: (CGPoint) p
 {
-    UIScreen* screen = [self screen];
-    CGPoint pS = [self convertPoint: p toCoordinateSpace: screen.fixedCoordinateSpace];
+    UIScreen* _screen = [self screen];
+    CGPoint pS = [self convertPoint: p toCoordinateSpace: _screen.fixedCoordinateSpace];
 
 #ifdef VERBOSE_ON
     CGRect winFrame = [self frame];
@@ -577,10 +782,13 @@ static jmethodID windowRepaintID = NULL;
 
 - (void) focusChanged: (BOOL) gained
 {
-    DBG_PRINT( "focusChanged: gained %d\n", gained);
-    NewtUIView* newtView = (NewtUIView *) self; // TODO [self contentView];
+    NewtUIView* newtView = contentNewtUIView;
+    DBG_PRINT( "focusChanged: gained %d, view %p\n", gained, newtView);
+    if( NULL == newtView ) {
+        return;
+    }
     jobject javaWindowObject = [newtView getJavaWindowObject];
-    if (javaWindowObject == NULL) {
+    if ( NULL == javaWindowObject ) {
         DBG_PRINT("focusChanged: null javaWindowObject\n");
         return;
     }
@@ -597,48 +805,55 @@ static jmethodID windowRepaintID = NULL;
     // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (void) flagsChanged:(UIEvent *) theEvent
+- (void) visibilityChanged: (BOOL) visible
 {
-    NSUInteger mods = [theEvent modifierFlags];
-    NewtUIView* newtView = (NewtUIView *) [self contentView];
-    if( [newtView isKindOfClass:[NewtUIView class]] ) {
-        [newtView handleFlagsChanged: mods];
+    DBG_PRINT( "visibilityChanged: visible %d\n", visible);
+    NewtUIView* newtView = contentNewtUIView;
+    if( NULL == newtView ) {
+        return;
     }
-}
+    jobject javaWindowObject = [newtView getJavaWindowObject];
+    if ( NULL == javaWindowObject ) {
+        DBG_PRINT("visibilityChanged: null javaWindowObject\n");
+        return;
+    }
+    int shallBeDetached = 0;
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+    if(NULL==env) {
+        DBG_PRINT("visibilityChanged: null JNIEnv\n");
+        return;
+    }
+    (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, (visible == YES) ? JNI_TRUE : JNI_FALSE);
 
-- (BOOL) acceptsMouseMovedEvents
-{
-    return YES;
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (BOOL) acceptsFirstResponder 
+- (BOOL) canBecomeFirstResponder 
 {
     return YES;
 }
-
 - (BOOL) becomeFirstResponder
 {
     DBG_PRINT( "*************** Win.becomeFirstResponder\n");
     return [super becomeFirstResponder];
 }
 
+- (BOOL) canResignFirstResponder
+{
+    return YES;
+}
 - (BOOL) resignFirstResponder
 {
     DBG_PRINT( "*************** Win.resignFirstResponder\n");
     return [super resignFirstResponder];
 }
 
-- (BOOL) canBecomeKeyWindow
-{
-    // Even if the window is borderless, we still want it to be able
-    // to become the key window to receive keyboard events
-    return YES;
-}
-
 - (void) becomeKeyWindow
 {
     DBG_PRINT( "*************** becomeKeyWindow\n");
     [super becomeKeyWindow];
+    [self focusChanged: YES];
 }
 
 - (void) resignKeyWindow
@@ -647,66 +862,53 @@ static jmethodID windowRepaintID = NULL;
     if(!isFullscreenWindow) {
         [super resignKeyWindow];
     }
-}
-
-- (void) windowDidResignKey: (NSNotification *) notification
-{
-    DBG_PRINT( "*************** windowDidResignKey\n");
-    // Implicit mouse exit by OS X
     [self focusChanged: NO];
 }
 
-- (void) windowWillStartLiveResize: (NSNotification *) notification
+- (void) becameVisible: (NSNotification*)notice
 {
-    DBG_PRINT( "*************** windowWillStartLiveResize\n");
-    withinLiveResize = JNI_TRUE;
-}
-- (void) windowDidEndLiveResize: (NSNotification *) notification
-{
-    DBG_PRINT( "*************** windowDidEndLiveResize\n");
-    withinLiveResize = JNI_FALSE;
-    [self sendResizeEvent];
+    DBG_PRINT( "*************** becameVisible\n");
+    [self visibilityChanged: YES];
 }
-- (CGSize) windowWillResize: (UIWindow *)sender toSize:(CGSize)frameSize
-{
-    DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height);
-    return frameSize;
-}
-- (void)windowDidResize: (NSNotification*) notification
+
+- (void) becameHidden: (NSNotification*)notice
 {
-    DBG_PRINT( "*************** windowDidResize\n");
-    [self sendResizeEvent];
+    DBG_PRINT( "*************** becameHidden\n");
+    [self visibilityChanged: NO];
 }
 
 - (void) sendResizeEvent
 {
-    jobject javaWindowObject = NULL;
+    // FIXME: Needs to be called
+    NewtUIView* newtView = contentNewtUIView;
+    if( NULL == newtView ) {
+        return;
+    }
+    jobject javaWindowObject = [newtView getJavaWindowObject];
+    if ( NULL == javaWindowObject ) {
+        DBG_PRINT("sendResizeEvent: null javaWindowObject\n");
+        return;
+    }
     int shallBeDetached = 0;
     JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
-
     if( NULL == env ) {
         DBG_PRINT("windowDidResize: null JNIEnv\n");
         return;
     }
-    NewtUIView* newtView = (NewtUIView *) [self contentView];
-    if( [newtView isKindOfClass:[NewtUIView class]] ) {
-        javaWindowObject = [newtView getJavaWindowObject];
-    }
-    if( NULL != javaWindowObject ) {
-        [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE];
-    }
+    [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE];
     // detaching thread not required - daemon
     // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
 - (void)windowDidMove: (NSNotification*) notification
 {
-    NewtUIView* newtView = (NewtUIView *) [self contentView];
-    if( ! [newtView isKindOfClass:[NewtUIView class]] ) {
+    // FIXME: Needs to be called
+    NewtUIView* newtView = contentNewtUIView;
+    if( NULL == newtView ) {
         return;
     }
     jobject javaWindowObject = [newtView getJavaWindowObject];
-    if (javaWindowObject == NULL) {
+    if ( NULL == javaWindowObject ) {
         DBG_PRINT("windowDidMove: null javaWindowObject\n");
         return;
     }
@@ -726,31 +928,21 @@ static jmethodID windowRepaintID = NULL;
     // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (BOOL)windowShouldClose: (id) sender
-{
-    return [self windowClosingImpl: NO];
-}
-
-- (void)windowWillClose: (NSNotification*) notification
-{
-    [self windowClosingImpl: YES];
-}
-
 - (BOOL) windowClosingImpl: (BOOL) force
 {
+    // FIXME: Needs to be called
     jboolean closed = JNI_FALSE;
 
-    NewtUIView* newtView = (NewtUIView *) [self contentView];
-    if( ! [newtView isKindOfClass:[NewtUIView class]] ) {
+    NewtUIView* newtView = contentNewtUIView;
+    if( NULL == newtView ) {
         return NO;
     }
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    [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) {
+        if ( NULL == javaWindowObject ) {
             DBG_PRINT("windowWillClose: null javaWindowObject\n");
             [pool release];
             return NO;
diff --git a/src/newt/native/IOSWindow.m b/src/newt/native/IOSWindow.m
index a8e816fbe..4778fed96 100644
--- a/src/newt/native/IOSWindow.m
+++ b/src/newt/native/IOSWindow.m
@@ -65,8 +65,7 @@ static void setWindowClientTopLeftPoint(NewtUIWindow* mWin, jint x, jint y, BOOL
     DBG_PRINT( "setWindowClientTopLeftPoint.X: %d/%d\n", (int)pS.x, (int)pS.y);
 
     if( doDisplay ) {
-        // TODO UIView* mView = [mWin contentView];
-        // TODO [mWin invalidateCursorRectsForView: mView];
+        [mWin setNeedsDisplay];
     }
 }
 
@@ -75,14 +74,14 @@ static void setWindowClientTopLeftPointAndSize(NewtUIWindow* mWin, jint x, jint
     CGRect rect = CGRectMake(x, y, width, height);
     DBG_PRINT( "setWindowClientTopLeftPointAndSize.1: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height);
 
-    // TODO [mWin setFrame: rect display:doDisplay];
     [mWin setFrame: rect];
+    if( doDisplay ) {
+        [mWin setNeedsDisplay];
+    }
     DBG_PRINT( "setWindowClientTopLeftPointAndSize.X: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height);
 
-    // -> display:YES
     // if( doDisplay ) {
-    //   UIView* mView = [mWin contentView];
-    //   [mWin invalidateCursorRectsForView: mView];
+    //     [mWin setNeedsDisplay];
     // }
 }
 
@@ -112,39 +111,20 @@ static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtUI
 }
 
 static void changeContentView(JNIEnv *env, jobject javaWindowObject, UIView *pview, NewtUIWindow *win, NewtUIView *newView, BOOL setJavaWindow) {
-    UIView* oldUIView = NULL; // TODO [win contentView];
-    NewtUIView* oldNewtUIView = NULL;
+    NewtUIView* oldNewtUIView = [win getContentNewtUIView];
 #ifdef VERBOSE_ON
     int dbgIdx = 1;
 #endif
+    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), parent view %p\n", 
+        dbgIdx++, win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView), pview);
 
-    if( [oldUIView isKindOfClass:[NewtUIView class]] ) {
-        oldNewtUIView = (NewtUIView *) oldUIView;
+    if( NULL != oldNewtUIView ) {
+        [oldNewtUIView setDestroyNotifySent: false];
+        setJavaWindowObject(env, NULL, oldNewtUIView);
+        [win setContentNewtUIView: NULL]; // includes [oldNewtUIView removeFromSuperview];
     }
-
-    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", 
-        dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView), pview);
-
-    if( NULL!=oldUIView ) {
-NS_DURING
-        // Available >= 10.5 - Makes the menubar disapear
-        BOOL iifs = NO; // TODO [oldUIView isInFullScreenMode];
-        if( iifs ) {
-            // TODO [oldUIView exitFullScreenModeWithOptions: NULL];
-        }
-NS_HANDLER
-NS_ENDHANDLER
-        DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d)\n", 
-            dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView));
-
-        if( NULL != oldNewtUIView ) {
-            [oldNewtUIView setDestroyNotifySent: false];
-            setJavaWindowObject(env, NULL, oldNewtUIView, NO);
-        }
-        // TODO [oldUIView removeFromSuperviewWithoutNeedingDisplay];
-    }
-    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
-        dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
+    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d\n", 
+        dbgIdx++, win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView), [newView isHidden]);
 
     if( NULL!=newView ) {
         [newView setDestroyNotifySent: false];
@@ -152,25 +132,22 @@ NS_ENDHANDLER
             setJavaWindowObject(env, javaWindowObject, newView);
         }
         DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d)\n", 
-            dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView));
-
-        if(NULL!=pview) {
-            // TODO [pview addSubview: newView positioned: UIWindowAbove relativeTo: nil];
-        }
-    }
-    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
-        dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
+            dbgIdx++, win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView));
 
-    // TODO [win setContentView: newView];
+        [win setContentNewtUIView: newView]; // includes [win addSubview: newView];
+        // FIXME: Done in initWindow0: [pview addSubview: newView] 
 
-    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
-        dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
+        DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d\n", 
+            dbgIdx++, win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView), [newView isHidden]);
+    }
+    DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d\n", 
+        dbgIdx++, win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView), [newView isHidden]);
 
     // make sure the insets are updated in the java object
     [win updateInsets: env jwin:javaWindowObject];
 
     DBG_PRINT( "changeContentView.X win %p, view (%p,%d -> %p,%d)\n", 
-        win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView));
+        win, oldNewtUIView, getRetainCount(oldNewtUIView), newView, getRetainCount(newView));
 }
 
 /*
@@ -205,16 +182,16 @@ static void NewtScreen_dump() {
     int i;
     for(i=0; i<[screens count]; i++) {
         UIScreen * screen = (UIScreen *) [screens objectAtIndex: i];
-        CGRect screenFrame = [screen frame];
-        CGRect screenVisibleFrame = [screen visibleFrame];
-        CGFloat pixelScale = 1.0; // default
-        pixelScale = [screen scale]; // HiDPI scaling
-        UIWindowDepth depth = [screen depth]; // an (int) value!
-        DBG_PRINT( "UIScreen #%d (%p): Frame %lf/%lf %lfx%lf (vis %lf/%lf %lfx%lf), scale %lf, depth %d\n",
+        CGRect screenPxFrame = [screen nativeBounds];
+        CGRect screenPtFrame = [screen bounds];
+        CGFloat pixelScale = [screen scale];
+        CGFloat nativeScale = [screen nativeScale];
+        int depth = 32; // [screen depth]; // an (int) value!
+        DBG_PRINT( "UIScreen #%d (%p): Frame %lf/%lf %lfx%lf px (%lf/%lf %lfx%lf pt), scale %lf (%lf native), depth %d\n",
             i, screen,
-            screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height,
-            screenVisibleFrame.origin.x, screenVisibleFrame.origin.y, screenVisibleFrame.size.width, screenVisibleFrame.size.height,
-            pixelScale, depth);
+            screenPxFrame.origin.x, screenPxFrame.origin.y, screenPxFrame.size.width, screenPxFrame.size.height,
+            screenPtFrame.origin.x, screenPtFrame.origin.y, screenPtFrame.size.width, screenPtFrame.size.height,
+            pixelScale, nativeScale, depth);
     }
 #endif
 }
@@ -270,7 +247,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorP
     fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL);
 #endif
     NSArray *screens = [UIScreen screens];
-    int count = [screens count];
+    // int count = [screens count];
     UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id];
     if( NULL == screen ) {
         [pool release];
@@ -282,18 +259,24 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorP
     fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL);
 #endif
 
-    UIScreenMode * screenMode = [screen currentMode];
+    // UIScreenMode * screenMode = [screen currentMode];
     CGSize sizeMM = CGSizeMake(161.0, 228.0); // TODO ???
 #ifdef DBG_PERF
     timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
     fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL);
 #endif
 
-    CGRect dBounds = [screen bounds];
+    CGRect bounds = [screen bounds];
 #ifdef VERBOSE_ON
-    DBG_PRINT( "getMonitorProps0: crt_id 0x%X (prim %d), top-left displayBounds[%d/%d %dx%d]\n", 
-                 (int)crt_id, isPrimary,
-                 (int)dBounds.origin.x, (int)dBounds.origin.y, (int)dBounds.size.width, (int)dBounds.size.height);
+    {
+        CGRect nativeBounds = [screen nativeBounds];
+        CGFloat nativeScale = [screen nativeScale];
+        CGFloat scale = [screen scale];
+        DBG_PRINT( "getMonitorProps0: crt_id 0x%X (prim %d) %p[\n  native %f/%f %fx%f scale %f; logical %f/%f %fx%f scale %f]\n",
+                   (int)crt_id, isPrimary, screen,
+                   nativeBounds.origin.x, nativeBounds.origin.y, nativeBounds.size.width, nativeBounds.size.height, nativeScale,
+                   bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height, scale);
+    }
 #endif
 
     jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES;
@@ -305,14 +288,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorP
     prop[offset++] = isPrimary ? 1 : 0; // isPrimary
     prop[offset++] = (jint) sizeMM.width;
     prop[offset++] = (jint) sizeMM.height;
-    prop[offset++] = (jint) dBounds.origin.x;    // rotated viewport x      (pixel units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.origin.y;    // rotated viewport y      (pixel units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.size.width;  // rotated viewport width  (pixel units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (pixel units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.origin.x;    // rotated viewport x      (window units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.origin.y;    // rotated viewport y      (window units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.size.width;  // rotated viewport width  (window units, will be fixed in java code)
-    prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (window units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.origin.x;    // rotated viewport x      (pixel units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.origin.y;    // rotated viewport y      (pixel units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.size.width;  // rotated viewport width  (pixel units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.size.height; // rotated viewport height (pixel units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.origin.x;    // rotated viewport x      (window units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.origin.y;    // rotated viewport y      (window units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.size.width;  // rotated viewport width  (window units, will be fixed in java code)
+    prop[offset++] = (jint) bounds.size.height; // rotated viewport height (window units, will be fixed in java code)
 
     jintArray properties = (*env)->NewIntArray(env, propCount);
     if (properties == NULL) {
@@ -336,19 +319,13 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorM
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSArray<UIScreen*> *screens = [UIScreen screens];
-    int count = [screens count];
+    // int count = [screens count];
     UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id];
     if( NULL == screen ) {
         [pool release];
         return NULL;
     }
-    CGFloat pixelScale = 1.0; // default
-NS_DURING
-    // Available >= 10.7
-    pixelScale = [screen scale]; // HiDPI scaling
-NS_HANDLER
-NS_ENDHANDLER
-
+    CGFloat pixelScale = [screen scale];
     NSArray<UIScreenMode*> *availableModes = [screen availableModes];
     int numberOfAvailableModes = [availableModes count];
     CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes; 
@@ -361,7 +338,7 @@ NS_ENDHANDLER
     if(0 >= mode_idx) {
         // only for current mode (-1) and first mode (scanning)
         DBG_PRINT( "getScreenMode0: crtID 0x%X (s %p, pscale %lf), mode %d, avail: %d/%d, current rot %d ccw\n",  
-            (uint32_t)displayID, screen, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
+            crt_id, screen, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
     }
 #endif
 
@@ -387,10 +364,6 @@ NS_ENDHANDLER
     CGSize mSize = [mode size];
     int mWidth = (int)mSize.width;
     int mHeight = (int)mSize.height;
-    if( -1 == mode_idx ) {
-        mWidth *= (int)pixelScale;   // accomodate HiDPI
-        mHeight *= (int)pixelScale; // accomodate HiDPI
-    }
 
     // swap width and height, since OSX reflects rotated dimension, we don't
     if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
@@ -491,15 +464,15 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initIDs0
  * Signature: (IIII)J
  */
 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createView0
-  (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h)
+  (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, jfloat reqPixelScale)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
-    DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d (START)\n",
-        (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h);
+    DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, reqPixelScale %f (START)\n",
+        (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale);
 
     CGRect rectView = CGRectMake(0, 0, w, h);
-    NewtUIView *myView = [[NewtUIView alloc] initWithFrame: rectView] ;
+    NewtUIView *myView = [[NewtUIView alloc] initWithFrame: rectView];
     DBG_PRINT( "createView0.X - new view: %p\n", myView);
 
     [pool release];
@@ -519,6 +492,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createWindow0
    jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [CATransaction begin];
     NewtUIView* myView = (NewtUIView*) (intptr_t) jview ;
 
     DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n",
@@ -526,21 +500,18 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createWindow0
         (int)styleMask, (int)bufferingType, myView);
     (void)myView;
 
-    if (fullscreen) {
-        // TODO styleMask = NSBorderlessWindowMask;
-    }
+    (void)fullscreen;
     CGRect rectWin = CGRectMake(x, y, w, h);
 
     // Allocate the window
-    NewtUIWindow* myWindow = [[NewtUIWindow alloc] initWithContentRect: rectWin
+    NewtUIWindow* myWindow = [[[[NewtUIWindow alloc] initWithFrame: rectWin
                                                styleMask: (NSUInteger) styleMask
                                                backing: 0 // TODO (NSBackingStoreType) bufferingType
                                                defer: YES
-                                               isFullscreenWindow: fullscreen];
-    // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
-
-    DBG_PRINT( "createWindow0.X - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
+                                               isFullscreenWindow: fullscreen] autorelease] retain];
+    DBG_PRINT( "createWindow0.X - %p, isHidden %d\n", myWindow, [myWindow isHidden]);
 
+    [CATransaction commit];
     [pool release];
 
     return (jlong) ((intptr_t) myWindow);
@@ -553,7 +524,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_ios_WindowDriver_getDisplayID0(JN
         return 0;
     }
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    UIScreen *screen =  [myWindow screen];
+    // UIScreen *screen =  [myWindow screen];
     int32_t displayID = 0; // TODO (int32_t)NewtScreen_getCGDirectDisplayIDByUIScreen(screen);
     [pool release];
     return (jint) displayID;
@@ -571,17 +542,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initWindow0
    jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [CATransaction begin];
+
     NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window);
     NewtUIView* myView = (NewtUIView*) (intptr_t) jview ;
+    CAEAGLLayer* l = (CAEAGLLayer*)[myView layer];
     BOOL fullscreen = myWindow->isFullscreenWindow;
 
-    DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n",
-        (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale,
-        (int) opaque, (int)atop, (int)abottom, (int)fullscreen, (int)visible, myView);
-
-    // TODO [myWindow setReleasedWhenClosed: NO]; // We control UIWindow destruction!
-    // TODO [myWindow setPreservesContentDuringLiveResize: NO];
-
     NSObject* nsParentObj = (NSObject*) ((intptr_t) parent);
     UIWindow* parentWindow = NULL;
     UIView* parentView = NULL;
@@ -596,121 +563,79 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initWindow0
     } else {
         DBG_PRINT( "initWindow0 - Parent is neither UIWindow nor UIView : %p\n", nsParentObj);
     }
-    DBG_PRINT( "initWindow0 - is visible.1: %d\n", [myWindow isVisible]);
+    DBG_PRINT( "initWindow0.1 - window %p, isHidden %d, rootViewController %p\n", myWindow, [myWindow isHidden], myWindow.rootViewController);
+    DBG_PRINT( "initWindow0.2 - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
 
     // Remove animations for child windows
-    if(NULL != parentWindow) {
-        [UIView setAnimationsEnabled: NO];
-    }
+    // if(NULL != parentWindow) {
+    //     [UIView setAnimationsEnabled: NO];
+    // }
 
-#ifdef VERBOSE_ON
-    int dbgIdx = 1;
-#endif
     if(opaque) {
-        [myWindow setOpaque: YES];
-        DBG_PRINT( "initWindow0.%d\n", dbgIdx++);
-        if (!fullscreen) {
-            // TODO [myWindow setShowsResizeIndicator: YES];
-        }
-        DBG_PRINT( "initWindow0.%d\n", dbgIdx++);
+        // FIXME [myWindow setOpaque: YES];
+        (void) fullscreen; // No extra handling
+        [myWindow setBackgroundColor: [UIColor redColor]]; // FIXME TEST
     } else {
         [myWindow setOpaque: NO];
         [myWindow setBackgroundColor: [UIColor clearColor]];
     }
     [myWindow setAlwaysOn: atop bottom:abottom];
 
-    // specify we want mouse-moved events
-    // TODO [myWindow setAcceptsMouseMovedEvents:YES];
-
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
+    DBG_PRINT( "initWindow0.3 - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
 
     // Set the content view
     changeContentView(env, jthis, parentView, myWindow, myView, NO);
-    // TODO [myWindow setInitialFirstResponder: myView];
 
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
+    DBG_PRINT( "initWindow0.4 - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
 
     if(NULL!=parentWindow) {
         [myWindow attachToParent: parentWindow];
     }
 
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d, visible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible], visible);
+    DBG_PRINT( "initWindow0.5 - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
 
     // Immediately re-position this window based on an upper-left coordinate system
     setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO);
-
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
-
-    // TODO [myWindow setAllowsConcurrentViewDrawing: YES];
-
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
-
-    // TODO [myView setCanDrawConcurrently: YES];
-
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
-
-    // visible on front
     if( visible ) {
-        // TODO [myWindow orderFront: myWindow];
+        [myWindow makeKeyAndVisible];
     }
 
-    DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
-        dbgIdx++, myWindow, myView, [myWindow isVisible]);
-
-    // force surface creation
-    // [myView lockFocus];
-    // [myView unlockFocus];
-
-    // Set the next responder to be the window so that we can forward
-    // right mouse button down events
-    // TODO [myView setNextResponder: myWindow];
-
-    DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
-        dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
-
+    DBG_PRINT( "initWindow0.6 - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
     [myView setDestroyNotifySent: false];
     setJavaWindowObject(env, jthis, myView);
 
-    DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
-        dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
-
-NS_DURING
-    if( fullscreen ) {
-        /** 
-         * See Bug 914: We don't use exclusive fullscreen anymore (capturing display)
-         * allowing ALT-TAB to allow process/app switching!
-         * Shall have no penalty on modern GPU and is also recommended, see bottom box @
-         * <https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html>
-         *
-        UIScreen *myScreen =  NewtScreen_getUIScreenByCoord(x, y);
-        if( NULL != myScreen ) {
-            if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) {
-                // Available >= 10.5 - Makes the menubar disapear
-                [myView enterFullScreenMode: myScreen withOptions:NULL];
-            } 
-        }
-        */
-        if( myWindow->hasPresentationSwitch ) {
-            DBG_PRINT( "initWindow0.%d - %p view %p, setPresentationOptions 0x%X\n", 
-                dbgIdx++, myWindow, myView, (int)myWindow->fullscreenPresentationOptions);
-            // TODO [NSApp setPresentationOptions: myWindow->fullscreenPresentationOptions];
-        }
-    }
-NS_HANDLER
-NS_ENDHANDLER
+    [myWindow setPixelScale: (CGFloat)reqPixelScale defer:NO];
+
+    (void) fullscreen; // No extra handling
 
-    DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
-        dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
+    DBG_PRINT( "initWindow0.X - parent(win %p scale %f, view %p scale %f), window %p (scale %f, superview %p), view: %p (scale %f, superview %p), CAEAGLLayer %p (opaque %d, scale %f, isCAEAGLLayer %d)\n", 
+        parentWindow, (NULL!=parentWindow?[parentWindow contentScaleFactor]:0.0f), parentView, (NULL!=parentView?[parentView contentScaleFactor]:0.0f), 
+        myWindow, [myWindow contentScaleFactor], [myWindow superview], 
+        myView, [myView contentScaleFactor], [myView superview], 
+        l, [l isOpaque], [l contentsScale], [l isKindOfClass:[CAEAGLLayer class]]);
 
+    [CATransaction commit];
     [pool release];
-    DBG_PRINT( "initWindow0.X - %p (this), %p (parent): new window: %p, view %p\n",
-        (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
 }
 
 /**
@@ -729,20 +654,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setPixelScale0
         return;
     }
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    NewtUIView* myView = (NewtUIView*) (intptr_t) view ;
-#ifdef VERBOSE_ON
-    int dbgIdx = 1;
-#endif
-    DBG_PRINT( "setPixelScale0 - %p (this), %p (window), view %p, reqPixScale %f (START)\n",
-        (void*)(intptr_t)jthis, myWindow, myView, (float)reqPixelScale);
-    (void)myWindow;
-
-    DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n",
-        dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView);
+    [myWindow setPixelScale: (CGFloat)reqPixelScale defer:YES];
 
     [pool release];
-    DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n",
-        (void*)(intptr_t)jthis, myWindow, myView);
 }
 
 /**
@@ -762,7 +676,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_close0
     }
     BOOL isNSWin = [mWin isKindOfClass:[UIWindow class]];
     BOOL isNewtWin = [mWin isKindOfClass:[NewtUIWindow class]];
-    UIWindow *pWin = NULL; // TODO [mWin parentWindow];
+    UIWindow *pWin;
+    {
+        UIView *superview = [mWin superview];
+        if( [superview isKindOfClass:[UIWindow class]] ) {
+            pWin = (UIWindow*)superview;
+        } else {
+            pWin = NULL;
+        }
+    }
     DBG_PRINT( "windowClose.0 - %p [isUIWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin);
     (void)isNSWin; // silence
     if( !isNewtWin ) {
@@ -770,7 +692,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_close0
         return;
     }
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    NewtUIView* mView = (NewtUIView *)mWin; // TODO [mWin contentView];
+    NewtUIView* mView = [mWin getContentNewtUIView];
     BOOL fullscreen = mWin->isFullscreenWindow;
     BOOL destroyNotifySent, isUIView, isNewtUIView;
     if( NULL != mView ) {
@@ -794,32 +716,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_close0
         setJavaWindowObject(env, NULL, mView);
     }
 
-NS_DURING
-    /** 
-     * See Bug 914: We don't use exclusive fullscreen anymore (capturing display)
-     * See initWindow0(..) above ..
-    if(NULL!=mView) {
-        BOOL iifs;
-        if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) {
-            iifs = [mView isInFullScreenMode];
-        } else {
-            iifs = NO;
-        }
-        if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
-            [mView exitFullScreenModeWithOptions: NULL];
-        }
-    } */
     // Note: mWin's release will also release it's mView!
-    DBG_PRINT( "windowClose.1a - %p view %p, fullscreen %d, hasPresSwitch %d, defaultPresentationOptions 0x%X\n", 
-        mWin, mView, (int)fullscreen, (int)mWin->hasPresentationSwitch, (int)mWin->defaultPresentationOptions);
-
-    if( fullscreen && mWin->hasPresentationSwitch ) {
-        DBG_PRINT( "windowClose.1b - %p view %p, setPresentationOptions 0x%X\n", 
-            mWin, mView, (int)mWin->defaultPresentationOptions);
-        // TODO [NSApp setPresentationOptions: mWin->defaultPresentationOptions];
-    }
-NS_HANDLER
-NS_ENDHANDLER
+    DBG_PRINT( "windowClose.1a - %p view %p, fullscreen %d\n", 
+        mWin, mView, (int)fullscreen);
 
     if(NULL!=pWin) {
         [mWin detachFromParent: pWin];
@@ -946,7 +845,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderFront0
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     UIWindow* pWin = NULL; // TODO [mWin parentWindow];
 
-    DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
+    DBG_PRINT( "orderFront0 - window: (parent %p) %p hidden %d (START)\n", pWin, mWin, [mWin isHidden]);
 
     if( NULL == pWin ) {
         // TODO [mWin orderFrontRegardless];
@@ -975,7 +874,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderOut0
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     UIWindow* pWin = NULL; // TODO [mWin parentWindow];
 
-    DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
+    DBG_PRINT( "orderOut0 - window: (parent %p) %p hidden %d (START)\n", pWin, mWin, [mWin isHidden]);
 
     if( NULL == pWin ) {
         // TODO [mWin orderOut: mWin];
@@ -1014,31 +913,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setTitle0
     [pool release];
 }
 
-/*
- * Class:     jogamp_newt_driver_ios_WindowDriver
- * Method:    contentView0
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_contentView0
-  (JNIEnv *env, jobject unused, jlong window)
-{
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    UIWindow* win = (UIWindow*) ((intptr_t) window);
-    UIView* nsView = (UIView*)win; // TODO [win contentView];
-    NewtUIView* newtView = NULL;
-
-    if( [nsView isKindOfClass:[NewtUIView class]] ) {
-        newtView = (NewtUIView *) nsView;
-    }
-
-    DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView);
-
-    jlong res = (jlong) ((intptr_t) nsView);
-
-    [pool release];
-    return res;
-}
-
 /**
  * Method is called on Main-Thread, hence no special invocation required inside method.
  *
@@ -1062,7 +936,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_changeContentVie
     if( NULL != nsParentObj ) {
         if( [nsParentObj isKindOfClass:[UIWindow class]] ) {
             UIWindow * pWin = (UIWindow*) nsParentObj;
-            pView = (UIView*)pWin; // TODO [pWin contentView];
+            pView = (UIView*)pWin;
         } else if( [nsParentObj isKindOfClass:[UIView class]] ) {
             pView = (UIView*) nsParentObj;
         }
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 5775633be..c1fcdf51e 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -126,11 +126,9 @@ static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pvi
 #ifdef VERBOSE_ON
     int dbgIdx = 1;
 #endif
-
     if( [oldNSView isKindOfClass:[NewtNSView class]] ) {
         oldNewtNSView = (NewtNSView *) oldNSView;
     }
-
     DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", 
         dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtNSView, newView, getRetainCount(newView), pview);
 
@@ -1066,9 +1064,6 @@ NS_DURING
 NS_HANDLER
 NS_ENDHANDLER
 
-    DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n",
-        dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView);
-
     [pool release];
     DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n",
         (void*)(intptr_t)jthis, myWindow, myView);
diff --git a/src/newt/native/MouseEvent.h b/src/newt/native/MouseEvent.h
index 59d63cecf..3baeb2dae 100644
--- a/src/newt/native/MouseEvent.h
+++ b/src/newt/native/MouseEvent.h
@@ -39,4 +39,10 @@
 #define EVENT_MOUSE_WHEEL_MOVED    207
 // Generated by Java:  EVENT_MOUSE_DRAGGED  = 206;
 
+#define POINTER_TYPE_MOUSE         0
+#define POINTER_TYPE_TOUCHPAD      1
+#define POINTER_TYPE_TOUCHSCREEN   2
+#define POINTER_TYPE_PEN           3
+#define POINTER_TYPE_UNDEF         4
+
 #endif
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c
index d580012ef..ec10b2da5 100644
--- a/src/newt/native/NewtCommon.c
+++ b/src/newt/native/NewtCommon.c
@@ -27,6 +27,7 @@
  */
 #include "NewtCommon.h"
 #include <string.h>
+#include <math.h>
 
 static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
 static jclass    runtimeExceptionClz=NULL;
@@ -166,3 +167,7 @@ void NewtCommon_ReleaseJNIEnv (int shallBeDetached) {
     }
 }
 
+int NewtCommon_isFloatZero(float f) {
+    // EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d
+    return fabsf(f) < 1.1920929E-7f;
+}
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 43db72b5b..d4ce2f3e8 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -74,4 +74,6 @@ JNIEnv* NewtCommon_GetJNIEnv (int asDaemon, int * shallBeDetached);
 
 void NewtCommon_ReleaseJNIEnv (int shallBeDetached);
 
+int NewtCommon_isFloatZero(float f);
+
 #endif
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
index 6aebeb91b..d87a18b2f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
@@ -201,7 +201,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
 
         System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
         System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
-        System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets());
+        System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+"[wu] "+glWindow.getWidth()+"x"+glWindow.getHeight()+"[wu] "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+"[px], "+glWindow.getInsets());
 
         final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]);
         System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
-- 
cgit v1.2.3