summaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2019-06-23 08:03:04 +0200
committerSven Gothel <[email protected]>2019-06-23 08:03:04 +0200
commitbba73bc096250a3c7fc036d84b1ea054d1b70b06 (patch)
treeed02575eac2a46bd49627444dcce972946ae8d2e /src/nativewindow
parent154e91978498d8b6db9ce34a1f06b298bcf4c361 (diff)
iOS: Initial working commit supporting iOS (ipad pro 11)
using our OpenJFK 9 x86_64 and arm64 build. Test demo class is 'com.jogamp.opengl.demos.ios.Hello', residing in the new demo folder 'src/demos/com/jogamp/opengl/demos/ios/Hello.java'. This commit does not yet include a working NEWT specialization for iOS, but it shall followup soon. Instead this commit demonstrates JOGL operating on native UIWindow, UIView and CAEAGLLayer as provided by Nativewindow's IOSUtil. Test Video https://www.youtube.com/watch?v=Z4lUQNFTGMI +++ Notable bug: The FBO used and sharing the COLORBUFFER RENDERBUFFER memory resources with CAEAGLLayer to be displayed in the UIView seemingly cannot handle GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT32 depth buffer - none at all (Device + Simulation). Therefor the default demo GLEventListener chosen here don't require a depth buffer ;-) This issue can hopefully be mitigated with other means than using a flat FBO sink similar to FBO multisampling.
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java17
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/ios/IOSGraphicsDevice.java46
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/ios/IOSDummyUpstreamSurfaceHook.java83
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/ios/IOSUtil.java333
-rw-r--r--src/nativewindow/native/JVM_JNI8.c47
-rw-r--r--src/nativewindow/native/ios/CAEAGLLayered.h50
-rw-r--r--src/nativewindow/native/ios/CAEAGLLayered.m66
-rw-r--r--src/nativewindow/native/ios/IOSmisc.m813
-rw-r--r--src/nativewindow/native/ios/NativeWindowProtocols.h59
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m16
11 files changed, 1524 insertions, 8 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
index 323bc8c86..8e00d318c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
@@ -52,6 +52,7 @@ import jogamp.nativewindow.NativeWindowFactoryImpl;
import jogamp.nativewindow.ToolkitProperties;
import jogamp.nativewindow.ResourceToolkitLock;
import jogamp.nativewindow.WrappedWindow;
+import jogamp.nativewindow.ios.IOSUtil;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.x11.X11Lib;
@@ -65,6 +66,7 @@ import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.nativewindow.ios.IOSGraphicsDevice;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -100,6 +102,9 @@ public abstract class NativeWindowFactory {
/** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
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";
+
/** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
public static final String TYPE_AWT = ".awt";
@@ -120,6 +125,8 @@ public abstract class NativeWindowFactory {
private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
/** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+ /** {@link jogamp.nativewindow.ios.IOSUtil} implements {@link ToolkitProperties}. */
+ private static final String IOSUtilClassName = "jogamp.nativewindow.ios.IOSUtil";
/** {@link jogamp.nativewindow.windows.GDIUtil} implements {@link ToolkitProperties}. */
private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
@@ -143,6 +150,8 @@ public abstract class NativeWindowFactory {
return TYPE_ANDROID;
case MACOS:
return TYPE_MACOSX;
+ case IOS:
+ return TYPE_IOS;
case WINDOWS:
return TYPE_WINDOWS;
case OPENKODE:
@@ -204,6 +213,8 @@ public abstract class NativeWindowFactory {
clazzName = GDIClassName;
} else if( TYPE_MACOSX == nativeWindowingTypePure ) {
clazzName = OSXUtilClassName;
+ } else if( TYPE_IOS == nativeWindowingTypePure ) {
+ clazzName = IOSUtilClassName;
} else {
clazzName = null;
}
@@ -294,6 +305,8 @@ public abstract class NativeWindowFactory {
clazzName = GDIClassName;
} else if( TYPE_MACOSX == nativeWindowingTypePure ) {
clazzName = OSXUtilClassName;
+ } else if( TYPE_IOS == nativeWindowingTypePure ) {
+ clazzName = IOSUtilClassName;
} else {
clazzName = null;
}
@@ -677,6 +690,8 @@ public abstract class NativeWindowFactory {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
} else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ } else if( NativeWindowFactory.TYPE_IOS == nwt ) {
+ return new IOSGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
} else if( NativeWindowFactory.TYPE_EGL == nwt ) {
final EGLGraphicsDevice device;
if( own ) {
@@ -742,6 +757,8 @@ public abstract class NativeWindowFactory {
return GDIUtil.GetRelativeLocation(nw.getWindowHandle(), 0, 0, 0);
} else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
return OSXUtil.GetLocationOnScreen(nw.getWindowHandle(), 0, 0);
+ } else if( NativeWindowFactory.TYPE_IOS == nwt ) {
+ return IOSUtil.GetLocationOnScreen(nw.getWindowHandle(), 0, 0);
/**
* FIXME: Needs service provider interface (SPI) for TK dependent implementation
} else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/ios/IOSGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/ios/IOSGraphicsDevice.java
new file mode 100644
index 000000000..0a4354c9d
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/ios/IOSGraphicsDevice.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.nativewindow.ios;
+
+import com.jogamp.nativewindow.*;
+
+/** Encapsulates a graphics device on IOS platforms.
+ */
+public class IOSGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
+ /** Constructs a new IOSGraphicsDevice */
+ public IOSGraphicsDevice(final int unitID) {
+ super(NativeWindowFactory.TYPE_IOS, AbstractGraphicsDevice.DEFAULT_CONNECTION, unitID);
+ }
+
+ @Override
+ public Object clone() {
+ return super.clone();
+ }
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java
index bffabdd5a..9d38b1f4b 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java
@@ -62,6 +62,7 @@ public class JFXAccessor {
private static final String nwt;
private static final boolean isOSX;
+ private static final boolean isIOS;
private static final boolean isWindows;
private static final boolean isX11;
@@ -130,6 +131,7 @@ public class JFXAccessor {
nwt = NativeWindowFactory.getNativeWindowType(false);
isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isIOS = NativeWindowFactory.TYPE_IOS == nwt;
isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
isX11 = NativeWindowFactory.TYPE_X11 == nwt;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ios/IOSDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/ios/IOSDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..a61287f8b
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ios/IOSDummyUpstreamSurfaceHook.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.nativewindow.ios;
+
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.ProxySurface;
+import com.jogamp.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class IOSDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ long uiWindow;
+
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getSurfaceWidth()} via {@link UpstreamSurfaceHook#getSurfaceWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getSurfaceHeight()} via {@link UpstreamSurfaceHook#getSurfaceHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public IOSDummyUpstreamSurfaceHook(final int width, final int height) {
+ super(width, height);
+ uiWindow = 0;
+ }
+
+ @Override
+ public final void create(final ProxySurface s) {
+ if(0 == uiWindow && 0 == s.getSurfaceHandle()) {
+ uiWindow = IOSUtil.CreateUIWindow(0, 0, 64, 64);
+ if(0 == uiWindow) {
+ throw new NativeWindowException("Error UI window 0");
+ }
+ final long uiView = IOSUtil.GetUIView(uiWindow, true);
+ if(0 == uiView) {
+ throw new NativeWindowException("Error UI view 0");
+ }
+ s.setSurfaceHandle(uiView);
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(final ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( 0 == uiWindow || 0 == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no IOS view/window: "+s+", uiWindow 0x"+Long.toHexString(uiWindow));
+ }
+ IOSUtil.DestroyUIWindow(uiWindow);
+ uiWindow = 0;
+ s.setSurfaceHandle(0);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ios/IOSUtil.java b/src/nativewindow/classes/jogamp/nativewindow/ios/IOSUtil.java
new file mode 100644
index 000000000..bd4b36239
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ios/IOSUtil.java
@@ -0,0 +1,333 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.nativewindow.ios;
+
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.util.Insets;
+import com.jogamp.nativewindow.util.Point;
+import com.jogamp.common.util.Function;
+import com.jogamp.common.util.FunctionTask;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.RunnableTask;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
+
+public class IOSUtil implements ToolkitProperties {
+ private static boolean isInit = false;
+ private static final boolean DEBUG = Debug.debug("IOSUtil");
+
+ /** FIXME HiDPI: OSX unique and maximum value {@value} */
+ public static final int MAX_PIXELSCALE = 2;
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static synchronized void initSingleton() {
+ if(!isInit) {
+ if(DEBUG) {
+ System.out.println("IOSUtil.initSingleton()");
+ }
+ if(!NWJNILibLoader.loadNativeWindow("ios")) {
+ throw new NativeWindowException("NativeWindow IOS native library load error.");
+ }
+
+ if( !initIDs0() ) {
+ throw new NativeWindowException("IOS: Could not initialized native stub");
+ }
+ isInit = true;
+ }
+ }
+
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * @see ToolkitProperties
+ */
+ public static void shutdown() { }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static boolean requiresToolkitLock() { return false; }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean hasThreadingIssues() { return false; }
+
+ public static boolean isCALayer(final long object) {
+ return 0 != object ? isCALayer0(object) : false;
+ }
+
+ public static boolean isCAEAGLLayer(final long object) {
+ return 0 != object ? isCAEAGLLayer0(object) : false;
+ }
+
+ public static boolean isUIView(final long object) {
+ return 0 != object ? isUIView0(object) : false;
+ }
+
+ public static boolean isUIWindow(final long object) {
+ return 0 != object ? isUIWindow0(object) : false;
+ }
+
+ /**
+ * @param windowOrView
+ * @param src_x
+ * @param src_y
+ * @return top-left client-area position in window units
+ */
+ public static Point GetLocationOnScreen(final long windowOrView, final int src_x, final int src_y) {
+ return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
+ }
+
+ public static Insets GetInsets(final long windowOrView) {
+ return (Insets) GetInsets0(windowOrView);
+ }
+
+ public static double GetPixelScaleByDisplayID(final int displayID) {
+ if( 0 != displayID ) {
+ return GetPixelScale1(displayID);
+ } else {
+ return 1.0; // default
+ }
+ }
+ public static double GetPixelScale(final long windowOrView) {
+ if( 0 != windowOrView ) {
+ return GetPixelScale2(windowOrView);
+ } else {
+ return 1.0; // default
+ }
+ }
+
+ public static long CreateUIWindow(final int x, final int y, final int width, final int height) {
+ final long res[] = { 0 };
+ RunOnMainThread(true, false /* kickNSApp */, new Runnable() {
+ @Override
+ public void run() {
+ res[0] = CreateUIWindow0(x, y, width, height);
+ } } );
+ return res[0];
+ }
+ public static void DestroyUIWindow(final long uiWindow) {
+ DestroyUIWindow0(uiWindow);
+ }
+ public static long GetCALayer(final long uiView) {
+ return 0 != uiView ? GetCALayer0(uiView) : 0;
+ }
+ public static long GetCAEAGLLayer(final long uiView) {
+ return 0 != uiView ? GetCAEAGLLayer0(uiView) : 0;
+ }
+ public static long GetUIView(final long uiWindow, final boolean onlyEAGL) {
+ return 0 != uiWindow ? GetUIView0(uiWindow, onlyEAGL) : 0;
+ }
+ public static long GetUIWindow(final long uiView) {
+ return 0 != uiView ? GetUIWindow0(uiView) : 0;
+ }
+
+ /**
+ * Set the UIView's pixelScale / contentScale for HiDPI
+ *
+ * @param uiView the mutable UIView instance
+ * @param contentScaleFactor scale for HiDPI support: pixel-dim = window-dim x scale
+ */
+ public static void SetUIViewPixelScale(final long uiView, final float contentScaleFactor) {
+ SetUIViewPixelScale0(uiView, contentScaleFactor);
+ }
+ /**
+ * Get the UIView's pixelScale / contentScale for HiDPI
+ *
+ * @param uiView the UIView instance
+ * @return used scale for HiDPI support: pixel-dim = window-dim x scale
+ */
+ public static float GetUIViewPixelScale(final long uiView) {
+ return GetUIViewPixelScale0(uiView);
+ }
+
+ /**
+ * Set root and sub CALayer pixelScale / contentScale for HiDPI
+ *
+ * @param rootCALayer the root surface layer, maybe null.
+ * @param subCALayer the client surface layer, maybe null.
+ * @param contentsScale scale for HiDPI support: pixel-dim = window-dim x scale
+ */
+ public static void SetCALayerPixelScale(final long rootCALayer, final long subCALayer, final float contentsScale) {
+ if( 0==rootCALayer && 0==subCALayer ) {
+ return;
+ }
+ SetCALayerPixelScale0(rootCALayer, subCALayer, contentsScale);
+ }
+ /**
+ * Get the CALayer's pixelScale / contentScale for HiDPI
+ *
+ * @param caLayer the CALayer instance
+ * @return used scale for HiDPI support: pixel-dim = window-dim x scale
+ */
+ public static float GetCALayerPixelScale(final long caLayer) {
+ return GetCALayerPixelScale0(caLayer);
+ }
+
+ /**
+ * Run on OSX UI main thread.
+ * <p>
+ * 'waitUntilDone' is implemented on Java site via lock/wait on {@link RunnableTask} to not freeze OSX main thread.
+ * </p>
+ *
+ * @param waitUntilDone
+ * @param kickNSApp if <code>true</code> issues {@link #KickUIApp()}
+ * @param runnable
+ */
+ public static void RunOnMainThread(final boolean waitUntilDone, final boolean kickNSApp, final Runnable runnable) {
+ if( IsMainThread0() ) {
+ runnable.run(); // don't leave the JVM
+ } else {
+ // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
+ // otherwise we may freeze the OSX main thread.
+ final Object sync = new Object();
+ final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err );
+ synchronized(sync) {
+ RunOnMainThread0(kickNSApp, rt);
+ if( waitUntilDone ) {
+ while( rt.isInQueue() ) {
+ try {
+ sync.wait();
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rt.getThrowable();
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Run later on ..
+ * @param onMain if true, run on main-thread, otherwise on the current OSX thread.
+ * @param runnable
+ * @param delay delay to run the runnable in milliseconds
+ */
+ public static void RunLater(final boolean onMain, final Runnable runnable, final int delay) {
+ RunLater0(onMain, false /* kickNSApp */, new RunnableTask( runnable, null, true, System.err ), delay);
+ }
+
+ private static Runnable _nop = new Runnable() { @Override public void run() {}; };
+
+ /** Issues a {@link #RunOnMainThread(boolean, boolean, Runnable)} w/ an <i>NOP</i> runnable, while waiting until done and issuing {@link #KickUIApp()}. */
+ public static void WaitUntilFinish() {
+ RunOnMainThread(true, true /* kickNSApp */, _nop);
+ }
+
+ /**
+ * Run on OSX UI main thread.
+ * <p>
+ * 'waitUntilDone' is implemented on Java site via lock/wait on {@link FunctionTask} to not freeze OSX main thread.
+ * </p>
+ *
+ * @param waitUntilDone
+ * @param kickUIApp if <code>true</code> issues {@link #KickUIApp()}
+ * @param func
+ */
+ public static <R,A> R RunOnMainThread(final boolean waitUntilDone, final boolean kickUIApp, final Function<R,A> func, final A... args) {
+ if( IsMainThread0() ) {
+ return func.eval(args); // don't leave the JVM
+ } else {
+ // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
+ // otherwise we may freeze the OSX main thread.
+ final Object sync = new Object();
+ final FunctionTask<R,A> rt = new FunctionTask<R,A>( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err );
+ synchronized(sync) {
+ rt.setArgs(args);
+ RunOnMainThread0(kickUIApp, rt);
+ if( waitUntilDone ) {
+ while( rt.isInQueue() ) {
+ try {
+ sync.wait();
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rt.getThrowable();
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ }
+ return rt.getResult();
+ }
+ }
+
+ public static boolean IsMainThread() {
+ return IsMainThread0();
+ }
+
+ /** Returns the screen refresh rate in Hz. If unavailable, returns 60Hz. */
+ public static int GetScreenRefreshRate(final int scrn_idx) {
+ return GetScreenRefreshRate0(scrn_idx);
+ }
+
+ public static void CreateGLViewDemoA() {
+ CreateGLViewDemoA0();
+ }
+
+ private static native boolean initIDs0();
+ private static native boolean isCALayer0(long object);
+ private static native boolean isCAEAGLLayer0(long object);
+ private static native boolean isUIView0(long object);
+ private static native boolean isUIWindow0(long object);
+ private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native Object GetInsets0(long windowOrView);
+ private static native double GetPixelScale1(int displayID);
+ private static native double GetPixelScale2(long windowOrView);
+ private static native long CreateUIWindow0(int x, int y, int width, int height);
+ private static native void DestroyUIWindow0(long uiWindow);
+ private static native long GetCALayer0(long uiView);
+ private static native long GetCAEAGLLayer0(long uiView);
+ private static native long GetUIView0(long uiWindow, boolean onlyEAGL);
+ private static native long GetUIWindow0(long uiView);
+ private static native void SetUIViewPixelScale0(final long uiView, final float contentScaleFactor);
+ private static native float GetUIViewPixelScale0(final long uiView);
+ private static native void SetCALayerPixelScale0(long rootCALayer, long subCALayer, float contentsScale);
+ private static native float GetCALayerPixelScale0(final long caLayer);
+
+ private static native void RunOnMainThread0(boolean kickNSApp, Runnable runnable);
+ private static native void RunLater0(boolean onMain, boolean kickNSApp, Runnable runnable, int delay);
+ private static native void KickUIApp0();
+ private static native boolean IsMainThread0();
+ private static native int GetScreenRefreshRate0(int scrn_idx);
+ private static native void CreateGLViewDemoA0();
+
+}
diff --git a/src/nativewindow/native/JVM_JNI8.c b/src/nativewindow/native/JVM_JNI8.c
new file mode 100644
index 000000000..a7b4e5d90
--- /dev/null
+++ b/src/nativewindow/native/JVM_JNI8.c
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include <stdio.h> //required by android to identify NULL
+#include <jni.h>
+
+#if defined (JNI_VERSION_1_8)
+
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_awt(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_x11(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_win32(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_macosx(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_ios(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_awt(JavaVM *vm, void *reserved) { }
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_x11(JavaVM *vm, void *reserved) { }
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_win32(JavaVM *vm, void *reserved) { }
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_macosx(JavaVM *vm, void *reserved) { }
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_ios(JavaVM *vm, void *reserved) { }
+
+#endif /* defined (JNI_VERSION_1_8) */
+
diff --git a/src/nativewindow/native/ios/CAEAGLLayered.h b/src/nativewindow/native/ios/CAEAGLLayered.h
new file mode 100644
index 000000000..fe94dc907
--- /dev/null
+++ b/src/nativewindow/native/ios/CAEAGLLayered.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#ifndef CAEAGL_LAYERED_H
+#define CAEAGL_LAYERED_H 1
+
+#import <UIKit/UIKit.h>
+#import <QuartzCore/QuartzCore.h>
+
+#include "NativewindowCommon.h"
+
+@interface CAEAGLUIView : UIView
+{
+}
+// override
++ (Class)layerClass;
+
++ (CAEAGLUIView*) findCAEAGLUIView: (UIWindow*) win
+ startIdx: (int) sidx;
+
++ (UIView*) getUIView: (UIWindow*) win
+ startIdx: (int) sidx;
+@end /* interface CAEAGLUIView */
+
+#endif
diff --git a/src/nativewindow/native/ios/CAEAGLLayered.m b/src/nativewindow/native/ios/CAEAGLLayered.m
new file mode 100644
index 000000000..3d378e997
--- /dev/null
+++ b/src/nativewindow/native/ios/CAEAGLLayered.m
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "CAEAGLLayered.h"
+
+@implementation CAEAGLUIView
+// override
++ (Class)layerClass {
+ return CAEAGLLayer.self;
+}
+/**
+override class var layerClass : AnyClass {
+ return CAEAGLLayer.self
+}
+*/
++ (CAEAGLUIView*) findCAEAGLUIView: (UIWindow*) win
+ startIdx: (int) sidx
+{
+ NSArray* subviews = [win subviews];
+ if(NULL != subviews) {
+ for(int i=sidx; i<[subviews count]; i++) {
+ UIView* sub = [subviews objectAtIndex: i];
+ if( [sub isKindOfClass:[CAEAGLUIView class]] ) {
+ return (CAEAGLUIView*)sub;
+ }
+ }
+ }
+ return (CAEAGLUIView*)NULL;
+}
++ (UIView*) getUIView: (UIWindow*) win
+ startIdx: (int) sidx
+{
+ NSArray* subviews = [win subviews];
+ if(NULL != subviews) {
+ if( sidx<[subviews count] ) {
+ return [subviews objectAtIndex: sidx];
+ }
+ }
+ return (UIView*)NULL;
+}
+@end /* implementation CAEAGLUIView */
diff --git a/src/nativewindow/native/ios/IOSmisc.m b/src/nativewindow/native/ios/IOSmisc.m
new file mode 100644
index 000000000..5826b9eef
--- /dev/null
+++ b/src/nativewindow/native/ios/IOSmisc.m
@@ -0,0 +1,813 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "CAEAGLLayered.h"
+
+#import "NativeWindowProtocols.h"
+
+#include "jogamp_nativewindow_ios_IOSUtil.h"
+
+// #define VERBOSE 1
+//
+#ifdef VERBOSE
+ // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+// #define VERBOSE2 1
+//
+#ifdef VERBOSE2
+ #define DBG_PRINT2(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT2(...)
+#endif
+
+// #define DBG_LIFECYCLE 1
+
+static const char * const ClazzNameRunnable = "java/lang/Runnable";
+static jmethodID runnableRunID = NULL;
+
+static const char * const ClazzAnyCstrName = "<init>";
+
+static const char * const ClazzNamePoint = "com/jogamp/nativewindow/util/Point";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
+static const char * const ClazzNameInsets = "com/jogamp/nativewindow/util/Insets";
+static const char * const ClazzNameInsetsCstrSignature = "(IIII)V";
+static jclass insetsClz = NULL;
+static jmethodID insetsCstr = NULL;
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_ios_IOSUtil_initIDs0(JNIEnv *env, jclass _unused) {
+ if( NativewindowCommon_init(env) ) {
+ jclass c;
+ c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+
+ c = (*env)->FindClass(env, ClazzNameInsets);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't find %s", ClazzNameInsets);
+ }
+ insetsClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==insetsClz) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't use %s", ClazzNameInsets);
+ }
+ insetsCstr = (*env)->GetMethodID(env, insetsClz, ClazzAnyCstrName, ClazzNameInsetsCstrSignature);
+ if(NULL==insetsCstr) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't fetch %s.%s %s",
+ ClazzNameInsets, ClazzAnyCstrName, ClazzNameInsetsCstrSignature);
+ }
+
+ c = (*env)->FindClass(env, ClazzNameRunnable);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't find %s", ClazzNameRunnable);
+ }
+ runnableRunID = (*env)->GetMethodID(env, c, "run", "()V");
+ if(NULL==runnableRunID) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_ios_IOSUtil_initIDs0: can't fetch %s.run()V", ClazzNameRunnable);
+ }
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_ios_IOSUtil_isCAEAGLLayer0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ jboolean u = [nsObj isKindOfClass:[CAEAGLLayer class]];
+ DBG_PRINT( "isEAGLCALayer(obj: %p): %s -> %d\n", nsObj, [[nsObj description] UTF8String], u);
+ return u;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_ios_IOSUtil_isCALayer0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ jboolean u = [nsObj isKindOfClass:[CALayer class]];
+ DBG_PRINT( "isCALayer(obj: %p): %s -> %d\n", nsObj, [[nsObj description] UTF8String], u);
+ return u;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_ios_IOSUtil_isUIView0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ jboolean u = [nsObj isKindOfClass:[UIView class]];
+ DBG_PRINT( "isUIView(obj: %p): %s -> %d\n", nsObj, [[nsObj description] UTF8String], u);
+ return u;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_ios_IOSUtil_isUIWindow0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ jboolean u = [nsObj isKindOfClass:[UIWindow class]];
+ DBG_PRINT( "isUIWindow(obj: %p): %s -> %d\n", nsObj, [[nsObj description] UTF8String], u);
+ return u;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: getLocationOnScreen0
+ * Signature: (JII)Lcom/jogamp/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetLocationOnScreen0
+ (JNIEnv *env, jclass unused, jlong winOrView, jint src_x, jint src_y)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ /**
+ * return location in 0/0 top-left space,
+ * OSX NSView is 0/0 bottom-left space naturally
+ * iOS UIView is 0/0 top-left space naturally
+ */
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
+ UIWindow* win = NULL;
+
+ if( [nsObj isKindOfClass:[UIWindow class]] ) {
+ win = (UIWindow*) nsObj;
+ } else if( nsObj != NULL && [nsObj isKindOfClass:[UIView class]] ) {
+ UIView* view = (UIView*) nsObj;
+ win = [view window];
+ if( NULL == win ) {
+ NativewindowCommon_throwNewRuntimeException(env, "view has null window, view %p\n", nsObj);
+ }
+ } else {
+ NativewindowCommon_throwNewRuntimeException(env, "neither win nor view %p\n", nsObj);
+ }
+ CGPoint p = CGPointMake(src_x, src_y);
+ UIScreen* screen = [win screen];
+ CGPoint pS = [win convertPoint: p toCoordinateSpace: screen.fixedCoordinateSpace];
+
+#ifdef VERBOSE_ON
+ CGRect winFrame = [self frame];
+ DBG_PRINT( "GetLocationOnScreen0(window: %p):: point-in[%d/%d], winFrame[%d/%d %dx%d] -> %d/%d\n",
+ win,
+ (int)p.x, (int)p.y,
+ (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height,
+ (int)pS.x, (int)pS.y);
+#endif
+
+ jobject res = (*env)->NewObject(env, pointClz, pointCstr, (jint)pS.x, (jint)pS.y);
+
+ [pool release];
+
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: getInsets0
+ * Signature: (J)Lcom/jogamp/nativewindow/util/Insets;
+ */
+JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetInsets0
+ (JNIEnv *env, jclass unused, jlong winOrView)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
+ UIWindow* win = NULL;
+ jint il,ir,it,ib;
+
+ if( [nsObj isKindOfClass:[UIWindow class]] ) {
+ win = (UIWindow*) nsObj;
+ } else if( nsObj != NULL && [nsObj isKindOfClass:[UIView class]] ) {
+ UIView* view = (UIView*) nsObj;
+ win = [view window];
+ if( NULL == win ) {
+ NativewindowCommon_throwNewRuntimeException(env, "view has null window, view %p\n", nsObj);
+ }
+ } else {
+ NativewindowCommon_throwNewRuntimeException(env, "neither win nor view %p\n", nsObj);
+ }
+
+ UIEdgeInsets uiInsets = [win safeAreaInsets];
+ il = uiInsets.left;
+ ir = uiInsets.right;
+ it = uiInsets.top;
+ ib = uiInsets.bottom;
+ /**
+ CGRect frameRect = [win frame];
+ CGRect contentRect = [win contentRectForFrameRect: frameRect];
+
+ // note: this is a simplistic implementation which doesn't take
+ // into account DPI and scaling factor
+ CGFloat l = contentRect.origin.x - frameRect.origin.x;
+ il = (jint)l; // l
+ ir = (jint)(frameRect.size.width - (contentRect.size.width + l)); // r
+ it = (jint)(frameRect.size.height - contentRect.size.height); // t
+ ib = (jint)(contentRect.origin.y - frameRect.origin.y); // b
+ */
+
+ jobject res = (*env)->NewObject(env, insetsClz, insetsCstr, il, ir, it, ib);
+
+ [pool release];
+
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetPixelScale1
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetPixelScale1
+ (JNIEnv *env, jclass unused, jint displayID)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ CGFloat pixelScale = 1.0; // default
+ // UIScreen *screen = IOSUtil_getUIScreenByCGDirectDisplayID((CGDirectDisplayID)displayID);
+ UIScreen *screen = [UIScreen mainScreen];
+ if( NULL != screen ) {
+NS_DURING
+ // Available >= 10.7
+ pixelScale = [screen scale]; // HiDPI scaling
+NS_HANDLER
+NS_ENDHANDLER
+ }
+ [pool release];
+
+ return (jdouble)pixelScale;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetPixelScale1
+ * Signature: (J)D
+ */
+JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetPixelScale2
+ (JNIEnv *env, jclass unused, jlong winOrView)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
+ UIScreen *screen = NULL;
+
+ if( [nsObj isKindOfClass:[UIWindow class]] ) {
+ UIWindow* win = (UIWindow*) nsObj;
+ screen = [win screen];
+ } else if( nsObj != NULL && [nsObj isKindOfClass:[UIView class]] ) {
+ UIView* view = (UIView*) nsObj;
+ UIWindow* win = [view window];
+ if( NULL == win ) {
+ NativewindowCommon_throwNewRuntimeException(env, "view has null window, view %p\n", nsObj);
+ }
+ screen = [win screen];
+ } else {
+ NativewindowCommon_throwNewRuntimeException(env, "neither win nor view %p\n", nsObj);
+ }
+
+ CGFloat pixelScale = 1.0; // default
+NS_DURING
+ // Available >= 10.7
+ pixelScale = [screen scale]; // HiDPI scaling
+NS_HANDLER
+NS_ENDHANDLER
+
+ [pool release];
+
+ return (jdouble)pixelScale;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: CreateUIWindow0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_ios_IOSUtil_CreateUIWindow0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [CATransaction begin];
+ CGRect boundsWin = CGRectMake(x, y, width, height);
+ CGRect boundsView = CGRectMake(0, 0, width, height);
+
+ // Allocate the window
+ UIWindow *myWindow = [[[[UIWindow alloc] initWithFrame:boundsWin] autorelease] retain];
+ myWindow.rootViewController = [[[UIViewController alloc] initWithNibName:nil bundle:nil] autorelease];
+ [myWindow setBackgroundColor: [UIColor redColor]];
+
+ // n/a iOS [myWindow setPreservesContentDuringLiveResize: YES];
+
+ // FIXME invisible .. (we keep it visible for testing)
+ // FIXME [myWindow setOpaque: NO];
+ // FIXME [myWindow setBackgroundColor: [UIColor clearColor]];
+ [myWindow makeKeyAndVisible];
+
+ CAEAGLUIView *uiView = [[CAEAGLUIView alloc] initWithFrame:boundsView];
+ CAEAGLLayer* l = (CAEAGLLayer*)[uiView layer];
+ [l setOpaque: YES];
+
+ [myWindow addSubview: uiView];
+
+ [CATransaction commit];
+ [pool release];
+ return (jlong) ((intptr_t) myWindow);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: DestroyUIWindow0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_DestroyUIWindow0
+ (JNIEnv *env, jclass unused, jlong nsWindow)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [CATransaction begin];
+
+NS_DURING
+ UIWindow* mWin = (UIWindow*) ((intptr_t) nsWindow);
+ [mWin resignKeyWindow];
+ [mWin setHidden: YES];
+ NSArray* subviews = [mWin subviews];
+ if(NULL != subviews) {
+ for(int i=0; i<[subviews count]; i++) {
+ UIView* sub = [subviews objectAtIndex: i];
+ [sub setHidden: YES];
+ [sub release];
+ }
+ }
+ [mWin release];
+NS_HANDLER
+ // On killing or terminating the process [UIWindow _close], rarely
+ // throws an NSRangeException while ordering out menu items
+NS_ENDHANDLER
+
+ [CATransaction commit];
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetCALayer0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetCALayer0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIView* uiView = (UIWindow*) ((intptr_t) view);
+
+ jlong res = (jlong) ((intptr_t) (CALayer *) [uiView layer]);
+
+ DBG_PRINT( "GetCALayer(view: %p): %p\n", uiView, (void*) (intptr_t) res);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetCAEAGLLayer0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetCAEAGLLayer0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIView* uiView = (UIWindow*) ((intptr_t) view);
+
+ CALayer* l = [uiView layer];
+ jboolean isRes = [l isKindOfClass:[CAEAGLLayer class]];
+ jlong res = isRes ? (jlong) ((intptr_t) l) : 0;
+
+ DBG_PRINT( "GetCAEAGLLayer(view: %p): CALayer %p, CAEAGLLayer %p (%d)\n", uiView, l, (void*) (intptr_t) res, isRes);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetUIView0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetUIView0
+ (JNIEnv *env, jclass unused, jlong window, jboolean onlyCAEAGLUIView)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIWindow* win = (UIWindow*) ((intptr_t) window);
+ jlong res;
+
+ if( onlyCAEAGLUIView ) {
+ CAEAGLUIView* v0 = [CAEAGLUIView findCAEAGLUIView: win
+ startIdx: 0];
+ res = (jlong) ((intptr_t) v0);
+ } else {
+ UIView* v0 = [CAEAGLUIView getUIView: win startIdx: 0];
+ res = (jlong) ((intptr_t) v0);
+ }
+
+ DBG_PRINT( "GetUIView(window: %p): %p\n", win, (void*) (intptr_t) res);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetUIWindow0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetUIWindow0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIView* v = (UIView*) ((intptr_t) view);
+
+ jlong res = (jlong) ((intptr_t) [v window]);
+
+ DBG_PRINT( "GetUIWindow(view: %p): %p\n", v, (void*) (intptr_t) res);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: SetUIViewPixelScale0
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_SetUIViewPixelScale0
+ (JNIEnv *env, jclass unused, jlong view, jfloat contentScale)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIView* v = (UIView*) ((intptr_t) view);
+
+NS_DURING
+ if( NULL != v ) {
+ [v setContentScaleFactor: (CGFloat)contentScale];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+
+ [pool release];
+}
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetUIViewPixelScale0
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetUIViewPixelScale0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ UIView* v = (UIView*) ((intptr_t) view);
+ jfloat r = 0.0f;
+
+NS_DURING
+ if( NULL != v ) {
+ r = [v contentScaleFactor];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+
+ [pool release];
+ return r;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: SetCALayerPixelScale0
+ * Signature: (JJF)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_SetCALayerPixelScale0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jfloat contentsScale)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+NS_DURING
+ if( NULL != rootLayer ) {
+ [rootLayer setContentsScale: (CGFloat)contentsScale];
+ }
+ if( NULL != subLayer ) {
+ [subLayer setContentsScale: (CGFloat)contentsScale];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+
+ [CATransaction commit];
+
+ [pool release];
+}
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: GetCALayerPixelScale0
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_jogamp_nativewindow_ios_IOSUtil_GetCALayerPixelScale0
+ (JNIEnv *env, jclass unused, jlong caLayer)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ CALayer* v = (CALayer*) ((intptr_t) caLayer);
+ jfloat r = 0.0f;
+
+NS_DURING
+ if( NULL != v ) {
+ r = [v contentsScale];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+
+ [pool release];
+ return r;
+}
+
+@interface MainRunnable : NSObject
+
+{
+ jobject runnableObj;
+}
+
+- (id) initWithRunnable: (jobject)runnable;
+- (void) jRun;
+
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+- (void)dealloc;
+#endif
+
+
+@end
+
+@implementation MainRunnable
+
+- (id) initWithRunnable: (jobject)runnable
+{
+ runnableObj = runnable;
+ return [super init];
+}
+
+- (void) jRun
+{
+ int shallBeDetached = 0;
+ JNIEnv* env = NativewindowCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+ DBG_PRINT2("MainRunnable.1 env: %d\n", (int)(NULL!=env));
+ if(NULL!=env) {
+ DBG_PRINT2("MainRunnable.1.0\n");
+ (*env)->CallVoidMethod(env, runnableObj, runnableRunID);
+ DBG_PRINT2("MainRunnable.1.1\n");
+ (*env)->DeleteGlobalRef(env, runnableObj);
+
+ DBG_PRINT2("MainRunnable.1.3\n");
+ // detaching thread not required - daemon
+ // NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
+ }
+ DBG_PRINT2("MainRunnable.X\n");
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT2("MainRunnable::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ id o = [super retain];
+ DBG_PRINT2("MainRunnable::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT2("MainRunnable::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super release];
+ // DBG_PRINT2("MainRunnable::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT2("MainRunnable::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super dealloc];
+ // DBG_PRINT2("MainRunnable.dealloc.X: %p\n", self);
+}
+
+#endif
+
+@end
+
+// #define UIApp [UIApplication sharedApplication]
+// #define NSApp [NSApplication sharedApplication]
+
+static void RunOnThread (JNIEnv *env, jobject runnable, BOOL onMain, jint delayInMS)
+{
+ BOOL isMainThread = [NSThread isMainThread];
+ BOOL forkOnMain = onMain && ( NO == isMainThread || 0 < delayInMS );
+ // UIApplication * UIApp = [UIApplication sharedApplication];
+
+ DBG_PRINT2( "RunOnThread0: forkOnMain %d [onMain %d, delay %dms, isMainThread %d], UIApp %d, UIApp-isRunning %d\n",
+ (int)forkOnMain, (int)onMain, (int)delayInMS, (int)isMainThread, (int)(NULL!=UIApp), (int)([UIApp applicationState]));
+
+ if ( forkOnMain ) {
+ jobject runnableObj = (*env)->NewGlobalRef(env, runnable);
+
+ DBG_PRINT2( "RunOnThread.1.0\n");
+ MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj];
+
+ if( onMain ) {
+ [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:NO];
+ } else {
+ NSTimeInterval delay = (double)delayInMS/1000.0;
+ [mr performSelector:@selector(jRun) withObject:nil afterDelay:delay];
+ }
+ DBG_PRINT2( "RunOnThread.1.1\n");
+
+ [mr release];
+ DBG_PRINT2( "RunOnThread.1.2\n");
+
+ } else {
+ DBG_PRINT2( "RunOnThread.2\n");
+ (*env)->CallVoidMethod(env, runnable, runnableRunID);
+ }
+ DBG_PRINT2( "RunOnThread.X\n");
+}
+
+static void IOSUtil_KickUIApp() {
+ // UIApplication * UIApp = [UIApplication sharedApplication];
+ /*** iOS-FIXME: UIEvent creation and post n/a !!!
+ UIEvent* event = [UIEvent otherEventWithType: UIApplicationDefined
+ location: NSMakePoint(0,0)
+ modifierFlags: 0
+ timestamp: 0.0
+ windowNumber: 0
+ context: nil
+ subtype: 0
+ data1: 0
+ data2: 0];
+ [UIApp postEvent: event atStart: true];
+ */
+}
+
+/**
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: RunOnMainThread0
+ * Signature: (ZLjava/lang/Runnable;)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_RunOnMainThread0
+ (JNIEnv *env, jclass unused, jboolean kickUIApp, jobject runnable)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ RunOnThread (env, runnable, YES, 0);
+ if( kickUIApp ) {
+ IOSUtil_KickUIApp();
+ }
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: RunLater0
+ * Signature: (ZZLjava/lang/Runnable;I)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_RunLater0
+ (JNIEnv *env, jclass unused, jboolean onMain, jboolean kickUIApp, jobject runnable, jint delay)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ RunOnThread (env, runnable, onMain ? YES : NO, delay);
+ if( kickUIApp ) {
+ IOSUtil_KickUIApp();
+ }
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_ios_IOSUtil
+ * Method: IsMainThread0
+ * Signature: (V)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_ios_IOSUtil_IsMainThread0
+ (JNIEnv *env, jclass unused)
+{
+ return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
+}
+
+#define EAGL_TEST 1
+
+#ifdef EAGL_TEST
+#include <OpenGLES/ES2/gl.h>
+#include <OpenGLES/ES2/glext.h>
+
+@interface GLView : UIView
+{
+ CAEAGLLayer *glLayer;
+ EAGLContext *glContext;
+ GLuint renderbuffer;
+}
+@end
+@implementation GLView
++ (Class)layerClass
+{
+ return [CAEAGLLayer class];
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if (self = [super initWithFrame:frame]) {
+ [self initGL];
+ [self render];
+ }
+
+ return self;
+}
+
+- (void)render
+{
+ glClearColor(150.0/255.0, 200.0/255.0, 255.0/255.0, 1.0);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ [glContext presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+- (void)initGL
+{
+ glLayer = (CAEAGLLayer *)self.layer;
+ glLayer.opaque = YES;
+
+ glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ if (!glContext) {
+ NSLog(@"Unable to create EAGLContext");
+ exit(1);
+ }
+ if (![EAGLContext setCurrentContext:glContext]) {
+ NSLog(@"Unable to set current EAGLContext");
+ exit(1);
+ }
+ glGenRenderbuffers(1, &renderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+ [glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:glLayer];
+
+ GLuint framebuffer;
+ glGenFramebuffers(1, &framebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
+}
+@end
+#endif /* EAGL_TEST */
+
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_ios_IOSUtil_CreateGLViewDemoA0
+ (JNIEnv *env, jclass unused)
+{
+#ifdef EAGL_TEST
+ CGRect boundsW2 = CGRectMake(500, 10, 320, 320);
+ CGRect boundsV2 = CGRectMake(0, 0, 320, 320);
+ UIWindow* window2 = [[[[UIWindow alloc] initWithFrame:boundsW2] autorelease] retain];
+ window2.rootViewController = [[[UIViewController alloc] initWithNibName:nil bundle:nil] autorelease];
+ [window2 setBackgroundColor: [UIColor redColor]];
+ [window2 makeKeyAndVisible];
+
+ GLView *glView = [[GLView alloc] initWithFrame:boundsV2];
+ [window2 addSubview:glView];
+#endif /* EAGL_TEST */
+}
+
diff --git a/src/nativewindow/native/ios/NativeWindowProtocols.h b/src/nativewindow/native/ios/NativeWindowProtocols.h
new file mode 100644
index 000000000..b27afc70d
--- /dev/null
+++ b/src/nativewindow/native/ios/NativeWindowProtocols.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#ifndef NATIVEWINDOWPROTOCOLS_H
+#define NATIVEWINDOWPROTOCOLS_H 1
+
+/**
+ * CALayer size needs to be set using the AWT component size.
+ * See detailed description in JAWTUtil.java and sync w/ changed.
+ */
+#define NW_DEDICATEDFRAME_QUIRK_SIZE ( 1 << 0 )
+
+/**
+ * CALayer position needs to be set to zero.
+ * See detailed description in JAWTUtil.java and sync w/ changed.
+ */
+#define NW_DEDICATEDFRAME_QUIRK_POSITION ( 1 << 1 )
+
+/**
+ * CALayer position needs to be derived from AWT position.
+ * in relation to super CALayer.
+ * See detailed description in JAWTUtil.java and sync w/ changed.
+ */
+#define NW_DEDICATEDFRAME_QUIRK_LAYOUT ( 1 << 2 )
+
+// n/a iOS #import <Foundation/NSGeometry.h>
+#import <UIKit/UIGeometry.h>
+
+@protocol NWDedicatedFrame
+- (void)setDedicatedFrame:(CGRect)dFrame quirks:(int)quirks;
+@end
+
+#endif /* NATIVEWINDOWPROTOCOLS_H_ */
+
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index c04ba786e..fb15c43b9 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -81,41 +81,41 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
jclass c;
c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't find %s", ClazzNamePoint);
}
pointClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==pointClz) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't use %s", ClazzNamePoint);
}
pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
if(NULL==pointCstr) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s",
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't fetch %s.%s %s",
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
c = (*env)->FindClass(env, ClazzNameInsets);
if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNameInsets);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't find %s", ClazzNameInsets);
}
insetsClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==insetsClz) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNameInsets);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't use %s", ClazzNameInsets);
}
insetsCstr = (*env)->GetMethodID(env, insetsClz, ClazzAnyCstrName, ClazzNameInsetsCstrSignature);
if(NULL==insetsCstr) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s",
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't fetch %s.%s %s",
ClazzNameInsets, ClazzAnyCstrName, ClazzNameInsetsCstrSignature);
}
c = (*env)->FindClass(env, ClazzNameRunnable);
if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNameRunnable);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't find %s", ClazzNameRunnable);
}
runnableRunID = (*env)->GetMethodID(env, c, "run", "()V");
if(NULL==runnableRunID) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.run()V", ClazzNameRunnable);
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0: can't fetch %s.run()V", ClazzNameRunnable);
}
}
return JNI_TRUE;