aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-jogl.xml5
-rw-r--r--make/build-nativewindow.xml13
-rw-r--r--make/build-newt.xml2
-rw-r--r--make/config/jogl/cgl-macosx.cfg7
-rw-r--r--make/config/jogl/gl-impl-CustomJavaCode-common.java5
-rw-r--r--make/config/nativewindow/jawt-CustomJavaCode.java57
-rw-r--r--make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java37
-rw-r--r--make/config/nativewindow/jawt-common.cfg2
-rw-r--r--make/config/nativewindow/jawt-macosx.cfg5
-rwxr-xr-xmake/scripts/tests-x64.bat6
-rwxr-xr-xmake/scripts/tests.sh12
-rw-r--r--make/stub_includes/jni/macosx/jawt_md.h20
-rw-r--r--make/stub_includes/macosx/AppKit/NSOpenGL.h3
-rw-r--r--make/stub_includes/macosx/AppKit/NSOpenGLLayer.h1
-rw-r--r--make/stub_includes/macosx/AppKit/NSOpenGLView.h1
-rw-r--r--make/stub_includes/macosx/OpenGL/CGLDevice.h2
-rw-r--r--make/stub_includes/macosx/OpenGL/OpenGL.h31
-rw-r--r--make/stub_includes/macosx/QuartzCore/CALayer.h1
-rw-r--r--make/stub_includes/opengl/macosx-window-system.h70
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java24
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java13
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java4
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java11
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java49
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java14
-rw-r--r--src/jogl/classes/jogamp/graph/curve/text/GlyphString.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/FPSCounterImpl.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java69
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/SharedResourceRunner.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java20
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java40
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java133
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java41
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java133
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java15
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java17
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java30
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java27
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java133
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java47
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java37
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java29
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java22
-rw-r--r--src/jogl/native/macosx/ContextUpdater.h6
-rw-r--r--src/jogl/native/macosx/ContextUpdater.m57
-rw-r--r--src/jogl/native/macosx/MacOSXCustomCGLCode.c5
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m140
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m466
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.h20
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m235
-rw-r--r--src/jogl/native/timespec.c63
-rw-r--r--src/jogl/native/timespec.h19
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java17
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java18
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java3
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java48
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java51
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java22
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java8
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java35
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java5
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java85
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java61
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java273
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java228
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java28
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java27
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java18
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java46
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java10
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m220
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java46
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java76
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java322
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java89
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java44
-rw-r--r--src/newt/classes/com/jogamp/newt/event/InputEvent.java5
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java29
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java28
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java7
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java319
-rw-r--r--src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java (renamed from src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java)37
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/DriverClearFocus.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java262
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java327
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java31
-rw-r--r--src/newt/native/MacWindow.m56
-rw-r--r--src/newt/native/NewtMacWindow.h5
-rw-r--r--src/newt/native/NewtMacWindow.m40
-rw-r--r--src/newt/native/WindowsWindow.c33
-rw-r--r--src/newt/native/X11Window.c133
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java15
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java70
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java334
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java225
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java23
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java71
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java1
-rw-r--r--src/test/jogamp/newt/WindowImplAccess.java16
153 files changed, 4741 insertions, 1648 deletions
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 58e018024..511f147be 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -1130,6 +1130,8 @@
<linker id="linker.cfg.macosx.jogl" extends="linker.cfg.macosx">
<linkerarg value="-framework" />
+ <linkerarg value="QuartzCore" />
+ <linkerarg value="-framework" />
<linkerarg value="Cocoa" />
<linkerarg value="-framework" />
<linkerarg value="OpenGL" />
@@ -1276,8 +1278,10 @@
<patternset id="c.src.files.jogl.desktop">
<include name="${rootrel.src.c}/JoglCommon.c"/>
<include name="${rootrel.src.c}/GLDebugMessageHandler.c"/>
+ <include name="${rootrel.src.c}/timespec.c" if="isOSX"/> <!-- currently only used for OSX -->
<include name="${rootrel.src.c}/macosx/MacOSXCustomCGLCode.c" if="isOSX"/>
<include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface.m" if="isOSX"/>
+ <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface-pbuffer.m" if="isOSX"/>
<include name="${rootrel.src.c}/macosx/ContextUpdater.m" if="isOSX"/>
<include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/>
<!-- FIXME: the Mixer should be moved to another library -->
@@ -1349,6 +1353,7 @@
<includepath path="stub_includes/cg" if="setup.addNativeNVidiaCG"/>
<!-- This is for the generated headers for handwritten C code -->
+ <includepath path="${src.c}"/>
<includepath path="${src.generated.c}" />
<includepath path="${src.generated.c}/X11" if="isX11"/>
<includepath path="${src.generated.c}/MacOSX" if="isOSX"/>
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index 4bbe667b8..9d0dff406 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -354,6 +354,10 @@
<compilerarg value="-I/usr/X11R6/include" />
</compiler>
+ <compiler id="compiler.cfg.macosx.nativewindow" extends="compiler.cfg.macosx">
+ <compilerarg value="-I${java.osx.frameworks.dir}/JavaNativeFoundation.framework/Headers" />
+ </compiler>
+
<!-- linker configuration -->
<linker id="linker.cfg.freebsd.nativewindow.x11" extends="linker.cfg.freebsd">
@@ -443,7 +447,13 @@
<linker id="linker.cfg.macosx.nativewindow" extends="linker.cfg.macosx">
<linkerarg value="-framework" />
+ <linkerarg value="QuartzCore" />
+ <linkerarg value="-framework" />
<linkerarg value="Cocoa" />
+ <linkerarg value="-framework" />
+ <linkerarg value="JavaNativeFoundation" />
+ <linkerarg value="-F" />
+ <linkerarg value="${java.osx.frameworks.dir}" />
</linker>
<linker id="linker.cfg.hpux.nativewindow" extends="linker.cfg.hpux">
@@ -547,7 +557,7 @@
<target name="c.configure.x11" if="isX11" />
<target name="c.configure.macosx" if="isOSX">
- <property name="compiler.cfg.id" value="compiler.cfg.macosx" />
+ <property name="compiler.cfg.id" value="compiler.cfg.macosx.nativewindow" />
<property name="linker.cfg.id.oswin" value="linker.cfg.macosx.nativewindow" />
</target>
@@ -734,6 +744,7 @@
<target name="c.build.nativewindow.windowlib.macosx" if="isOSX">
<javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.nativewindow.macosx.OSXUtil" />
+ <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow" />
<c.build c.compiler.src.files="c.src.files.macosx"
output.lib.name="nativewindow_macosx"
diff --git a/make/build-newt.xml b/make/build-newt.xml
index d3248fa9d..56ebfaccc 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -96,7 +96,7 @@
<!-- partitioning -->
<property name="java.part.core"
- value="com/jogamp/newt/* com/jogamp/newt/event/* com/jogamp/newt/util/* jogamp/newt/* jogamp/newt/event/*"/>
+ value="com/jogamp/newt/* com/jogamp/newt/event/* com/jogamp/newt/util/* jogamp/newt/* jogamp/newt/event/* jogamp/newt/driver/*"/>
<property name="java.part.opengl"
value="com/jogamp/newt/opengl/**"/>
diff --git a/make/config/jogl/cgl-macosx.cfg b/make/config/jogl/cgl-macosx.cfg
index 06bc94626..7d17c4aff 100644
--- a/make/config/jogl/cgl-macosx.cfg
+++ b/make/config/jogl/cgl-macosx.cfg
@@ -20,6 +20,13 @@ Opaque long CGLShareGroupObj
Opaque long CGLPBufferObj
Opaque long CGLPixelFormatObj
+Opaque long NSOpenGLPixelFormat *
+Opaque long NSOpenGLContext *
+Opaque long NSView *
+Opaque long NSOpenGLView *
+Opaque long NSOpenGLPixelBuffer *
+Opaque long NSOpenGLLayer *
+
CustomCCode #include </usr/include/machine/types.h>
CustomCCode #include "macosx-window-system.h"
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index 0a8e90171..0878bd236 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -35,6 +35,11 @@
return _context.isExtensionAvailable(glExtensionName);
}
+ public boolean isNPOTTextureAvailable() {
+ return isGL3() || isGLES2() || isExtensionAvailable(GL_ARB_texture_non_power_of_two);
+ }
+ private static final String GL_ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two";
+
public Object getExtension(String extensionName) {
// At this point we don't expose any extensions using this mechanism
return null;
diff --git a/make/config/nativewindow/jawt-CustomJavaCode.java b/make/config/nativewindow/jawt-CustomJavaCode.java
index 3223a74b1..d3dc3845f 100644
--- a/make/config/nativewindow/jawt-CustomJavaCode.java
+++ b/make/config/nativewindow/jawt-CustomJavaCode.java
@@ -1,27 +1,38 @@
-private static volatile JAWT jawt;
+/** Available and recommended on Mac OS X >= 10.6 Update 4 */
+public static final int JAWT_MACOSX_USE_CALAYER = 0x80000000;
+public static final VersionNumber JAWT_MacOSXCALayerMinVersion = new VersionNumber(10,6,4);
+
+private int jawt_version_cached = 0;
+
+public final int getCachedVersion() {
+ return jawt_version_cached;
+}
/** Helper routine for all users to call to access the JAWT. */
-public static JAWT getJAWT() {
- if (jawt == null) {
- synchronized (JAWT.class) {
- if (jawt == null) {
- JAWTUtil.initSingleton();
- // Workaround for 4845371.
- // Make sure the first reference to the JNI GetDirectBufferAddress is done
- // from a privileged context so the VM's internal class lookups will succeed.
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- JAWT j = JAWT.create();
- j.setVersion(JAWTFactory.JAWT_VERSION_1_4);
- if (!JAWTFactory.JAWT_GetAWT(j)) {
- throw new RuntimeException("Unable to initialize JAWT");
+public static JAWT getJAWT(final int jawt_version_flags) {
+ JAWTUtil.initSingleton();
+ // Workaround for 4845371.
+ // Make sure the first reference to the JNI GetDirectBufferAddress is done
+ // from a privileged context so the VM's internal class lookups will succeed.
+ return AccessController.doPrivileged(new PrivilegedAction<JAWT>() {
+ public JAWT run() {
+ int jawt_version_flags_mod = jawt_version_flags;
+ JAWT jawt = JAWT.create();
+ if( 0 != ( jawt_version_flags_mod & JAWT_MACOSX_USE_CALAYER ) ) {
+ jawt.setVersion(jawt_version_flags_mod);
+ if (JAWTFactory.JAWT_GetAWT(jawt)) {
+ jawt.jawt_version_cached = jawt.getVersion();
+ return jawt;
}
- jawt = j;
- return null;
- }
- });
- }
- }
- }
- return jawt;
+ jawt_version_flags_mod &= ~JAWT_MACOSX_USE_CALAYER;
+ System.err.println("MacOSX "+Platform.OS_VERSION_NUMBER+" >= "+JAWT_MacOSXCALayerMinVersion+": Failed to use JAWT_MACOSX_USE_CALAYER");
+ }
+ jawt.setVersion(jawt_version_flags_mod);
+ if (!JAWTFactory.JAWT_GetAWT(jawt)) {
+ throw new RuntimeException("Unable to initialize JAWT: 0x"+Integer.toHexString(jawt_version_flags_mod));
+ }
+ jawt.jawt_version_cached = jawt.getVersion();
+ return jawt;
+ }
+ });
}
diff --git a/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java b/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java
index 598ced346..4ff3a45b0 100644
--- a/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java
+++ b/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java
@@ -1,30 +1,29 @@
-public JAWT_PlatformInfo platformInfo() {
- return newPlatformInfo(platformInfo0(getBuffer()));
+public JAWT_PlatformInfo platformInfo(final JAWT jawt) {
+ return newPlatformInfo(jawt, platformInfo0(getBuffer()));
}
private native ByteBuffer platformInfo0(Buffer jthis0);
private static java.lang.reflect.Method platformInfoFactoryMethod;
-private static JAWT_PlatformInfo newPlatformInfo(ByteBuffer buf) {
+private static JAWT_PlatformInfo newPlatformInfo(JAWT jawt, ByteBuffer buf) {
if (platformInfoFactoryMethod == null) {
- String osName = (String) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- return System.getProperty("os.name").toLowerCase();
- }
- });
try {
- Class factoryClass;
- if (osName.startsWith("wind")) {
- factoryClass = Class.forName("jogamp.nativewindow.jawt.windows.JAWT_Win32DrawingSurfaceInfo");
- } else if (osName.startsWith("mac os x")) {
- factoryClass = Class.forName("jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo");
- } else {
- // Assume Linux, Solaris, etc. Should probably test for these explicitly.
- factoryClass = Class.forName("jogamp.nativewindow.jawt.x11.JAWT_X11DrawingSurfaceInfo");
- }
- platformInfoFactoryMethod = factoryClass.getMethod("create",
- new Class[] { ByteBuffer.class });
+ Class<?> factoryClass;
+ if (Platform.OS_TYPE == Platform.OSType.WINDOWS) {
+ factoryClass = Class.forName("jogamp.nativewindow.jawt.windows.JAWT_Win32DrawingSurfaceInfo");
+ } else if (Platform.OS_TYPE == Platform.OSType.MACOS) {
+ if( 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER ) ) {
+ factoryClass = Class.forName("jogamp.nativewindow.jawt.macosx.JAWT_SurfaceLayers");
+ } else {
+ factoryClass = Class.forName("jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo");
+ }
+ } else {
+ // Assume Linux, Solaris, etc. Should probably test for these explicitly.
+ factoryClass = Class.forName("jogamp.nativewindow.jawt.x11.JAWT_X11DrawingSurfaceInfo");
+ }
+ platformInfoFactoryMethod = factoryClass.getMethod("create",
+ new Class[] { ByteBuffer.class });
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/make/config/nativewindow/jawt-common.cfg b/make/config/nativewindow/jawt-common.cfg
index d633c47d6..55f3f368b 100644
--- a/make/config/nativewindow/jawt-common.cfg
+++ b/make/config/nativewindow/jawt-common.cfg
@@ -22,5 +22,7 @@ CustomCCode #include <jawt.h>
import java.security.*
import jogamp.nativewindow.jawt.*
+import com.jogamp.common.os.Platform
+import com.jogamp.common.util.VersionNumber
IncludeAs CustomJavaCode JAWT_DrawingSurfaceInfo jawt-DrawingSurfaceInfo-CustomJavaCode.java
diff --git a/make/config/nativewindow/jawt-macosx.cfg b/make/config/nativewindow/jawt-macosx.cfg
index c41367f4a..20260f693 100644
--- a/make/config/nativewindow/jawt-macosx.cfg
+++ b/make/config/nativewindow/jawt-macosx.cfg
@@ -5,6 +5,7 @@ NativeOutputDir gensrc/native/MacOSX
Opaque long void *
Opaque long NSView *
+Opaque long CALayer *
CustomCCode #include <inttypes.h>
CustomCCode #include </usr/include/machine/types.h>
@@ -12,3 +13,7 @@ CustomCCode #include </usr/include/machine/types.h>
StructPackage JAWT_MacOSXDrawingSurfaceInfo jogamp.nativewindow.jawt.macosx
EmitStruct JAWT_MacOSXDrawingSurfaceInfo
Implements JAWT_MacOSXDrawingSurfaceInfo JAWT_PlatformInfo
+
+StructPackage JAWT_SurfaceLayers jogamp.nativewindow.jawt.macosx
+EmitStruct JAWT_SurfaceLayers
+Implements JAWT_SurfaceLayers JAWT_PlatformInfo
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index b45b49e89..d8bf861e0 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -12,7 +12,7 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLPro
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %1 %2 %3 %4 %5 %6
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %1 %2 %3
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %1 %2 %3 %4 %5 %6
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %1 %2 %3 %4 %5 %6
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01
@@ -30,10 +30,12 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NE
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot %1 %2 %3 %4 %5 %6
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot %1 %2 %3 %4 %5 %6
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT -time 100000
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT %1 %2 %3
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT %1 %2 %3
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03bAWT -time 100000
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index cbea43cc9..4fc859829 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -49,7 +49,7 @@ function jrun() {
shift
#D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
- D_ARGS="-Dnativewindow.debug=all"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.ExtensionAvailabilityCache"
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable"
@@ -75,7 +75,7 @@ function jrun() {
#D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.GLContext"
#D_ARGS="-Dnewt.debug.Window -Djogl.debug.Animator -Dnewt.debug.Screen"
- #D_ARGS="-Dnewt.debug.Window"
+ D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.KeyEvent"
#D_ARGS="-Dnewt.debug.Window.MouseEvent"
#D_ARGS="-Xprof"
#D_ARGS="-Djogl.debug.Animator"
@@ -223,13 +223,16 @@ function testswt() {
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper
#testawt com.jogamp.opengl.test.junit.newt.TestEventSourceNotAWTBug
#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
-#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot
+#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
#testawt com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cSwingAWT $*
-testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02AWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT $*
+testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleAWT $*
@@ -273,6 +276,7 @@ testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT $*
#
# regressions
#
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT $*
$spath/count-edt-start.sh java-run.log
diff --git a/make/stub_includes/jni/macosx/jawt_md.h b/make/stub_includes/jni/macosx/jawt_md.h
index aca47f66e..3a371af0d 100644
--- a/make/stub_includes/jni/macosx/jawt_md.h
+++ b/make/stub_includes/jni/macosx/jawt_md.h
@@ -9,17 +9,35 @@
#include <jawt.h>
#include <AppKit/NSView.h>
+#include <QuartzCore/CALayer.h>
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * JAWT_DrawingSurfaceInfo.getPlatformInfo()
+ *
+ * Only if not JAWT_SurfaceLayers, see below!
+ */
typedef struct JAWT_MacOSXDrawingSurfaceInfo
{
- NSView *cocoaViewRef; // the view is guaranteed to be valid only for the duration of Component.paint method
+ /** the view is guaranteed to be valid only for the duration of Component.paint method */
+ NSView *cocoaViewRef;
}
JAWT_MacOSXDrawingSurfaceInfo;
+/**
+ * JAWT_DrawingSurfaceInfo.getPlatformInfo()
+ *
+ * >= 10.6.4 if JAWT_MACOSX_USE_CALAYER is set in JAWT version
+ */
+typedef struct JAWT_SurfaceLayers
+{
+ CALayer *layer;
+}
+JAWT_SurfaceLayers;
+
#ifdef __cplusplus
}
#endif
diff --git a/make/stub_includes/macosx/AppKit/NSOpenGL.h b/make/stub_includes/macosx/AppKit/NSOpenGL.h
new file mode 100644
index 000000000..1b7656dc1
--- /dev/null
+++ b/make/stub_includes/macosx/AppKit/NSOpenGL.h
@@ -0,0 +1,3 @@
+typedef struct _NSOpenGLPixelFormat NSOpenGLPixelFormat;
+typedef struct _NSOpenGLContext NSOpenGLContext;
+typedef struct _NSOpenGLPixelBuffer NSOpenGLPixelBuffer;
diff --git a/make/stub_includes/macosx/AppKit/NSOpenGLLayer.h b/make/stub_includes/macosx/AppKit/NSOpenGLLayer.h
new file mode 100644
index 000000000..2e5e81a68
--- /dev/null
+++ b/make/stub_includes/macosx/AppKit/NSOpenGLLayer.h
@@ -0,0 +1 @@
+typedef struct _NSOpenGLLayer NSOpenGLLayer;
diff --git a/make/stub_includes/macosx/AppKit/NSOpenGLView.h b/make/stub_includes/macosx/AppKit/NSOpenGLView.h
new file mode 100644
index 000000000..6492287df
--- /dev/null
+++ b/make/stub_includes/macosx/AppKit/NSOpenGLView.h
@@ -0,0 +1 @@
+typedef struct _NSOpenGLView NSOpenGLView;
diff --git a/make/stub_includes/macosx/OpenGL/CGLDevice.h b/make/stub_includes/macosx/OpenGL/CGLDevice.h
new file mode 100644
index 000000000..1d4170975
--- /dev/null
+++ b/make/stub_includes/macosx/OpenGL/CGLDevice.h
@@ -0,0 +1,2 @@
+typedef struct _cglShareGroupObj* CGLShareGroupObj;
+
diff --git a/make/stub_includes/macosx/OpenGL/OpenGL.h b/make/stub_includes/macosx/OpenGL/OpenGL.h
index 1a3ddf203..33cfa46b6 100644
--- a/make/stub_includes/macosx/OpenGL/OpenGL.h
+++ b/make/stub_includes/macosx/OpenGL/OpenGL.h
@@ -2,10 +2,13 @@
OpenGL.h to expose portions of the low-level CGL API to Java */
/* Typedefs to get things working */
-typedef struct _cglObj* CGLContextObj;
-typedef struct _cglObj* CGLShareGroupObj;
-typedef struct _cglObj* CGLPBufferObj;
-typedef struct _cglObj* CGLPixelFormatObj;
+typedef struct _cglContextObj* CGLContextObj;
+typedef struct _cglPBufferObj* CGLPBufferObj;
+typedef struct _cglPixelFormatObj* CGLPixelFormatObj;
+
+typedef int GLint; /* 4-byte signed */
+typedef unsigned int GLenum;
+typedef int GLsizei; /* 4-byte signed */
/*
** Attribute names for CGLChoosePixelFormat and CGLDescribePixelFormat.
@@ -105,7 +108,7 @@ typedef enum _CGLContextParameter {
/* Pixel format manipulation */
CGLError CGLChoosePixelFormat(const CGLPixelFormatAttribute *attribs,
CGLPixelFormatObj *pix,
- long *npix);
+ GLint *npix);
CGLError CGLDestroyPixelFormat(CGLPixelFormatObj pix);
CGLPixelFormatObj CGLGetPixelFormat ( CGLContextObj ctx );
@@ -123,16 +126,16 @@ CGLError CGLCopyContext ( CGLContextObj src, CGLContextObj dst, int mask );
CGLShareGroupObj CGLGetShareGroup(CGLContextObj ctx);
-/* PBuffer manipulation */
-CGLError CGLCreatePBuffer(long width,
- long height,
- unsigned long target,
- unsigned long internalFormat,
- long max_level,
+/* PBuffer manipulation (deprecated in 10.7) */
+CGLError CGLCreatePBuffer(GLsizei width,
+ GLsizei height,
+ GLenum target,
+ GLenum internalFormat,
+ GLint max_level,
CGLPBufferObj* pbuffer);
CGLError CGLDestroyPBuffer(CGLPBufferObj pbuffer);
CGLError CGLSetPBuffer(CGLContextObj ctx,
CGLPBufferObj pbuffer,
- unsigned long face,
- long level,
- long screen);
+ GLenum face,
+ GLint level,
+ GLint screen);
diff --git a/make/stub_includes/macosx/QuartzCore/CALayer.h b/make/stub_includes/macosx/QuartzCore/CALayer.h
new file mode 100644
index 000000000..a5a6579a6
--- /dev/null
+++ b/make/stub_includes/macosx/QuartzCore/CALayer.h
@@ -0,0 +1 @@
+typedef struct _CALayer CALayer;
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index 65d8e41f7..347de6299 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -7,55 +7,63 @@
compilation then the build fails.
*/
+#include <AppKit/NSView.h>
+#include <AppKit/NSOpenGL.h>
+#include <AppKit/NSOpenGLView.h>
+#include <AppKit/NSOpenGLLayer.h>
+#include <OpenGL/CGLDevice.h>
+#include <OpenGL/OpenGL.h>
+
typedef int Bool;
// CGL ..
-void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues);
+void CGLQueryPixelFormat(CGLPixelFormatObj fmt, int* iattrs, int niattrs, int* ivalues);
// NS ..
-void* createPixelFormat(int* iattrs, int niattrs, int* ivalues);
-void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues);
-void deletePixelFormat(void* pixelFormat);
+NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues);
+void queryPixelFormat(NSOpenGLPixelFormat* fmt, int* iattrs, int niattrs, int* ivalues);
+void deletePixelFormat(NSOpenGLPixelFormat* fmt);
// NS ..
-void *getCurrentContext(void);
-void *getNSView(void* nsContext);
+NSOpenGLContext* getCurrentContext(void);
+CGLContextObj getCGLContext(NSOpenGLContext* ctx);
+NSView* getNSView(NSOpenGLContext* ctx);
-void* createContext(void* shareContext,
- void* nsView,
- void* pixelFormat,
+NSOpenGLContext* createContext(NSOpenGLContext* shareContext,
+ NSView* nsView,
+ Bool isBackingLayerView,
+ NSOpenGLPixelFormat* pixelFormat,
Bool opaque,
int* viewNotReady);
-void *getCGLContext(void* nsContext);
-Bool makeCurrentContext(void* nsContext);
-Bool clearCurrentContext(void *nsContext);
-Bool deleteContext(void* nsContext, Bool releaseOnMainThread);
-Bool flushBuffer(void* nsContext);
-void setContextOpacity(void* nsContext, int opacity);
-void updateContext(void* nsContext);
-void copyContext(void* destContext, void* srcContext, int mask);
-
-void* updateContextRegister(void* nsContext, void* nsView);
+Bool makeCurrentContext(NSOpenGLContext* ctx);
+Bool clearCurrentContext(NSOpenGLContext *ctx);
+Bool deleteContext(NSOpenGLContext* ctx, Bool releaseOnMainThread);
+Bool flushBuffer(NSOpenGLContext* ctx);
+void setContextOpacity(NSOpenGLContext* ctx, int opacity);
+void updateContext(NSOpenGLContext* ctx);
+void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask);
+
+void* updateContextRegister(NSOpenGLContext* ctx, NSView* view);
Bool updateContextNeedsUpdate(void* updater);
void updateContextUnregister(void* updater);
-void* createPBuffer(int renderTarget, int internalFormat, int width, int height);
-Bool destroyPBuffer(void* pBuffer);
-void setContextPBuffer(void* nsContext, void* pBuffer);
-void setContextTextureImageToPBuffer(void* nsContext, void* pBuffer, int colorBuffer);
+NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height);
+Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer);
+void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer);
+void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer);
+
+// NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque);
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* pbuffer, Bool opaque, int texWidth, int texHeight);
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval);
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_ms);
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* glLayer);
+void releaseNSOpenGLLayer(NSOpenGLLayer *glLayer);
void* getProcAddress(const char *procName);
-void setSwapInterval(void* nsContext, int interval);
+void setSwapInterval(NSOpenGLContext* ctx, int interval);
/* Gamma-related functionality */
Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp);
void resetGammaRamp();
-/****************************************************************************************/
-/* Java2D/JOGL bridge support; need to be able to create pbuffers and
- contexts using the CGL APIs to be able to share textures, etc. with
- contexts created by Java2D/JOGL bridge, which are CGLContextObjs */
-
-/* Pick up copies of CGL signatures from Mac OS X stub_includes/window-system-build directory */
-#include <OpenGL/OpenGL.h>
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index 93b75e70b..26d299663 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -164,7 +164,7 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
}
};
- public boolean skipWaitForCompletion(Thread thread) {
- return ((Thread.currentThread() == thread) || EventQueue.isDispatchThread());
+ public boolean blockUntilDone(Thread thread) {
+ return ((Thread.currentThread() != thread) && !EventQueue.isDispatchThread());
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
index 16aac957a..a9023886d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -59,7 +59,9 @@ import javax.media.opengl.GLAutoDrawable;
*/
public class Animator extends AnimatorBase {
-
+ /** timeout in milliseconds, 15 frames @ 60Hz = 240ms, limiting {@link #finishLifecycleAction(Condition)} */
+ private static final long TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION = 15*16;
+
protected ThreadGroup threadGroup;
private Runnable runnable;
private boolean runAsFastAsPossible;
@@ -241,16 +243,20 @@ public class Animator extends AnimatorBase {
// dependencies on the Animator's internal thread. Currently we
// use a couple of heuristics to determine whether we should do
// the blocking wait().
- boolean doWait = !impl.skipWaitForCompletion(animThread);
- if (doWait) {
- while (condition.result()) {
- try {
- wait();
- } catch (InterruptedException ie) { }
- }
+ long remaining = impl.blockUntilDone(animThread) ? TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION : 0;
+ while (remaining>0 && condition.result()) {
+ long td = System.currentTimeMillis();
+ try {
+ wait(remaining);
+ } catch (InterruptedException ie) { }
+ remaining -= (System.currentTimeMillis() - td) ;
}
if(DEBUG) {
- System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): finished - waited " + doWait +
+ if(remaining<0) {
+ System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): ++++++ timeout reached ++++++ ");
+ }
+ System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): finished "+
+ "- waited " + (TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION-remaining) + "/" + TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION +
", started: " + isStartedImpl() +", animating: " + isAnimatingImpl() +
", paused: " + isPausedImpl() + ", drawables " + drawables.size());
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index e84a9bf78..9bea27f45 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -56,7 +56,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
public interface AnimatorImpl {
void display(ArrayList<GLAutoDrawable> drawables, boolean ignoreExceptions, boolean printExceptions);
- boolean skipWaitForCompletion(Thread thread);
+ boolean blockUntilDone(Thread thread);
}
protected ArrayList<GLAutoDrawable> drawables = new ArrayList<GLAutoDrawable>();
@@ -101,7 +101,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
if(paused) {
resume();
}
- if(!impl.skipWaitForCompletion(animThread)) {
+ if(impl.blockUntilDone(animThread)) {
while(isStarted() && !isPaused() && !isAnimating()) {
try {
wait();
@@ -123,7 +123,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
if(paused) {
resume();
}
- if(!impl.skipWaitForCompletion(animThread)) {
+ if(impl.blockUntilDone(animThread)) {
while(isStarted() && drawablesEmpty && isAnimating()) {
try {
wait();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
index bad268f70..23b0845ee 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
@@ -60,7 +60,7 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl {
}
}
- public boolean skipWaitForCompletion(Thread thread) {
- return (Thread.currentThread() == thread);
+ public boolean blockUntilDone(Thread thread) {
+ return (Thread.currentThread() != thread);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index f2e742cda..62441d8b8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -491,6 +491,19 @@ public class GLBuffers extends Buffers {
return sizeof(gl, tmp, elements * esize, width, height, depth, pack);
}
+
+ public static final int getNextPowerOf2(int number) {
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
//----------------------------------------------------------------------
// Conversion routines
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index b6df365ba..7f3aa8a39 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -1055,9 +1055,7 @@ public class Texture {
// Helper routines for disabling certain codepaths
private static boolean haveNPOT(GL gl) {
- return (!disableNPOT &&
- ( gl.isGLES2() ||
- gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ) );
+ return !disableNPOT && gl.isNPOTTextureAvailable();
}
private static boolean haveTexRect(GL gl) {
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f93d443e0..534e449bc 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -294,6 +294,17 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns true if the GL context supports non power of two (NPOT) textures,
+ * otherwise false.
+ * <p>
+ * NPOT textures are supported in OpenGL >= 3, GLES2 or if the
+ * 'GL_ARB_texture_non_power_of_two' extension is available.
+ * </p>
+ * @return
+ */
+ public boolean isNPOTTextureAvailable();
+
/** Provides a platform-independent way to specify the minimum swap
interval for buffer swaps. An argument of 0 disables
sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 9d99a32ff..31125af59 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -45,6 +45,7 @@ import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.HashMap;
import java.util.HashSet;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import com.jogamp.common.util.IntObjectHashMap;
@@ -767,12 +768,12 @@ public abstract class GLContext {
/**
* @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
*/
- protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+ protected static /*final*/ HashMap<String, Integer> deviceVersionAvailable = new HashMap<String, Integer>();
/**
* @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
*/
- private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+ private static /*final*/ HashSet<String> deviceVersionsAvailableSet = new HashSet<String>();
protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0));
@@ -824,7 +825,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.put( key, val );
+ val = deviceVersionAvailable.put( key, val );
}
return val;
}
@@ -833,7 +834,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val;
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.get( key );
+ val = deviceVersionAvailable.get( key );
}
return val;
}
@@ -875,29 +876,29 @@ public abstract class GLContext {
return null != getAvailableGLVersion(device, major, profile);
}
- public static boolean isGLES1Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGLES2Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL4Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
- }
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
- public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL3Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
- }
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
public static boolean isGL2Available(AbstractGraphicsDevice device) {
return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
@@ -941,6 +942,10 @@ public abstract class GLContext {
return sb.toString();
}
+ //
+ // internal string utils
+ //
+
protected static String toString(int val, boolean hex) {
if(hex) {
return "0x" + Integer.toHexString(val);
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
index f4cd77059..2b86a04ba 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -158,6 +158,12 @@ public interface GLDrawable {
*/
public GLProfile getGLProfile();
+ /**
+ * Returns the underlying native surface which surface handle
+ * represents this OpenGL drawable's native resource.
+ *
+ * @see #getHandle()
+ */
public NativeSurface getNativeSurface();
/**
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 92be62b4d..94fb250ce 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -83,6 +83,8 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.util.GLBuffers;
+
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -776,17 +778,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (number == 0) {
return 2;
}
-
- if (((number-1) & number) == 0) {
- //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
- return number;
- }
- int power = 0;
- while (number > 0) {
- number = number>>1;
- power++;
- }
- return (1<<power);
+ return GLBuffers.getNextPowerOf2(number);
}
private int getGLInteger(GL gl, int which) {
diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
index 2fa708404..bc9a93042 100644
--- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
+++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
@@ -79,7 +79,7 @@ public class GlyphString {
* @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance.
* @param vertexFactory vertex impl factory {@link Factory}
* @param font the target {@link Font}
- * @param size font size
+ * @param fontSize font size
* @param str string text
* @return the created {@link GlyphString} instance
*/
diff --git a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
index 96d62fbb3..27569d210 100644
--- a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
+++ b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
@@ -28,6 +28,8 @@
package jogamp.opengl;
import java.io.PrintStream;
+import java.util.concurrent.TimeUnit;
+
import javax.media.opengl.FPSCounter;
/**
@@ -55,7 +57,7 @@ public class FPSCounterImpl implements FPSCounter {
public final synchronized void tickFPS() {
fpsTotalFrames++;
if(fpsUpdateFramesInterval>0 && fpsTotalFrames%fpsUpdateFramesInterval == 0) {
- final long now = System.currentTimeMillis();
+ final long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
fpsLastPeriod = now - fpsLastUpdateTime;
fpsLastPeriod = Math.max(fpsLastPeriod, 1); // div 0
fpsLast = ( (float)fpsUpdateFramesInterval * 1000f ) / ( (float) fpsLastPeriod ) ;
@@ -96,7 +98,7 @@ public class FPSCounterImpl implements FPSCounter {
}
public final synchronized void resetFPSCounter() {
- fpsStartTime = System.currentTimeMillis(); // overwrite startTime to real init one
+ fpsStartTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); // overwrite startTime to real init one
fpsLastUpdateTime = fpsStartTime;
fpsLastPeriod = 0;
fpsTotalFrames = 0;
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 704f71457..068190cb2 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -40,9 +40,26 @@
package jogamp.opengl;
-import java.nio.*;
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
+import java.nio.Buffer;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.Threading;
+
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.common.util.VersionNumber;
@@ -103,24 +120,43 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
AbstractGraphicsDevice adevice = config.getScreen().getDevice();
GLDrawable result = null;
adevice.lock();
try {
- if(caps.isOnscreen()) {
- if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
+ if(chosenCaps.isOnscreen()) {
+ // onscreen
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
+ if(null == ols) {
+ // traditional onscreen
+ if(DEBUG) {
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
+ }
+ result = createOnscreenDrawableImpl(target);
+ } else {
+ // layered surface -> offscreen/PBuffer
+ final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
+ chosenCapsMod.setOnscreen(false);
+ chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice));
+ config.setChosenCapabilities(chosenCapsMod);
+ if(DEBUG) {
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+ }
+ if( ! ( target instanceof SurfaceChangeable ) ) {
+ throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
+ }
+ result = createOffscreenDrawableImpl(target);
}
- result = createOnscreenDrawableImpl(target);
} else {
+ // offscreen
+ if(DEBUG) {
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target);
+ }
if( ! ( target instanceof SurfaceChangeable ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
}
- if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+caps.isPBuffer()+"): "+target);
- }
result = createOffscreenDrawableImpl(target);
}
} finally {
@@ -287,15 +323,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// GLDrawableFactoryImpl details
//
- protected void maybeDoSingleThreadedWorkaround(Runnable action) {
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- Threading.invokeOnOpenGLThread(action);
- } else {
- action.run();
- }
- }
-
/**
* Returns the sole GLDrawableFactoryImpl instance.
*
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 58c9aaaa6..6b6ce9f9e 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -125,7 +125,10 @@ public abstract class GLDrawableImpl implements GLDrawable {
return surface;
}
+ /** called with locked surface @ setRealized(false) */
protected void destroyHandle() {}
+
+ /** called with locked surface @ setRealized(true) or @ lockSurface(..) when surface changed */
protected void updateHandle() {}
public long getHandle() {
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 318d00637..6e2b7b744 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -29,6 +29,7 @@
package jogamp.opengl;
import java.util.ArrayList;
+
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -86,6 +87,7 @@ public class GLGraphicsConfigurationUtil {
return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
int preSize = capsBucket.size();
if( 0 != ( WINDOW_BIT & winattrbits ) ) {
@@ -138,7 +140,7 @@ public class GLGraphicsConfigurationUtil {
if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer()) {
// fix caps ..
GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
caps2.setOnscreen(false);
caps2.setPBuffer(true);
return caps2;
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
index 2c396e265..5979056f3 100644
--- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
+++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
@@ -61,7 +61,7 @@ public class SharedResourceRunner implements Runnable {
String initConnection = null;
String releaseConnection = null;
- HashSet devicesTried = new HashSet();
+ HashSet<String> devicesTried = new HashSet<String>();
private boolean getDeviceTried(String connection) {
synchronized (devicesTried) {
@@ -86,7 +86,7 @@ public class SharedResourceRunner implements Runnable {
public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) {
SharedResourceRunner.Resource sr = null;
if(null != device) {
- String connection = device.getConnection();
+ final String connection = device.getConnection();
sr = impl.mapGet(connection);
if (null == sr && !getDeviceTried(connection)) {
addDeviceTried(connection);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index a9cc40335..de10b066d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -197,6 +197,16 @@ public abstract class EGLDrawable extends GLDrawableImpl {
}
}
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) {
+ if(DEBUG) {
+ System.err.println("eglSwapBuffers failed:");
+ Thread.dumpStack();
+ }
+ }
+ }
+
public int getWidth() {
int[] tmp = new int[1];
if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 79d96bdb6..decc74258 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -268,7 +268,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser));
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 4fb3dca78..ea625fb27 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -38,15 +38,25 @@ package jogamp.opengl.egl;
import java.nio.IntBuffer;
import java.util.ArrayList;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.egl.*;
-import javax.media.opengl.*;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.egl.EGLGraphicsDevice;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.MutableGraphicsConfiguration;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
-import jogamp.opengl.*;
-public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
public final long getNativeConfig() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index 7d5e0448d..42f067b29 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -55,15 +55,5 @@ public class EGLOnscreenDrawable extends EGLDrawable {
protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
}
-
- protected void swapBuffersImpl() {
- if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) {
- if(DEBUG) {
- System.err.println("eglSwapBuffers failed:");
- Thread.dumpStack();
- }
- }
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 5fb32e6cd..be6c80c41 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -40,48 +40,40 @@
package jogamp.opengl.egl;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.SurfaceChangeable;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
-import jogamp.opengl.x11.glx.GLX;
-
public class EGLPbufferDrawable extends EGLDrawable {
private int texFormat;
protected static final boolean useTexture = false; // No yet ..
protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeSurface target) {
super(factory, target);
+ setRealized(true);
+ }
- // get choosen ones ..
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
+ protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
+ final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(useTexture) {
- this.texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
} else {
- this.texFormat = EGL.EGL_NO_TEXTURE;
+ texFormat = EGL.EGL_NO_TEXTURE;
}
if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ System.out.println("Pbuffer config: " + config);
}
- setRealized(true);
-
- if (DEBUG) {
- System.out.println("Created pbuffer: " + this);
- }
-
- }
-
- protected void destroyImpl() {
- setRealized(false);
- }
-
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
NativeSurface nw = getNativeSurface();
int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
@@ -97,11 +89,5 @@ public class EGLPbufferDrawable extends EGLDrawable {
public GLContext createContext(GLContext shareWith) {
return new EGLPbufferContext(this, shareWith);
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 1fe47f60b..f5970fad9 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -45,7 +45,9 @@ import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
@@ -63,7 +65,6 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
-
public abstract class MacOSXCGLContext extends GLContextImpl
{
// Abstract interface for implementation of this context (either
@@ -76,7 +77,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
boolean makeCurrent(long ctx);
boolean release(long ctx);
boolean setSwapInterval(int interval);
- boolean swapBuffers(boolean isOnscreen);
+ boolean swapBuffers();
}
/* package */ static final boolean isTigerOrLater;
@@ -268,9 +269,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
protected void swapBuffers() {
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- if(!impl.swapBuffers(caps.isOnscreen())) {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!impl.swapBuffers()) {
throw new GLException("Error swapping buffers: "+this);
}
}
@@ -282,12 +282,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
if(!impl.setSwapInterval(interval)) {
throw new GLException("Error set swap-interval: "+this);
}
- if ( isNSContext() ) {
- CGL.setSwapInterval(contextHandle, interval);
- } else {
- int[] lval = new int[] { (int) interval } ;
- CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
- }
currentSwapInterval = interval ;
}
@@ -403,31 +397,44 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// NSOpenGLContext-based implementation
class NSOpenGLImpl implements GLBackendImpl {
+ long nsOpenGLLayer = 0;
+ long nsOpenGLLayerPFmt = 0;
+
public boolean isNSContext() { return true; }
public long create(long share, int ctp, int major, int minor) {
long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.drawable;
+ final NativeSurface surface = drawable.getNativeSurface();
+ final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
if (pixelFormat == 0) {
throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
}
config.setChosenPixelFormat(pixelFormat);
+ if(DEBUG) {
+ System.err.println("NS create OSX>=lion "+isLionOrLater);
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create chosenCaps: "+chosenCaps);
+ System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create drawable NSView-handle: "+toHexString(drawable.getNSViewHandle()));
+ // Thread.dumpStack();
+ }
try {
int[] viewNotReady = new int[1];
// Try to allocate a context with this
ctx = CGL.createContext(share,
- drawable.getHandle(),
+ drawable.getNSViewHandle(), null!=backingLayerHost,
pixelFormat,
chosenCaps.isBackgroundOpaque(),
viewNotReady, 0);
if (0 == ctx) {
- if (viewNotReady[0] == 1) {
- if (DEBUG) {
- System.err.println("!!! View not ready for " + getClass().getName());
- }
- // View not ready at the window system level
+ if(DEBUG) {
+ System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
}
return 0;
}
@@ -439,22 +446,63 @@ public abstract class MacOSXCGLContext extends GLContextImpl
if(DEBUG) {
GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat);
- System.err.println("NS created(>=lion "+isLionOrLater+"): "+caps0);
+ System.err.println("NS create pixelformat2GLCaps: "+caps0);
+ }
+ GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("NS create fixedCaps: "+fixedCaps);
}
- GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
- caps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, chosenCaps.isBackgroundOpaque());
- config.setChosenCapabilities(caps);
- if(caps.isPBuffer()) {
+ if(fixedCaps.isPBuffer()) {
// Must now associate the pbuffer with our newly-created context
CGL.setContextPBuffer(ctx, drawable.getHandle());
- }
+ }
+ //
+ // handled layered surface
+ //
+ if(null != backingLayerHost) {
+ nsOpenGLLayerPFmt = pixelFormat;
+ pixelFormat = 0;
+ final int texWidth, texHeight;
+ if(drawable instanceof MacOSXPbufferCGLDrawable) {
+ final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
+ texWidth = osxPDrawable.getTextureWidth();
+ texHeight = osxPDrawable.getTextureHeight();
+ } else {
+ texWidth = drawable.getWidth();
+ texHeight = drawable.getHeight();
+ }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer));
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ }
} finally {
- CGL.deletePixelFormat(pixelFormat);
+ if(0!=pixelFormat) {
+ CGL.deletePixelFormat(pixelFormat);
+ }
}
return ctx;
}
public boolean destroy(long ctx) {
+ if(0 != nsOpenGLLayer) {
+ final NativeSurface surface = drawable.getNativeSurface();
+ if (DEBUG) {
+ System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
+ }
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ if(null == ols) {
+ throw new InternalError("XXX: "+ols);
+ }
+ CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+ ols.detachSurfaceLayer(nsOpenGLLayer);
+ CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+ nsOpenGLLayerPFmt = 0;
+ nsOpenGLLayer = 0;
+ }
return CGL.deleteContext(ctx, true);
}
@@ -472,14 +520,26 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
public boolean setSwapInterval(int interval) {
- CGL.setSwapInterval(contextHandle, interval);
+ if(0 != nsOpenGLLayer) {
+ CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+ }
+ CGL.setSwapInterval(contextHandle, interval);
return true;
}
- public boolean swapBuffers(boolean isOnscreen) {
- if(isOnscreen) {
- return CGL.flushBuffer(contextHandle);
- }
- return true;
+
+ public boolean swapBuffers() {
+ if(0 != nsOpenGLLayer) {
+ // sync w/ CALayer renderer - wait until next frame is required (v-sync)
+ CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, 16); // timeout 16ms -> 60Hz
+ }
+ if(CGL.flushBuffer(contextHandle)) {
+ if(0 != nsOpenGLLayer) {
+ // trigger CALayer to update
+ CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+ }
+ return true;
+ }
+ return false;
}
}
@@ -547,11 +607,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
return true;
}
- public boolean swapBuffers(boolean isOnscreen) {
- if(isOnscreen) {
- return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
- }
- return true;
+ public boolean swapBuffers() {
+ return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index 5a35f661d..12d480fd1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -40,6 +40,11 @@
package jogamp.opengl.macosx.cgl;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -87,18 +92,46 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
this.id = id;
}
}
-
+ private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
+
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
public MacOSXCGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) {
super(factory, comp, realized);
- initOpenGLImpl(getOpenGLMode());
- }
-
+ initOpenGLImpl(getOpenGLMode());
+ }
+
protected void setRealizedImpl() {
}
+ protected long getNSViewHandle() {
+ return GLBackendType.NSOPENGL == openGLMode ? getHandle() : null;
+ }
+
+ protected void registerContext(MacOSXCGLContext ctx) {
+ // NOTE: we need to keep track of the created contexts in order to
+ // implement swapBuffers() because of how Mac OS X implements its
+ // OpenGL window interface
+ synchronized (createdContexts) {
+ createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
+ }
+ }
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ synchronized (createdContexts) {
+ for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
+ WeakReference<MacOSXCGLContext> ref = iter.next();
+ MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.swapBuffers();
+ } else {
+ iter.remove();
+ }
+ }
+ }
+ }
+
public GLDynamicLookupHelper getGLDynamicLookupHelper() {
return getFactoryImpl().getGLDynamicLookupHelper(0);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 5c726bc54..30917476e 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -42,6 +42,7 @@ package jogamp.opengl.macosx.cgl;
import java.nio.Buffer;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -52,6 +53,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -113,18 +115,28 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
// private MacOSXCGLContext context;
MacOSXGraphicsDevice device;
boolean wasContextCreated;
+ boolean hasNPOTTextures;
+ boolean hasRECTTextures;
+ boolean hasAppletFloatPixels;
- SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated
+ SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated,
+ boolean hasNPOTTextures, boolean hasRECTTextures, boolean hasAppletFloatPixels
/* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) {
// drawable = draw;
// context = ctx;
this.device = device;
this.wasContextCreated = wasContextCreated;
+ this.hasNPOTTextures = hasNPOTTextures;
+ this.hasRECTTextures = hasRECTTextures;
+ this.hasAppletFloatPixels = hasAppletFloatPixels;
}
final MacOSXGraphicsDevice getDevice() { return device; }
final boolean wasContextAvailable() { return wasContextCreated; }
+ final boolean isNPOTTextureAvailable() { return hasNPOTTextures; }
+ final boolean isRECTTextureAvailable() { return hasRECTTextures; }
+ final boolean isAppletFloatPixelsAvailable() { return hasAppletFloatPixels; }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ HashMap<String, SharedResource> sharedMap = new HashMap<String, SharedResource>();
MacOSXGraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
@@ -138,52 +150,78 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- private boolean isOSXContextAvailable(AbstractGraphicsDevice sharedDevice) {
- boolean madeCurrent = false;
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
- if (null == glp) {
- throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
- }
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setPBuffer(true);
- final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
- if(null!=drawable) {
- final GLContext context = drawable.createContext(null);
- if (null != context) {
- context.setSynchronized(true);
- try {
- context.makeCurrent(); // could cause exception
- madeCurrent = context.isCurrent();
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent failed");
- gle.printStackTrace();
- }
- } finally {
- context.destroy();
- }
- }
- drawable.destroy();
- }
- return madeCurrent;
+ private HashSet<String> devicesTried = new HashSet<String>();
+
+ private boolean getDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private void addDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+ private void removeDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.remove(connection);
+ }
}
/* package */ SharedResource getOrCreateOSXSharedResource(AbstractGraphicsDevice adevice) {
- String connection = adevice.getConnection();
+ final String connection = adevice.getConnection();
SharedResource sr;
synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
+ sr = sharedMap.get(connection);
}
- if(null==sr) {
+ if(null==sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID());
- final boolean madeCurrent = isOSXContextAvailable(sharedDevice);
- sr = new SharedResource(sharedDevice, madeCurrent);
+ boolean madeCurrent = false;
+ boolean hasNPOTTextures = false;
+ boolean hasRECTTextures = false;
+ boolean hasAppletFloatPixels = false;
+ {
+ GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
+ caps.setDoubleBuffered(false);
+ caps.setOnscreen(false);
+ caps.setPBuffer(true);
+ final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
+ if(null!=drawable) {
+ final GLContext context = drawable.createContext(null);
+ if (null != context) {
+ context.setSynchronized(true);
+ try {
+ context.makeCurrent(); // could cause exception
+ madeCurrent = context.isCurrent();
+ if(madeCurrent) {
+ GL gl = context.getGL();
+ hasNPOTTextures = gl.isNPOTTextureAvailable();
+ hasRECTTextures = gl.isExtensionAvailable("GL_EXT_texture_rectangle");
+ hasAppletFloatPixels = gl.isExtensionAvailable("GL_APPLE_float_pixels");
+ }
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent failed");
+ gle.printStackTrace();
+ }
+ } finally {
+ context.destroy();
+ }
+ }
+ drawable.destroy();
+ }
+ }
+ sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppletFloatPixels);
synchronized(sharedMap) {
sharedMap.put(connection, sr);
}
+ removeDeviceTried(connection);
if (DEBUG) {
System.err.println("MacOSXCGLDrawableFactory.createShared: device: " + sharedDevice);
System.err.println("MacOSXCGLDrawableFactory.createShared: context: " + madeCurrent);
@@ -232,22 +270,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if(!caps.isPBuffer()) {
return new MacOSXOffscreenCGLDrawable(this, target);
}
-
- // PBuffer GLDrawable Creation
- /**
- * FIXME: Think about this ..
- * should not be necessary ? ..
- final List returnList = new ArrayList();
- final GLDrawableFactory factory = this;
- Runnable r = new Runnable() {
- public void run() {
- returnList.add(new MacOSXPbufferCGLDrawable(factory, target));
- }
- };
- maybeDoSingleThreadedWorkaround(r);
- return (GLDrawableImpl) returnList.get(0);
- */
- return new MacOSXPbufferCGLDrawable(this, target);
+ return new MacOSXPbufferCGLDrawable(this, target, true);
}
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
@@ -257,7 +280,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true));
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index a429720db..f552ab3dd 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -41,15 +41,16 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
+
import com.jogamp.common.nio.PointerBuffer;
-public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
long pixelformat;
MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen,
@@ -67,10 +68,6 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
this.pixelformat=pixelformat;
}
- void setChosenCapabilities(GLCapabilitiesImmutable caps) {
- super.setChosenCapabilities(caps);
- }
-
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) {
MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device);
if(null == sharedResource) {
@@ -83,6 +80,8 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
static final int[] cglInternalAttributeToken = new int[] {
CGL.kCGLPFAOpenGLProfile,
CGL.kCGLPFAColorFloat,
+ CGL.NSOpenGLPFANoRecovery,
+ CGL.NSOpenGLPFAAccelerated,
CGL.NSOpenGLPFAPixelBuffer,
CGL.NSOpenGLPFADoubleBuffer,
CGL.NSOpenGLPFAStereo,
@@ -114,6 +113,13 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
break;
+ case CGL.NSOpenGLPFANoRecovery:
+ ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+ break;
+ case CGL.NSOpenGLPFAAccelerated:
+ ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+ break;
+
case CGL.NSOpenGLPFAPixelBuffer:
ivalues[idx] = caps.isPBuffer() ? 1 : 0;
break;
@@ -222,7 +228,7 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
// Use attribute array to select pixel format
PointerBuffer fmt = PointerBuffer.allocateDirect(1);
- long[] numScreens = new long[1];
+ int[] numScreens = new int[1];
int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0);
if (res != CGL.kCGLNoError) {
throw new GLException("Error code " + res + " while choosing pixel format");
@@ -285,6 +291,10 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
break;
+ case CGL.NSOpenGLPFAAccelerated:
+ caps.setHardwareAccelerated(ivalues[i] != 0);
+ break;
+
case CGL.NSOpenGLPFAPixelBuffer:
caps.setPBuffer(ivalues[i] != 0);
break;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 08a531200..ba384fc71 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -48,7 +48,6 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.GLContextShareSet;
@@ -61,7 +60,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) {
super(drawable, null);
setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
- drawable.setExternalCGLContext(this);
+ drawable.registerContext(this);
this.contextHandle = handle;
GLContextShareSet.contextCreated(this);
setGLFunctionAvailability(false, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
@@ -150,16 +149,10 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
// Need to provide the display connection to extension querying APIs
static class Drawable extends MacOSXCGLDrawable {
- MacOSXExternalCGLContext extCtx;
-
Drawable(GLDrawableFactory factory, NativeSurface comp) {
super(factory, comp, true);
}
- void setExternalCGLContext(MacOSXExternalCGLContext externalContext) {
- extCtx = externalContext;
- }
-
public GLContext createContext(GLContext shareWith) {
throw new GLException("Should not call this");
}
@@ -175,11 +168,5 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
public void setSize(int width, int height) {
throw new GLException("Should not call this");
}
-
- protected void swapBuffersImpl() {
- if (extCtx != null) {
- extCtx.swapBuffers();
- }
- }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
index bec4cf32a..ae3fa1428 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
@@ -40,15 +40,15 @@
package jogamp.opengl.macosx.cgl;
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import jogamp.opengl.*;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable {
public MacOSXOffscreenCGLDrawable(GLDrawableFactory factory,
NativeSurface target) {
- super(factory, target);
+ super(factory, target, true);
}
public GLContext createContext(GLContext shareWith) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
index 97d198c92..4fe6fa484 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -57,7 +57,13 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
@Override
protected void drawableUpdatedNotify() throws GLException {
- if(0==updateHandle || CGL.updateContextNeedsUpdate(updateHandle)) {
+ final int w = drawable.getWidth();
+ final int h = drawable.getHeight();
+ final boolean updateContext = ( 0!=updateHandle && CGL.updateContextNeedsUpdate(updateHandle) ) ||
+ w != lastWidth || h != lastHeight;
+ if(updateContext) {
+ lastWidth = w;
+ lastHeight = h;
if (contextHandle == 0) {
throw new GLException("Context not created");
}
@@ -65,11 +71,11 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
}
}
- protected long updateHandle = 0;
-
@Override
protected boolean createImpl() {
boolean res = super.createImpl();
+ lastWidth = -1;
+ lastHeight = -1;
if(res && isNSContext()) {
if(0 != updateHandle) {
throw new InternalError("XXX1");
@@ -89,5 +95,8 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
updateHandle = 0;
}
super.destroyImpl();
- }
+ }
+
+ private long updateHandle = 0;
+ private int lastWidth, lastHeight;
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
index 24276c39e..80c54042f 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -40,44 +40,20 @@
package jogamp.opengl.macosx.cgl;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
- private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
-
+
protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeSurface component) {
super(factory, component, false);
}
public GLContext createContext(GLContext shareWith) {
- MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
- // NOTE: we need to keep track of the created contexts in order to
- // implement swapBuffers() because of how Mac OS X implements its
- // OpenGL window interface
- synchronized (createdContexts) {
- createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
- }
+ final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
+ registerContext(ctx);
return ctx;
}
- protected void swapBuffersImpl() {
- synchronized (createdContexts) {
- for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
- WeakReference<MacOSXCGLContext> ref = iter.next();
- MacOSXCGLContext ctx = ref.get();
- if (ctx != null) {
- ctx.swapBuffers();
- } else {
- iter.remove();
- }
- }
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
index c5743b923..f4b71d37d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -33,19 +33,14 @@
package jogamp.opengl.macosx.cgl;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2;
-import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
-
public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
// State for render-to-texture and render-to-texture-rectangle support
- private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
private int texture; // actual texture object
public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable,
@@ -55,7 +50,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
public void bindPbufferToTexture() {
GL gl = getGL();
- gl.glBindTexture(textureTarget, texture);
+ gl.glBindTexture(((MacOSXPbufferCGLDrawable)drawable).getTextureTarget(), texture);
// FIXME: not clear whether this is really necessary, but since
// the API docs seem to imply it is and since it doesn't seem to
// impact performance, leaving it in
@@ -70,18 +65,10 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
if (newCreated) {
// Initialize render-to-texture support if requested
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GL gl = getGL();
- boolean rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle();
- if (rect) {
- if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) {
- System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " +
- "supported; skipping requested render_to_texture_rectangle support for pbuffer");
- rect = false;
- }
- }
- textureTarget = (rect ? GL2.GL_TEXTURE_RECTANGLE : GL.GL_TEXTURE_2D);
+ final GL gl = getGL();
+ final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
+ final int textureTarget = osxPDrawable.getTextureTarget();
+
int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
texture = tmp[0];
@@ -90,7 +77,9 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
- gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+ gl.glTexImage2D(textureTarget, 0, GL.GL_RGB, osxPDrawable.getTextureWidth(), osxPDrawable.getTextureHeight(),
+ 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, null);
+ gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, drawable.getWidth(), drawable.getHeight());
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index fdbfaf6d6..4c985fd00 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -51,14 +51,10 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import jogamp.opengl.Debug;
-
import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.opengl.util.GLBuffers;
-
-public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
- private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable");
-
+public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// Abstract interface for implementation of this drawable (either
// NSOpenGL-based or CGL-based)
interface GLBackendImpl {
@@ -76,34 +72,50 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// Note that we can not store this in the NativeSurface because the
// semantic is that contains an NSView
protected long pBuffer;
+ protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight;
- public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer();
+ public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target, boolean realizeNow) {
+ super(factory, target, false);
- if (DEBUG) {
- System.err.println("Created pbuffer " + this);
+ if(realizeNow) {
+ setRealized(true);
}
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
public GLContext createContext(GLContext shareWith) {
- return new MacOSXPbufferCGLContext(this, shareWith);
+ final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith);
+ registerContext(ctx);
+ return ctx;
}
- protected void destroyImpl() {
+ @Override
+ protected long getNSViewHandle() {
+ // pbuffer handle is NSOpenGLPixelBuffer
+ return 0;
+ }
+
+ @Override
+ public long getHandle() {
+ return pBuffer;
+ }
+
+ protected int getTextureTarget() { return pBufferTexTarget; }
+ protected int getTextureWidth() { return pBufferTexWidth; }
+ protected int getTextureHeight() { return pBufferTexHeight; }
+
+ protected void destroyPbuffer() {
if (this.pBuffer != 0) {
NativeSurface ns = getNativeSurface();
impl.destroy(pBuffer);
@@ -112,73 +124,56 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
}
}
- public long getHandle() {
- return pBuffer;
- }
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ private void createPbuffer() {
+ final NativeSurface ns = getNativeSurface();
+ final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ final GLProfile glProfile = capabilities.getGLProfile();
+ MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
}
- }
- private void createPbuffer() {
- NativeSurface ns = getNativeSurface();
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GLProfile glProfile = capabilities.getGLProfile();
- int renderTarget;
- if (glProfile.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle()) {
- renderTarget = GL2.GL_TEXTURE_RECTANGLE;
+ if ( capabilities.getPbufferRenderToTextureRectangle() && null!=sr && sr.isRECTTextureAvailable() ) {
+ pBufferTexTarget = GL2.GL_TEXTURE_RECTANGLE;
+ } else {
+ pBufferTexTarget = GL.GL_TEXTURE_2D;
+ }
+ if ( GL2.GL_TEXTURE_RECTANGLE == pBufferTexTarget || ( null!=sr && sr.isNPOTTextureAvailable() ) ) {
+ pBufferTexWidth = getWidth();
+ pBufferTexHeight = getHeight();
} else {
- int w = getNextPowerOf2(getWidth());
- int h = getNextPowerOf2(getHeight());
- ((SurfaceChangeable)ns).setSize(w, h);
- renderTarget = GL.GL_TEXTURE_2D;
+ pBufferTexWidth = GLBuffers.getNextPowerOf2(getWidth());
+ pBufferTexHeight = GLBuffers.getNextPowerOf2(getHeight());
}
int internalFormat = GL.GL_RGBA;
if (capabilities.getPbufferFloatingPointBuffers()) {
- // FIXME: want to check availability of GL_APPLE_float_pixels
- // extension, but need valid OpenGL context in order to do so --
- // in worst case would need to create dummy window / GLCanvas
- // (undesirable) -- could maybe also do this with pbuffers
- /*
- if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) {
- throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
- }
- */
- if(glProfile.isGL2GL3()) {
- switch (capabilities.getRedBits()) {
+ if(!glProfile.isGL2GL3() || null==sr || sr.isAppletFloatPixelsAvailable()) {
+ throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
+ }
+ switch (capabilities.getRedBits()) {
case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break;
case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break;
default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)");
- }
- } else {
- internalFormat = GL.GL_RGBA;
}
}
-
- pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight());
+
+ pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
+ if(DEBUG) {
+ System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+
+ ", pbufferSize "+getWidth()+"x"+getHeight()+
+ ", texSize "+pBufferTexWidth+"x"+pBufferTexHeight+
+ ", internal-fmt "+toHexString(internalFormat));
+ System.err.println("MacOSXPbufferCGLDrawable pBuffer: "+toHexString(pBuffer));
+ // Thread.dumpStack();
+ }
if (pBuffer == 0) {
throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
}
((SurfaceChangeable)ns).setSurfaceHandle(pBuffer);
-
- }
-
- private int getNextPowerOf2(int number) {
- if (((number-1) & number) == 0) {
- //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
- return number;
- }
- int power = 0;
- while (number > 0) {
- number = number>>1;
- power++;
- }
- return (1<<power);
}
public void setOpenGLMode(GLBackendType mode) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index b2c95de39..aa5da9f2b 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -57,15 +57,19 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
private long hbitmap;
protected WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
- create();
+ super(factory, target, false);
+ setRealized(true);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- create();
+ createBitmap();
} else {
- destroyImpl();
+ destroyBitmap();
}
}
@@ -73,7 +77,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
return new WindowsBitmapWGLContext(this, shareWith);
}
- private void create() {
+ private void createBitmap() {
int werr;
NativeSurface ns = getNativeSurface();
if(DEBUG) {
@@ -153,7 +157,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
config.updateGraphicsConfiguration(getFactory(), ns, null);
}
- protected void destroyImpl() {
+ protected void destroyBitmap() {
NativeSurface ns = getNativeSurface();
if (ns.getSurfaceHandle() != 0) {
// Must destroy bitmap and device context
@@ -165,11 +169,4 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
((SurfaceChangeable)ns).setSurfaceHandle(0);
}
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
index 3d0cce725..966ad867f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -84,7 +84,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
GLCapabilities caps = new GLCapabilities(glp);
WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen);
GDISurface ns = new GDISurface(cfg, windowHandle);
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return new WindowsDummyWGLDrawable(factory, ns, handleWindowLifecycle);
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 7be2c1ac7..cda839967 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -51,6 +51,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -60,27 +61,22 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
private long buffer; // pbuffer handle
private int floatMode;
-
- protected WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target,
- WindowsWGLDrawableFactory.SharedResource sharedResource) {
- super(factory, target, true);
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer(sharedResource);
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + this);
- }
+
+ protected WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target) {
+ super(factory, target, false);
+
+ setRealized(true);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- throw new GLException("Recreation via setRealized not supported.");
+ createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
@@ -88,7 +84,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
return new WindowsPbufferWGLContext(this, shareWith);
}
- protected void destroyImpl() {
+ protected void destroyPbuffer() {
NativeSurface ns = getNativeSurface();
if(0!=buffer) {
WGLExt wglExt = cachedWGLExt;
@@ -120,23 +116,22 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
return floatMode;
}
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
-
- private void createPbuffer(WindowsWGLDrawableFactory.SharedResource sharedResource) {
+ private void createPbuffer() {
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(config.getScreen().getDevice());
long parentHdc = sharedResource.getDrawable().getNativeSurface().getSurfaceHandle();
WGLExt wglExt = sharedResource.getContext().getWGLExt();
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
+
int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
float[] fattributes = new float[1];
int[] floatModeTmp = new int[1];
int niattribs = 0;
int width, height;
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
GLProfile glProfile = chosenCaps.getGLProfile();
@@ -260,7 +255,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
width = tmp[0];
wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
height = tmp[0];
- ((SurfaceChangeable)ns).setSize(width, height);
+ ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
}
private static String wglGetLastError() {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index 4ed9a00c3..fe446e8fe 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -41,6 +41,7 @@
package jogamp.opengl.windows.wgl;
import java.security.AccessController;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -74,7 +75,8 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
}
}
- protected void swapBuffersImpl() {
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
long startTime = 0;
if (PROFILING) {
startTime = System.currentTimeMillis();
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index cd22127a3..5a1f997a6 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -436,33 +436,32 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
// PBuffer GLDrawable Creation
+ GLDrawableImpl pbufferDrawable;
final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ /**
+ * Similar to ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
+ * we need to have a context current on the same Display to create a PBuffer.
+ */
final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
- if(null==sr) {
- throw new IllegalArgumentException("No shared resource for "+device);
- }
- final List returnList = new ArrayList();
- Runnable r = new Runnable() {
- public void run() {
- GLContext lastContext = GLContext.getCurrent();
- if (lastContext != null) {
+ if(null!=sr) {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
lastContext.release();
- }
- sr.context.makeCurrent();
- try {
- GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target, sr);
- returnList.add(pbufferDrawable);
- } finally {
+ }
+ sr.context.makeCurrent();
+ try {
+ pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target);
+ } finally {
sr.context.release();
if (lastContext != null) {
lastContext.makeCurrent();
}
- }
}
- };
- maybeDoSingleThreadedWorkaround(r);
- return (GLDrawableImpl) returnList.get(0);
+ } else {
+ pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target);
+ }
+ return pbufferDrawable;
}
/**
@@ -489,7 +488,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
WrappedSurface ns = new WrappedSurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
capsChosen, capsRequested, chooser, screen) );
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 989906514..d472d0358 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -37,7 +37,6 @@ import java.util.ArrayList;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
@@ -48,13 +47,14 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.windows.DWM_BLURBEHIND;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.MARGINS;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLGraphicsConfigurationUtil;
-public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
// Keep this under the same debug flag as the drawable factory for convenience
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
@@ -733,10 +733,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
- pfd.setNSize((short) pfd.size());
+ pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
pfd.setNVersion((short) 1);
if(0 != hdc && 1 <= pfdID) {
- if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ if (GDI.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
// Accelerated pixel formats that are non displayable
if(DEBUG) {
System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
index 68bdb4ab8..720a1c293 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
@@ -59,7 +59,7 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
dummyWindow = X11Util.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim);
ns.setSurfaceHandle( dummyWindow );
- ns.setSize(f_dim, f_dim);
+ ns.surfaceSizeChanged(f_dim, f_dim);
updateHandle();
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index eb286cdf0..c3d2530f2 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -85,7 +85,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
}
WrappedSurface ns = new WrappedSurface(cfg);
ns.setSurfaceHandle(drawable);
- ns.setSize(w, h);
+ ns.surfaceSizeChanged(w, h);
return new X11ExternalGLXDrawable(factory, ns);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index d2ce629df..d27b9a92b 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -42,6 +42,7 @@ package jogamp.opengl.x11.glx;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
+
import jogamp.opengl.*;
public abstract class X11GLXDrawable extends GLDrawableImpl {
@@ -64,9 +65,10 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
}
}
- protected void swapBuffersImpl() {
- GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
- }
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ }
//---------------------------------------------------------------------------
// Internals only below this point
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 51316dc77..d040775ed 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -423,7 +423,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
WrappedSurface ns = new WrappedSurface(
X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen) );
if(ns != null) {
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
}
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 8ef642322..8cea2a550 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -56,14 +56,16 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
}
@SuppressWarnings("unused")
+ @Override
public long getHandle() {
if(USE_GLXWINDOW && useGLXWindow) {
return glXWindow;
}
- return getNativeSurface().getSurfaceHandle();
+ return super.getHandle();
}
@SuppressWarnings("unused")
+ @Override
protected void destroyHandle() {
if(USE_GLXWINDOW && 0!=glXWindow) {
GLX.glXDestroyWindow(getNativeSurface().getDisplayHandle(), glXWindow);
@@ -72,7 +74,7 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
}
}
- /** must be locked already */
+ @Override
protected void updateHandle() {
if(USE_GLXWINDOW) {
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index 8ea989267..7bfffd091 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -48,24 +48,24 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
/* GLCapabilities caps,
GLCapabilitiesChooser chooser,
int width, int height */
- super(factory, target, true);
+ super(factory, target, false);
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer();
+ setRealized(true);
if (DEBUG) {
System.err.println("Created pbuffer " + this);
}
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
@@ -73,7 +73,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
return new X11PbufferGLXContext(this, shareWith);
}
- protected void destroyImpl() {
+ protected void destroyPbuffer() {
NativeSurface ns = getNativeSurface();
if (ns.getSurfaceHandle() != 0) {
GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle());
@@ -86,7 +86,10 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
AbstractGraphicsScreen aScreen = config.getScreen();
AbstractGraphicsDevice aDevice = aScreen.getDevice();
long display = aDevice.getHandle();
- int screen = aScreen.getIndex();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
if (display==0) {
throw new GLException("Null display");
@@ -129,17 +132,11 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
int width = tmp[0];
GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
int height = tmp[0];
- ((SurfaceChangeable)ns).setSize(width, height);
+ ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
}
public int getFloatingPointMode() {
// Floating-point pbuffers currently require NVidia hardware on X11
return GLPbuffer.NV_FLOAT;
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index f5d321561..6ede6e13d 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -48,15 +48,19 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
private long pixmap;
protected X11PixmapGLXDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
- create();
+ super(factory, target, false);
+ setRealized(true);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- create();
+ createPixmap();
} else {
- destroyImpl();
+ destroyPixmap();
}
}
@@ -64,7 +68,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
return new X11PixmapGLXContext(this, shareWith);
}
- private void create() {
+ private void createPixmap() {
NativeSurface ns = getNativeSurface();
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
XVisualInfo vis = config.getXVisualInfo();
@@ -93,7 +97,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
}
}
- protected void destroyImpl() {
+ protected void destroyPixmap() {
if (pixmap == 0) return;
NativeSurface ns = getNativeSurface();
@@ -128,10 +132,4 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
((SurfaceChangeable)ns).setSurfaceHandle(0);
display = 0;
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/native/macosx/ContextUpdater.h b/src/jogl/native/macosx/ContextUpdater.h
index 3cf7315af..f00b2be57 100644
--- a/src/jogl/native/macosx/ContextUpdater.h
+++ b/src/jogl/native/macosx/ContextUpdater.h
@@ -25,17 +25,13 @@ This notification is sent whenever an NSView that has an attached NSSurface chan
@interface ContextUpdater : NSObject
{
@protected
+ pthread_mutex_t resourceLock;
NSView * view;
NSRect viewRect;
NSOpenGLContext *ctx;
BOOL viewUpdated;
}
-- (void) lock;
-- (void) lockInFunction:(char *)func atLine:(int)line;
-- (void) unlock;
-- (void) unlockInFunction:(char *)func atLine:(int)line;
-
- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView;
- (void) update:(NSNotification *)notification;
diff --git a/src/jogl/native/macosx/ContextUpdater.m b/src/jogl/native/macosx/ContextUpdater.m
index 21f98ad5e..a3b9b5c8c 100644
--- a/src/jogl/native/macosx/ContextUpdater.m
+++ b/src/jogl/native/macosx/ContextUpdater.m
@@ -1,43 +1,26 @@
#import "ContextUpdater.h"
#import <pthread.h>
-@implementation ContextUpdater
-{
-}
-
-static pthread_mutex_t resourceLock = PTHREAD_MUTEX_INITIALIZER;
-
-static void printLockDebugInfo(char *message, char *func, int line)
-{
- fprintf(stderr, "%s in function: \"%s\" at line: %d\n", message, func, line);
- fflush(NULL);
-}
-
-- (void) lock
-{
- pthread_mutex_lock(&resourceLock);
-}
+#define VERBOSE_ON 1
-- (void) lockInFunction:(char *)func atLine:(int)line
-{
- printLockDebugInfo("locked ", func, line);
- [self lock];
-}
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
-- (void) unlock
-{
- pthread_mutex_unlock(&resourceLock);
-}
+#ifndef CGL_VERSION_1_3
+ #warning this SDK doesn't support OpenGL profile
+#endif
-- (void) unlockInFunction:(char *)func atLine:(int)line
+@implementation ContextUpdater
{
- printLockDebugInfo("unlocked", func, line);
- [self unlock];
}
- (void) update:(NSNotification *)notification
{
- [self lock];
+ pthread_mutex_lock(&resourceLock);
NSRect r = [view frame];
if(viewRect.origin.x != r.origin.x ||
@@ -47,41 +30,47 @@ static void printLockDebugInfo(char *message, char *func, int line)
viewUpdated = TRUE;
viewRect = r;
}
-
- [self unlock];
+
+ pthread_mutex_unlock(&resourceLock);
}
- (BOOL) needsUpdate
{
BOOL r;
- [self lock];
+ pthread_mutex_lock(&resourceLock);
r = viewUpdated;
viewUpdated = FALSE;
- [self unlock];
+ pthread_mutex_unlock(&resourceLock);
return r;
}
- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView
{
+ DBG_PRINT("ContextUpdater::init.0 view %p, ctx %p\n", view, ctx);
+ pthread_mutex_init(&resourceLock, NULL); // fast non-recursive
ctx = context;
view = nsView;
[ctx retain];
[view retain];
viewRect = [view frame];
- viewUpdated = FALSE;
+ viewUpdated = TRUE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view];
+ DBG_PRINT("ContextUpdater::init.X\n");
return [super init];
}
- (void) dealloc
{
+ DBG_PRINT("ContextUpdater::dealloc.0 view %p, ctx %p\n", view, ctx);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[view release];
[ctx release];
+ pthread_mutex_destroy(&resourceLock);
+ DBG_PRINT("ContextUpdater::dealloc.X\n");
[super dealloc];
}
diff --git a/src/jogl/native/macosx/MacOSXCustomCGLCode.c b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
index c29be889d..f8b7a800f 100644
--- a/src/jogl/native/macosx/MacOSXCustomCGLCode.c
+++ b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
@@ -5,8 +5,7 @@
#include </usr/include/machine/types.h>
#include "macosx-window-system.h"
-void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) {
- CGLPixelFormatObj pix = (CGLPixelFormatObj) pixelFormat;
+void CGLQueryPixelFormat(CGLPixelFormatObj fmt, int* iattrs, int niattrs, int* ivalues) {
// FIXME: think about how specifying this might affect the API
int virtualScreen = 0;
@@ -14,7 +13,7 @@ void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalu
GLint value;
for (i = 0; i < niattrs && iattrs[i]>0; i++) {
CGLPixelFormatAttribute attr = (CGLPixelFormatAttribute) iattrs[i];
- if ( kCGLNoError == CGLDescribePixelFormat(pix, virtualScreen, attr, &value) ) {
+ if ( kCGLNoError == CGLDescribePixelFormat(fmt, virtualScreen, attr, &value) ) {
ivalues[i] = value;
} else {
ivalues[i] = 0;
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m
new file mode 100644
index 000000000..7233f40ce
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m
@@ -0,0 +1,140 @@
+
+@interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+@protected
+ NSOpenGLContext* ctxShared;
+ NSView* view;
+ NSOpenGLPixelFormat* fmt;
+@public
+ volatile BOOL shallDraw;
+}
+
+- (id) initWithContext: (NSOpenGLContext*) ctx
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ view: (NSView*) v
+ opaque: (Bool) opaque;
+
+@end
+
+@implementation MyNSOpenGLLayer
+
+- (id) initWithContext: (NSOpenGLContext*) _ctx
+ pixelFormat: (NSOpenGLPixelFormat*) _fmt
+ view: (NSView*) _view
+ opaque: (Bool) opaque
+{
+ self = [super init];
+ ctxShared = _ctx;
+ [ctxShared retain];
+
+ fmt = _fmt;
+ [fmt retain];
+
+ view = _view;
+ [view retain];
+ [self setView: view];
+ [view setLayer: self];
+ [view setWantsLayer: YES];
+
+ [self setAsynchronous: NO];
+ // [self setAsynchronous: YES]; // FIXME: JAU
+ [self setNeedsDisplayOnBoundsChange: NO];
+ [self setOpaque: opaque ? YES : NO];
+ shallDraw = NO;
+ textureID = 0;
+ DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, view %p, opaque %d\n", self, ctx, fmt, view, opaque);
+ return self;
+}
+
+- (void)dealloc
+{
+ [fmt release];
+ [ctxShared release];
+ [view release];
+ DBG_PRINT("MyNSOpenGLLayer::dealloc %p\n", self);
+ [super dealloc];
+}
+
+- (void) setOpenGLContext: (NSOpenGLContext*) _ctx
+{
+ DBG_PRINT("MyNSOpenGLLayer::setOpenGLContext: %p %p -> %p\n", self, [self openGLContext], _ctx);
+ [super setOpenGLContext: _ctx];
+}
+
+- (void) setOpenGLPixelFormat: (NSOpenGLPixelFormat*) _fmt
+{
+ DBG_PRINT("MyNSOpenGLLayer::setOpenGLPixelFormat %p %p -> %p\n", self, fmt, _fmt);
+ [super setOpenGLPixelFormat: fmt];
+}
+
+- (NSOpenGLPixelFormat *) openGLPixelFormat
+{
+ return fmt;
+}
+
+- (void) setView: (NSView*) v
+{
+ DBG_PRINT("MyNSOpenGLLayer::setView %p %p -> %p (ignored/propagated)\n", self, view, v);
+ [super setView: view]; // propagate
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask %p %d -> %p\n", self, mask, fmt);
+ return fmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ NSOpenGLContext* ctx = NULL;
+ if(NULL == ctx) {
+ int viewNotReady[] = { 0 };
+ ctx = createContext(ctxShared, view, true, fmt, [self isOpaque], viewNotReady);
+ }
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat %p, fmt %p/%p, view %p, shared %p -> %p\n",
+ self, fmt, pixelFormat, view, ctxShared, ctx);
+ return ctx;
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ DBG_PRINT("MyNSOpenGLLayer::canDrawInOpenGLContext %p: %d\n", self, self->shallDraw);
+ return self->shallDraw;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ self->shallDraw = NO;
+
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p\n", self, context, pixelFormat);
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+}
+
+@end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque) {
+ return [[MyNSOpenGLLayer alloc] initWithContext:ctx pixelFormat: fmt view: view opaque: opaque];
+}
+
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ l->shallDraw = YES;
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
+ // NSView* view = [l view];
+ // [view setNeedsDisplay: YES]; // FIXME: JAU
+ // [view performSelectorOnMainThread:@selector(setNeedsDisplay:) withObject:YES waitUntilDone:YES];
+ // [view performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES];
+ DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* l) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [l release];
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
new file mode 100644
index 000000000..47f679fac
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
@@ -0,0 +1,466 @@
+#import "MacOSXWindowSystemInterface.h"
+#import <QuartzCore/QuartzCore.h>
+#import <pthread.h>
+#include "timespec.h"
+
+//
+// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
+// Use CVDisplayLink otherwise.
+//
+// #define HAS_CADisplayLink 1
+//
+
+// lock/sync debug output
+//
+// #define DBG_SYNC 1
+//
+#ifdef DBG_SYNC
+ // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define SYNC_PRINT(...)
+#endif
+
+// fps debug output
+//
+// #define DBG_PERF 1
+
+@interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+@protected
+ NSOpenGLPixelBuffer* pbuffer;
+ int texWidth;
+ int texHeight;
+ GLuint textureID;
+ GLint swapInterval;
+#ifdef HAS_CADisplayLink
+ CADisplayLink* displayLink;
+#else
+ CVDisplayLinkRef displayLink;
+#endif
+ int tc;
+ struct timespec t0;
+@public
+ pthread_mutex_t renderLock;
+ pthread_cond_t renderSignal;
+ BOOL shallDraw;
+}
+
+- (id) setupWithContext: (NSOpenGLContext*) ctx
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ opaque: (Bool) opaque
+ texWidth: (int) texWidth
+ texHeight: (int) texHeight;
+
+- (void)deallocTex;
+- (void)disableAnimation;
+- (int)getSwapInterval;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+
+@end
+
+#ifndef HAS_CADisplayLink
+
+static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
+ pthread_mutex_lock(&l->renderLock);
+ #ifdef DBG_PERF
+ [l tick];
+ #endif
+ pthread_cond_signal(&l->renderSignal);
+ SYNC_PRINT("-*-");
+ pthread_mutex_unlock(&l->renderLock);
+ [pool release];
+ return kCVReturnSuccess;
+}
+
+#endif
+
+@implementation MyNSOpenGLLayer
+
+- (id) setupWithContext: (NSOpenGLContext*) _ctx
+ pixelFormat: (NSOpenGLPixelFormat*) _fmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ opaque: (Bool) opaque
+ texWidth: (int) _texWidth
+ texHeight: (int) _texHeight;
+{
+ pthread_mutex_init(&renderLock, NULL); // fast non-recursive
+ pthread_cond_init(&renderSignal, NULL); // no attribute
+
+ pbuffer = p;
+ [pbuffer retain];
+
+ // instantiate a deactivated displayLink
+#ifdef HAS_CADisplayLink
+ displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
+ [displayLink setPaused: YES];
+#else
+ CVReturn cvres;
+ {
+ int allDisplaysMask = 0;
+ int virtualScreen, accelerated, displayMask;
+ for (virtualScreen = 0; virtualScreen < [_fmt numberOfVirtualScreens]; virtualScreen++) {
+ [_fmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
+ [_fmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
+ if (accelerated) {
+ allDisplaysMask |= displayMask;
+ }
+ }
+ cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [_ctx CGLContextObj], [_fmt CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ CVDisplayLinkStop(displayLink);
+ }
+#endif
+ [self setAsynchronous: YES];
+
+ [self setNeedsDisplayOnBoundsChange: YES]; // FIXME: learn how to recreate on size change!
+ [self setOpaque: opaque ? YES : NO];
+ texWidth = _texWidth;
+ texHeight = _texHeight;
+ textureID = 0;
+ swapInterval = -1;
+ shallDraw = NO;
+
+ CGRect lRect = [self frame];
+
+ DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n",
+ self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+ return self;
+}
+
+- (void)disableAnimation
+{
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+ pthread_mutex_lock(&renderLock);
+ [self setAsynchronous: NO];
+ if(NULL != displayLink) {
+#ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ [displayLink release];
+#else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStop(displayLink);
+ CVDisplayLinkRelease(displayLink);
+ }
+#endif
+ displayLink = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)deallocTex
+{
+ pthread_mutex_lock(&renderLock);
+ NSOpenGLContext* context = [self openGLContext];
+ DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer);
+ if(NULL != pbuffer) {
+ if(NULL!=context) {
+ [context makeCurrentContext];
+ if(0 != textureID) {
+ glDeleteTextures(1, &textureID);
+ textureID = 0;
+ }
+ [context clearDrawable];
+ }
+ [pbuffer release];
+ pbuffer = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [self disableAnimation];
+ [self deallocTex];
+ pthread_cond_destroy(&renderSignal);
+ pthread_mutex_destroy(&renderLock);
+ [super dealloc];
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext'
+ // are called from the same thread subsequently
+ pthread_mutex_lock(&renderLock);
+ Bool res = NULL != pbuffer && YES == shallDraw;
+ if(!res) {
+ SYNC_PRINT("<0>");
+ pthread_mutex_unlock(&renderLock);
+ } else {
+ SYNC_PRINT("<");
+ }
+ return res;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ [context makeCurrentContext];
+ // FIXME ?? [context update];
+
+ /**
+ * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
+ * Using CVDisplayLink .. see setSwapInterval() below.
+ *
+ if(0 <= swapInterval) {
+ GLint si;
+ [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
+ if(si != swapInterval) {
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
+ [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ }
+ } */
+ GLenum textureTarget = [pbuffer textureTarget];
+ GLfloat tWidth, tHeight;
+ {
+ GLsizei pwidth = [pbuffer pixelsWide];
+ GLsizei pheight = [pbuffer pixelsHigh];
+ tWidth = textureTarget == GL_TEXTURE_2D ? (GLfloat)pwidth /(GLfloat)texWidth : pwidth;
+ tHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)pheight/(GLfloat)texHeight : pheight;
+ }
+ Bool texCreated = 0 == textureID;
+
+ if(texCreated) {
+ glGenTextures(1, &textureID);
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p tex %dx%d -> %fx%f 0x%X: creating texID 0x%X\n",
+ self, context, pixelFormat, texWidth, texHeight, tWidth, tHeight, textureTarget, textureID);
+
+ CGRect lRect = [self frame];
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p frame0: %lf/%lf %lfx%lf\n",
+ self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+ if(lRect.origin.x<0 || lRect.origin.y<0) {
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ [self setFrame: lRect];
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p frame*: %lf/%lf %lfx%lf\n",
+ self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+ }
+ }
+
+ glBindTexture(textureTarget, textureID);
+
+ /**
+ if(texCreated) {
+ // proper tex size setup
+ glTexImage2D(textureTarget, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ } */
+
+ [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
+
+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glEnable(textureTarget);
+
+ static GLfloat verts[] = {
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+ };
+
+ GLfloat tex[] = {
+ 0.0, 0.0,
+ 0.0, tHeight,
+ tWidth, tHeight,
+ tWidth, 0.0
+ };
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(textureTarget);
+ glBindTexture(textureTarget, 0);
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+ shallDraw = NO;
+ if(0 >= swapInterval) {
+ pthread_cond_signal(&renderSignal);
+ SYNC_PRINT("*");
+ }
+ SYNC_PRINT("1>");
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (int)getSwapInterval
+{
+ return swapInterval;
+}
+
+- (void)setSwapInterval:(int)interval
+{
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval: %d\n", interval);
+ swapInterval = interval;
+ if(0 < swapInterval) {
+ tc = 0;
+ timespec_now(&t0);
+
+ [self setAsynchronous: NO];
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: NO];
+ [displayLink setFrameInterval: interval];
+ #else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStart(displayLink);
+ // FIXME: doesn't support interval ..
+ }
+ #endif
+ } else {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ #else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStop(displayLink);
+ }
+ #endif
+ [self setAsynchronous: YES];
+ }
+}
+
+-(void)tick
+{
+ tc++;
+ if(tc%60==0) {
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
+ td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
+ fflush(NULL);
+ }
+}
+
+@end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) {
+ // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
+ // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
+ // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
+
+ return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
+}
+
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ pthread_mutex_lock(&l->renderLock);
+ [l setSwapInterval: interval];
+ pthread_mutex_unlock(&l->renderLock);
+}
+
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_ms) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ BOOL ready = NO;
+ int wr = 0;
+ pthread_mutex_lock(&l->renderLock);
+ SYNC_PRINT("{");
+ do {
+ if([l getSwapInterval] <= 0) {
+ ready = !l->shallDraw;
+ }
+ if(NO == ready) {
+ if(0 < to_ms) {
+ struct timespec to_abs;
+ timespec_now(&to_abs);
+ timespec_addms(&to_abs, to_ms);
+ wr = pthread_cond_timedwait(&l->renderSignal, &l->renderLock, &to_abs);
+ #ifdef DBG_SYNC
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &to_abs);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "%ld ms", td_ms);
+ #endif
+ } else {
+ pthread_cond_wait (&l->renderSignal, &l->renderLock);
+ }
+ ready = !l->shallDraw;
+ }
+ } while (NO == ready && 0 == wr) ;
+ SYNC_PRINT("-%d}", ready);
+ pthread_mutex_unlock(&l->renderLock);
+}
+
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ @synchronized(l) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ pthread_mutex_lock(&l->renderLock);
+ SYNC_PRINT("[");
+ l->shallDraw = YES;
+ if([l getSwapInterval] > 0) {
+ // only trigger update if async mode is off (swapInterval>0)
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // can't wait, otherwise we may deadlock AWT
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ SYNC_PRINT("1]");
+ } else {
+ SYNC_PRINT("0]");
+ }
+ pthread_mutex_unlock(&l->renderLock);
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+ }
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p (refcnt %d)\n", l, (int)[l retainCount]);
+
+ [l performSelectorOnMainThread:@selector(disableAnimation) withObject:nil waitUntilDone:YES];
+ // [l disableAnimation];
+
+ [l performSelectorOnMainThread:@selector(deallocTex) withObject:nil waitUntilDone:YES];
+ // [l deallocTex];
+
+ [l release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p (refcnt %d)\n", l, (int)[l retainCount]);
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.h b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h
new file mode 100644
index 000000000..b2d7f9db8
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h
@@ -0,0 +1,20 @@
+#import <Cocoa/Cocoa.h>
+#import <OpenGL/gl.h>
+#import <OpenGL/CGLTypes.h>
+#import <jni.h>
+
+#define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+#ifndef CGL_VERSION_1_3
+ #warning this SDK doesn't support OpenGL profile
+#endif
+
+#import "macosx-window-system.h"
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 751fba9c0..af269a4b5 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -14,19 +14,10 @@
#endif
*/
-#import <Cocoa/Cocoa.h>
-#import <OpenGL/gl.h>
-#import <OpenGL/CGLTypes.h>
-#import <jni.h>
-
-#ifndef CGL_VERSION_1_3
- #warning this SDK doesn't support OpenGL profile
-#endif
+#import "MacOSXWindowSystemInterface.h"
#import "ContextUpdater.h"
-#import "macosx-window-system.h"
-
// see MacOSXPbufferGLContext.java createPbuffer
#define USE_GL_TEXTURE_RECTANGLE_EXT
@@ -377,7 +368,7 @@ long validateParameter(NSOpenGLPixelFormatAttribute attribute, long value)
return value;
}
-void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
+NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
getRendererInfo();
@@ -390,6 +381,18 @@ void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
for (i = 0; i < niattrs && iattrs[i]>0; i++) {
int attr = iattrs[i];
switch (attr) {
+ case NSOpenGLPFANoRecovery:
+ if (ivalues[i] != 0) {
+ attribs[idx++] = NSOpenGLPFANoRecovery;
+ }
+ break;
+
+ case NSOpenGLPFAAccelerated:
+ if (ivalues[i] != 0) {
+ attribs[idx++] = NSOpenGLPFAAccelerated;
+ }
+ break;
+
case NSOpenGLPFAPixelBuffer:
if (ivalues[i] != 0) {
attribs[idx++] = NSOpenGLPFAPixelBuffer;
@@ -451,9 +454,8 @@ void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
return fmt;
}
-void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) {
+void queryPixelFormat(NSOpenGLPixelFormat* fmt, int* iattrs, int niattrs, int* ivalues) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
GLint tmp;
// FIXME: think about how specifying this might affect the API
GLint virtualScreen = 0;
@@ -468,16 +470,43 @@ void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues)
[pool release];
}
-void deletePixelFormat(void* pixelFormat) {
+void deletePixelFormat(NSOpenGLPixelFormat* fmt) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
[fmt release];
[pool release];
}
-void* createContext(void* shareContext,
- void* view,
- void* pixelFormat,
+NSOpenGLContext* getCurrentContext() {
+ NSOpenGLContext *ctx = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ ctx = [NSOpenGLContext currentContext];
+ [pool release];
+ return ctx;
+}
+
+CGLContextObj getCGLContext(NSOpenGLContext* ctx) {
+ void * cglContext = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ cglContext = [ctx CGLContextObj];
+ [pool release];
+ return cglContext;
+}
+
+NSView* getNSView(NSOpenGLContext* ctx) {
+ NSView* view = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ view = [ctx view];
+ [pool release];
+ return view;
+}
+
+NSOpenGLContext* createContext(NSOpenGLContext* share,
+ NSView* view,
+ Bool isBackingLayerView,
+ NSOpenGLPixelFormat* fmt,
Bool opaque,
int* viewNotReady)
{
@@ -485,27 +514,22 @@ void* createContext(void* shareContext,
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSView *nsView = NULL;
- NSObject *nsObj = (NSObject*) view;
-
- if( nsObj != NULL && [nsObj isKindOfClass:[NSView class]] ) {
- nsView = (NSView*)nsObj;
- }
-
- if (nsView != NULL)
- {
+ if (view != NULL) {
Bool viewReady = true;
- if ([nsView lockFocusIfCanDraw] == NO)
- {
- viewReady = false;
+ if(!isBackingLayerView) {
+ if ([view lockFocusIfCanDraw] == NO) {
+ DBG_PRINT("createContext [view lockFocusIfCanDraw] failed\n");
+ viewReady = false;
+ }
}
- else
- {
- NSRect frame = [nsView frame];
- if ((frame.size.width == 0) || (frame.size.height == 0))
- {
- [nsView unlockFocus];
+ if(viewReady) {
+ NSRect frame = [view frame];
+ if ((frame.size.width == 0) || (frame.size.height == 0)) {
+ if(!isBackingLayerView) {
+ [view unlockFocus];
+ }
+ DBG_PRINT("createContext view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
viewReady = false;
}
}
@@ -523,126 +547,80 @@ void* createContext(void* shareContext,
}
}
- NSOpenGLContext* nsContext = [[NSOpenGLContext alloc]
- initWithFormat: (NSOpenGLPixelFormat*) pixelFormat
- shareContext: (NSOpenGLContext*) shareContext];
+ NSOpenGLContext* ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share];
- if (nsContext != nil) {
- if (nsView != nil) {
- if(!opaque) {
- GLint zeroOpacity = 0;
- [nsContext setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
- }
- [nsContext setView:nsView];
- [nsView unlockFocus];
- }
+ if (ctx != nil) {
+ if (view != nil) {
+ if(!opaque) {
+ GLint zeroOpacity = 0;
+ [ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
+ }
+ [ctx setView:view];
+ if(!isBackingLayerView) {
+ [view unlockFocus];
}
+ }
+ }
[pool release];
- return nsContext;
-}
-
-void * getCurrentContext() {
- NSOpenGLContext *nsContext = NULL;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- nsContext = [NSOpenGLContext currentContext];
- [pool release];
- return nsContext;;
-}
-
-void * getCGLContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- void * cglContext = NULL;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- cglContext = [nsContext CGLContextObj];
- [pool release];
- return cglContext;
+ return ctx;
}
-void * getNSView(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- void * view = NULL;
-
+Bool makeCurrentContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- view = [nsContext view];
- [pool release];
- return view;
-}
-
-Bool makeCurrentContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext makeCurrentContext];
+ [ctx makeCurrentContext];
[pool release];
return true;
}
-Bool clearCurrentContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool clearCurrentContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSOpenGLContext *currentNSContext = [NSOpenGLContext currentContext];
- if( currentNSContext != nsContext ) {
- [nsContext makeCurrentContext];
+ if( currentNSContext != ctx ) {
+ [ctx makeCurrentContext];
}
[NSOpenGLContext clearCurrentContext];
[pool release];
return true;
}
-Bool deleteContext(void* nsJContext, Bool releaseOnMainThread) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool deleteContext(NSOpenGLContext* ctx, Bool releaseOnMainThread) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext clearDrawable];
+ [ctx clearDrawable];
if(releaseOnMainThread && NO == [NSThread isMainThread]) {
- [nsContext performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES];
+ [ctx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES];
} else {
// would hangs for ~10s for 1 of a shared context set or offscreen context, set releaseOnMainThread=true !
- [nsContext release];
+ [ctx release];
}
[pool release];
return true;
}
-Bool flushBuffer(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool flushBuffer(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext flushBuffer];
+ [ctx flushBuffer];
[pool release];
return true;
}
-void setContextOpacity(void* nsJContext, int opacity) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
- [nsContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
+void setContextOpacity(NSOpenGLContext* ctx, int opacity) {
+ [ctx setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
}
-void updateContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+void updateContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext update];
+ [ctx update];
[pool release];
}
-void copyContext(void* destContext, void* srcContext, int mask) {
- NSOpenGLContext *src = (NSOpenGLContext*) srcContext;
- NSOpenGLContext *dst = (NSOpenGLContext*) destContext;
- [dst copyAttributesFromContext: src withMask: mask];
+void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask) {
+ [dest copyAttributesFromContext: src withMask: mask];
}
-void* updateContextRegister(void* nsJContext, void* nsJView) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSView *nsView = (NSView*)nsJView;
-
+void* updateContextRegister(NSOpenGLContext* ctx, NSView* view) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: nsContext view: nsView];
+ ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: ctx view: view];
[pool release];
return contextUpdater;
}
@@ -666,7 +644,7 @@ void updateContextUnregister(void* updater) {
[pool release];
}
-void* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
+NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
initWithTextureTarget:renderTarget
@@ -678,35 +656,25 @@ void* createPBuffer(int renderTarget, int internalFormat, int width, int height)
return pBuffer;
}
-Bool destroyPBuffer(void* buffer) {
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[pBuffer release];
[pool release];
-
return true;
}
-void setContextPBuffer(void* nsJContext, void* buffer) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext setPixelBuffer: pBuffer
+ [ctx setPixelBuffer: pBuffer
cubeMapFace: 0
mipMapLevel: 0
- currentVirtualScreen: [nsContext currentVirtualScreen]];
+ currentVirtualScreen: [ctx currentVirtualScreen]];
[pool release];
}
-void setContextTextureImageToPBuffer(void* nsJContext, void* buffer, int colorBuffer) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext setTextureImageToPixelBuffer: pBuffer
- colorBuffer: (unsigned long) colorBuffer];
+ [ctx setTextureImageToPixelBuffer: pBuffer colorBuffer: colorBuffer];
[pool release];
}
@@ -746,10 +714,9 @@ void* getProcAddress(const char *procname) {
return NULL;
}
-void setSwapInterval(void* nsJContext, int interval) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
+void setSwapInterval(NSOpenGLContext* ctx, int interval) {
GLint swapInterval = interval;
- [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ [ctx setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
}
Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp) {
diff --git a/src/jogl/native/timespec.c b/src/jogl/native/timespec.c
new file mode 100644
index 000000000..74c1a6901
--- /dev/null
+++ b/src/jogl/native/timespec.c
@@ -0,0 +1,63 @@
+#include "timespec.h"
+#include <sys/time.h>
+
+void timespec_now(struct timespec *ts)
+{
+ struct timeval tv;
+
+ // not using clock_gettime() [of rt library] due to portability
+ gettimeofday(&tv, NULL);
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec*1000;
+}
+
+void timespec_addms(struct timespec *ts, long ms)
+{
+ int sec=ms/1000;
+ ms=ms-sec*1000;
+
+ // perform the addition
+ ts->tv_nsec+=ms*1000000;
+
+ // adjust the time
+ ts->tv_sec+=ts->tv_nsec/1000000000 + sec;
+ ts->tv_nsec=ts->tv_nsec%1000000000;
+}
+
+void timespec_addns(struct timespec *ts, long ns)
+{
+ int sec=ns/1000000000;
+ ns=ns - sec*1000000000;
+
+ // perform the addition
+ ts->tv_nsec+=ns;
+
+ // adjust the time
+ ts->tv_sec+=ts->tv_nsec/1000000000 + sec;
+ ts->tv_nsec=ts->tv_nsec%1000000000;
+
+}
+
+int timespec_compare(struct timespec *a, struct timespec *b)
+{
+ if (a->tv_sec!=b->tv_sec)
+ return a->tv_sec-b->tv_sec;
+ return a->tv_nsec-b->tv_nsec;
+}
+
+void timespec_subtract(struct timespec *r, struct timespec *a, struct timespec *b)
+{
+ r->tv_sec = a->tv_sec;
+ r->tv_nsec = a->tv_nsec - b->tv_nsec;
+ if (r->tv_nsec < 0) {
+ // borrow.
+ r->tv_nsec += 1000000000;
+ r->tv_sec --;
+ }
+ r->tv_sec = r->tv_sec - b->tv_sec;
+}
+
+long timespec_milliseconds(struct timespec *a)
+{
+ return a->tv_sec*1000 + a->tv_nsec/1000000;
+}
diff --git a/src/jogl/native/timespec.h b/src/jogl/native/timespec.h
new file mode 100644
index 000000000..671eb4716
--- /dev/null
+++ b/src/jogl/native/timespec.h
@@ -0,0 +1,19 @@
+#ifndef _timespec_h
+#define _timespec_h
+
+#include <time.h>
+
+void timespec_now(struct timespec *ts);
+void timespec_addms(struct timespec *ts, long ms);
+void timespec_addns(struct timespec *ts, long ns);
+
+/** returns 0: a==b, >0: a>b, <0: a<b */
+int timespec_compare(struct timespec *a, struct timespec *b);
+
+/** computes r = a - b */
+void timespec_subtract(struct timespec *r, struct timespec *a, struct timespec *b);
+
+/** convert the timespec into milliseconds (may overflow) */
+long timespec_milliseconds(struct timespec *a);
+
+#endif /* _timespec_h */
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
index ffa8bfae6..3eb7a6c9a 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
@@ -84,8 +84,6 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics
* The use case for setting the Capabilities at a later time is
* a change of the graphics device in a multi-screen environment.<br>
*
- * The objects reference is being used.
- *
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
protected void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index fa3923dcf..e510c0b78 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -60,9 +60,9 @@ import java.util.Map;
public abstract class GraphicsConfigurationFactory {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
- private static Map/*<Class, NativeWindowFactory>*/ registeredFactories =
- Collections.synchronizedMap(new HashMap());
- private static Class abstractGraphicsDeviceClass;
+ private static Map<Class<?>, GraphicsConfigurationFactory> registeredFactories =
+ Collections.synchronizedMap(new HashMap<Class<?>, GraphicsConfigurationFactory>());
+ private static Class<?> abstractGraphicsDeviceClass;
static {
initialize();
@@ -122,7 +122,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- public static GraphicsConfigurationFactory getFactory(Class abstractGraphicsDeviceImplementor)
+ public static GraphicsConfigurationFactory getFactory(Class<?> abstractGraphicsDeviceImplementor)
throws IllegalArgumentException, NativeWindowException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
@@ -130,10 +130,9 @@ public abstract class GraphicsConfigurationFactory {
}
GraphicsConfigurationFactory factory = null;
- Class clazz = abstractGraphicsDeviceImplementor;
+ Class<?> clazz = abstractGraphicsDeviceImplementor;
while (clazz != null) {
- factory =
- (GraphicsConfigurationFactory) registeredFactories.get(clazz);
+ factory = registeredFactories.get(clazz);
if (factory != null) {
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory);
@@ -143,7 +142,7 @@ public abstract class GraphicsConfigurationFactory {
clazz = clazz.getSuperclass();
}
// Return the default
- factory = (GraphicsConfigurationFactory)registeredFactories.get(abstractGraphicsDeviceClass);
+ factory = registeredFactories.get(abstractGraphicsDeviceClass);
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+abstractGraphicsDeviceClass+" -> "+factory);
}
@@ -157,7 +156,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- protected static void registerFactory(Class abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
+ protected static void registerFactory(Class<?> abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
throws IllegalArgumentException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index e691ba8e6..b2a2bc4ee 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -118,6 +118,24 @@ public interface NativeSurface extends SurfaceUpdatedListener {
*/
public boolean surfaceSwap();
+ /** Appends the given {@link SurfaceUpdatedListener} to the end of the list. */
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+ /**
+ * Inserts the given {@link SurfaceUpdatedListener} at the
+ * specified position in the list.<br>
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
+ * @param l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
+
+ /** Remove the specified {@link SurfaceUpdatedListener} from the list. */
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
/**
* Returns the handle to the surface for this NativeSurface. <P>
*
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
index 76ac72953..e3ee85cf4 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
@@ -126,4 +126,7 @@ public interface NativeWindow extends NativeSurface {
*/
public Point getLocationOnScreen(Point point);
+ /** Returns true if this native window owns the focus, otherwise false. */
+ boolean hasFocus();
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index ef8876f50..b6c850098 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,15 +33,20 @@
package javax.media.nativewindow;
-import java.security.*;
-import java.util.*;
-
-import com.jogamp.common.util.*;
-import com.jogamp.common.os.Platform;
-
-import jogamp.nativewindow.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NativeWindowFactoryImpl;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
/** Provides a pluggable mechanism for arbitrary window toolkits to
adapt their components to the {@link NativeWindow} interface,
@@ -470,4 +475,33 @@ public abstract class NativeWindowFactory {
NativeWindow. Implementors of concrete NativeWindowFactory
subclasses should override this method. */
protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException;
+
+ /**
+ * Returns the {@link OffscreenLayerSurface} instance of this {@link NativeSurface}.
+ * <p>
+ * In case this surface is a {@link NativeWindow}, we traverse from the given surface
+ * up to root until a {@link OffscreenLayerSurface} is found.
+ * </p>
+ *
+ * @param surface The surface to query.
+ * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerSurface#isOffscreenLayerSurfaceEnabled()}.
+ * @return
+ */
+ public static OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled) {
+ if(surface instanceof OffscreenLayerSurface) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface;
+ return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ if(surface instanceof NativeWindow) {
+ NativeWindow nw = ((NativeWindow) surface).getParent();
+ while(null != nw) {
+ if(nw instanceof OffscreenLayerSurface) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw;
+ return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ nw = nw.getParent();
+ }
+ }
+ return null;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
new file mode 100644
index 000000000..82ae0f39e
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2011 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 javax.media.nativewindow;
+
+/**
+ * Interface specifying the offscreen layer surface protocol.
+ */
+public interface OffscreenLayerSurface {
+ /** Returns true if this instance uses an offscreen layer, otherwise false. */
+ public boolean isOffscreenLayerSurfaceEnabled();
+
+ /**
+ * Attach the offscreen layer to this offscreen layer surface.
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+
+ /**
+ * Detaches a previously attached offscreen layer from this offscreen layer surface.
+ * @see #attachSurfaceLayer(long)
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void detachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index e34476228..7380d19b6 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,6 +28,8 @@
package javax.media.nativewindow;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
@@ -38,6 +40,7 @@ public abstract class ProxySurface implements NativeSurface {
protected int height;
protected int scrnIndex;
protected int width;
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
public ProxySurface(AbstractGraphicsConfiguration cfg) {
invalidate();
@@ -73,7 +76,7 @@ public abstract class ProxySurface implements NativeSurface {
return height;
}
- public void setSize(int width, int height) {
+ public void surfaceSizeChanged(int width, int height) {
this.width = width;
this.height = height;
}
@@ -82,9 +85,22 @@ public abstract class ProxySurface implements NativeSurface {
return false;
}
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
}
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
+
public int lockSurface() throws NativeWindowException {
surfaceLock.lock();
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
@@ -143,5 +159,5 @@ public abstract class ProxySurface implements NativeSurface {
return surfaceLock.getOwner();
}
- public abstract String toString();
+ public abstract String toString();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
index fc32b57b3..956e68e61 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
@@ -41,8 +41,14 @@ package javax.media.nativewindow;
public interface SurfaceChangeable {
+ /** Sets the surface handle which is created outside of this implementation */
public void setSurfaceHandle(long surfaceHandle);
- public void setSize(int width, int height);
+
+ /**
+ * The surface's size has been determined or changed.
+ * Implementation shall update the stored surface size with the given ones.
+ */
+ public void surfaceSizeChanged(int width, int height);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
index 88e805d14..0912b5afe 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
@@ -34,8 +34,12 @@
package javax.media.nativewindow;
+/**
+ * Clients may add their SurfaceUpdateListener implementation to a {@link javax.media.nativewindow.NativeSurface}
+ * allowing to get notified after the surface has been updated, eg. after a swap buffer operation.
+ */
public interface SurfaceUpdatedListener {
- /** Notification of a surface update event.
+ /** Notification of a surface update event, eg. after a swap buffer operation.
*
* @param updater is the caller object who updated the surface,
* e.g. a JOGL GLDrawable.
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
index d83a92a5b..38ad2d795 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -41,6 +41,7 @@
package javax.media.nativewindow.awt;
import javax.media.nativewindow.*;
+
import java.awt.Component;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -98,12 +99,42 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
if(null==capsChosen) {
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
- capsChosen = setupCapabilitiesRGBABits(capsChosen, gc);
+ capsChosen = setupCapabilitiesRGBABits(capsRequested, gc);
}
return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig);
}
- @Override
+ public void updateGraphicsConfiguration(Component awtComp)
+ {
+ AWTGraphicsScreen awtScreen = null;
+ AWTGraphicsDevice awtDevice = null;
+ GraphicsDevice awtGraphicsDevice = null;
+ GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration();
+ if(null!=awtGfxConfig) {
+ awtGraphicsDevice = awtGfxConfig.getDevice();
+ if(null!=awtGraphicsDevice) {
+ // Create Device/Screen
+ awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
+ awtScreen = new AWTGraphicsScreen(awtDevice);
+ }
+ }
+ if(null==awtScreen) {
+ throw new NativeWindowException("native peer n/a: "+awtComp);
+ }
+ config = awtGfxConfig;
+ setScreen(awtScreen);
+
+ CapabilitiesImmutable caps = ( null != getChosenCapabilities() ) ? getChosenCapabilities() : getRequestedCapabilities();
+ GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
+ setChosenCapabilities(setupCapabilitiesRGBABits(caps, gc));
+ }
+
+ // open access to superclass method
+ public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
+ super.setChosenCapabilities(capsChosen);
+ }
+
+ @Override
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
index 100b6b839..9869e1eb3 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
@@ -32,8 +32,9 @@
package javax.media.nativewindow.x11;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.x11.XVisualInfo;
/** Encapsulates a graphics configuration, or OpenGL pixel format, on
@@ -42,7 +43,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
GraphicsConfigurationFactory.chooseGraphicsConfiguration()} on X11
platforms when toolkits other than the AWT are being used. */
-public class X11GraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
public X11GraphicsConfiguration(X11GraphicsScreen screen,
diff --git a/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
new file mode 100644
index 000000000..ee3ab73ba
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2011 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;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsConfiguration;
+
+public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
+ public MutableGraphicsConfiguration(AbstractGraphicsScreen screen,
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ }
+
+ public void setChosenCapabilities(CapabilitiesImmutable caps) {
+ super.setChosenCapabilities(caps);
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index d34d4e58f..5cb7d5aca 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -32,11 +32,16 @@
package jogamp.nativewindow;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.*;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
-import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
@@ -44,13 +49,10 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
public static ToolkitLock getNullToolkitLock() {
return nullToolkitLock;
}
-
+
// This subclass of NativeWindowFactory handles the case of
// NativeWindows being passed in
protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException {
- if (null == winObj) {
- throw new IllegalArgumentException("winObj is null");
- }
if (winObj instanceof NativeWindow) {
// Use the NativeWindow directly
return (NativeWindow) winObj;
@@ -69,7 +71,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
"javax.media.nativewindow.NativeWindow or "+AWTComponentClassName);
}
- private Constructor nativeWindowConstructor = null;
+ private Constructor<?> nativeWindowConstructor = null;
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
new file mode 100644
index 000000000..4877d5c4f
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright 2010 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;
+
+import java.util.ArrayList;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+
+public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
+ private Object surfaceUpdatedListenersLock = new Object();
+ private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
+
+ //
+ // Management Utils
+ //
+ public int size() { return surfaceUpdatedListeners.size(); }
+ public SurfaceUpdatedListener get(int i) { return surfaceUpdatedListeners.get(i); }
+
+ //
+ // Implementation of NativeSurface SurfaceUpdatedListener methods
+ //
+
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ addSurfaceUpdatedListener(-1, l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size();
+ }
+ surfaceUpdatedListeners.add(index, l);
+ }
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners.remove(l);
+ }
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index 4c2b1c875..65ecc48fe 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -33,7 +33,7 @@ import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.SurfaceChangeable;
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
+public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
protected long surfaceHandle;
public WrappedSurface(AbstractGraphicsConfiguration cfg) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index c1c97eece..ddf453bab 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -42,6 +42,8 @@ import java.awt.EventQueue;
import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
@@ -55,6 +57,7 @@ public class JAWTUtil {
// See whether we're running in headless mode
private static final boolean headlessMode;
+ private static final JAWT jawtLockObject;
// Java2D magic ..
private static final Method isQueueFlusherThread;
@@ -75,31 +78,63 @@ public class JAWTUtil {
boolean ok;
}
+ /**
+ * Returns true if this platform's JAWT implementation supports
+ * or uses offscreen layer.
+ */
+ public static boolean isOffscreenLayerSupported() {
+ return Platform.OS_TYPE == Platform.OSType.MACOS &&
+ Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0;
+ }
+
+ /**
+ * @param useOffscreenLayerIfAvailable
+ * @return
+ */
+ public static JAWT getJAWT(boolean useOffscreenLayerIfAvailable) {
+ int jawt_version_flags = JAWTFactory.JAWT_VERSION_1_4;
+ if(useOffscreenLayerIfAvailable) {
+ switch(Platform.OS_TYPE) {
+ case MACOS:
+ if(Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0) {
+ jawt_version_flags |= JAWT.JAWT_MACOSX_USE_CALAYER;
+ }
+ }
+ }
+ return JAWT.getJAWT(jawt_version_flags);
+ }
+
+ public static boolean isJAWTUsingOffscreenLayer(JAWT jawt) {
+ return 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER );
+ }
+
static {
JAWTJNILibLoader.loadAWTImpl();
JAWTJNILibLoader.loadNativeWindow("awt");
headlessMode = GraphicsEnvironment.isHeadless();
-
boolean ok = false;
- Class jC = null;
+ Class<?> jC = null;
Method m = null;
if (!headlessMode) {
+ jawtLockObject = getJAWT(false); // don't care for offscreen layer here
try {
jC = Class.forName("jogamp.opengl.awt.Java2D");
m = jC.getMethod("isQueueFlusherThread", (Class[])null);
ok = true;
} catch (Exception e) {
}
+ } else {
+ jawtLockObject = null; // headless !
}
isQueueFlusherThread = m;
j2dExist = ok;
- PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction() {
+ PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
PrivilegedDataBlob1 d = new PrivilegedDataBlob1();
try {
- final Class sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ final Class<?> sunToolkitClass = Class.forName("sun.awt.SunToolkit");
d.sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{});
d.sunToolkitAWTLockMethod.setAccessible(true);
d.sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{});
@@ -129,21 +164,21 @@ public class JAWTUtil {
jawtToolkitLock = new JAWTToolkitLock();
// trigger native AWT toolkit / properties initialization
- Map desktophints = null;
+ Map<?,?> desktophints = null;
try {
if(EventQueue.isDispatchThread()) {
- desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
} else {
- final ArrayList desktophintsBucket = new ArrayList(1);
+ final ArrayList<Map<?,?>> desktophintsBucket = new ArrayList<Map<?,?>>(1);
EventQueue.invokeAndWait(new Runnable() {
public void run() {
- Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ Map<?,?> _desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
if(null!=_desktophints) {
desktophintsBucket.add(_desktophints);
}
}
});
- desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ;
+ desktophints = ( desktophintsBucket.size() > 0 ) ? desktophintsBucket.get(0) : null ;
}
} catch (InterruptedException ex) {
ex.printStackTrace();
@@ -189,7 +224,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtLock() {
+ private static void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -197,7 +232,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtLock failed", e);
}
} else {
- JAWT.getJAWT().Lock();
+ jawtLockObject.Lock();
}
}
@@ -207,7 +242,7 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtUnlock() {
+ private static void awtUnlock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -215,7 +250,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtUnlock failed", e);
}
} else {
- JAWT.getJAWT().Unlock();
+ jawtLockObject.Unlock();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
index 2c80392ad..0f97b0b9f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
@@ -42,48 +42,101 @@ import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
import java.awt.Window;
+import java.applet.Applet;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
-public abstract class JAWTWindow implements NativeWindow {
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
+public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
+ // user properties
+ protected boolean shallUseOffscreenLayer = false;
+
// lifetime: forever
protected Component component;
- protected AbstractGraphicsConfiguration config;
+ protected AWTGraphicsConfiguration config;
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- // lifetime: valid after lock, forever until invalidate
+ // lifetime: valid after lock but may change with each 1st lock, purges after invalidate
+ private boolean isApplet;
+ private JAWT jawt;
+ private boolean isOffscreenLayerSurface;
protected long drawable;
protected Rectangle bounds;
- public JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
+ /**
+ * Constructed by {@link jogamp.nativewindow.NativeWindowFactoryImpl#getNativeWindow(Object, AbstractGraphicsConfiguration)}
+ * via this platform's specialization (X11, OSX, Windows, ..).
+ *
+ * @param comp
+ * @param config
+ */
+ protected JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
if (config == null) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
}
- this.config = config;
+ if(! ( config instanceof AWTGraphicsConfiguration ) ) {
+ throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration");
+ }
+ this.config = (AWTGraphicsConfiguration) config;
init((Component)comp);
}
private void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
+ this.isApplet = false;
validateNative();
}
+
+ /**
+ * Request an JAWT offscreen layer if supported.
+ * Shall be called before {@link #lockSurface()}.
+ *
+ * @see #getShallUseOffscreenLayer()
+ * @see #isOffscreenLayerSurfaceEnabled()
+ */
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ /**
+ * Implementors shall ensure that all native handles are valid, eg. the {@link javax.media.nativewindow.awt.AWTGraphicsDevice AWTGraphicsDevice}'s
+ * subtype via {@link javax.media.nativewindow.awt.AWTGraphicsDevice#setSubType(String, long) awtGraphicsDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle)}.
+ * <p>
+ * This method may be called several times,
+ * hence the implementation shall check for valid values 1st and bail out early if satisfied.
+ * </p>
+ * @throws NativeWindowException
+ */
protected abstract void validateNative() throws NativeWindowException;
protected synchronized void invalidate() {
- component = null;
+ invalidateNative();
+ jawt = null;
+ isOffscreenLayerSurface = false;
drawable= 0;
bounds = new Rectangle();
}
+ protected abstract void invalidateNative();
protected final void updateBounds(JAWT_Rectangle jawtBounds) {
bounds.setX(jawtBounds.getX());
@@ -100,14 +153,91 @@ public abstract class JAWTWindow implements NativeWindow {
public final Component getAWTComponent() {
return component;
}
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #lockSurface()}.
+ */
+ public final boolean isApplet() {
+ return isApplet;
+ }
+ /** Returns the underlying JAWT instance created @ {@link #lockSurface()}. */
+ public final JAWT getJAWT() {
+ return jawt;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see #setShallUseOffscreenLayer(boolean)
+ */
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new NativeWindowException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ attachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void attachSurfaceLayerImpl(final long layerHandle);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ detachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void detachSurfaceLayerImpl(final long layerHandle);
+
//
// SurfaceUpdateListener
//
- public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- // nop
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
//
// NativeSurface
@@ -115,17 +245,39 @@ public abstract class JAWTWindow implements NativeWindow {
private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private void determineIfApplet() {
+ Component c = component;
+ while(!isApplet && null != c) {
+ isApplet = c instanceof Applet;
+ c = c.getParent();
+ }
+ }
+
+ /**
+ * If JAWT offscreen layer is supported,
+ * implementation shall respect {@link #getShallUseOffscreenLayer()}
+ * and may respect {@link #isApplet()}.
+ *
+ * @return The JAWT instance reflecting offscreen layer support, etc.
+ *
+ * @throws NativeWindowException
+ */
+ protected abstract JAWT fetchJAWTImpl() throws NativeWindowException;
protected abstract int lockSurfaceImpl() throws NativeWindowException;
public final int lockSurface() throws NativeWindowException {
+ validateNative();
surfaceLock.lock();
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
+ determineIfApplet();
try {
final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
adevice.lock();
try {
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
res = lockSurfaceImpl();
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
@@ -169,15 +321,14 @@ public abstract class JAWTWindow implements NativeWindow {
return surfaceLock.getOwner();
}
- public final boolean surfaceSwap() {
+ public boolean surfaceSwap() {
return false;
}
- public final void surfaceUpdated(Object updater, NativeWindow window, long when) { }
-
- public final long getSurfaceHandle() {
+ public long getSurfaceHandle() {
return drawable;
}
+
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config;
}
@@ -190,15 +341,11 @@ public abstract class JAWTWindow implements NativeWindow {
return config.getScreen().getIndex();
}
- public final void setSize(int width, int height) {
- component.setSize(width, height);
- }
-
- public final int getWidth() {
+ public int getWidth() {
return component.getWidth();
}
- public final int getHeight() {
+ public int getHeight() {
return component.getHeight();
}
@@ -207,12 +354,13 @@ public abstract class JAWTWindow implements NativeWindow {
//
public synchronized void destroy() {
+ invalidate();
if(null!=component) {
if(component instanceof Window) {
((Window)component).dispose();
}
+ component = null;
}
- invalidate();
}
public final NativeWindow getParent() {
@@ -222,7 +370,7 @@ public abstract class JAWTWindow implements NativeWindow {
public long getWindowHandle() {
return drawable;
}
-
+
public final int getX() {
return component.getX();
}
@@ -230,44 +378,85 @@ public abstract class JAWTWindow implements NativeWindow {
public final int getY() {
return component.getY();
}
-
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This JAWT default implementation is currently still using
+ * a blocking implementation. It first attempts to retrieve the location
+ * via a native implementation. If this fails, it tries the blocking AWT implementation.
+ * If the latter fails due to an external AWT tree-lock, the non block
+ * implementation {@link #getLocationOnScreenNonBlocking(Point, Component)} is being used.
+ * The latter simply traverse up to the AWT component tree and sums the rel. position.
+ * We have to determine whether the latter is good enough for all cases,
+ * currently only OS X utilizes the non blocking method per default.
+ * </p>
+ */
public Point getLocationOnScreen(Point storage) {
+ Point los = getLocationOnScreenNative(storage);
+ if(null == los) {
+ if(!Thread.holdsLock(component.getTreeLock())) {
+ // avoid deadlock ..
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this);
+ Thread.dumpStack();
+ }
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ java.awt.Point awtLOS = component.getLocationOnScreen();
+ if(null!=storage) {
+ los = storage.translate(awtLOS.x, awtLOS.y);
+ } else {
+ los = new Point(awtLOS.x, awtLOS.y);
+ }
+ }
+ return los;
+ }
+
+ protected Point getLocationOnScreenNative(Point storage) {
int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
- // FIXME: Shall we deal with already locked or unrealized surfaces ?
- System.err.println("Warning: JAWT Lock couldn't be acquired!");
- Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock couldn't be acquired: "+this);
+ Thread.dumpStack();
+ }
return null;
}
try {
- Point d = getLocationOnScreenImpl(0, 0);
+ Point d = getLocationOnScreenNativeImpl(0, 0);
if(null!=d) {
if(null!=storage) {
storage.translate(d.getX(),d.getY());
return storage;
}
- return d;
- }
- // fall through intended ..
- if(!Thread.holdsLock(component.getTreeLock())) {
- // FIXME: Verify if this check is still required!
- System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock!");
- Thread.dumpStack();
- return null; // avoid deadlock ..
}
- java.awt.Point awtLOS = component.getLocationOnScreen();
- int dx = (int) ( awtLOS.getX() + .5 ) ;
- int dy = (int) ( awtLOS.getY() + .5 ) ;
- if(null!=storage) {
- return storage.translate(dx, dy);
- }
- return new Point(dx, dy);
+ return d;
} finally {
unlockSurface();
+ }
+ }
+ protected abstract Point getLocationOnScreenNativeImpl(int x, int y);
+
+ protected static Point getLocationOnScreenNonBlocking(Point storage, Component comp) {
+ int x = 0;
+ int y = 0;
+ while(null != comp) {
+ x += comp.getX();
+ y += comp.getY();
+ comp = comp.getParent();
+ }
+ if(null!=storage) {
+ storage.translate(x, y);
+ return storage;
}
+ return new Point(x, y);
}
- protected abstract Point getLocationOnScreenImpl(int x, int y);
-
+
+ public boolean hasFocus() {
+ return component.hasFocus();
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index d4f6a95d4..70fc1d62f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -41,37 +41,96 @@
package jogamp.nativewindow.jawt.macosx;
import java.awt.Component;
+import java.nio.Buffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-// import jogamp.nativewindow.macosx.OSXUtil;
-
-public class MacOSXJAWTWindow extends JAWTWindow {
+import jogamp.nativewindow.macosx.OSXUtil;
+public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
super(comp, config);
+ if(DEBUG) {
+ dumpInfo();
+ }
}
protected void validateNative() throws NativeWindowException {
+ }
+
+ protected void invalidateNative() {
+ surfaceHandle=0;
+ if(isOffscreenLayerSurfaceEnabled()) {
+ if(0 != drawable) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ }
+ }
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ public long getSurfaceHandle() {
+ return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not using CALAYER");
+ }
+ if(DEBUG) {
+ System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
+ this.surfaceHandle = surfaceHandle;
+ }
+
+ public void surfaceSizeChanged(int width, int height) {
+ sscSet = true;
+ sscWidth = width;
+ sscHeight = height;
+ }
+
+ public int getWidth() {
+ return sscSet ? sscWidth : super.getWidth();
+ }
+
+ public int getHeight() {
+ return sscSet ? sscHeight: super.getHeight();
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ // use offscreen if supported and [ applet or requested ]
+ return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
+ }
protected int lockSurfaceImpl() throws NativeWindowException {
- int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ int ret = NativeWindow.LOCK_SURFACE_NOT_READY;
+ if(null == ds) {
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
int res = ds.Lock();
dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
@@ -87,37 +146,83 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
ret = NativeWindow.LOCK_SURFACE_CHANGED;
}
- if (firstLock) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- dsi = ds.GetDrawingSurfaceInfo();
- return null;
- }
- });
- } else {
- dsi = ds.GetDrawingSurfaceInfo();
+ if(null == dsi) {
+ if (firstLock) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ dsi = ds.GetDrawingSurfaceInfo();
+ return null;
+ }
+ });
+ } else {
+ dsi = ds.GetDrawingSurfaceInfo();
+ }
+ if (dsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
- if (dsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ updateBounds(dsi.getBounds());
+ if (DEBUG && firstLock ) {
+ dumpInfo();
}
firstLock = false;
- macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo();
- if (macosxdsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
- }
- drawable = macosxdsi.getCocoaViewRef();
-
- if (drawable == 0) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(getJAWT());
+ if (macosxdsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ drawable = macosxdsi.getCocoaViewRef();
+
+ if (drawable == 0) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ } else {
+ ret = NativeWindow.LOCK_SUCCESS;
+ }
} else {
- updateBounds(dsi.getBounds());
+ /**
+ * Only create a fake invisible NSWindow for the drawable handle
+ * to please frameworks requiring such (eg. NEWT).
+ *
+ * The actual surface/ca-layer shall be created/attached
+ * by the upper framework (JOGL) since they require more information.
+ */
+ if(0 == drawable) {
+ drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
+ if(0 == drawable) {
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ }
+ // fix caps reflecting offscreen!
+ Capabilities caps = (Capabilities) config.getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ config.setChosenCapabilities(caps);
+ }
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer();
+ if(0 == rootSurfaceLayerHandle) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not create root CALayer: "+this);
+ }
+ if(!AttachJAWTSurfaceLayer(dsi, rootSurfaceLayerHandle)) {
+ OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
+ rootSurfaceLayerHandle = 0;
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this);
+ }
+ }
+ ret = NativeWindow.LOCK_SUCCESS;
}
+
return ret;
}
-
+
protected void unlockSurfaceImpl() throws NativeWindowException {
if(null!=ds) {
if (null!=dsi) {
@@ -126,30 +231,65 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
- macosxdsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- Component c = component;
- while(null != c) {
- x += c.getX();
- y += c.getY();
- c = c.getParent();
+ private void dumpInfo() {
+ System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName());
+ if(null != getJAWT()) {
+ System.err.println("JAWT version: 0x"+Integer.toHexString(getJAWT().getCachedVersion())+
+ ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(getJAWT())+
+ ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds);
+ } else {
+ System.err.println("JAWT n/a, bounds "+bounds);
}
- // return OSXUtil.GetLocationOnScreen(getWindowHandle(), x, y);
- return new Point(x, y);
+ // Thread.dumpStack();
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * On OS X locking the surface at this point (ie after creation and for location validation)
+ * is 'tricky' since the JVM traverses through many threads and crashes at:
+ * lockSurfaceImpl() {
+ * ..
+ * ds = getJAWT().GetDrawingSurface(component);
+ * due to a SIGSEGV.
+ *
+ * Hence we have some threading / sync issues with the native JAWT implementation.
+ * </p>
+ */
+ @Override
+ public Point getLocationOnScreen(Point storage) {
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
+ private static boolean AttachJAWTSurfaceLayer(JAWT_DrawingSurfaceInfo dsi, long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ return AttachJAWTSurfaceLayer0(dsi.getBuffer(), caLayer);
+ }
+
+ private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
private boolean dsLocked;
private JAWT_DrawingSurfaceInfo dsi;
+
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
-
+
+ private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer
+
+ private long surfaceHandle = 0;
+ private int sscWidth, sscHeight;
+ private boolean sscSet = false;
+
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index 982b94888..adb9353ce 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -47,6 +47,7 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
@@ -61,15 +62,24 @@ public class WindowsJAWTWindow extends JAWTWindow {
protected void validateNative() throws NativeWindowException {
}
- @Override
- protected synchronized void invalidate() {
- super.invalidate();
+ protected void invalidateNative() {
windowHandle = 0;
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -94,7 +104,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (win32dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -104,14 +115,11 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (windowHandle == 0 || drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
protected void unlockSurfaceImpl() throws NativeWindowException {
- long startTime = 0;
if(null!=ds) {
if (null!=dsi) {
ds.FreeDrawingSurfaceInfo(dsi);
@@ -119,7 +127,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
@@ -131,7 +139,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
return windowHandle;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 2319d6269..236d380d8 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
@@ -60,7 +61,7 @@ public class X11JAWTWindow extends JAWTWindow {
}
protected void validateNative() throws NativeWindowException {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ final AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
if(awtDevice.getHandle() != 0) {
// subtype and handle set already, done
@@ -85,10 +86,23 @@ public class X11JAWTWindow extends JAWTWindow {
}
awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
}
+
+ protected void invalidateNative() { }
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -113,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (x11dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -122,8 +137,6 @@ public class X11JAWTWindow extends JAWTWindow {
if (drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
@@ -136,14 +149,14 @@ public class X11JAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
x11dsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
index b576b0c6b..6dbf36612 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
@@ -55,14 +55,14 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
the purposes of correctly enumerating the available visuals. */
public class X11SunJDKReflection {
- private static Class x11GraphicsDeviceClass;
- private static Method x11GraphicsDeviceGetDisplayMethod;
- private static Class x11GraphicsConfigClass;
- private static Method x11GraphicsConfigGetVisualMethod;
- private static boolean initted;
+ private static Class<?> x11GraphicsDeviceClass;
+ private static Method x11GraphicsDeviceGetDisplayMethod;
+ private static Class<?> x11GraphicsConfigClass;
+ private static Method x11GraphicsConfigGetVisualMethod;
+ private static boolean initialized;
static {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice");
@@ -72,7 +72,7 @@ public class X11SunJDKReflection {
x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig");
x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {});
x11GraphicsConfigGetVisualMethod.setAccessible(true);
- initted = true;
+ initialized = true;
} catch (Exception e) {
// Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
}
@@ -82,7 +82,7 @@ public class X11SunJDKReflection {
}
public static long graphicsDeviceGetDisplay(GraphicsDevice device) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
@@ -105,7 +105,7 @@ public class X11SunJDKReflection {
}
public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index cd558c05d..a93ab2ac1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -1,5 +1,7 @@
package jogamp.nativewindow.macosx;
+import java.nio.Buffer;
+
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Point;
@@ -34,6 +36,42 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
+ public static long CreateNSView(int x, int y, int width, int height) {
+ return CreateNSView0(x, y, width, height);
+ }
+ public static void DestroyNSView(long nsView) {
+ DestroyNSView0(nsView);
+ }
+
+ public static long CreateNSWindow(int x, int y, int width, int height) {
+ return CreateNSWindow0(x, y, width, height);
+ }
+ public static void DestroyNSWindow(long nsWindow) {
+ DestroyNSWindow0(nsWindow);
+ }
+
+ public static long CreateCALayer() {
+ return CreateCALayer0();
+ }
+ public static void AddCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ AddCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void RemoveCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ RemoveCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void DestroyCALayer(long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ DestroyCALayer0(caLayer);
+ }
+
public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) {
if(IsMainThread0()) {
runnable.run(); // don't leave the JVM
@@ -48,6 +86,14 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native long CreateNSView0(int x, int y, int width, int height);
+ private static native void DestroyNSView0(long nsView);
+ private static native long CreateNSWindow0(int x, int y, int width, int height);
+ private static native void DestroyNSWindow0(long nsWindow);
+ private static native long CreateCALayer0();
+ private static native void AddCASublayer0(long rootCALayer, long subCALayer);
+ private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
+ private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index b669bce75..910e564af 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -33,8 +33,14 @@
package jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e19d5ecf7..d7a2feff3 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -35,6 +35,19 @@
#include "NativewindowCommon.h"
#include "jogamp_nativewindow_macosx_OSXUtil.h"
+#include "jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow.h"
+
+#include <jawt_md.h>
+#import <JavaNativeFoundation.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
static const char * const ClazzNameRunnable = "java/lang/Runnable";
static jmethodID runnableRunID = NULL;
@@ -81,7 +94,7 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: getLocationOnScreenImpl0
+ * Method: getLocationOnScreen0
* Signature: (JII)Ljavax/media/nativewindow/util/Point;
*/
JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnScreen0
@@ -97,7 +110,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
int dest_x=-1;
int dest_y=-1;
- NSObject *nsObj = (NSObject*) ((intptr_t) winOrView);
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
NSWindow* win = NULL;
NSView* view = NULL;
@@ -135,6 +148,182 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
return res;
}
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSView0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+ NSView * view = [[NSView alloc] initWithFrame: rect] ;
+ [view setCanDrawConcurrently: YES];
+ [pool release];
+
+ return (jlong) (intptr_t) view;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSView0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0
+ (JNIEnv *env, jclass unused, jlong nsView)
+{
+ NSView* view = (NSView*) (intptr_t) nsView;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [view release];
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSWindow0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+
+ // Allocate the window
+ NSWindow* myWindow = [[NSWindow alloc] initWithContentRect: rect
+ styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered
+ defer: YES];
+ [myWindow setReleasedWhenClosed: YES]; // default
+ [myWindow setPreservesContentDuringLiveResize: YES];
+
+ // invisible ..
+ [myWindow setOpaque: NO];
+ [myWindow setBackgroundColor: [NSColor clearColor]];
+
+ // force surface creation
+ // [myView lockFocus];
+ // [myView unlockFocus];
+
+ [pool release];
+
+ return (jlong) ((intptr_t) myWindow);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSWindow0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
+ (JNIEnv *env, jclass unused, jlong nsWindow)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) nsWindow);
+ NSView* mView = [mWin contentView];
+
+ if(NULL!=mView) {
+ [mWin setContentView: nil];
+ [mView release];
+ }
+ [mWin orderOut: mWin];
+ [mWin close]; // performs release!
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateCALayer0
+ * Signature: (V)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
+ (JNIEnv *env, jclass unused)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ // CALayer* layer = [[CALayer alloc] init];
+ CALayer* layer = [CALayer layer];
+
+ // initial dummy size !
+ CGRect lRect = [layer frame];
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = 32;
+ lRect.size.height = 32;
+ [layer setFrame: lRect];
+ DBG_PRINT("CALayer::CreateCALayer0: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [pool release];
+
+ return (jlong) ((intptr_t) layer);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: AddCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ CGRect lRectRoot = [rootLayer frame];
+ // simple 1:1 layout !
+ [subLayer setFrame:lRectRoot];
+ DBG_PRINT("CALayer::AddCASublayer0.0: %p . %p %lf/%lf %lfx%lf (refcnt %d)\n",
+ rootLayer, subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [rootLayer addSublayer:subLayer];
+ }];
+ DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: RemoveCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ (void)rootLayer; // no warnings
+
+ DBG_PRINT("CALayer::RemoveCASublayer0.0: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [subLayer removeFromSuperlayer];
+ }];
+ DBG_PRINT("CALayer::RemoveCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyCALayer0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
+ (JNIEnv *env, jclass unused, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* layer = (CALayer*) ((intptr_t) caLayer);
+
+ DBG_PRINT("CALayer::DestroyCALayer0.0: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [layer release]; // performs release!
+ }];
+ DBG_PRINT("CALayer::DestroyCALayer0.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
@interface MainRunnable : NSObject
{
@@ -212,10 +401,35 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: RunOnMainThread0
- * Signature: (ZLjava/lang/Runnable;)V
+ * Signature: (V)V
*/
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
(JNIEnv *env, jclass unused)
{
return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
}
+
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: AttachJAWTSurfaceLayer
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_AttachJAWTSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::attachJAWTSurfaceLayer: %p -> %p\n", surfaceLayers.layer, layer);
+ surfaceLayers.layer = [layer autorelease];
+ }];
+ JNF_COCOA_EXIT(env);
+ return JNI_TRUE;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index d3be098c0..f38876128 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -34,14 +34,19 @@
package com.jogamp.newt;
-import javax.media.nativewindow.*;
-
-import com.jogamp.common.os.Platform;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.WindowImpl;
-import jogamp.newt.Debug;
+
+import com.jogamp.common.os.Platform;
public class NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
@@ -141,35 +146,34 @@ public class NewtFactory {
*
* @param parentWindowObject either a NativeWindow instance
*/
- public static Window createWindow(NativeWindow nParentWindow, CapabilitiesImmutable caps) {
+ public static Window createWindow(NativeWindow parentWindow, CapabilitiesImmutable caps) {
final String type = NativeWindowFactory.getNativeWindowType(true);
-
Screen screen = null;
- Window parentWindow = null;
+ Window newtParentWindow = null;
- if ( nParentWindow instanceof Window ) {
+ if ( parentWindow instanceof Window ) {
// use parent NEWT Windows Display/Screen
- parentWindow = (Window) nParentWindow ;
- screen = parentWindow.getScreen();
+ newtParentWindow = (Window) parentWindow ;
+ screen = newtParentWindow.getScreen();
} else {
// create a Display/Screen compatible to the NativeWindow
- AbstractGraphicsConfiguration nParentConfig = nParentWindow.getGraphicsConfiguration();
- if(null!=nParentConfig) {
- AbstractGraphicsScreen nParentScreen = nParentConfig.getScreen();
- AbstractGraphicsDevice nParentDevice = nParentScreen.getDevice();
- Display display = NewtFactory.createDisplay(type, nParentDevice.getHandle(), true);
- screen = NewtFactory.createScreen(display, nParentScreen.getIndex());
+ AbstractGraphicsConfiguration parentConfig = parentWindow.getGraphicsConfiguration();
+ if(null!=parentConfig) {
+ AbstractGraphicsScreen parentScreen = parentConfig.getScreen();
+ AbstractGraphicsDevice parentDevice = parentScreen.getDevice();
+ Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true);
+ screen = NewtFactory.createScreen(display, parentScreen.getIndex());
} else {
Display display = NewtFactory.createDisplay(type, null, true); // local display
screen = NewtFactory.createScreen(display, 0); // screen 0
}
}
- final Window win = createWindowImpl(nParentWindow, screen, caps);
+ final Window win = createWindowImpl(parentWindow, screen, caps);
- win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight());
- if ( null != parentWindow ) {
- parentWindow.addChild(win);
- win.setVisible(parentWindow.isVisible());
+ win.setSize(parentWindow.getWidth(), parentWindow.getHeight());
+ if ( null != newtParentWindow ) {
+ newtParentWindow.addChild(win);
+ win.setVisible(newtParentWindow.isVisible());
}
return win;
}
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index a78f81668..32024a49a 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -30,12 +30,13 @@ package com.jogamp.newt;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.MouseListener;
import jogamp.newt.Debug;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.WindowClosingProtocol;
/**
@@ -133,6 +134,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
boolean isVisible();
+ /**
+ * If the implementation uses delegation, return the delegated {@link Window} instance,
+ * otherwise return <code>this</code> instance. */
+ Window getDelegatedWindow();
+
//
// Child Window Management
//
@@ -310,16 +316,46 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
}
/**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * Sets a {@link FocusRunnable},
+ * which {@link FocusRunnable#run()} method is executed before the native focus is requested.
+ * <p>
* This allows notifying a covered window toolkit like AWT that the focus is requested,
* hence focus traversal can be made transparent.
+ * </p>
*/
void setFocusAction(FocusRunnable focusAction);
+
+ /**
+ * Sets a {@link KeyListener} allowing focus traversal with a covered window toolkit like AWT.
+ * <p>
+ * The {@link KeyListener} methods are invoked prior to all other {@link KeyListener}'s
+ * allowing to suppress the {@link KeyEvent} via the {@link InputEvent#consumedTag}.
+ * </p>
+ * @param l
+ */
+ void setKeyboardFocusHandler(KeyListener l);
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT and blocked until finished.
+ * </p>
+ *
+ * @see #requestFocus(boolean)
+ */
void requestFocus();
- boolean hasFocus();
-
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT.
+ * </p>
+ *
+ * @param wait true if waiting until the request is executed, otherwise false
+ * @see #requestFocus()
+ */
+ void requestFocus(boolean wait);
+
void windowRepaint(int x, int y, int width, int height);
void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
@@ -328,38 +364,6 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
//
- // SurfaceUpdateListener
- //
-
- /**
- * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
- * the list.
- */
- void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
-
- /**
- *
- * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
- * specified position in the list.<br>
- *
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
- * @param l The listener object to be inserted
- * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
- */
- void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
-
- void removeAllSurfaceUpdatedListener();
-
- void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
-
- SurfaceUpdatedListener getSurfaceUpdatedListener(int index);
-
- SurfaceUpdatedListener[] getSurfaceUpdatedListeners();
-
-
- //
// WindowListener
//
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 31d42d21b..f56a95537 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -29,42 +29,56 @@
package com.jogamp.newt.awt;
-import com.jogamp.newt.Display;
-import java.lang.reflect.*;
-import java.security.*;
-
+import java.awt.AWTKeyStroke;
import java.awt.Canvas;
-import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
-
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
+
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+import javax.swing.MenuSelectionManager;
+
import jogamp.nativewindow.awt.AWTMisc;
+import jogamp.nativewindow.jawt.JAWTWindow;
+import jogamp.newt.Debug;
+import jogamp.newt.awt.NewtFactoryAWT;
+import jogamp.newt.awt.event.AWTParentWindowAdapter;
+import jogamp.newt.driver.DriverClearFocus;
-import com.jogamp.newt.event.awt.AWTAdapter;
-import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.Display;
import com.jogamp.newt.Window;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
-import jogamp.newt.Debug;
-import jogamp.newt.awt.event.AWTParentWindowAdapter;
-import jogamp.newt.awt.event.NewtFactoryAWT;
-
-import javax.swing.MenuSelectionManager;
+import com.jogamp.newt.event.awt.AWTAdapter;
+import com.jogamp.newt.event.awt.AWTKeyAdapter;
+import com.jogamp.newt.event.awt.AWTMouseAdapter;
@SuppressWarnings("serial")
public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol {
public static final boolean DEBUG = Debug.debug("Window");
- NativeWindow nativeWindow = null;
- Window newtChild = null;
- int newtChildCloseOp;
- AWTAdapter awtAdapter = null;
-
+ private JAWTWindow jawtWindow = null;
+ private Window newtChild = null;
+ private boolean isOnscreen = true;
+ private int newtChildCloseOp;
+ private AWTAdapter awtAdapter = null;
+ private AWTAdapter awtMouseAdapter = null;
+ private AWTAdapter awtKeyAdapter = null;
+
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
public void run() {
@@ -77,6 +91,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
*/
public NewtCanvasAWT() {
super();
+ createNativeWindow(new Capabilities());
}
/**
@@ -84,6 +99,23 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
*/
public NewtCanvasAWT(GraphicsConfiguration gc) {
super(gc);
+ createNativeWindow(new Capabilities());
+ }
+
+ /**
+ * Instantiates a NewtCanvas without a NEWT child.<br>
+ */
+ public NewtCanvasAWT(CapabilitiesImmutable caps) {
+ super();
+ createNativeWindow(caps);
+ }
+
+ /**
+ * Instantiates a NewtCanvas without a NEWT child.<br>
+ */
+ public NewtCanvasAWT(GraphicsConfiguration gc, CapabilitiesImmutable caps) {
+ super(gc);
+ createNativeWindow(caps);
}
/**
@@ -91,6 +123,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
*/
public NewtCanvasAWT(Window child) {
super();
+ createNativeWindow(child.getRequestedCapabilities());
setNEWTChild(child);
}
@@ -99,56 +132,154 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
*/
public NewtCanvasAWT(GraphicsConfiguration gc, Window child) {
super(gc);
+ createNativeWindow(child.getRequestedCapabilities());
setNEWTChild(child);
}
+ private final void createNativeWindow(CapabilitiesImmutable caps) {
+ jawtWindow = NewtFactoryAWT.getNativeWindow(this, caps);
+ }
+
+ /**
+ * Request an JAWT offscreen layer if supported it.
+ * Shall be called before {@link #addNotify()} is issued,
+ * ie. before adding the component to the AWT tree and make it visible.
+ *
+ * @see #isOffscreenLayerSurface()
+ */
+ public void setShallUseOffscreenLayer(boolean v) {
+ jawtWindow.setShallUseOffscreenLayer(v);
+ }
+
+ /**
+ * Returns true if the underlying JAWT uses offscreen layering,
+ * otherwise false. This information is valid only after {@link #addNotify()} is issued,
+ * ie. before adding the component to the AWT tree and make it visible.
+ *
+ * @see #setShallUseOffscreenLayer(boolean)
+ */
+ public boolean isOffscreenLayerSurface() {
+ return jawtWindow.isOffscreenLayerSurfaceEnabled();
+ }
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #addNotify()} is issued,
+ * ie. before adding the component to the AWT tree and make it visible.
+ */
+ public boolean isApplet() {
+ return jawtWindow.isApplet();
+ }
+
class FocusAction implements Window.FocusRunnable {
public boolean run() {
- if ( EventQueue.isDispatchThread() ) {
- focusActionImpl.run();
- } else {
- try {
- EventQueue.invokeAndWait(focusActionImpl);
- } catch (Exception e) {
- throw new NativeWindowException(e);
- }
- /**
- // wait for AWT focus !
- for(long sleep = Window.TIMEOUT_NATIVEWINDOW; 0<sleep && !isFocusOwner(); sleep-=10 ) {
- try { Thread.sleep(10); } catch (InterruptedException e) { }
- } */
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusAction: "+Display.getThreadName()+", isOnscreen "+isOnscreen+", hasFocus "+hasFocus());
}
- return focusActionImpl.result;
- }
-
- class FocusActionImpl implements Runnable {
- public final boolean result = false; // NEWT shall always proceed requesting the native focus
- public void run() {
- if(DEBUG) {
- System.err.println("FocusActionImpl.run() "+Display.getThreadName());
- }
- NewtCanvasAWT.this.requestFocusAWTParent();
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ if(!hasFocus()) {
+ // Acquire the AWT focus 1st for proper AWT traversal
+ NewtCanvasAWT.super.requestFocus();
+ }
+ if(isOnscreen) {
+ // Remove the AWT focus in favor of the native NEWT focus
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ return false; // NEWT shall proceed requesting the native focus
}
- FocusActionImpl focusActionImpl = new FocusActionImpl();
}
- FocusAction focusAction = new FocusAction();
+ private FocusAction focusAction = new FocusAction();
WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent arg0) {
- MenuSelectionManager.defaultManager().clearSelectedPath();
+ MenuSelectionManager.defaultManager().clearSelectedPath();
}
};
- /** sets a new NEWT child, provoking reparenting on the NEWT level. */
- /*package */ NewtCanvasAWT setNEWTChild(Window child) {
+ class FocusTraversalKeyListener implements KeyListener {
+ boolean suppress = false;
+
+ public void keyPressed(KeyEvent e) {
+ handleKey(e, false);
+ }
+ public void keyReleased(KeyEvent e) {
+ handleKey(e, true);
+ }
+ public void keyTyped(KeyEvent e) {
+ if(suppress) {
+ e.setAttachment(InputEvent.consumedTag);
+ suppress = false; // reset
+ }
+ }
+
+ void handleKey(KeyEvent evt, boolean onRelease) {
+ if(null == keyboardFocusManager) {
+ throw new InternalError("XXX");
+ }
+ final AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(evt.getKeyCode(), evt.getModifiers(), onRelease);
+ if(null != ks) {
+ final Set<AWTKeyStroke> fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ final Set<AWTKeyStroke> bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ if(fwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocus();
+ suppress = true;
+ } else if(bwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocusBackward();
+ suppress = true;
+ }
+ }
+ if(suppress) {
+ evt.setAttachment(InputEvent.consumedTag);
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey: XXX: "+ks);
+ }
+ }
+ }
+ private final FocusTraversalKeyListener newtFocusTraversalKeyListener = new FocusTraversalKeyListener();
+
+ class FocusPropertyChangeListener implements PropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent evt) {
+ final Object oldF = evt.getOldValue();
+ final Object newF = evt.getNewValue();
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: "+evt.getPropertyName()+", src "+evt.getSource()+", "+oldF+" -> "+newF);
+ }
+ if(oldF == NewtCanvasAWT.this && newF == null) {
+ // focus traversal to NEWT - NOP
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: NEWT focus traversal");
+ }
+ } else if(null != newF && newF != NewtCanvasAWT.this) {
+ // focus traversal to another AWT component
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: lost focus - clear focus");
+ }
+ if(newtChild.getDelegatedWindow() instanceof DriverClearFocus) {
+ ((DriverClearFocus)newtChild.getDelegatedWindow()).clearFocus();
+ }
+ }
+ }
+ }
+ private final FocusPropertyChangeListener focusPropertyChangeListener = new FocusPropertyChangeListener();
+ private volatile KeyboardFocusManager keyboardFocusManager = null;
+
+ /** sets a new NEWT child, provoking reparenting. */
+ private NewtCanvasAWT setNEWTChild(Window child) {
if(newtChild!=child) {
newtChild = child;
- if(null!=nativeWindow) {
- java.awt.Container cont = AWTMisc.getContainer(this);
+ if(isDisplayable()) {
// reparent right away, addNotify has been called already
+ final java.awt.Container cont = AWTMisc.getContainer(this);
reparentWindow( (null!=child) ? true : false, cont );
}
}
@@ -162,8 +293,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
/** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called,
* or {@link #addNotify()} hasn't been called yet.*/
- public NativeWindow getNativeWindow() { return nativeWindow; }
-
+ public NativeWindow getNativeWindow() { return jawtWindow; }
+
public int getDefaultCloseOperation() {
return awtWindowClosingProtocol.getDefaultCloseOperation();
}
@@ -177,13 +308,41 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
awtAdapter.removeFrom(this);
awtAdapter=null;
}
+ if(null!=awtMouseAdapter) {
+ awtMouseAdapter.removeFrom(this);
+ awtMouseAdapter = null;
+ }
+ if(null!=awtKeyAdapter) {
+ awtKeyAdapter.removeFrom(this);
+ awtKeyAdapter = null;
+ }
+ newtChild.setKeyboardFocusHandler(null);
+ if(null != keyboardFocusManager) {
+ keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ keyboardFocusManager = null;
+ }
+
if( null != newtChild ) {
if(attach) {
+ if(null == jawtWindow.getGraphicsConfiguration()) {
+ throw new InternalError("XXX");
+ }
+ isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(focusAction); // enable AWT focus traversal
newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE);
awtWindowClosingProtocol.addClosingListenerOneShot();
+ keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ keyboardFocusManager.addPropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ if(isOnscreen) {
+ // onscreen newt child needs to fwd AWT focus
+ newtChild.setKeyboardFocusHandler(newtFocusTraversalKeyListener);
+ } else {
+ // offscreen newt child requires AWT to fwd AWT key/mouse event
+ awtMouseAdapter = new AWTMouseAdapter(newtChild).addTo(this);
+ awtKeyAdapter = new AWTKeyAdapter(newtChild).addTo(this);
+ }
} else {
newtChild.removeWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(null);
@@ -232,24 +391,40 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
newtChild.setFocusAction(null); // no AWT focus traversal ..
if(add) {
- nativeWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
- if(null!=nativeWindow) {
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild);
- }
- final int w = cont.getWidth();
- final int h = cont.getHeight();
- setSize(w, h);
- newtChild.setSize(w, h);
- newtChild.reparentWindow(nativeWindow);
- newtChild.setVisible(true);
- configureNewtChild(true);
- newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- newtChild.windowRepaint(0, 0, w, h);
+ NewtFactoryAWT.updateGraphicsConfiguration(jawtWindow, this);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild);
}
+ final int w;
+ final int h;
+ if(isPreferredSizeSet()) {
+ java.awt.Dimension d = getPreferredSize();
+ w = d.width;
+ h = d.height;
+ } else {
+ final java.awt.Dimension min;
+ if(this.isMinimumSizeSet()) {
+ min = getMinimumSize();
+ } else {
+ min = new java.awt.Dimension(0, 0);
+ }
+ java.awt.Insets ins = cont.getInsets();
+ w = Math.max(min.width, cont.getWidth() - ins.left - ins.right);
+ h = Math.max(min.height, cont.getHeight() - ins.top - ins.bottom);
+ }
+ setSize(w, h);
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(jawtWindow);
+ newtChild.setVisible(true);
+ configureNewtChild(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+ newtChild.windowRepaint(0, 0, w, h);
+
+ // force this AWT Canvas to be focus-able,
+ // since this it is completely covered by the newtChild (z-order).
+ setFocusable(true);
} else {
configureNewtChild(false);
- nativeWindow = null;
newtChild.setVisible(false);
newtChild.reparentWindow(null);
}
@@ -273,7 +448,10 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont);
}
configureNewtChild(false);
- nativeWindow = null;
+ if(null!=jawtWindow) {
+ jawtWindow.destroy();
+ jawtWindow=null;
+ }
newtChild.setVisible(false);
newtChild.reparentWindow(null);
newtChild.destroy();
@@ -299,14 +477,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
- final void requestFocusAWTParent() {
- super.requestFocusInWindow();
- }
-
- final void requestFocusNEWTChild() {
+ private final void requestFocusNEWTChild() {
if(null!=newtChild) {
newtChild.setFocusAction(null);
- KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ }
newtChild.requestFocus();
newtChild.setFocusAction(focusAction);
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
index 2e86cb512..7ba892b37 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
@@ -1,20 +1,50 @@
+/**
+ * Copyright 2011 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.newt.awt.applet;
-import java.applet.*;
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Button;
import java.awt.Component;
import java.awt.Container;
-import java.awt.Label;
+import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.awt.event.KeyListener;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.newt.Debug;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
-import java.awt.BorderLayout;
-
-import jogamp.newt.Debug;
/**
* Simple GLEventListener deployment as an applet using JOGL. This demo must be
@@ -62,7 +92,7 @@ import jogamp.newt.Debug;
*/
@SuppressWarnings("serial")
public class JOGLNewtApplet1Run extends Applet {
- public static final boolean DEBUG = Debug.debug("Applet");
+ public static final boolean DEBUG = JOGLNewtAppletBase.DEBUG;
GLWindow glWindow;
NewtCanvasAWT newtCanvasAWT;
@@ -72,6 +102,9 @@ public class JOGLNewtApplet1Run extends Applet {
boolean glStandalone = false;
public void init() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() START");
+ }
if(!(this instanceof Container)) {
throw new RuntimeException("This Applet is not a AWT Container");
}
@@ -88,6 +121,7 @@ public class JOGLNewtApplet1Run extends Applet {
int glAlphaBits=0;
int glNumMultisampleBuffer=0;
boolean glNoDefaultKeyListener = false;
+ boolean appletDebugTestBorder = false;
try {
glEventListenerClazzName = getParameter("gl_event_listener_class");
glProfileName = getParameter("gl_profile");
@@ -104,6 +138,7 @@ public class JOGLNewtApplet1Run extends Applet {
glWidth = JOGLNewtAppletBase.str2Int(getParameter("gl_width"), glWidth);
glHeight = JOGLNewtAppletBase.str2Int(getParameter("gl_height"), glHeight);
glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener);
+ appletDebugTestBorder = JOGLNewtAppletBase.str2Bool(getParameter("appletDebugTestBorder"), appletDebugTestBorder);
} catch (Exception e) {
e.printStackTrace();
}
@@ -149,18 +184,19 @@ public class JOGLNewtApplet1Run extends Applet {
glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
glWindow.setUndecorated(glUndecorated);
glWindow.setAlwaysOnTop(glAlwaysOnTop);
+ container.setLayout(new BorderLayout());
+ if(appletDebugTestBorder) {
+ container.add(new Button("North"), BorderLayout.NORTH);
+ container.add(new Button("South"), BorderLayout.SOUTH);
+ container.add(new Button("East"), BorderLayout.EAST);
+ container.add(new Button("West"), BorderLayout.WEST);
+ }
if(glStandalone) {
newtCanvasAWT = null;
} else {
newtCanvasAWT = new NewtCanvasAWT(glWindow);
- container.setLayout(new BorderLayout());
container.add(newtCanvasAWT, BorderLayout.CENTER);
- }
- if(DEBUG) {
- container.add(new Label("North"), BorderLayout.NORTH);
- container.add(new Label("South"), BorderLayout.SOUTH);
- container.add(new Label("East"), BorderLayout.EAST);
- container.add(new Label("West"), BorderLayout.WEST);
+ container.validate();
}
base.init(glWindow);
if(base.isValid()) {
@@ -179,9 +215,15 @@ public class JOGLNewtApplet1Run extends Applet {
} catch (Throwable t) {
throw new RuntimeException(t);
}
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() END");
+ }
}
public void start() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.start() START");
+ }
this.validate();
this.setVisible(true);
@@ -195,21 +237,35 @@ public class JOGLNewtApplet1Run extends Applet {
while (null != topC.getParent()) {
topC = topC.getParent();
}
+ System.err.println("JOGLNewtApplet1Run start:");
System.err.println("TopComponent: "+topC.getLocation()+" rel, "+topC.getLocationOnScreen()+" screen, visible "+topC.isVisible()+", "+topC);
System.err.println("Applet Pos: "+this.getLocation()+" rel, "+p0+" screen, visible "+this.isVisible()+", "+this);
if(null != newtCanvasAWT) {
System.err.println("NewtCanvasAWT Pos: "+newtCanvasAWT.getLocation()+" rel, "+newtCanvasAWT.getLocationOnScreen()+" screen, visible "+newtCanvasAWT.isVisible()+", "+newtCanvasAWT);
}
System.err.println("GLWindow Pos: "+glWindow.getX()+"/"+glWindow.getY()+" rel, "+glWindow.getLocationOnScreen(null)+" screen");
+ System.err.println("GLWindow: "+glWindow);
}
base.start();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() END");
+ }
}
public void stop() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() START");
+ }
base.stop();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() END");
+ }
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() START");
+ }
glWindow.setVisible(false); // hide 1st
if(!glStandalone) {
glWindow.reparentWindow(null); // get out of newtCanvasAWT
@@ -217,6 +273,9 @@ public class JOGLNewtApplet1Run extends Applet {
}
base.destroy(); // destroy glWindow unrecoverable
base=null;
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() END");
+ }
}
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
index b1061dd14..6b135976b 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
@@ -1,18 +1,52 @@
+/**
+ * Copyright 2011 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.newt.awt.applet;
-import java.lang.reflect.*;
+import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.NativeWindow;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
import jogamp.newt.Debug;
-import com.jogamp.opengl.util.*;
-
-import com.jogamp.newt.event.*;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+
/** Shows how to deploy an applet using JOGL. This demo must be
referenced from a web page via an &lt;applet&gt; tag. */
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index 51ceccf31..d8a9235c1 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -48,6 +48,11 @@ public abstract class InputEvent extends NEWTEvent
public static final int CONFINED_MASK = 1 << 16;
public static final int INVISIBLE_MASK = 1 << 17;
+ /** Object when attached via {@link #setAttachment(Object)} marks the event consumed,
+ * ie. stops propagating the event any further to the event listener.
+ */
+ public static final Object consumedTag = new Object();
+
protected InputEvent(int eventType, Object source, long when, int modifiers) {
super(eventType, source, when);
this.modifiers=modifiers;
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 9e4fe372b..44fcea49c 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -34,6 +34,7 @@
package com.jogamp.newt.event;
+@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
{
public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
@@ -42,9 +43,12 @@ public class KeyEvent extends InputEvent
this.keyChar=keyChar;
}
+ /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */
public char getKeyChar() {
return keyChar;
}
+
+ /** Always valid. */
public int getKeyCode() {
return keyCode;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 50aed2c8e..3f3817b91 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -46,6 +46,7 @@ package com.jogamp.newt.event;
* <li> KeyEvent <code>300..30x</code></li>
* </ul><br>
*/
+@SuppressWarnings("serial")
public class NEWTEvent extends java.util.EventObject {
private final boolean isSystemEvent;
private final int eventType;
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 2cd8c2ced..166718423 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -41,6 +41,7 @@ import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
+
import jogamp.newt.WindowImpl;
import javax.media.nativewindow.*;
@@ -54,8 +55,8 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.util.Animator;
/**
- * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
- * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
+ * An implementation of {@link GLAutoDrawable} and {@link Window} interface,
+ * using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
* <P>
* This implementation does not make the OpenGL context current<br>
* before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
@@ -195,8 +196,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
return window.getRequestedCapabilities();
}
- public final Window getWindow() {
- return window;
+ public final Window getDelegatedWindow() {
+ return window.getDelegatedWindow();
}
public final NativeWindow getParent() {
@@ -254,10 +255,18 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
window.setFocusAction(focusAction);
}
+ public void setKeyboardFocusHandler(KeyListener l) {
+ window.setKeyboardFocusHandler(l);
+ }
+
public final void requestFocus() {
window.requestFocus();
}
+ public final void requestFocus(boolean wait) {
+ window.requestFocus(wait);
+ }
+
public boolean hasFocus() {
return window.hasFocus();
}
@@ -753,18 +762,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
window.runOnEDTIfAvail(wait, task);
}
- public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- return window.getSurfaceUpdatedListener(index);
- }
-
- public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- return window.getSurfaceUpdatedListeners();
- }
-
- public final void removeAllSurfaceUpdatedListener() {
- window.removeAllSurfaceUpdatedListener();
- }
-
public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
window.removeSurfaceUpdatedListener(l);
}
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index fa7bafe5b..e923c37a9 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -48,9 +48,6 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
static long nextWindowHandle = 0x100; // start here - a marker
protected void createNativeImpl() {
- if(0!=getParentWindowHandle()) {
- throw new NativeWindowException("OffscreenWindow does not support window parenting");
- }
if(capsRequested.isOnscreen()) {
throw new NativeWindowException("Capabilities is onscreen");
}
@@ -70,6 +67,10 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
// nop
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
public synchronized void destroy() {
super.destroy();
@@ -89,29 +90,30 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
}
@Override
- public void setSize(int width, int height) {
- if(!isVisible()) {
- sizeChanged(false, width, height, false);
- }
- }
- @Override
public void setPosition(int x, int y) {
// nop
}
+
@Override
public boolean setFullscreen(boolean fullscreen) {
// nop
return false;
}
-
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
sizeChanged(false, width, height, false);
- visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
+ visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
} else {
- shouldNotCallThis();
+ /**
+ * silently ignore:
+ FLAG_CHANGE_PARENTING
+ FLAG_CHANGE_DECORATION
+ FLAG_CHANGE_FULLSCREEN
+ FLAG_CHANGE_ALWAYSONTOP
+ */
}
- return false;
+ return true;
}
@Override
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 9c51fe973..252be7cfd 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -208,6 +208,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int addReference() throws NativeWindowException {
if(DEBUG) {
System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ // Thread.dumpStack();
}
if ( 0 == refCount ) {
createNative();
@@ -220,10 +221,8 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int removeReference() {
if(DEBUG) {
- String msg = "Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1);
- // Throwable t = new Throwable(msg);
- // t.printStackTrace();
- System.err.println(msg);
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ // Thread.dumpStack();
}
refCount--; // could become < 0, in case of manual destruction without actual creation/addReference
if(0>=refCount) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 7df326e8e..f4856bafe 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -72,6 +72,8 @@ import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
public abstract class WindowImpl implements Window, NEWTEventConsumer
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
@@ -108,10 +110,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private RequestFocusAction requestFocusAction = new RequestFocusAction();
private FocusRunnable focusAction = null;
+ private KeyListener keyboardFocusHandler = null;
- private Object surfaceUpdatedListenersLock = new Object();
- private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
-
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+
private Object childWindowsLock = new Object();
private ArrayList<NativeWindow> childWindows = new ArrayList<NativeWindow>();
@@ -682,6 +684,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
+ protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ }
final void setVisibleActionImpl(boolean visible) {
boolean nativeWindowCreated = false;
boolean madeVisible = false;
@@ -740,8 +745,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( nativeWindowCreated || madeVisible ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
- }
-
+ }
private class VisibleAction implements Runnable {
boolean visible;
@@ -752,8 +756,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final void run() {
setVisibleActionImpl(visible);
}
- }
-
+ }
public void setVisible(boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
@@ -762,59 +765,67 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, new VisibleAction(visible));
}
- protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ final void setSizeActionImpl(int width, int height) {
+ boolean recreate = false;
+ windowLock.lock();
+ try {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
+ }
+ if(recreate) {
+ // will trigger visibleAction:=2 -> create if wasVisible
+ final boolean wasVisible = WindowImpl.this.visible;
+ screen.addReference(); // retain screen
+ destroyAction.run();
+ WindowImpl.this.visible = wasVisible;
+ }
+ if ( isNativeValid() && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( !isNativeValid() && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ } else if ( isNativeValid() ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
+ } else {
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
+ }
+ switch(visibleAction) {
+ case 1: setVisibleActionImpl(false); break;
+ case 2: setVisibleActionImpl(true); break;
+ }
+ }
+ } finally {
+ if(recreate) {
+ screen.removeReference(); // bring back ref-count
+ }
+ windowLock.unlock();
+ }
}
-
- private class SetSizeActionImpl implements Runnable {
+ private class SetSizeAction implements Runnable {
int width, height;
- private SetSizeActionImpl(int w, int h) {
+ private SetSizeAction(int w, int h) {
width = w;
height = h;
}
public final void run() {
- windowLock.lock();
- try {
- int visibleAction = 0; // 1 invisible, 2 visible (create)
- if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = "Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible;
- System.err.println(msg);
- }
- if ( isNativeValid() && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- WindowImpl.this.width = 0;
- WindowImpl.this.height = 0;
- } else if ( !isNativeValid() && 0<width*height && visible ) {
- visibleAction = 2; // visible (create)
- WindowImpl.this.width = width;
- WindowImpl.this.height = height;
- } else if ( isNativeValid() ) {
- // this width/height will be set by windowChanged, called by the native implementation
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
- } else {
- WindowImpl.this.width = width;
- WindowImpl.this.height = height;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
- }
- switch(visibleAction) {
- case 1: setVisibleActionImpl(false); break;
- case 2: setVisibleActionImpl(true); break;
- }
- }
- } finally {
- windowLock.unlock();
- }
+ setSizeActionImpl(width, height);
}
- }
-
+ }
public void setSize(int width, int height) {
- runOnEDTIfAvail(true, new SetSizeActionImpl(width, height));
- }
-
+ runOnEDTIfAvail(true, new SetSizeAction(width, height));
+ }
public void setTopLevelSize(int width, int height) {
setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
}
@@ -911,6 +922,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, destroyAction);
}
+ /**
+ * @param cWin child window, must not be null
+ * @param pWin parent window, may be null
+ * @return true if at least one of both window's configurations is offscreen
+ */
+ protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
+ boolean ofs = false;
+ if( null != cWin.getGraphicsConfiguration() ) {
+ ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
+ ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ return ofs;
+ }
+
private class ReparentActionImpl implements Runnable, ReparentAction {
NativeWindow newParentWindow;
boolean forceDestroyCreate;
@@ -918,7 +945,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) {
this.newParentWindow = newParentWindow;
- this.forceDestroyCreate = forceDestroyCreate;
+ this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE;
this.reparentAction = -1; // ensure it's set
}
@@ -927,10 +954,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private void setScreen(ScreenImpl newScreen) { // never null !
- WindowImpl.this.removeScreenReference();
+ removeScreenReference();
screen = newScreen;
}
-
+
public final void run() {
boolean animatorPaused = false;
if(null!=lifecycleHook) {
@@ -952,6 +979,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowLock.lock();
try {
+ if(isNativeValid()) {
+ // force recreation if offscreen, since it may become onscreen
+ forceDestroyCreate |= isOffscreenInstance(WindowImpl.this, newParentWindow);
+ }
+
wasVisible = isVisible();
Window newParentWindowNEWT = null;
@@ -962,7 +994,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
long newParentWindowHandle = 0 ;
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+x+"/"+y+" "+width+"x"+height);
+ System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", "+x+"/"+y+" "+width+"x"+height);
}
if(null!=lifecycleHook) {
@@ -1013,8 +1045,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else {
reparentAction = ACTION_NATIVE_CREATION_PENDING;
}
- } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
- !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
// Destroy this window, may create a new compatible Screen/Display,
// and mark it for creation.
destroy();
@@ -1045,7 +1076,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( 0 == parentWindowHandle ) {
// Already Top Window
reparentAction = ACTION_UNCHANGED;
- } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ } else if( !isNativeValid() || forceDestroyCreate ) {
// Destroy this window and mark it for [pending] creation.
destroy();
if( 0<width*height ) {
@@ -1138,7 +1169,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
}
if(ok) {
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
}
}
@@ -1208,7 +1239,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
- ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ final ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
runOnEDTIfAvail(true, reparentAction);
return reparentAction.getStrategy();
}
@@ -1385,14 +1416,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void requestFocus() {
- enqueueRequestFocus(true);
- }
-
- public final boolean hasFocus() {
- return hasFocus;
- }
-
public final InsetsImmutable getInsets() {
if(isUndecorated()) {
return Insets.getZero();
@@ -1452,7 +1475,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public Object getWrappedWindow() {
return null;
}
-
+
+ public final Window getDelegatedWindow() {
+ return this;
+ }
+
/**
* If set to true, the default value, this NEWT Window implementation will
* handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
@@ -1487,9 +1514,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
"\n, WrappedWindow "+getWrappedWindow()+
"\n, ChildWindows "+childWindows.size());
- sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
- for (int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
- sb.append(surfaceUpdatedListeners.get(i)+", ");
+ sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedHelper.size()+" [");
+ for (int i = 0; i < surfaceUpdatedHelper.size(); i++ ) {
+ sb.append(surfaceUpdatedHelper.get(i)+", ");
}
sb.append("], WindowListeners num "+windowListeners.size()+" [");
for (int i = 0; i < windowListeners.size(); i++ ) {
@@ -1529,21 +1556,32 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- protected void enqueueRequestFocus(boolean wait) {
- runOnEDTIfAvail(wait, requestFocusAction);
+ public final boolean hasFocus() {
+ return hasFocus;
}
- /**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
- * This allows notifying a covered window toolkit like AWT that the focus is requested,
- * hence focus traversal can be made transparent.
- */
+ public void requestFocus() {
+ requestFocus(true);
+ }
+
+ public void requestFocus(boolean wait) {
+ if(!focusAction()) {
+ runOnEDTIfAvail(wait, requestFocusAction);
+ }
+ }
+
+ /** Internal request focus on current thread */
+ private void requestFocusInt(boolean force) {
+ if(!focusAction()) {
+ requestFocusImpl(force);
+ }
+ }
+
public void setFocusAction(FocusRunnable focusAction) {
this.focusAction = focusAction;
}
-
- /** Called by native requestFocusImpl() */
- protected boolean focusAction() {
+
+ private boolean focusAction() {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.focusAction() START - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle()));
}
@@ -1558,7 +1596,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
return res;
}
-
+
+ public void setKeyboardFocusHandler(KeyListener l) {
+ keyboardFocusHandler = l;
+ }
+
private class SetPositionActionImpl implements Runnable {
int x, y;
@@ -1680,7 +1722,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
display.dispatchMessagesNative(); // status up2date
WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW);
display.dispatchMessagesNative(); // status up2date
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
if(DEBUG_IMPLEMENTATION) {
@@ -1800,8 +1842,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// queue event in case window is locked, ie in operation
if( isWindowLocked() ) {
if(DEBUG_IMPLEMENTATION) {
- // System.err.println("Window.consumeEvent: queued "+e);
- // Thread.dumpStack(); // JAU
+ System.err.println("Window.consumeEvent: queued "+e);
+ // Thread.dumpStack();
}
return false;
}
@@ -1824,62 +1866,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// SurfaceUpdatedListener Support
//
-
public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- addSurfaceUpdatedListener(-1, l);
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
- throws IndexOutOfBoundsException
- {
- if(l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size();
- }
- surfaceUpdatedListeners.add(index, l);
- }
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
}
public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- if (l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners.remove(l);
- }
- }
-
- public void removeAllSurfaceUpdatedListener() {
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
- }
- }
-
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size()-1;
- }
- return surfaceUpdatedListeners.get(index);
- }
- }
-
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- synchronized(surfaceUpdatedListenersLock) {
- return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
- }
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
}
public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- synchronized(surfaceUpdatedListenersLock) {
- for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
- SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
- l.surfaceUpdated(updater, ns, when);
- }
- }
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
}
//
@@ -2033,8 +2033,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(DEBUG_MOUSE_EVENT) {
System.err.println("consumeMouseEvent: event: "+e);
}
-
- for(int i = 0; i < mouseListeners.size(); i++ ) {
+ boolean consumed = false;
+ for(int i = 0; !consumed && i < mouseListeners.size(); i++ ) {
MouseListener l = mouseListeners.get(i);
switch(e.getEventType()) {
case MouseEvent.EVENT_MOUSE_CLICKED:
@@ -2064,13 +2064,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
default:
throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
}
+ consumed = InputEvent.consumedTag == e.getAttachment();
}
}
//
// KeyListener/Event Support
//
-
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
}
@@ -2119,26 +2119,39 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return (KeyListener[]) keyListeners.toArray();
}
- protected void consumeKeyEvent(KeyEvent e) {
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e);
+ private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) {
+ switch(e.getEventType()) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ l.keyPressed(e);
+ break;
+ case KeyEvent.EVENT_KEY_RELEASED:
+ l.keyReleased(e);
+ break;
+ case KeyEvent.EVENT_KEY_TYPED:
+ l.keyTyped(e);
+ break;
+ default:
+ throw new NativeWindowException("Unexpected key event type " + e.getEventType());
}
- for(int i = 0; i < keyListeners.size(); i++ ) {
- KeyListener l = keyListeners.get(i);
- switch(e.getEventType()) {
- case KeyEvent.EVENT_KEY_PRESSED:
- l.keyPressed(e);
- break;
- case KeyEvent.EVENT_KEY_RELEASED:
- l.keyReleased(e);
- break;
- case KeyEvent.EVENT_KEY_TYPED:
- l.keyTyped(e);
- break;
- default:
- throw new NativeWindowException("Unexpected key event type " + e.getEventType());
+ return InputEvent.consumedTag == e.getAttachment();
+ }
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ boolean consumed;
+ if(null != keyboardFocusHandler) {
+ consumed = propagateKeyEvent(e, keyboardFocusHandler);
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumed);
+ }
+ } else {
+ consumed = false;
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
}
}
+ for(int i = 0; !consumed && i < keyListeners.size(); i++ ) {
+ consumed = propagateKeyEvent(e, keyListeners.get(i));
+ }
}
//
diff --git a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
index aa98d3a37..d4b2fd3d6 100644
--- a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java
+++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
@@ -27,13 +27,15 @@
*/
-package jogamp.newt.awt.event;
+package jogamp.newt.awt;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
import com.jogamp.newt.NewtFactory;
+
+import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.newt.Debug;
public class NewtFactoryAWT extends NewtFactory {
@@ -51,7 +53,7 @@ public class NewtFactoryAWT extends NewtFactory {
*
* @param awtCompObject must be of type java.awt.Component
*/
- public static NativeWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
+ public static JAWTWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
if(null==awtCompObject) {
throw new NativeWindowException("Null AWT Component");
}
@@ -61,13 +63,34 @@ public class NewtFactoryAWT extends NewtFactory {
return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
}
- public static NativeWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
- DefaultGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, capsRequested, capsRequested);
- NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ public static JAWTWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
+ AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
+ NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ if(! ( nw instanceof JAWTWindow ) ) {
+ throw new NativeWindowException("Not an AWT NativeWindow: "+nw);
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+nw);
+ }
+ return (JAWTWindow)nw;
+ }
+
+ public static void updateGraphicsConfiguration(JAWTWindow nw, java.awt.Component awtComp) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("NewtFactoryAWT.updateGraphicsConfiguration: (pre) "+awtComp+" -> "+nw);
+ }
+ final AWTGraphicsConfiguration awtConfig = (AWTGraphicsConfiguration) nw.getGraphicsConfiguration();
+ awtConfig.updateGraphicsConfiguration(awtComp);
+ // lockSurface() re-issues JAWTWindow's native validation
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= nw.lockSurface() ) {
+ throw new NativeWindowException("could not lock "+nw);
+ }
+ nw.unlockSurface();
+
if(DEBUG_IMPLEMENTATION) {
- System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative);
+ System.err.println("NewtFactoryAWT.updateGraphicsConfiguration: (post) "+awtComp+" -> "+nw);
}
- return awtNative;
}
+
}
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index 358864547..313a5e868 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -28,6 +28,8 @@
package jogamp.newt.awt.event;
+import java.awt.KeyboardFocusManager;
+
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -54,9 +56,16 @@ public class AWTParentWindowAdapter
}
public void focusGained(java.awt.event.FocusEvent e) {
+ // forward focus to NEWT child
+ final com.jogamp.newt.Window newtChild = getNewtWindow();
+ final boolean isOnscreen = newtChild.isNativeValid() && newtChild.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: focusGained: "+ e);
+ System.err.println("AWT: focusGained: onscreen "+ isOnscreen+", "+e);
+ }
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ newtChild.requestFocus(false);
}
public void focusLost(java.awt.event.FocusEvent e) {
diff --git a/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
new file mode 100644
index 000000000..4d23c4ea8
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
@@ -0,0 +1,12 @@
+package jogamp.newt.driver;
+
+/**
+ * Interface tagging driver feature / requirement of clearing the focus.
+ * <p>
+ * Some drivers require a programmatic {@link #clearFocus()} when traversing the focus.
+ * </p>
+ */
+public interface DriverClearFocus {
+ /** Programmatic clear the focus */
+ void clearFocus();
+}
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index bb678935a..a7326d916 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -30,7 +30,6 @@ package jogamp.newt.driver.android;
import javax.media.opengl.GLProfile;
import com.jogamp.newt.Window;
-import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import jogamp.newt.driver.android.AndroidWindow;
@@ -63,9 +62,7 @@ public class NewtBaseActivity extends Activity {
}
public void setContentView(android.view.Window androidWindow, Window newtWindow) {
- if(newtWindow instanceof GLWindow) {
- newtWindow = ((GLWindow)newtWindow).getWindow();
- }
+ newtWindow = newtWindow.getDelegatedWindow();
if(newtWindow instanceof AndroidWindow) {
this.newtWindow = (AndroidWindow)newtWindow;
this.newtWindow.setAndroidWindow(androidWindow);
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
new file mode 100644
index 000000000..46625f7a9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -0,0 +1,262 @@
+package jogamp.newt.driver.macosx;
+
+import com.jogamp.newt.event.KeyEvent;
+
+public class MacKeyUtil {
+
+ // KeyCodes (independent)
+ private static final int kVK_Return = 0x24;
+ private static final int kVK_Tab = 0x30;
+ private static final int kVK_Space = 0x31;
+ private static final int kVK_Delete = 0x33;
+ private static final int kVK_Escape = 0x35;
+ private static final int kVK_Command = 0x37;
+ private static final int kVK_Shift = 0x38;
+ private static final int kVK_CapsLock = 0x39;
+ private static final int kVK_Option = 0x3A;
+ private static final int kVK_Control = 0x3B;
+ private static final int kVK_RightShift = 0x3C;
+ private static final int kVK_RightOption = 0x3D;
+ private static final int kVK_RightControl = 0x3E;
+ private static final int kVK_Function = 0x3F;
+ private static final int kVK_F17 = 0x40;
+ private static final int kVK_VolumeUp = 0x48;
+ private static final int kVK_VolumeDown = 0x49;
+ private static final int kVK_Mute = 0x4A;
+ private static final int kVK_F18 = 0x4F;
+ private static final int kVK_F19 = 0x50;
+ private static final int kVK_F20 = 0x5A;
+ private static final int kVK_F5 = 0x60;
+ private static final int kVK_F6 = 0x61;
+ private static final int kVK_F7 = 0x62;
+ private static final int kVK_F3 = 0x63;
+ private static final int kVK_F8 = 0x64;
+ private static final int kVK_F9 = 0x65;
+ private static final int kVK_F11 = 0x67;
+ private static final int kVK_F13 = 0x69;
+ private static final int kVK_F16 = 0x6A;
+ private static final int kVK_F14 = 0x6B;
+ private static final int kVK_F10 = 0x6D;
+ private static final int kVK_F12 = 0x6F;
+ private static final int kVK_F15 = 0x71;
+ private static final int kVK_Help = 0x72;
+ private static final int kVK_Home = 0x73;
+ private static final int kVK_PageUp = 0x74;
+ private static final int kVK_ForwardDelete = 0x75;
+ private static final int kVK_F4 = 0x76;
+ private static final int kVK_End = 0x77;
+ private static final int kVK_F2 = 0x78;
+ private static final int kVK_PageDown = 0x79;
+ private static final int kVK_F1 = 0x7A;
+ private static final int kVK_LeftArrow = 0x7B;
+ private static final int kVK_RightArrow = 0x7C;
+ private static final int kVK_DownArrow = 0x7D;
+ private static final int kVK_UpArrow = 0x7E;
+
+ // Key constants handled differently on Mac OS X than other platforms
+ private static final char NSUpArrowFunctionKey = 0xF700;
+ private static final char NSDownArrowFunctionKey = 0xF701;
+ private static final char NSLeftArrowFunctionKey = 0xF702;
+ private static final char NSRightArrowFunctionKey = 0xF703;
+ private static final char NSF1FunctionKey = 0xF704;
+ private static final char NSF2FunctionKey = 0xF705;
+ private static final char NSF3FunctionKey = 0xF706;
+ private static final char NSF4FunctionKey = 0xF707;
+ private static final char NSF5FunctionKey = 0xF708;
+ private static final char NSF6FunctionKey = 0xF709;
+ private static final char NSF7FunctionKey = 0xF70A;
+ private static final char NSF8FunctionKey = 0xF70B;
+ private static final char NSF9FunctionKey = 0xF70C;
+ private static final char NSF10FunctionKey = 0xF70D;
+ private static final char NSF11FunctionKey = 0xF70E;
+ private static final char NSF12FunctionKey = 0xF70F;
+ private static final char NSF13FunctionKey = 0xF710;
+ private static final char NSF14FunctionKey = 0xF711;
+ private static final char NSF15FunctionKey = 0xF712;
+ private static final char NSF16FunctionKey = 0xF713;
+ private static final char NSF17FunctionKey = 0xF714;
+ private static final char NSF18FunctionKey = 0xF715;
+ private static final char NSF19FunctionKey = 0xF716;
+ private static final char NSF20FunctionKey = 0xF717;
+ private static final char NSF21FunctionKey = 0xF718;
+ private static final char NSF22FunctionKey = 0xF719;
+ private static final char NSF23FunctionKey = 0xF71A;
+ private static final char NSF24FunctionKey = 0xF71B;
+ private static final char NSF25FunctionKey = 0xF71C;
+ private static final char NSF26FunctionKey = 0xF71D;
+ private static final char NSF27FunctionKey = 0xF71E;
+ private static final char NSF28FunctionKey = 0xF71F;
+ private static final char NSF29FunctionKey = 0xF720;
+ private static final char NSF30FunctionKey = 0xF721;
+ private static final char NSF31FunctionKey = 0xF722;
+ private static final char NSF32FunctionKey = 0xF723;
+ private static final char NSF33FunctionKey = 0xF724;
+ private static final char NSF34FunctionKey = 0xF725;
+ private static final char NSF35FunctionKey = 0xF726;
+ private static final char NSInsertFunctionKey = 0xF727;
+ private static final char NSDeleteFunctionKey = 0xF728;
+ private static final char NSHomeFunctionKey = 0xF729;
+ private static final char NSBeginFunctionKey = 0xF72A;
+ private static final char NSEndFunctionKey = 0xF72B;
+ private static final char NSPageUpFunctionKey = 0xF72C;
+ private static final char NSPageDownFunctionKey = 0xF72D;
+ private static final char NSPrintScreenFunctionKey = 0xF72E;
+ private static final char NSScrollLockFunctionKey = 0xF72F;
+ private static final char NSPauseFunctionKey = 0xF730;
+ private static final char NSSysReqFunctionKey = 0xF731;
+ private static final char NSBreakFunctionKey = 0xF732;
+ private static final char NSResetFunctionKey = 0xF733;
+ private static final char NSStopFunctionKey = 0xF734;
+ private static final char NSMenuFunctionKey = 0xF735;
+ private static final char NSUserFunctionKey = 0xF736;
+ private static final char NSSystemFunctionKey = 0xF737;
+ private static final char NSPrintFunctionKey = 0xF738;
+ private static final char NSClearLineFunctionKey = 0xF739;
+ private static final char NSClearDisplayFunctionKey = 0xF73A;
+ private static final char NSInsertLineFunctionKey = 0xF73B;
+ private static final char NSDeleteLineFunctionKey = 0xF73C;
+ private static final char NSInsertCharFunctionKey = 0xF73D;
+ private static final char NSDeleteCharFunctionKey = 0xF73E;
+ private static final char NSPrevFunctionKey = 0xF73F;
+ private static final char NSNextFunctionKey = 0xF740;
+ private static final char NSSelectFunctionKey = 0xF741;
+ private static final char NSExecuteFunctionKey = 0xF742;
+ private static final char NSUndoFunctionKey = 0xF743;
+ private static final char NSRedoFunctionKey = 0xF744;
+ private static final char NSFindFunctionKey = 0xF745;
+ private static final char NSHelpFunctionKey = 0xF746;
+ private static final char NSModeSwitchFunctionKey = 0xF747;
+
+ static int validateKeyCode(int keyCode, char keyChar) {
+ // OS X Virtual Keycodes
+ switch(keyCode) {
+ case kVK_Return: return KeyEvent.VK_ENTER;
+ case kVK_Tab: return KeyEvent.VK_TAB;
+ case kVK_Space: return KeyEvent.VK_SPACE;
+ case kVK_Delete: return KeyEvent.VK_BACK_SPACE;
+ case kVK_Escape: return KeyEvent.VK_ESCAPE;
+ case kVK_Command: return KeyEvent.VK_ALT;
+ case kVK_Shift: return KeyEvent.VK_SHIFT;
+ case kVK_CapsLock: return KeyEvent.VK_CAPS_LOCK;
+ case kVK_Option: return KeyEvent.VK_WINDOWS;
+ case kVK_Control: return KeyEvent.VK_CONTROL;
+ case kVK_RightShift: return KeyEvent.VK_SHIFT;
+ case kVK_RightOption: return KeyEvent.VK_WINDOWS;
+ case kVK_RightControl: return KeyEvent.VK_CONTROL;
+ // case kVK_Function: return KeyEvent.VK_F;
+ case kVK_F17: return KeyEvent.VK_F17;
+ // case kVK_VolumeUp:
+ // case kVK_VolumeDown:
+ // case kVK_Mute:
+ case kVK_F18: return KeyEvent.VK_F18;
+ case kVK_F19: return KeyEvent.VK_F19;
+ case kVK_F20: return KeyEvent.VK_F20;
+ case kVK_F5: return KeyEvent.VK_F5;
+ case kVK_F6: return KeyEvent.VK_F6;
+ case kVK_F7: return KeyEvent.VK_F7;
+ case kVK_F3: return KeyEvent.VK_F3;
+ case kVK_F8: return KeyEvent.VK_F8;
+ case kVK_F9: return KeyEvent.VK_F9;
+ case kVK_F11: return KeyEvent.VK_F11;
+ case kVK_F13: return KeyEvent.VK_F13;
+ case kVK_F16: return KeyEvent.VK_F16;
+ case kVK_F14: return KeyEvent.VK_F14;
+ case kVK_F10: return KeyEvent.VK_F10;
+ case kVK_F12: return KeyEvent.VK_F12;
+ case kVK_F15: return KeyEvent.VK_F15;
+ case kVK_Help: return KeyEvent.VK_HELP;
+ case kVK_Home: return KeyEvent.VK_HOME;
+ case kVK_PageUp: return KeyEvent.VK_PAGE_UP;
+ case kVK_ForwardDelete: return KeyEvent.VK_DELETE;
+ case kVK_F4: return KeyEvent.VK_F4;
+ case kVK_End: return KeyEvent.VK_END;
+ case kVK_F2: return KeyEvent.VK_F2;
+ case kVK_PageDown: return KeyEvent.VK_PAGE_DOWN;
+ case kVK_F1: return KeyEvent.VK_F1;
+ case kVK_LeftArrow: return KeyEvent.VK_LEFT;
+ case kVK_RightArrow: return KeyEvent.VK_RIGHT;
+ case kVK_DownArrow: return KeyEvent.VK_DOWN;
+ case kVK_UpArrow: return KeyEvent.VK_UP;
+ }
+
+ if (keyChar == '\r') {
+ // Turn these into \n
+ return KeyEvent.VK_ENTER;
+ }
+
+ if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
+ switch (keyChar) {
+ case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
+ case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
+ case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
+ case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
+ case NSF1FunctionKey: return KeyEvent.VK_F1;
+ case NSF2FunctionKey: return KeyEvent.VK_F2;
+ case NSF3FunctionKey: return KeyEvent.VK_F3;
+ case NSF4FunctionKey: return KeyEvent.VK_F4;
+ case NSF5FunctionKey: return KeyEvent.VK_F5;
+ case NSF6FunctionKey: return KeyEvent.VK_F6;
+ case NSF7FunctionKey: return KeyEvent.VK_F7;
+ case NSF8FunctionKey: return KeyEvent.VK_F8;
+ case NSF9FunctionKey: return KeyEvent.VK_F9;
+ case NSF10FunctionKey: return KeyEvent.VK_F10;
+ case NSF11FunctionKey: return KeyEvent.VK_F11;
+ case NSF12FunctionKey: return KeyEvent.VK_F12;
+ case NSF13FunctionKey: return KeyEvent.VK_F13;
+ case NSF14FunctionKey: return KeyEvent.VK_F14;
+ case NSF15FunctionKey: return KeyEvent.VK_F15;
+ case NSF16FunctionKey: return KeyEvent.VK_F16;
+ case NSF17FunctionKey: return KeyEvent.VK_F17;
+ case NSF18FunctionKey: return KeyEvent.VK_F18;
+ case NSF19FunctionKey: return KeyEvent.VK_F19;
+ case NSF20FunctionKey: return KeyEvent.VK_F20;
+ case NSF21FunctionKey: return KeyEvent.VK_F21;
+ case NSF22FunctionKey: return KeyEvent.VK_F22;
+ case NSF23FunctionKey: return KeyEvent.VK_F23;
+ case NSF24FunctionKey: return KeyEvent.VK_F24;
+ case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
+ case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
+ case NSHomeFunctionKey: return KeyEvent.VK_HOME;
+ case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
+ case NSEndFunctionKey: return KeyEvent.VK_END;
+ case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
+ case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
+ case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+ case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
+ case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
+ // Not handled:
+ // NSSysReqFunctionKey
+ // NSBreakFunctionKey
+ // NSResetFunctionKey
+ case NSStopFunctionKey: return KeyEvent.VK_STOP;
+ // Not handled:
+ // NSMenuFunctionKey
+ // NSUserFunctionKey
+ // NSSystemFunctionKey
+ // NSPrintFunctionKey
+ // NSClearLineFunctionKey
+ // NSClearDisplayFunctionKey
+ // NSInsertLineFunctionKey
+ // NSDeleteLineFunctionKey
+ // NSInsertCharFunctionKey
+ // NSDeleteCharFunctionKey
+ // NSPrevFunctionKey
+ // NSNextFunctionKey
+ // NSSelectFunctionKey
+ // NSExecuteFunctionKey
+ // NSUndoFunctionKey
+ // NSRedoFunctionKey
+ // NSFindFunctionKey
+ // NSHelpFunctionKey
+ // NSModeSwitchFunctionKey
+ default: break;
+ }
+ }
+
+ if ('a' <= keyChar && keyChar <= 'z') {
+ return KeyEvent.VK_A + ( keyChar - 'a' ) ;
+ }
+
+ return (int) keyChar; // let's hope for the best (compatibility of keyChar/keyCode's)
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index d09ac72ba..b7e572b6c 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -37,105 +37,19 @@ package jogamp.newt.driver.macosx;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.DriverClearFocus;
import com.jogamp.newt.event.KeyEvent;
-public class MacWindow extends WindowImpl {
+public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus {
- // Window styles
- private static final int NSBorderlessWindowMask = 0;
- private static final int NSTitledWindowMask = 1 << 0;
- private static final int NSClosableWindowMask = 1 << 1;
- private static final int NSMiniaturizableWindowMask = 1 << 2;
- private static final int NSResizableWindowMask = 1 << 3;
-
- // Window backing store types
- private static final int NSBackingStoreRetained = 0;
- private static final int NSBackingStoreNonretained = 1;
- private static final int NSBackingStoreBuffered = 2;
-
- // Key constants handled differently on Mac OS X than other platforms
- private static final int NSUpArrowFunctionKey = 0xF700;
- private static final int NSDownArrowFunctionKey = 0xF701;
- private static final int NSLeftArrowFunctionKey = 0xF702;
- private static final int NSRightArrowFunctionKey = 0xF703;
- private static final int NSF1FunctionKey = 0xF704;
- private static final int NSF2FunctionKey = 0xF705;
- private static final int NSF3FunctionKey = 0xF706;
- private static final int NSF4FunctionKey = 0xF707;
- private static final int NSF5FunctionKey = 0xF708;
- private static final int NSF6FunctionKey = 0xF709;
- private static final int NSF7FunctionKey = 0xF70A;
- private static final int NSF8FunctionKey = 0xF70B;
- private static final int NSF9FunctionKey = 0xF70C;
- private static final int NSF10FunctionKey = 0xF70D;
- private static final int NSF11FunctionKey = 0xF70E;
- private static final int NSF12FunctionKey = 0xF70F;
- private static final int NSF13FunctionKey = 0xF710;
- private static final int NSF14FunctionKey = 0xF711;
- private static final int NSF15FunctionKey = 0xF712;
- private static final int NSF16FunctionKey = 0xF713;
- private static final int NSF17FunctionKey = 0xF714;
- private static final int NSF18FunctionKey = 0xF715;
- private static final int NSF19FunctionKey = 0xF716;
- private static final int NSF20FunctionKey = 0xF717;
- private static final int NSF21FunctionKey = 0xF718;
- private static final int NSF22FunctionKey = 0xF719;
- private static final int NSF23FunctionKey = 0xF71A;
- private static final int NSF24FunctionKey = 0xF71B;
- private static final int NSF25FunctionKey = 0xF71C;
- private static final int NSF26FunctionKey = 0xF71D;
- private static final int NSF27FunctionKey = 0xF71E;
- private static final int NSF28FunctionKey = 0xF71F;
- private static final int NSF29FunctionKey = 0xF720;
- private static final int NSF30FunctionKey = 0xF721;
- private static final int NSF31FunctionKey = 0xF722;
- private static final int NSF32FunctionKey = 0xF723;
- private static final int NSF33FunctionKey = 0xF724;
- private static final int NSF34FunctionKey = 0xF725;
- private static final int NSF35FunctionKey = 0xF726;
- private static final int NSInsertFunctionKey = 0xF727;
- private static final int NSDeleteFunctionKey = 0xF728;
- private static final int NSHomeFunctionKey = 0xF729;
- private static final int NSBeginFunctionKey = 0xF72A;
- private static final int NSEndFunctionKey = 0xF72B;
- private static final int NSPageUpFunctionKey = 0xF72C;
- private static final int NSPageDownFunctionKey = 0xF72D;
- private static final int NSPrintScreenFunctionKey = 0xF72E;
- private static final int NSScrollLockFunctionKey = 0xF72F;
- private static final int NSPauseFunctionKey = 0xF730;
- private static final int NSSysReqFunctionKey = 0xF731;
- private static final int NSBreakFunctionKey = 0xF732;
- private static final int NSResetFunctionKey = 0xF733;
- private static final int NSStopFunctionKey = 0xF734;
- private static final int NSMenuFunctionKey = 0xF735;
- private static final int NSUserFunctionKey = 0xF736;
- private static final int NSSystemFunctionKey = 0xF737;
- private static final int NSPrintFunctionKey = 0xF738;
- private static final int NSClearLineFunctionKey = 0xF739;
- private static final int NSClearDisplayFunctionKey = 0xF73A;
- private static final int NSInsertLineFunctionKey = 0xF73B;
- private static final int NSDeleteLineFunctionKey = 0xF73C;
- private static final int NSInsertCharFunctionKey = 0xF73D;
- private static final int NSDeleteCharFunctionKey = 0xF73E;
- private static final int NSPrevFunctionKey = 0xF73F;
- private static final int NSNextFunctionKey = 0xF740;
- private static final int NSSelectFunctionKey = 0xF741;
- private static final int NSExecuteFunctionKey = 0xF742;
- private static final int NSUndoFunctionKey = 0xF743;
- private static final int NSRedoFunctionKey = 0xF744;
- private static final int NSFindFunctionKey = 0xF745;
- private static final int NSHelpFunctionKey = 0xF746;
- private static final int NSModeSwitchFunctionKey = 0xF747;
-
- private volatile long surfaceHandle;
-
static {
MacDisplay.initSingleton();
}
@@ -143,6 +57,7 @@ public class MacWindow extends WindowImpl {
public MacWindow() {
}
+ @Override
protected void createNativeImpl() {
config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
@@ -155,6 +70,7 @@ public class MacWindow extends WindowImpl {
}
}
+ @Override
protected void closeNativeImpl() {
try {
if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
@@ -173,76 +89,128 @@ public class MacWindow extends WindowImpl {
@Override
protected int lockSurfaceImpl() {
- return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ if(!isOffscreenInstance) {
+ return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ }
+ return LOCK_SUCCESS;
}
@Override
protected void unlockSurfaceImpl() {
- unlockSurface0(getWindowHandle());
+ if(!isOffscreenInstance) {
+ unlockSurface0(getWindowHandle());
+ }
}
@Override
public final long getSurfaceHandle() {
- return surfaceHandle;
+ return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSurfaceHandle = surfaceHandle;
+ if (isNativeValid()) {
+ if (0 != sscSurfaceHandle) {
+ orderOut0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
+ } /** this is done by recreation!
+ else if (isVisible()){
+ orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
+ } */
+ }
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
protected void setTitleImpl(final String title) {
setTitle0(getWindowHandle(), title);
}
protected void requestFocusImpl(boolean force) {
- requestFocus0(getWindowHandle(), force);
+ if(!isOffscreenInstance) {
+ requestFocus0(getWindowHandle(), force);
+ } else {
+ focusChanged(false, true);
+ }
+ }
+
+ public final void clearFocus() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance);
+ }
+ if(!isOffscreenInstance) {
+ requestFocusParent0(getWindowHandle());
+ } else {
+ focusChanged(false, false);
+ }
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
final PointImmutable pS = position2TopLevel(new Point(x, y));
+ isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent());
if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+", "+
- getReconfigureFlagsAsString(null, flags));
+ System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
+ ", offscreenInstance "+isOffscreenInstance+
+ ", "+getReconfigureFlagsAsString(null, flags));
}
if( getWindowHandle() == 0 ) {
if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
- createWindow(false, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ createWindow(isOffscreenInstance, false, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
// no native event ..
visibleChanged(true, true);
} /* else { ?? } */
} else {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
- orderOut0(getWindowHandle());
+ if ( !isOffscreenInstance ) {
+ orderOut0(getWindowHandle());
+ }
// no native event ..
visibleChanged(true, false);
- }
+ }
if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
0 != ( FLAG_CHANGE_PARENTING & flags) ||
0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(true, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ createWindow(isOffscreenInstance, true, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
}
if(x>=0 && y>=0) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
+ if( !isOffscreenInstance ) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
+ } // else no offscreen position
// no native event (fullscreen, some reparenting)
positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
}
if(width>0 && height>0) {
- setContentSize0(getWindowHandle(), width, height);
+ if( !isOffscreenInstance ) {
+ setContentSize0(getWindowHandle(), width, height);
+ } // else offscreen size is realized via recreation
// no native event (fullscreen, some reparenting)
sizeChanged(true, width, height, false); // incl. validation (incl. repositioning)
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) {
- orderFront0(getWindowHandle());
+ if( !isOffscreenInstance ) {
+ orderFront0(getWindowHandle());
+ }
// no native event ..
visibleChanged(true, true);
}
- setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
+ if( !isOffscreenInstance ) {
+ setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
+ }
}
return true;
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return (Point) getLocationOnScreen0(getWindowHandle(), x, y);
+ return position2TopLevel(new Point(x, y)); // allows offscreen ..
+ // return (Point) getLocationOnScreen0(getWindowHandle(), x, y);
}
protected void updateInsetsImpl(Insets insets) {
@@ -265,125 +233,54 @@ public class MacWindow extends WindowImpl {
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- return setPointerVisible0(getWindowHandle(), pointerVisible);
+ if( !isOffscreenInstance ) {
+ return setPointerVisible0(getWindowHandle(), pointerVisible);
+ } // else may need offscreen solution ? FIXME
+ return false;
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return confinePointer0(getWindowHandle(), confine);
+ if( !isOffscreenInstance ) {
+ return confinePointer0(getWindowHandle(), confine);
+ } // else may need offscreen solution ? FIXME
+ return false;
}
@Override
protected void warpPointerImpl(final int x, final int y) {
- warpPointer0(getWindowHandle(), x, y);
+ if( !isOffscreenInstance ) {
+ warpPointer0(getWindowHandle(), x, y);
+ } // else may need offscreen solution ? FIXME
}
@Override
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- final int key = convertKeyChar(keyChar);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName());
// Note that we send the key char for the key code on this
// platform -- we do not get any useful key codes out of the system
- super.sendKeyEvent(eventType, modifiers, key, keyChar);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2));
+ // only deliver keyChar on key Typed events, harmonizing platform behavior
+ keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
+ super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar);
}
@Override
public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- final int key = convertKeyChar(keyChar);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName());
// Note that we send the key char for the key code on this
// platform -- we do not get any useful key codes out of the system
- super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2));
+ // only deliver keyChar on key Typed events, harmonizing platform behavior
+ keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar);
}
//----------------------------------------------------------------------
// Internals only
//
- private char convertKeyChar(char keyChar) {
- if (keyChar == '\r') {
- // Turn these into \n
- return '\n';
- }
-
- if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
- switch (keyChar) {
- case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
- case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
- case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
- case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
- case NSF1FunctionKey: return KeyEvent.VK_F1;
- case NSF2FunctionKey: return KeyEvent.VK_F2;
- case NSF3FunctionKey: return KeyEvent.VK_F3;
- case NSF4FunctionKey: return KeyEvent.VK_F4;
- case NSF5FunctionKey: return KeyEvent.VK_F5;
- case NSF6FunctionKey: return KeyEvent.VK_F6;
- case NSF7FunctionKey: return KeyEvent.VK_F7;
- case NSF8FunctionKey: return KeyEvent.VK_F8;
- case NSF9FunctionKey: return KeyEvent.VK_F9;
- case NSF10FunctionKey: return KeyEvent.VK_F10;
- case NSF11FunctionKey: return KeyEvent.VK_F11;
- case NSF12FunctionKey: return KeyEvent.VK_F12;
- case NSF13FunctionKey: return KeyEvent.VK_F13;
- case NSF14FunctionKey: return KeyEvent.VK_F14;
- case NSF15FunctionKey: return KeyEvent.VK_F15;
- case NSF16FunctionKey: return KeyEvent.VK_F16;
- case NSF17FunctionKey: return KeyEvent.VK_F17;
- case NSF18FunctionKey: return KeyEvent.VK_F18;
- case NSF19FunctionKey: return KeyEvent.VK_F19;
- case NSF20FunctionKey: return KeyEvent.VK_F20;
- case NSF21FunctionKey: return KeyEvent.VK_F21;
- case NSF22FunctionKey: return KeyEvent.VK_F22;
- case NSF23FunctionKey: return KeyEvent.VK_F23;
- case NSF24FunctionKey: return KeyEvent.VK_F24;
- case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
- case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
- case NSHomeFunctionKey: return KeyEvent.VK_HOME;
- case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
- case NSEndFunctionKey: return KeyEvent.VK_END;
- case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
- case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
- case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
- case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
- case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
- // Not handled:
- // NSSysReqFunctionKey
- // NSBreakFunctionKey
- // NSResetFunctionKey
- case NSStopFunctionKey: return KeyEvent.VK_STOP;
- // Not handled:
- // NSMenuFunctionKey
- // NSUserFunctionKey
- // NSSystemFunctionKey
- // NSPrintFunctionKey
- // NSClearLineFunctionKey
- // NSClearDisplayFunctionKey
- // NSInsertLineFunctionKey
- // NSDeleteLineFunctionKey
- // NSInsertCharFunctionKey
- // NSDeleteCharFunctionKey
- // NSPrevFunctionKey
- // NSNextFunctionKey
- // NSSelectFunctionKey
- // NSExecuteFunctionKey
- // NSUndoFunctionKey
- // NSRedoFunctionKey
- // NSFindFunctionKey
- // NSHelpFunctionKey
- // NSModeSwitchFunctionKey
- default: break;
- }
- }
-
- // NSEvent's charactersIgnoringModifiers doesn't ignore the shift key
- if (keyChar >= 'a' && keyChar <= 'z') {
- return Character.toUpperCase(keyChar);
- }
-
- return keyChar;
- }
-
- private void createWindow(final boolean recreate,
+ private void createWindow(final boolean offscreenInstance, final boolean recreate,
final PointImmutable pS, final int width, final int height,
final boolean fullscreen) {
@@ -406,20 +303,24 @@ public class MacWindow extends WindowImpl {
}
setWindowHandle(createWindow0(getParentWindowHandle(),
pS.getX(), pS.getY(), width, height,
- config.getChosenCapabilities().isBackgroundOpaque(),
+ (config.getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance),
fullscreen,
- (isUndecorated() ?
- NSBorderlessWindowMask :
- NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ ((isUndecorated() || offscreenInstance) ?
+ NSBorderlessWindowMask :
+ NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
NSBackingStoreBuffered,
getScreen().getIndex(), surfaceHandle));
if (getWindowHandle() == 0) {
throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
}
surfaceHandle = contentView0(getWindowHandle());
- setTitle0(getWindowHandle(), getTitle());
- // need to revalidate real position
- positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
+ if( offscreenInstance ) {
+ orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle());
+ } else {
+ setTitle0(getWindowHandle(), getTitle());
+ // need to revalidate real position
+ positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
+ }
} catch (Exception ie) {
ie.printStackTrace();
}
@@ -467,6 +368,7 @@ public class MacWindow extends WindowImpl {
private native boolean lockSurface0(long window);
private native void unlockSurface0(long window);
private native void requestFocus0(long window, boolean force);
+ private native void requestFocusParent0(long window);
/** in case of a child window, it actually only issues orderBack(..) */
private native void orderOut0(long window);
private native void orderFront0(long window);
@@ -481,4 +383,21 @@ public class MacWindow extends WindowImpl {
private static native boolean setPointerVisible0(long windowHandle, boolean visible);
private static native boolean confinePointer0(long windowHandle, boolean confine);
private static native void warpPointer0(long windowHandle, int x, int y);
+
+ // Window styles
+ private static final int NSBorderlessWindowMask = 0;
+ private static final int NSTitledWindowMask = 1 << 0;
+ private static final int NSClosableWindowMask = 1 << 1;
+ private static final int NSMiniaturizableWindowMask = 1 << 2;
+ private static final int NSResizableWindowMask = 1 << 3;
+
+ // Window backing store types
+ private static final int NSBackingStoreRetained = 0;
+ private static final int NSBackingStoreNonretained = 1;
+ private static final int NSBackingStoreBuffered = 2;
+
+ private volatile long surfaceHandle;
+ private long sscSurfaceHandle;
+ private boolean isOffscreenInstance;
+
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
index cd5909d42..28be93acd 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
@@ -42,6 +42,7 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
@@ -244,6 +245,36 @@ public class WindowsWindow extends WindowImpl {
// nop - using event driven insetsChange(..)
}
+ private final int validateKeyCode(int eventType, int keyCode) {
+ switch(eventType) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ lastPressedKeyCode = keyCode;
+ break;
+ case KeyEvent.EVENT_KEY_TYPED:
+ if(-1==keyCode) {
+ keyCode = lastPressedKeyCode;
+ }
+ lastPressedKeyCode = -1;
+ break;
+ }
+ return keyCode;
+ }
+ private int lastPressedKeyCode = 0;
+
+ @Override
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
+ keyCode = validateKeyCode(eventType, keyCode);
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ }
+
+ @Override
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
+ keyCode = validateKeyCode(eventType, keyCode);
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index a13ffaf31..3a5a7cff6 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -48,7 +48,6 @@ static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
static jclass pointClz = NULL;
static jmethodID pointCstr = NULL;
-static jmethodID focusActionID = NULL;
static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
@@ -272,11 +271,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
- if(NULL==focusActionID) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch method focusAction()Z");
- }
-
// Need this when debugging, as it is necessary to attach gdb to
// the running java process -- "gdb java" doesn't work
// printf("Going to sleep for 10 seconds\n");
@@ -510,26 +504,44 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) w);
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
#ifdef VERBOSE_ON
- BOOL hasFocus = [win isKeyWindow];
+ BOOL hasFocus = [mWin isKeyWindow];
#endif
- DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", win, force, hasFocus);
-
- // Even if we already own the focus, we need the 'focusAction()' call
- // and the other probably redundant NS calls to force proper focus traversal
- // of the parent TK (AWT doesn't do it properly on OSX).
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "makeKeyWindow win %p\n", win);
- // [win performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
- // [win performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
- [win orderFrontRegardless];
- [win makeKeyWindow];
- [win makeFirstResponder: nil];
- }
+ DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+
+ [mWin makeFirstResponder: nil];
+ // [mWin performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
+ // [mWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
+ [mWin orderFrontRegardless];
+ [mWin makeKeyWindow];
+
+ DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force);
- DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", win, force);
+ [pool release];
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: requestFocusParent0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocusParent0
+ (JNIEnv *env, jobject window, jlong w)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ NSWindow* pWin = [mWin parentWindow];
+#ifdef VERBOSE_ON
+ BOOL hasFocus = [mWin isKeyWindow];
+#endif
+
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ if(NULL != pWin) {
+ [pWin makeKeyWindow];
+ }
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p (END)\n", mWin, pWin);
[pool release];
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index cb256e71f..861811b6c 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -37,10 +37,11 @@
#include "NewtCommon.h"
-// #define VERBOSE_ON 1
+#define VERBOSE_ON 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#else
#define DBG_PRINT(...)
#endif
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 1f74742ec..a3b6fa871 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -76,7 +76,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
@@ -252,7 +252,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -272,7 +272,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -290,7 +290,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -325,9 +325,9 @@ static jmethodID windowRepaintID = NULL;
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID && windowRepaintID)
+ positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
return YES;
}
@@ -512,14 +512,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendKeyEvent: null javaWindowObject");
+ DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendKeyEvent: null JNIEnv");
+ DBG_PRINT("sendKeyEvent: null JNIEnv\n");
return;
}
@@ -533,6 +533,8 @@ static jint mods2JavaMods(NSUInteger mods)
// Note: the key code in the NSEvent does not map to anything we can use
jchar keyChar = (jchar) [chars characterAtIndex: i];
+ DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
evType, javaMods, keyCode, keyChar);
@@ -567,14 +569,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendMouseEvent: null javaWindowObject");
+ DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendMouseEvent: null JNIEnv");
+ DBG_PRINT("sendMouseEvent: null JNIEnv\n");
return;
}
jint javaMods = mods2JavaMods([event modifierFlags]);
@@ -613,7 +615,7 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
if (evType == EVENT_MOUSE_PRESSED) {
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
}
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
@@ -770,14 +772,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidResize: null javaWindowObject");
+ DBG_PRINT("windowDidResize: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidResize: null JNIEnv");
+ DBG_PRINT("windowDidResize: null JNIEnv\n");
return;
}
@@ -805,14 +807,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidMove: null javaWindowObject");
+ DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidMove: null JNIEnv");
+ DBG_PRINT("windowDidMove: null JNIEnv\n");
return;
}
@@ -841,14 +843,14 @@ static jint mods2JavaMods(NSUInteger mods)
jobject javaWindowObject = [view getJavaWindowObject];
DBG_PRINT( "*************** windowWillClose.0: 0x%p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
- NSLog(@"windowWillClose: null javaWindowObject");
+ DBG_PRINT("windowWillClose: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowWillClose: null JNIEnv");
+ DBG_PRINT("windowWillClose: null JNIEnv\n");
return;
}
@@ -916,14 +918,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"focusChanged: null javaWindowObject");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"focusChanged: null JNIEnv");
+ DBG_PRINT("focusChanged: null JNIEnv\n");
return;
}
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index d60c40496..b654fbe85 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -115,8 +115,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
@@ -602,18 +601,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jb
(void*) pHwnd, (void*)hwnd, current==hwnd);
if( JNI_TRUE==force || current!=hwnd) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
- SetForegroundWindow(hwnd); // Slightly Higher Priority
- SetFocus(hwnd);// Sets Keyboard Focus To Window
- if(NULL!=pHwnd) {
- SetActiveWindow(hwnd);
- }
- DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
- } else {
- DBG_PRINT("*** WindowsWindow: requestFocus.X0\n");
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ SetFocus(hwnd);// Sets Keyboard Focus To Window
+ if(NULL!=pHwnd) {
+ SetActiveWindow(hwnd);
}
+ DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
}
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
@@ -870,7 +865,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_LBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
@@ -890,7 +885,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_MBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
@@ -910,7 +905,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_RBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
@@ -1270,8 +1265,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
@@ -1284,8 +1278,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
+ requestFocusID == NULL) {
return JNI_FALSE;
}
BuildDynamicKeyMapTable();
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f14138a0a..3613f0018 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -105,34 +105,91 @@
static jint X11KeySym2NewtVKey(KeySym keySym) {
if(IS_WITHIN(keySym,XK_F1,XK_F12))
return (keySym-XK_F1)+J_VK_F1;
+ if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9))
+ return (keySym-XK_KP_0)+J_VK_NUMPAD0;
switch(keySym) {
+ case XK_Return:
+ case XK_KP_Enter:
+ return J_VK_ENTER;
+ case XK_BackSpace:
+ return J_VK_BACK_SPACE;
+ case XK_Tab:
+ case XK_KP_Tab:
+ case XK_ISO_Left_Tab:
+ return J_VK_TAB;
+ case XK_Cancel:
+ return J_VK_CANCEL;
+ case XK_Clear:
+ return J_VK_CLEAR;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ return J_VK_SHIFT;
+ case XK_Control_L:
+ case XK_Control_R:
+ return J_VK_CONTROL;
case XK_Alt_L:
case XK_Alt_R:
return J_VK_ALT;
-
+ case XK_Pause:
+ return J_VK_PAUSE;
+ case XK_Caps_Lock:
+ return J_VK_CAPS_LOCK;
+ case XK_Escape:
+ return J_VK_ESCAPE;
+ case XK_space:
+ case XK_KP_Space:
+ return J_VK_SPACE;
+ case XK_Page_Up:
+ case XK_KP_Page_Up:
+ return J_VK_PAGE_UP;
+ case XK_Page_Down:
+ case XK_KP_Page_Down:
+ return J_VK_PAGE_DOWN;
+ case XK_End:
+ case XK_KP_End:
+ return J_VK_END;
+ case XK_Home:
+ case XK_KP_Home:
+ return J_VK_HOME;
case XK_Left:
+ case XK_KP_Left:
return J_VK_LEFT;
- case XK_Right:
- return J_VK_RIGHT;
case XK_Up:
+ case XK_KP_Up:
return J_VK_UP;
+ case XK_Right:
+ case XK_KP_Right:
+ return J_VK_RIGHT;
case XK_Down:
+ case XK_KP_Down:
return J_VK_DOWN;
- case XK_Page_Up:
- return J_VK_PAGE_UP;
- case XK_Page_Down:
- return J_VK_PAGE_DOWN;
- case XK_Shift_L:
- case XK_Shift_R:
- return J_VK_SHIFT;
- case XK_Control_L:
- case XK_Control_R:
- return J_VK_CONTROL;
- case XK_Escape:
- return J_VK_ESCAPE;
+ case XK_KP_Multiply:
+ return J_VK_MULTIPLY;
+ case XK_KP_Add:
+ return J_VK_ADD;
+ case XK_KP_Separator:
+ return J_VK_SEPARATOR;
+ case XK_KP_Subtract:
+ return J_VK_SUBTRACT;
+ case XK_KP_Decimal:
+ return J_VK_DECIMAL;
+ case XK_KP_Divide:
+ return J_VK_DIVIDE;
case XK_Delete:
+ case XK_KP_Delete:
return J_VK_DELETE;
+ case XK_Num_Lock:
+ return J_VK_NUM_LOCK;
+ case XK_Scroll_Lock:
+ return J_VK_SCROLL_LOCK;
+ case XK_Print:
+ return J_VK_PRINTSCREEN;
+ case XK_Insert:
+ case XK_KP_Insert:
+ return J_VK_INSERT;
+ case XK_Help:
+ return J_VK_HELP;
}
return keySym;
}
@@ -179,8 +236,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static jmethodID displayCompletedID = NULL;
@@ -535,16 +591,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
if( JNI_TRUE==force || focus_return!=w) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
- XRaiseWindow(dpy, w);
- NewtWindows_setCWAbove(dpy, w);
- // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
- XGetWindowAttributes(dpy, w, &xwa);
- if(xwa.map_state == IsViewable) {
- DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
- XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
- }
+ DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
+ XRaiseWindow(dpy, w);
+ NewtWindows_setCWAbove(dpy, w);
+ // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(xwa.map_state == IsViewable) {
+ DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
+ XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
}
}
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
@@ -787,11 +841,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
keyChar=text[0];
XConvertCase(keySym, &lower_return, &upper_return);
// always return upper case, set modifier masks (SHIFT, ..)
- keySym = upper_return;
- modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ keySym = X11KeySym2NewtVKey(upper_return);
} else {
keyChar=0;
+ keySym = X11KeySym2NewtVKey(keySym);
}
+ modifiers = X11InputState2NewtModifiers(evt.xkey.state);
break;
case ButtonPress:
@@ -806,7 +861,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
switch(evt.type) {
case ButtonPress:
- (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
modifiers,
@@ -866,26 +921,26 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
case KeyPress:
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ modifiers, keySym, (jchar) -1);
#else
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ modifiers, keySym, (jchar) -1);
#endif
break;
case KeyRelease:
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ modifiers, keySym, (jchar) -1);
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
- modifiers, (jint) -1, (jchar) keyChar);
+ modifiers, keySym, (jchar) keyChar);
#else
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ modifiers, keySym, (jchar) -1);
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
- modifiers, (jint) -1, (jchar) keyChar);
+ modifiers, keySym, (jchar) keyChar);
#endif
break;
@@ -1480,8 +1535,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
@@ -1495,8 +1549,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
+ requestFocusID == NULL) {
return JNI_FALSE;
}
return JNI_TRUE;
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
index 21eb8af2d..74419e564 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
@@ -62,7 +62,7 @@ public class NEWTElektronActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new ElektronenMultiplizierer());
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
index 337dafc71..ba861d012 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
@@ -62,7 +62,7 @@ public class NEWTGearsES1Activity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GearsES1(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
index 6abb0b354..89ecf4cb9 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
@@ -65,7 +65,7 @@ public class NEWTGearsES2Activity extends NewtBaseActivity {
GearsES2 demo = new GearsES2(0);
// demo.enableAndroidTrace(true);
glWindow.addGLEventListener(demo);
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
index 691151ef3..d6b7507a3 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
@@ -61,7 +61,7 @@ public class NEWTGearsES2TransActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GearsES2(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
index 83f35879b..1efedcd6d 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
@@ -61,7 +61,7 @@ public class NEWTGraphUI1pActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GPUUISceneGLListener0A(0));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
index 17924d43d..39fb5e2cc 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
@@ -62,7 +62,7 @@ public class NEWTGraphUI2pActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GPUUISceneGLListener0A(Region.VBAA_RENDERING_BIT));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
index 24b4eaf0c..99d7fd723 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
@@ -61,7 +61,7 @@ public class NEWTRedSquareES1Activity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new RedSquareES1(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
index 51cddd523..804e627a5 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
@@ -64,7 +64,7 @@ public class NEWTRedSquareES2Activity extends NewtBaseActivity {
final RedSquareES2 demo = new RedSquareES2(0);
// demo.enableAndroidTrace(true);
glWindow.addGLEventListener(demo);
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 8d579ce5d..b5a729e02 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -21,6 +21,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es1;
+import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
@@ -181,8 +182,18 @@ public class GearsES1 implements GLEventListener {
// Get the GL corresponding to the drawable we are animating
GL2ES1 gl = drawable.getGL().getGL2ES1();
- gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
+ final boolean hasFocus;
+ if(drawable.getNativeSurface() instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ } else {
+ hasFocus = true;
+ }
+ if(hasFocus) {
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ } else {
+ gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ }
+
// Special handling for the case where the GLJPanel is translucent
// and wants to be composited with other Java 2D content
if (GLProfile.isAWTAvailable() &&
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 3fa61bf1d..51bc7d137 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -34,6 +34,8 @@ import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
import java.nio.FloatBuffer;
+
+import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
@@ -244,8 +246,18 @@ public class GearsES2 implements GLEventListener {
// Get the GL corresponding to the drawable we are animating
GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
+ final boolean hasFocus;
+ if(drawable.getNativeSurface() instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ } else {
+ hasFocus = true;
+ }
+ if(hasFocus) {
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ } else {
+ gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ }
+
// Special handling for the case where the GLJPanel is translucent
// and wants to be composited with other Java 2D content
if (GLProfile.isAWTAvailable() &&
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index 01790de10..d645fb9f8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -205,7 +205,7 @@ public class RedSquareES2 implements GLEventListener {
class MyMouseAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
System.err.println(e);
- if(null != glWindow && e.getSource() == glWindow.getWindow()) {
+ if(null != glWindow && e.getSource() == glWindow.getDelegatedWindow()) {
if(e.getX() < glWindow.getWidth()/2) {
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("setFullscreen: "+glWindow.isFullscreen());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
index 8ab641267..83e3663dc 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
@@ -72,7 +72,7 @@ public class TestGearsAWT extends UITestCase {
frame.add(glCanvas);
frame.setSize(512, 512);
- glCanvas.addGLEventListener(new Gears());
+ glCanvas.addGLEventListener(new Gears(1));
Animator animator = new Animator(glCanvas);
QuitAdapter quitAdapter = new QuitAdapter();
@@ -81,7 +81,7 @@ public class TestGearsAWT extends UITestCase {
new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter)).addTo(frame);
frame.setVisible(true);
- animator.setUpdateFPSFrames(1, null);
+ animator.setUpdateFPSFrames(60, System.err);
animator.start();
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
index 199b094f2..1d1ee1e0c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
@@ -103,7 +103,7 @@ public class WindowUtilNEWT {
while ( windowOffScreen.getTotalFPSFrames() < frames) {
windowOffScreen.display();
}
- windowOffScreen.removeAllSurfaceUpdatedListener();
+ windowOffScreen.removeSurfaceUpdatedListener(ul);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
index 3e153214b..b2a7e9a5e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
@@ -156,7 +156,7 @@ public class TestSWT02GLn extends UITestCase {
ProxySurface proxySurface = factory.createProxySurface(device, nativeWindowHandle, caps, null);
Assert.assertNotNull( proxySurface );
- proxySurface.setSize( 640, 480 );
+ proxySurface.surfaceSizeChanged( 640, 480 );
System.err.println("*** ProxySurface: " + proxySurface);
final GLDrawable drawable = factory.createGLDrawable(proxySurface);
Assert.assertNotNull( drawable );
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
index adc885191..664cab03b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
@@ -39,10 +39,9 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
+
import com.jogamp.newt.Window;
import com.jogamp.newt.awt.NewtCanvasAWT;
-import com.jogamp.newt.event.WindowAdapter;
-import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -53,6 +52,7 @@ public class TestCloseNewtAWT extends UITestCase {
NewtCanvasAWT newtCanvas = null;
JFrame frame = null;
+ @SuppressWarnings("serial")
class MyCanvas extends NewtCanvasAWT {
public MyCanvas(Window window) {
super(window);
@@ -78,7 +78,7 @@ public class TestCloseNewtAWT extends UITestCase {
NativeWindow nw = MyCanvas.this.getNativeWindow();
if(null != nw) {
Point p = nw.getLocationOnScreen(null);
- System.err.println("MyCanvas On NEWT-EDT: position: "+p);
+ System.err.println("MyCanvas On NEWT-EDT: position: "+p);
} else {
System.err.println("MyCanvas On NEWT-EDT: position n/a, null NativeWindow");
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
index 13653b907..fe7fef09f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
@@ -35,6 +35,7 @@ import org.junit.Assume;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Button;
+import java.awt.Color;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
@@ -119,7 +120,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
frame1.addFocusListener(frame1FA);
frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
- Button button = new Button("Click me ..");
+ final Button button = new Button("Click me ..");
AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
button.addFocusListener(buttonFA);
AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
@@ -127,7 +128,10 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
eventCountAdapters.add(buttonKA);
frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
- frame1.setVisible(true);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(true);
+ } } );
Assert.assertTrue(AWTRobotUtil.toFront(robot, frame1));
Thread.sleep(durationPerTest); // manual testing
@@ -162,7 +166,6 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
Assert.assertEquals(true, glWindow1FA.focusGained());
Assert.assertEquals(false, buttonFA.focusGained());
Assert.assertEquals(true, buttonFA.focusLost());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
index 56b08b52a..b9eb748b7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
@@ -145,14 +145,17 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
jPanel1.add(new Button("west"), BorderLayout.WEST);
jPanel1.add(container1, BorderLayout.CENTER);
- JFrame jFrame1 = new JFrame("Swing Parent JFrame");
+ final JFrame jFrame1 = new JFrame("Swing Parent JFrame");
AWTFocusAdapter jFrame1FA = new AWTFocusAdapter("JFrame1");
jFrame1.addFocusListener(jFrame1FA);
// jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
jFrame1.setContentPane(jPanel1);
jFrame1.setSize(width, height);
- jFrame1.setVisible(true); // from here on, we need to run modifications on EDT
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame1.setVisible(true);
+ } } );
Assert.assertTrue(AWTRobotUtil.toFront(robot, jFrame1));
int wait=0;
@@ -192,7 +195,6 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonNorthOuterFA);
- Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
Assert.assertEquals(true, glWindow1FA.focusGained());
Assert.assertEquals(false, buttonNorthOuterFA.focusGained());
Assert.assertEquals(true, buttonNorthOuterFA.focusLost());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
index 15151fa2c..429ef59cd 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
@@ -111,7 +111,7 @@ public class TestListenerCom01AWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
index 46748cb52..473f2f584 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
@@ -51,7 +51,11 @@ class NewtAWTReparentingKeyAdapter extends KeyAdapter {
if(e.getKeyChar()=='d') {
glWindow.setUndecorated(!glWindow.isUndecorated());
} else if(e.getKeyChar()=='f') {
- glWindow.setFullscreen(!glWindow.isFullscreen());
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ } else if(e.getKeyChar()=='l') {
+ javax.media.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null);
+ javax.media.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
+ System.err.println("NewtCanvasAWT position: "+p0+", "+p1);
} else if(e.getKeyChar()=='p') {
new Thread() {
public void run() {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
index 7f97be649..b49cf2670 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
@@ -654,7 +654,7 @@ public class TestParenting01NEWT extends UITestCase {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
}
- if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getWindow())) {
+ if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getDelegatedWindow())) {
MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
index 674cf4a06..2040fb9b6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
@@ -467,7 +467,7 @@ public class TestParenting01aAWT extends UITestCase {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
}
- if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getWindow())) {
+ if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getDelegatedWindow())) {
MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
index 8571609a8..d98a540ec 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
@@ -173,7 +173,7 @@ public class TestParenting01bAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
index 3b40554d2..dfd0787e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
@@ -228,7 +228,7 @@ public class TestParenting01cAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
index f505547d4..22ed7c6fd 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
@@ -319,7 +319,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
index f01468c2a..39759de9f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
@@ -233,7 +233,7 @@ public class TestParenting02AWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
index aded8f163..8f0da4000 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
@@ -35,10 +35,10 @@ import org.junit.BeforeClass;
import org.junit.Test;
import java.awt.BorderLayout;
+import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
-import java.awt.Label;
import javax.media.opengl.*;
@@ -53,28 +53,34 @@ import com.jogamp.opengl.test.junit.util.*;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
public class TestParenting03AWT extends UITestCase {
- static Dimension size;
+ static Dimension glSize, fSize;
static long durationPerTest = 800;
static long waitAdd2nd = 500;
static GLCapabilities glCaps;
@BeforeClass
public static void initClass() {
- size = new Dimension(400,200);
+ glSize = new Dimension(400,200);
+ fSize = new Dimension(3*400,2*200);
glCaps = new GLCapabilities(null);
}
@Test
- public void testWindowParenting1AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException {
- testWindowParenting1AWTTwoNewtChilds();
+ public void testWindowParenting1AWTOneNewtChilds01() throws InterruptedException, InvocationTargetException {
+ testWindowParenting1AWT(false);
}
- public void testWindowParenting1AWTTwoNewtChilds() throws InterruptedException, InvocationTargetException {
+ @Test
+ public void testWindowParenting1AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException {
+ testWindowParenting1AWT(true);
+ }
+
+ public void testWindowParenting1AWT(boolean use2nd) throws InterruptedException, InvocationTargetException {
final Frame frame1 = new Frame("AWT Parent Frame");
GLWindow glWindow1 = GLWindow.create(glCaps);
glWindow1.setUpdateFPSFrames(1, null);
final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
- newtCanvasAWT1.setPreferredSize(size);
+ newtCanvasAWT1.setPreferredSize(glSize);
GLEventListener demo1 = new GearsES2(1);
setDemoFields(demo1, glWindow1, false);
@@ -83,7 +89,6 @@ public class TestParenting03AWT extends UITestCase {
GLAnimatorControl animator1 = new Animator(glWindow1);
animator1.start();
- final boolean use2nd = true;
GLWindow glWindow2 = null;
NewtCanvasAWT newtCanvasAWT2 = null;
GLAnimatorControl animator2 = null;
@@ -91,7 +96,7 @@ public class TestParenting03AWT extends UITestCase {
glWindow2 = GLWindow.create(glCaps);
glWindow2.setUpdateFPSFrames(1, null);
newtCanvasAWT2 = new NewtCanvasAWT(glWindow2);
- newtCanvasAWT2.setPreferredSize(size);
+ newtCanvasAWT2.setPreferredSize(glSize);
GLEventListener demo2 = new GearsES2(1);
setDemoFields(demo2, glWindow2, false);
@@ -103,10 +108,10 @@ public class TestParenting03AWT extends UITestCase {
final Container cont1 = new Container();
cont1.setLayout(new BorderLayout());
- cont1.add(new Label("iNORTH"), BorderLayout.NORTH);
- cont1.add(new Label("iSOUTH"), BorderLayout.SOUTH);
- cont1.add(new Label("iEAST"), BorderLayout.EAST);
- cont1.add(new Label("iWEST"), BorderLayout.WEST);
+ cont1.add(new Button("NORTH"), BorderLayout.NORTH);
+ cont1.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ cont1.add(new Button("EAST"), BorderLayout.EAST);
+ cont1.add(new Button("WEST"), BorderLayout.WEST);
cont1.add(newtCanvasAWT1, BorderLayout.CENTER);
System.err.println("******* Cont1 setVisible");
cont1.setVisible(true);
@@ -114,34 +119,31 @@ public class TestParenting03AWT extends UITestCase {
final Container cont2 = new Container();
cont2.setLayout(new BorderLayout());
if(use2nd) {
- cont2.add(new Label("iNORTH"), BorderLayout.NORTH);
- cont2.add(new Label("iSOUTH"), BorderLayout.SOUTH);
- cont2.add(new Label("iEAST"), BorderLayout.EAST);
- cont2.add(new Label("iWEST"), BorderLayout.WEST);
+ cont2.add(new Button("north"), BorderLayout.NORTH);
+ cont2.add(new Button("sourth"), BorderLayout.SOUTH);
+ cont2.add(new Button("east"), BorderLayout.EAST);
+ cont2.add(new Button("west"), BorderLayout.WEST);
cont2.add(newtCanvasAWT2, BorderLayout.CENTER);
}
System.err.println("******* Cont2 setVisible");
cont2.setVisible(true);
frame1.setLayout(new BorderLayout());
- frame1.add(new Label("NORTH"), BorderLayout.NORTH);
- frame1.add(new Label("CENTER"), BorderLayout.CENTER);
- frame1.add(new Label("SOUTH"), BorderLayout.SOUTH);
+ frame1.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame1.add(new Button("CENTER"), BorderLayout.CENTER);
+ frame1.add(new Button("SOUTH"), BorderLayout.SOUTH);
frame1.add(cont1, BorderLayout.EAST);
frame1.setLocation(0, 0);
- frame1.setSize((int)size.getWidth()*3, (int)size.getHeight()*2);
+ frame1.setSize(fSize);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.err.println("******* Frame setVisible");
+ frame1.validate();
frame1.setVisible(true);
}});
Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
- if(use2nd) {
- Assert.assertEquals(newtCanvasAWT2.getNativeWindow(),glWindow2.getParent());
- }
-
Assert.assertEquals(true, animator1.isAnimating());
Assert.assertEquals(false, animator1.isPaused());
Assert.assertNotNull(animator1.getThread());
@@ -150,15 +152,17 @@ public class TestParenting03AWT extends UITestCase {
Assert.assertEquals(true, animator2.isAnimating());
Assert.assertEquals(false, animator2.isPaused());
Assert.assertNotNull(animator2.getThread());
- }
- Thread.sleep(waitAdd2nd);
+ Thread.sleep(waitAdd2nd);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.add(cont2, BorderLayout.WEST);
+ frame1.validate();
+ }});
+ Assert.assertEquals(newtCanvasAWT2.getNativeWindow(),glWindow2.getParent());
+ }
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame1.add(cont2, BorderLayout.WEST);
- frame1.validate();
- }});
Thread.sleep(durationPerTest);
@@ -187,7 +191,7 @@ public class TestParenting03AWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
new file mode 100644
index 000000000..b23c17022
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
@@ -0,0 +1,334 @@
+/**
+ * Copyright 2010 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.opengl.test.junit.newt.parenting;
+
+import java.lang.reflect.*;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.awt.AWTException;
+import java.awt.AWTKeyStroke;
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.KeyboardFocusManager;
+import java.awt.Robot;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.newt.*;
+import com.jogamp.newt.opengl.*;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+
+import java.io.IOException;
+
+import jogamp.newt.driver.DriverClearFocus;
+
+import com.jogamp.opengl.test.junit.util.*;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+public class TestParentingFocusTraversal01AWT extends UITestCase {
+ static Dimension glSize, fSize;
+ static int numFocus = 8;
+ static long durationPerTest = numFocus * 100;
+ static GLCapabilities glCaps;
+ static boolean manual = false;
+
+ @BeforeClass
+ public static void initClass() {
+ glSize = new Dimension(200,200);
+ fSize = new Dimension(300,300);
+ glCaps = new GLCapabilities(null);
+ }
+
+ @Test
+ public void testWindowParentingAWTFocusTraversal01Onscreen() throws InterruptedException, InvocationTargetException, AWTException {
+ testWindowParentingAWTFocusTraversal(true);
+ }
+
+ @Test
+ public void testWindowParentingAWTFocusTraversal02Offscreen() throws InterruptedException, InvocationTargetException, AWTException {
+ testWindowParentingAWTFocusTraversal(false);
+ }
+
+ public void testWindowParentingAWTFocusTraversal(boolean onscreen) throws InterruptedException, InvocationTargetException, AWTException {
+ Robot robot = new Robot();
+
+ // Bug 4908075 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4908075
+ // Bug 6463168 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6463168
+ {
+ final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ final AWTKeyStroke newBack = AWTKeyStroke.getAWTKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE, 0, false);
+ Assert.assertNotNull(newBack);
+ final Set<AWTKeyStroke> bwdKeys2 = new HashSet<AWTKeyStroke>(bwdKeys);
+ bwdKeys2.add(newBack);
+ kfm.setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, bwdKeys2);
+ }
+ {
+ final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ final Set<AWTKeyStroke> fwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ Iterator<AWTKeyStroke> iter;
+ for(iter = fwdKeys.iterator(); iter.hasNext(); ) {
+ System.err.println("FTKL.fwd-keys: "+iter.next());
+ }
+ for(iter = bwdKeys.iterator(); iter.hasNext(); ) {
+ System.err.println("FTKL.bwd-keys: "+iter.next());
+ }
+ }
+
+ final Frame frame1 = new Frame("AWT Parent Frame");
+ final Button cWest = new Button("WEST");
+ final Button cEast = new Button("EAST");
+ final GLWindow glWindow1 = GLWindow.create(glCaps);
+ glWindow1.setUpdateFPSFrames(1, null);
+ final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
+ newtCanvasAWT1.setPreferredSize(glSize);
+ newtCanvasAWT1.setShallUseOffscreenLayer(!onscreen);
+ newtCanvasAWT1.setFocusable(true);
+
+ // Test FocusAdapter
+ NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+ glWindow1.addWindowListener(glWindow1FA);
+ AWTFocusAdapter bWestFA = new AWTFocusAdapter("WEST");
+ cWest.addFocusListener(bWestFA);
+ AWTFocusAdapter bEastFA = new AWTFocusAdapter("EAST");
+ cEast.addFocusListener(bEastFA);
+
+ // Test KeyAdapter
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1.addKeyListener(glWindow1KA);
+ AWTKeyAdapter bWestKA = new AWTKeyAdapter("West");
+ cWest.addKeyListener(bWestKA);
+ AWTKeyAdapter bEastKA = new AWTKeyAdapter("East");
+ cEast.addKeyListener(bEastKA);
+
+ // demo ..
+ GLEventListener demo1 = new GearsES2(1);
+ setDemoFields(demo1, glWindow1, false);
+ glWindow1.addGLEventListener(demo1);
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
+ glWindow1.addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar()=='c') {
+ System.err.println("Focus Clear");
+ if(glWindow1.getDelegatedWindow() instanceof DriverClearFocus) {
+ ((DriverClearFocus)glWindow1.getDelegatedWindow()).clearFocus();
+ }
+ } else if(e.getKeyChar()=='e') {
+ System.err.println("Focus East");
+ try {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ cEast.requestFocusInWindow();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(e.getKeyChar()=='w') {
+ System.err.println("Focus West");
+ try {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ cWest.requestFocusInWindow();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ });
+ GLAnimatorControl animator1 = new Animator(glWindow1);
+ animator1.start();
+
+ // make frame
+ frame1.setLayout(new BorderLayout());
+ frame1.setLayout(new BorderLayout());
+ frame1.add(cWest, BorderLayout.WEST);
+ frame1.add(newtCanvasAWT1, BorderLayout.CENTER);
+ frame1.add(cEast, BorderLayout.EAST);
+
+ frame1.setLocation(0, 0);
+ frame1.setSize(fSize);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.validate();
+ frame1.setVisible(true);
+ }});
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
+ Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
+
+ Assert.assertEquals(true, animator1.isAnimating());
+ Assert.assertEquals(false, animator1.isPaused());
+ Assert.assertNotNull(animator1.getThread());
+
+ if(manual) {
+ Thread.sleep(durationPerTest);
+ } else {
+ //
+ // initial focus on bWest
+ //
+ AWTRobotUtil.assertRequestFocusAndWait(robot, cWest, cWest, bWestFA, null);
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Thread.sleep(durationPerTest/numFocus);
+
+ //
+ // forth
+ //
+
+ // bWest -> glWin
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, cWest, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // glWin -> bEast
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, glWindow1, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cEast, bEastFA, glWindow1FA));
+ Assert.assertEquals(true, bEastFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ //
+ // back (using custom back traversal key 'backspace')
+ //
+ // bEast -> glWin
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, cEast, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bEastFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bEastFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, glWindow1, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA));
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct AWT request focus
+ try {
+ java.awt.EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ newtCanvasAWT1.requestFocus();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct AWT request focus
+ try {
+ java.awt.EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ cWest.requestFocus();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA));
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct NEWT request focus
+ glWindow1.requestFocus();
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+ }
+
+ animator1.stop();
+ Assert.assertEquals(false, animator1.isAnimating());
+ Assert.assertEquals(false, animator1.isPaused());
+ Assert.assertEquals(null, animator1.getThread());
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.dispose();
+ } } );
+ glWindow1.destroy();
+ }
+
+ public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(glWindow);
+ Window window = glWindow.getDelegatedWindow();
+ if(debug) {
+ MiscUtils.setFieldIfExists(demo, "glDebug", true);
+ MiscUtils.setFieldIfExists(demo, "glTrace", true);
+ }
+ if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
+ MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
+ }
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
+ }
+ }
+ String tstname = TestParentingFocusTraversal01AWT.class.getName();
+ /*
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java
new file mode 100644
index 000000000..fb2f7342e
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java
@@ -0,0 +1,225 @@
+/**
+ * Copyright 2011 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.opengl.test.junit.newt.parenting;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.awt.GLCanvas;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.Window;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestParentingOffscreenLayer01AWT extends UITestCase {
+ static Dimension frameSize;
+ static Dimension preferredGLSize;
+ static Dimension minGLSize;
+ static long durationPerTest = 800;
+
+ @BeforeClass
+ public static void initClass() {
+ frameSize = new Dimension(500,300);
+ preferredGLSize = new Dimension(400,200);
+ minGLSize = new Dimension(200,100);
+ }
+
+ private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
+
+ Container c = new Container();
+ c.setLayout(new BorderLayout());
+ c.add(new Button("north"), BorderLayout.NORTH);
+ c.add(new Button("south"), BorderLayout.SOUTH);
+ c.add(new Button("east"), BorderLayout.EAST);
+ c.add(new Button("west"), BorderLayout.WEST);
+ c.add(comp, BorderLayout.CENTER);
+
+ f.setLayout(new BorderLayout());
+ f.add(new Button("NORTH"), BorderLayout.NORTH);
+ f.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ f.add(new Button("EAST"), BorderLayout.EAST);
+ f.add(new Button("WEST"), BorderLayout.WEST);
+ f.add(c, BorderLayout.CENTER);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ // f.pack();
+ f.validate();
+ f.setVisible(true);
+ }});
+ }
+ private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
+ actrl.stop();
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.dispose();
+ } } );
+ if(null != w) {
+ w.destroy();
+ }
+ }
+
+ // @Test
+ public void testOffscreenLayerPath0_GLCanvas() throws InterruptedException, InvocationTargetException {
+ final Frame frame1 = new Frame("AWT Parent Frame");
+
+ GLCapabilities glCaps = new GLCapabilities(null);
+ final GLCanvas glc = new GLCanvas(glCaps);
+ glc.setPreferredSize(preferredGLSize);
+ glc.setMinimumSize(minGLSize);
+
+ GLEventListener demo1 = new GearsES2(1);
+ glc.addGLEventListener(demo1);
+
+ frame1.setSize(frameSize);
+ setupFrameAndShow(frame1, glc);
+
+ GLAnimatorControl animator1 = new Animator(glc);
+ animator1.start();
+
+ Thread.sleep(durationPerTest);
+ end(animator1, frame1, null);
+ }
+
+ @Test
+ public void testOnscreenLayer() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerPath1_Impl(false, false);
+ }
+
+ @Test
+ public void testOffscreenLayerPath1_NewtOffscreen() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerPath1_Impl(true, true);
+ }
+
+ @Test
+ public void testOffscreenLayerPath1_NewtOnscreen() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerPath1_Impl(true, false);
+ }
+
+ private void testOffscreenLayerPath1_Impl(boolean offscreenLayer, boolean newtOffscreenClass) throws InterruptedException, InvocationTargetException {
+ final Frame frame1 = new Frame("AWT Parent Frame");
+
+ GLCapabilities glCaps = new GLCapabilities(null);
+ if(newtOffscreenClass) {
+ glCaps.setOnscreen(false);
+ glCaps.setPBuffer(true);
+ }
+
+ GLWindow glWindow1 = GLWindow.create(glCaps);
+
+ final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
+ newtCanvasAWT1.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ newtCanvasAWT1.setPreferredSize(preferredGLSize);
+ newtCanvasAWT1.setMinimumSize(minGLSize);
+
+ GLEventListener demo1 = new GearsES2(1);
+ setDemoFields(demo1, glWindow1, false);
+ glWindow1.addGLEventListener(demo1);
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
+
+ frame1.setSize(frameSize);
+ setupFrameAndShow(frame1, newtCanvasAWT1);
+ Assert.assertTrue(glWindow1.isNativeValid());
+ Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
+
+ GLAnimatorControl animator1 = new Animator(glWindow1);
+ animator1.start();
+
+ Thread.sleep(durationPerTest);
+ end(animator1, frame1, glWindow1);
+ }
+
+ // @Test
+ public void testOffscreenLayerPath2_NewtOffscreen() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerPath2_Impl(true);
+ }
+
+ private void testOffscreenLayerPath2_Impl(boolean newtOffscreenClass) throws InterruptedException, InvocationTargetException {
+ }
+
+ public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(glWindow);
+ Window window = glWindow.getDelegatedWindow();
+ if(debug) {
+ MiscUtils.setFieldIfExists(demo, "glDebug", true);
+ MiscUtils.setFieldIfExists(demo, "glTrace", true);
+ }
+ if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
+ MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
+ }
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ }
+ }
+ String tstname = TestParentingOffscreenLayer01AWT.class.getName();
+ /*
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
index be812e6aa..86a76f9ff 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
@@ -157,7 +157,7 @@ public class TestTranslucentParentingAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
index 7df8645de..a27bdd7a2 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -67,7 +67,7 @@ public class AWTRobotUtil {
int x0, y0;
if(null!=comp) {
- java.awt.Point p0 = comp.getLocationOnScreen();
+ java.awt.Point p0 = comp.getLocationOnScreen();
java.awt.Rectangle r0 = comp.getBounds();
if( onTitleBarIfWindow && comp instanceof java.awt.Window) {
java.awt.Window window = (java.awt.Window) comp;
@@ -78,7 +78,7 @@ public class AWTRobotUtil {
}
x0 = (int) ( p0.getX() + r0.getWidth() / 2.0 + .5 ) ;
} else {
- javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null);
+ javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null);
if( onTitleBarIfWindow ) {
javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets();
p0.translate(win.getWidth()/2, insets.getTopHeight()/2);
@@ -102,6 +102,9 @@ public class AWTRobotUtil {
public static boolean toFront(Robot robot, final java.awt.Window window)
throws AWTException, InterruptedException, InvocationTargetException {
+ AWTWindowFocusAdapter winFA = new AWTWindowFocusAdapter("window");
+ window.addWindowFocusListener(winFA);
+
if(null == robot) {
robot = new Robot();
robot.setAutoWaitForIdle(true);
@@ -119,11 +122,11 @@ public class AWTRobotUtil {
}});
robot.delay(ROBOT_DELAY);
- KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
int wait;
- for (wait=0; wait<POLL_DIVIDER && window != kfm.getFocusedWindow(); wait++) {
+ for (wait=0; wait<POLL_DIVIDER && !winFA.focusGained(); wait++) {
Thread.sleep(TIME_SLICE);
}
+ window.removeWindowFocusListener(winFA);
return wait<POLL_DIVIDER;
}
@@ -280,8 +283,8 @@ public class AWTRobotUtil {
Assert.assertTrue("Did not gain focus", hasFocus);
}
- static int keyType(int i, Robot robot, int keyCode,
- Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
+ public static int keyType(int i, Robot robot, int keyCode,
+ Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
{
int tc = 0;
int j;
@@ -293,13 +296,13 @@ public class AWTRobotUtil {
if(DEBUG) { System.err.println(i+":"+j+" KC1.0: "+counter+" - regain focus"); }
requestFocus(null, obj);
}
- final int c0 = counter.getCount();
+ final int c0 = null!=counter ? counter.getCount() : 0;
if(DEBUG) { System.err.println(i+":"+j+" KC1.1: "+counter); }
robot.waitForIdle();
robot.keyPress(keyCode);
robot.keyRelease(keyCode);
if(DEBUG) { System.err.println(i+":"+j+" KC1.2: "+counter); }
- tc = counter.getCount() - c0;
+ tc = ( null!=counter ? counter.getCount() : 1 ) - c0;
for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
robot.delay(TIME_SLICE);
tc = counter.getCount() - c0;
@@ -355,13 +358,13 @@ public class AWTRobotUtil {
if(DEBUG) { System.err.println(i+":"+j+" MC1.0: "+counter+" - regain focus"); }
requestFocus(null, obj);
}
- final int c0 = counter.getCount();
+ final int c0 = null != counter ? counter.getCount() : 0;
if(DEBUG) { System.err.println(i+":"+j+" MC1.1: "+counter); }
robot.waitForIdle();
robot.mousePress(mouseButton);
robot.mouseRelease(mouseButton);
if(DEBUG) { System.err.println(i+":"+j+" MC1.2: "+counter); }
- tc = counter.getCount() - c0;
+ tc = ( null != counter ? counter.getCount() : 1 ) - c0;
for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
robot.delay(TIME_SLICE);
tc = counter.getCount() - c0;
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
new file mode 100644
index 000000000..16aacd2fd
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 2010 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.opengl.test.junit.util;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+
+public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocusListener {
+
+ String prefix;
+ int focusCount;
+
+ public AWTWindowFocusAdapter(String prefix) {
+ this.prefix = prefix;
+ reset();
+ }
+
+ public boolean focusLost() {
+ return focusCount<0;
+ }
+
+ public boolean focusGained() {
+ return focusCount>0;
+ }
+
+ public void reset() {
+ focusCount = 0;
+ }
+
+ /* @Override */
+ public void windowGainedFocus(WindowEvent e) {
+ if(focusCount<0) { focusCount=0; }
+ focusCount++;
+ System.err.println("FOCUS AWT GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
+
+ /* @Override */
+ public void windowLostFocus(WindowEvent e) {
+ if(focusCount>0) { focusCount=0; }
+ focusCount--;
+ System.err.println("FOCUS AWT LOST (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
+
+ public String toString() { return prefix+"[focusCount "+focusCount +"]"; }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
index 6a6cf390f..c74d2eaa7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
@@ -78,6 +78,7 @@ public class NEWTGLContext {
Assert.assertNotNull(drawable);
drawable.setRealized(true);
+ Assert.assertTrue(drawable.isRealized());
GLContext context = drawable.createContext(null);
Assert.assertNotNull(context);
diff --git a/src/test/jogamp/newt/WindowImplAccess.java b/src/test/jogamp/newt/WindowImplAccess.java
index 76d0dc050..e8be5f68a 100644
--- a/src/test/jogamp/newt/WindowImplAccess.java
+++ b/src/test/jogamp/newt/WindowImplAccess.java
@@ -29,26 +29,16 @@
package jogamp.newt;
import com.jogamp.newt.Window;
-import com.jogamp.newt.opengl.GLWindow;
/**
* Allows access to protected methods of WindowImpl
*/
public class WindowImplAccess {
public static final void windowDestroyNotify(Window win) {
- WindowImpl winImpl = null;
- if(win instanceof GLWindow) {
- GLWindow glwin = (GLWindow) win;
- winImpl = (WindowImpl) glwin.getWindow();
- } else if(win instanceof WindowImpl) {
- winImpl = (WindowImpl) win;
- } else {
- throw new RuntimeException("Given Window not a GLWindow, not WindowImpl, but "+win.getClass());
- }
- final WindowImpl winImplF = winImpl;
- winImplF.runOnEDTIfAvail(true, new Runnable() {
+ final WindowImpl winImpl = (WindowImpl) win.getDelegatedWindow();
+ winImpl.runOnEDTIfAvail(true, new Runnable() {
public void run() {
- winImplF.windowDestroyNotify();
+ winImpl.windowDestroyNotify();
}
});
}