summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java37
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java264
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java51
-rw-r--r--src/jogl/classes/jogamp/opengl/FPSCounterImpl.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java80
-rw-r--r--src/jogl/classes/jogamp/opengl/GLVersionNumber.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/Java2D.java254
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java41
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java4
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m322
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m1
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java85
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java27
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java19
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java3
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java23
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java69
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java153
-rw-r--r--src/nativewindow/native/macosx/NativeWindowProtocols.h34
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m352
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java36
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java404
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/event/InputEvent.java15
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java552
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyListener.java18
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseEvent.java61
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java78
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowEvent.java18
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowListener.java5
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java7
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java20
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java14
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java26
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java250
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java110
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java100
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java8
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java33
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java14
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java262
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java207
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java89
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java33
-rw-r--r--src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java52
-rw-r--r--src/newt/native/KDWindow.c12
-rw-r--r--src/newt/native/MacWindow.m105
-rw-r--r--src/newt/native/NewtMacWindow.h11
-rw-r--r--src/newt/native/NewtMacWindow.m89
-rw-r--r--src/newt/native/WindowsWindow.c743
-rw-r--r--src/newt/native/X11Display.c142
-rw-r--r--src/newt/native/bcm_vc_iv.c8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove01GLCanvasSwingAWT.java241
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove02GLWindowNewtCanvasAWT.java246
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove03GLWindowNEWT.java130
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java160
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java11
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java15
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java283
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug675BeansInDesignTimeAWT.java111
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java125
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java19
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java192
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java375
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/swt/TestGearsES2SWT.java340
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java33
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java14
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java45
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java59
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersAWTCanvas.java10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNEWTWindowAWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasSWT.java55
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java113
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java52
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java21
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java32
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java26
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java83
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java136
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/UITestCase.java11
100 files changed, 5879 insertions, 2543 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
index 206331ac0..0f0f03ac4 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -51,12 +51,12 @@ import jogamp.opengl.GLDrawableImpl;
* utilizing already created {@link GLDrawable} and {@link GLContext} instances.
* <p>
* Since no native windowing system events are being processed, it is recommended
- * to handle at least:
+ * to handle at least the {@link com.jogamp.newt.event.WindowEvent window events}:
* <ul>
* <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #windowRepaintOp()}</li>
* <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #windowResizedOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #windowDestroyNotifyOp()}</li>
- * </ul>
+ * </ul>
+ * and setup a {@link com.jogamp.newt.Window#setWindowDestroyNotifyAction(Runnable) custom toolkit destruction} issuing {@link #windowDestroyNotifyOp()}.
* </p>
* <p>
* See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 9a13ff904..715511d1b 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -73,12 +73,20 @@ public class GLRendererQuirks {
*/
public static final int GLNonCompliant = 6;
+ /**
+ * The OpenGL Context needs a <code>glFlush()</code> before releasing it, otherwise driver may freeze:
+ * <ul>
+ * <li>OSX < 10.7.3 - NVidia Driver. Bug 533 and Bug 548 @ https://jogamp.org/bugzilla/.</li>
+ * </ul>
+ */
+ public static final int GLFlushBeforeRelease = 7;
+
/** Number of quirks known. */
- public static final int COUNT = 7;
+ public static final int COUNT = 8;
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
- "GLNonCompliant"
+ "GLNonCompliant", "GLFlushBeforeRelease"
};
private final int _bitmask;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index 53a99b640..aa0e70132 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -537,7 +537,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
remaining -= System.currentTimeMillis() - t1 ;
nok = waitCondition.eval();
}
- if(DEBUG || nok) {
+ if(DEBUG || blocking && nok) { // Info only if DEBUG or ( blocking && not-ok ) ; !blocking possible if AWT
if( remaining<=0 && nok ) {
System.err.println("finishLifecycleAction(" + waitCondition.getClass().getName() + "): ++++++ timeout reached ++++++ " + Thread.currentThread().getName());
}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 4817add4d..c31b76401 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -442,7 +442,7 @@ public abstract class GLContext {
* new GLContext implementations; not for use by end users.
*/
protected static void setCurrent(GLContext cur) {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
if(null == cur) {
System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - NULL");
} else {
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index f916ab8b1..25bba1725 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -543,8 +543,20 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GLES2 };
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GLES2 };
+ /**
+ * Order of maximum programmable shader <i>core only</i> profiles
+ *
+ * <ul>
+ * <li> GL4
+ * <li> GL3
+ * <li> GLES2
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER_CORE = new String[] { GL4, GL3, GLES2 };
+
/** Returns a default GLProfile object, reflecting the best for the running platform.
* It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
* and favors hardware acceleration.
@@ -659,6 +671,29 @@ public class GLProfile {
return get(GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
}
+ /**
+ * Returns the highest profile, implementing the programmable shader <i>core</i> pipeline <i>only</i>.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_PROGSHADER_CORE}
+ *
+ * @throws GLException if no programmable core profile is available for the device.
+ * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
+ */
+ public static GLProfile getMaxProgrammableCore(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
+ }
+
+ /** Uses the default device
+ * @throws GLException if no programmable core profile is available for the default device.
+ * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
+ */
+ public static GLProfile getMaxProgrammableCore(boolean favorHardwareRasterizer)
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
+ }
+
/**
* Returns the GL2ES1 profile implementation, hence compatible w/ GL2ES1.<br/>
* It returns:
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 2de86b545..94e123b3e 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -174,9 +174,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
new AWTWindowClosingProtocol(this, new Runnable() {
@Override
public void run() {
- GLCanvas.this.destroy();
+ GLCanvas.this.destroyImpl( true );
}
- });
+ }, null);
/** Creates a new GLCanvas component with a default set of OpenGL
capabilities, using the default OpenGL capabilities selection
@@ -312,6 +312,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* all platforms since the peer hasn't been created.
*/
final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+
+ if( Beans.isDesignTime() ) {
+ return gc;
+ }
+
/*
* chosen is only non-null on platforms where the GLDrawableFactory
* returns a non-null GraphicsConfiguration (in the GLCanvas
@@ -370,10 +375,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
*/
chosen = compatible;
- awtConfig = config;
-
if( !equalCaps && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) {
- dispose(true);
+ // complete destruction!
+ destroyImpl( true );
+ // recreation!
+ awtConfig = config;
+ createDrawableAndContext( true );
+ validateGLDrawable();
+ } else {
+ awtConfig = config;
}
}
}
@@ -447,26 +457,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
return; // not yet available ..
}
- Threading.invoke(true, displayOnEDTAction, getTreeLock());
- awtWindowClosingProtocol.addClosingListenerOneShot();
- }
-
- private void dispose(boolean regenerate) {
- disposeRegenerate=regenerate;
- Threading.invoke(true, disposeOnEDTAction, getTreeLock());
+ if( isVisible() ) {
+ Threading.invoke(true, displayOnEDTAction, getTreeLock());
+ }
}
/**
* {@inheritDoc}
*
* <p>
- * This impl. calls this class's {@link #removeNotify()} AWT override,
- * where the actual implementation resides.
+ * This impl. only destroys all GL related resources.
+ * </p>
+ * <p>
+ * This impl. does not remove the GLCanvas from it's parent AWT container
+ * so this class's {@link #removeNotify()} AWT override won't get called.
+ * To do so, remove this component from it's parent AWT container.
* </p>
*/
@Override
public void destroy() {
- removeNotify();
+ destroyImpl( false );
+ }
+
+ protected void destroyImpl(boolean destroyJAWTWindowAndAWTDevice) {
+ Threading.invoke(true, destroyOnEDTAction, getTreeLock());
+ if( destroyJAWTWindowAndAWTDevice ) {
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true /* allowOnNonEDT */, true /* wait */, disposeJAWTWindowAndAWTDeviceOnEDT);
+ }
}
/** Overridden to cause OpenGL rendering to be performed during
@@ -476,7 +493,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
*/
@Override
public void paint(Graphics g) {
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
// Make GLCanvas behave better in NetBeans GUI builder
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
@@ -494,9 +511,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
g.drawString(name,
(int) ((getWidth() - bounds.getWidth()) / 2),
(int) ((getHeight() + bounds.getHeight()) / 2));
- return;
- }
- if( ! this.helper.isAnimatorAnimatingOnOtherThread() ) {
+ } else if( !this.helper.isAnimatorAnimatingOnOtherThread() ) {
display();
}
}
@@ -513,42 +528,47 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
public void addNotify() {
final RecursiveLock _lock = lock;
_lock.lock();
- try {
+ try {
+ final boolean isBeansDesignTime = Beans.isDesignTime();
+
if(DEBUG) {
- System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds());
+ System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds()+", isBeansDesignTime "+isBeansDesignTime);
Thread.dumpStack();
}
- /**
- * 'super.addNotify()' determines the GraphicsConfiguration,
- * while calling this class's overriden 'getGraphicsConfiguration()' method
- * after which it creates the native peer.
- * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
- * is being used in getGraphicsConfiguration().
- * This code order also allows recreation, ie re-adding the GLCanvas.
- */
- awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
- if(null==awtConfig) {
- throw new GLException("Error: NULL AWTGraphicsConfiguration");
- }
-
- // before native peer is valid: X11
- disableBackgroundErase();
-
- // issues getGraphicsConfiguration() and creates the native peer
- super.addNotify();
-
- // after native peer is valid: Windows
- disableBackgroundErase();
-
- if (!Beans.isDesignTime()) {
- createDrawableAndContext();
+ if( isBeansDesignTime ) {
+ super.addNotify();
+ } else {
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overriden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
+ awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
+
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
+ // issues getGraphicsConfiguration() and creates the native peer
+ super.addNotify();
+
+ // after native peer is valid: Windows
+ disableBackgroundErase();
+
+ createDrawableAndContext( true );
+
+ // init drawable by paint/display makes the init sequence more equal
+ // for all launch flavors (applet/javaws/..)
+ // validateGLDrawable();
}
-
- // init drawable by paint/display makes the init sequence more equal
- // for all launch flavors (applet/javaws/..)
- // validateGLDrawable();
-
+ awtWindowClosingProtocol.addClosingListener();
+
if(DEBUG) {
System.err.println(getThreadName()+": Info: addNotify - end: peer: "+getPeer());
}
@@ -557,27 +577,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
- private void createDrawableAndContext() {
- // no lock required, since this resource ain't available yet
- jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
- jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
- jawtWindow.lockSurface();
- try {
- drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setContextCreationFlags(additionalCtxCreationFlags);
- } finally {
- jawtWindow.unlockSurface();
+ private void createDrawableAndContext(boolean createJAWTWindow) {
+ if ( !Beans.isDesignTime() ) {
+ if( createJAWTWindow ) {
+ jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ }
+ jawtWindow.lockSurface();
+ try {
+ drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ } finally {
+ jawtWindow.unlockSurface();
+ }
}
- }
+ }
private boolean validateGLDrawable() {
+ if( Beans.isDesignTime() || !isDisplayable() ) {
+ return false; // early out!
+ }
final GLDrawable _drawable = drawable;
if ( null != _drawable ) {
if( _drawable.isRealized() ) {
return true;
}
- if( Beans.isDesignTime() || !isDisplayable() || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+ if( 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
return false; // early out!
}
// Make sure drawable realization happens on AWT-EDT and only there. Consider the AWTTree lock!
@@ -627,11 +653,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
awtWindowClosingProtocol.removeClosingListener();
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
super.removeNotify();
} else {
try {
- dispose(false);
+ destroyImpl( true );
} finally {
super.removeNotify();
}
@@ -676,6 +702,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ if(null != jawtWindow && jawtWindow.isOffscreenLayerSurfaceEnabled() ) {
+ jawtWindow.layoutSurfaceLayer();
+ }
}
}
}
@@ -790,7 +819,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GL getGL() {
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
return null;
}
final GLContext _context = context;
@@ -844,18 +873,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GLCapabilitiesImmutable getChosenGLCapabilities() {
- if (awtConfig == null) {
+ if( Beans.isDesignTime() ) {
+ return capsReqUser;
+ } else if( null == awtConfig ) {
throw new GLException("No AWTGraphicsConfiguration: "+this);
}
-
return (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities();
}
public GLCapabilitiesImmutable getRequestedGLCapabilities() {
- if (awtConfig == null) {
+ if( null == awtConfig ) {
return capsReqUser;
}
-
return (GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities();
}
@@ -897,8 +926,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// Internals only below this point
//
- private boolean disposeRegenerate;
- private final Runnable disposeOnEDTAction = new Runnable() {
+ private final Runnable destroyOnEDTAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
@@ -907,11 +935,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
final GLAnimatorControl animator = getAnimator();
if(DEBUG) {
- System.err.println(getThreadName()+": Info: dispose("+disposeRegenerate+") - START, hasContext " +
+ System.err.println(getThreadName()+": Info: destroyOnEDTAction() - START, hasContext " +
(null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
Thread.dumpStack();
}
-
+
final boolean animatorPaused;
if(null!=animator) {
// can't remove us from animator for recreational addNotify()
@@ -926,50 +954,29 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// so we can continue with the destruction.
try {
helper.disposeGL(GLCanvas.this, context, true);
+ if(DEBUG) {
+ System.err.println(getThreadName()+": destroyOnEDTAction() - post ctx: "+context);
+ }
} catch (GLException gle) {
gle.printStackTrace();
}
- }
- context=null;
+ }
+ context = null;
}
if( null != drawable ) {
drawable.setRealized(false);
if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - 1: "+drawable);
+ System.err.println(getThreadName()+": destroyOnEDTAction() - post drawable: "+drawable);
}
- drawable=null;
+ drawable = null;
}
- if( null != jawtWindow ) {
- jawtWindow.destroy();
- if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - 2: "+jawtWindow);
- }
- jawtWindow=null;
- }
-
- if(disposeRegenerate) {
- // Similar process as in addNotify()!
-
- // Recreate GLDrawable/GLContext to reflect it's new graphics configuration
- createDrawableAndContext();
- if(DEBUG) {
- System.err.println(getThreadName()+": GLCanvas.dispose(true): new drawable: "+drawable);
- }
- validateGLDrawable(); // immediate attempt to recreate the drawable
- } else {
- if(null != awtConfig) {
- AWTEDTExecutor.singleton.invoke(getTreeLock(), true /* allowOnNonEDT */, true /* wait */, disposeAbstractGraphicsDeviceActionOnEDT);
- }
- awtConfig=null;
- }
-
if(animatorPaused) {
animator.resume();
}
if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - END, animator "+animator);
+ System.err.println(getThreadName()+": dispose() - END, animator "+animator);
}
} finally {
@@ -979,28 +986,43 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
};
/**
- * Disposes the AbstractGraphicsDevice within EDT,
+ * Disposes the JAWTWindow and AbstractGraphicsDevice within EDT,
* since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ * <p>
+ * The drawable and context handle are null'ed as well, assuming {@link #destroy()} has been called already.
+ * </p>
*
* @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
*/
- private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
+ private final Runnable disposeJAWTWindowAndAWTDeviceOnEDT = new Runnable() {
@Override
public void run() {
- if(null != awtConfig) {
- final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
- final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- final String adeviceMsg;
- if(DEBUG) {
- adeviceMsg = adevice.toString();
- } else {
- adeviceMsg = null;
- }
- boolean closed = adevice.close();
- if(DEBUG) {
- System.err.println(getThreadName()+": GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
- }
- }
+ context=null;
+ drawable=null;
+
+ if( null != jawtWindow ) {
+ jawtWindow.destroy();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": GLCanvas.disposeJAWTWindowAndAWTDeviceOnEDT(): post JAWTWindow: "+jawtWindow);
+ }
+ jawtWindow=null;
+ }
+
+ if(null != awtConfig) {
+ final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final String adeviceMsg;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ } else {
+ adeviceMsg = null;
+ }
+ boolean closed = adevice.close();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": GLCanvas.disposeJAWTWindowAndAWTDeviceOnEDT(): post GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ awtConfig=null;
}
};
@@ -1139,14 +1161,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* @param device
* @return the chosen AWTGraphicsConfiguration
*
- * @see #disposeAbstractGraphicsDeviceActionOnEDT
+ * @see #disposeJAWTWindowAndAWTDeviceOnEDT
*/
private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsRequested,
final GLCapabilitiesChooser chooser,
final GraphicsDevice device) {
// Make GLCanvas behave better in NetBeans GUI builder
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
return null;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 664edb996..6c28c75ab 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -152,9 +152,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Used by all backends either directly or indirectly to hook up callbacks
private Updater updater = new Updater();
- // Indicates whether the Java 2D OpenGL pipeline is enabled
- private boolean oglPipelineEnabled =
- Java2D.isOGLPipelineActive() &&
+ // Indicates whether the Java 2D OpenGL pipeline is enabled and resource-compatible
+ private boolean oglPipelineUsable =
+ Java2D.isOGLPipelineResourceCompatible() &&
!Debug.isPropertyDefined("jogl.gljpanel.noogl", true);
// For handling reshape events lazily
@@ -174,13 +174,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
public void run() {
GLJPanel.this.destroy();
}
- });
+ }, null);
static {
// Force eager initialization of part of the Java2D class since
// otherwise it's likely it will try to be initialized while on
// the Queue Flusher Thread, which is not allowed
- if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) {
+ if (Java2D.isOGLPipelineResourceCompatible() && Java2D.isFBOEnabled()) {
Java2D.getShareContext(GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice());
@@ -250,17 +250,19 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public void display() {
- if (EventQueue.isDispatchThread()) {
- // Want display() to be synchronous, so call paintImmediately()
- paintImmediately(0, 0, getWidth(), getHeight());
- } else {
- // Multithreaded redrawing of Swing components is not allowed,
- // so do everything on the event dispatch thread
- try {
- EventQueue.invokeAndWait(paintImmediatelyAction);
- } catch (Exception e) {
- throw new GLException(e);
- }
+ if( isVisible() ) {
+ if (EventQueue.isDispatchThread()) {
+ // Want display() to be synchronous, so call paintImmediately()
+ paintImmediately(0, 0, getWidth(), getHeight());
+ } else {
+ // Multithreaded redrawing of Swing components is not allowed,
+ // so do everything on the event dispatch thread
+ try {
+ EventQueue.invokeAndWait(paintImmediatelyAction);
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
}
}
@@ -350,9 +352,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
sendReshape = handleReshape();
}
- updater.setGraphics(g);
-
- backend.doPaintComponent(g);
+ if( isVisible() ) {
+ updater.setGraphics(g);
+
+ backend.doPaintComponent(g);
+ }
}
@@ -365,6 +369,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public void addNotify() {
super.addNotify();
+ awtWindowClosingProtocol.addClosingListener();
if (DEBUG) {
System.err.println(getThreadName()+": GLJPanel.addNotify()");
}
@@ -608,7 +613,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
to perform OpenGL rendering using the GLJPanel into the same
OpenGL drawable as the Swing implementation uses. */
public boolean shouldPreserveColorBufferIfTranslucent() {
- return oglPipelineEnabled;
+ return oglPipelineUsable;
}
@Override
@@ -662,7 +667,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
if ( null == backend ) {
- if (oglPipelineEnabled) {
+ if (oglPipelineUsable) {
backend = new J2DOGLBackend();
} else {
backend = new OffscreenBackend();
@@ -673,8 +678,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (!isInitialized) {
backend.initialize();
}
-
- awtWindowClosingProtocol.addClosingListenerOneShot();
}
@Override
@@ -1560,7 +1563,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
isInitialized = false;
backend = null;
- oglPipelineEnabled = false;
+ oglPipelineUsable = false;
handleReshape = true;
j2dContext.destroy();
j2dContext = null;
diff --git a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
index 27569d210..b74ac9f41 100644
--- a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
+++ b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
@@ -103,6 +103,7 @@ public class FPSCounterImpl implements FPSCounter {
fpsLastPeriod = 0;
fpsTotalFrames = 0;
fpsLast = 0f; fpsTotal = 0f;
+ fpsLastPeriod = 0; fpsTotalDuration=0;
}
public final synchronized int getUpdateFPSFrames() {
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index b17fce569..42364dbfd 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -278,14 +278,14 @@ public abstract class GLContextImpl extends GLContext {
release(false);
}
private void release(boolean inDestruction) throws GLException {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[release.0]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+", inDestruction: "+inDestruction+", "+lock);
}
if ( !lock.isOwner(Thread.currentThread()) ) {
final String msg = getThreadName() +": Context not current on current thread, obj " + toHexString(hashCode())+", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+", inDestruction: "+inDestruction+", "+lock;
if( DEBUG_TRACE_SWITCH ) {
System.err.println(msg);
- if( null != lastCtxReleaseStack) {
+ if( null != lastCtxReleaseStack ) {
System.err.print("Last release call: ");
lastCtxReleaseStack.printStackTrace();
} else {
@@ -318,7 +318,7 @@ public abstract class GLContextImpl extends GLContext {
if( DEBUG_TRACE_SWITCH ) {
final String msg = getThreadName() +": GLContext.ContextSwitch[release.X]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+(actualRelease?"switch":"keep ")+" - "+lock;
lastCtxReleaseStack = new Throwable(msg);
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(msg);
// Thread.dumpStack();
}
@@ -334,7 +334,7 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void destroy() {
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
@@ -351,7 +351,7 @@ public abstract class GLContextImpl extends GLContext {
lock.lock(); // holdCount++ -> 1 - n (1: not locked, 2-n: destroy while rendering)
if ( lock.getHoldCount() > 2 ) {
final String msg = getThreadName() + ": GLContextImpl.destroy: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle);
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(msg+" - Lock was hold more than once - makeCurrent/release imbalance: "+lock);
Thread.dumpStack();
}
@@ -388,7 +388,7 @@ public abstract class GLContextImpl extends GLContext {
}
} finally {
lock.unlock();
- if (TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() + ": GLContextImpl.destroy.X: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
@@ -468,14 +468,14 @@ public abstract class GLContextImpl extends GLContext {
*/
@Override
public int makeCurrent() throws GLException {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.0]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+lock);
}
// Note: the surface is locked within [makeCurrent .. swap .. release]
final int lockRes = drawable.lockSurface();
if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X1]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - Surface Not Ready - CONTEXT_NOT_CURRENT - "+lock);
}
return CONTEXT_NOT_CURRENT;
@@ -503,7 +503,7 @@ public abstract class GLContextImpl extends GLContext {
// For Mac OS X, however, we need to update the context to track resizes
drawableUpdatedNotify();
unlockContextAndSurface = false; // success
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X2]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep - CONTEXT_CURRENT - "+lock);
}
return CONTEXT_CURRENT;
@@ -526,7 +526,7 @@ public abstract class GLContextImpl extends GLContext {
throw e;
} finally {
if (unlockContextAndSurface) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.1]: Context lock.unlock() due to error, res "+makeCurrentResultToString(res)+", "+lock);
}
lock.unlock();
@@ -575,7 +575,7 @@ public abstract class GLContextImpl extends GLContext {
}
*/
}
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X3]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - "+makeCurrentResultToString(res)+" - "+lock);
}
return res;
@@ -611,7 +611,7 @@ public abstract class GLContextImpl extends GLContext {
shareWith.getDrawableImpl().unlockSurface();
}
}
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
if(created) {
System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName()+" - "+getGLVersion());
// Thread.dumpStack();
@@ -811,7 +811,7 @@ public abstract class GLContextImpl extends GLContext {
if(PROFILE_ALIASING) {
hasGL3 = true;
}
- resetStates(); // clean this context states, since creation was temporary
+ resetStates(); // clean context states, since creation was temporary
}
}
if(!hasGL3) {
@@ -1301,7 +1301,7 @@ public abstract class GLContextImpl extends GLContext {
// Only validate if a valid int version was fetched, otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX!
if ( GLContext.isValidGLVersion(glIntMajor[0], glIntMinor[0]) ) {
if( glIntMajor[0]<major || ( glIntMajor[0]==major && glIntMinor[0]<minor ) || 0 == major ) {
- if( strictMatch && 0 < major ) {
+ if( strictMatch && 2 < major ) { // relaxed match for versions major < 3 requests, last resort!
if(DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+glIntMajor[0]+"."+glIntMinor[0]);
}
@@ -1326,7 +1326,7 @@ public abstract class GLContextImpl extends GLContext {
// Only validate if a valid string version was fetched -> MIN > Version || Version > MAX!
if( null != strGLVersionNumber ) {
if( strGLVersionNumber.compareTo(setGLVersionNumber) < 0 || 0 == major ) {
- if( strictMatch && 0 < major ) {
+ if( strictMatch && 2 < major ) { // relaxed match for versions major < 3 requests, last resort!
if(DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (String): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+strGLVersionNumber);
}
@@ -1462,29 +1462,55 @@ public abstract class GLContextImpl extends GLContext {
final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
+ //
// OS related quirks
+ //
if( Platform.getOSType() == Platform.OSType.MACOS ) {
- final int quirk1 = GLRendererQuirks.NoOffscreenBitmap;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk1)+": cause: OS "+Platform.getOSType());
+ //
+ // OSX
+ //
+ {
+ final int quirk = GLRendererQuirks.NoOffscreenBitmap;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
+ }
+ quirks[i++] = quirk;
+ }
+
+ final VersionNumber OSXVersion173 = new VersionNumber(1,7,3);
+ if( Platform.getOSVersionNumber().compareTo(OSXVersion173) < 0 && glRendererLowerCase.contains("nvidia") ) {
+ final int quirk = GLRendererQuirks.GLFlushBeforeRelease;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", Renderer "+glRenderer);
+ }
+ quirks[i++] = quirk;
}
- quirks[i++] = quirk1;
} else if( Platform.getOSType() == Platform.OSType.WINDOWS ) {
+ //
+ // WINDOWS
+ //
final int quirk = GLRendererQuirks.NoDoubleBufferedBitmap;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
}
quirks[i++] = quirk;
- }
-
- // Renderer related quirks, may also involve OS
- if( Platform.OSType.ANDROID == Platform.getOSType() && glRendererLowerCase.contains("powervr") ) {
- final int quirk = GLRendererQuirks.NoSetSwapInterval;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ } else if( Platform.OSType.ANDROID == Platform.getOSType() ) {
+ //
+ // ANDROID
+ //
+ // Renderer related quirks, may also involve OS
+ if( glRendererLowerCase.contains("powervr") ) {
+ final int quirk = GLRendererQuirks.NoSetSwapInterval;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ }
+ quirks[i++] = quirk;
}
- quirks[i++] = quirk;
}
+
+ //
+ // RENDERER related quirks
+ //
if( glRendererLowerCase.contains("mesa") || glRendererLowerCase.contains("gallium") ) {
{
final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
index 1004f04c6..83815f7a4 100644
--- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
+++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
@@ -29,6 +29,9 @@
package jogamp.opengl;
import java.util.StringTokenizer;
+
+import javax.media.opengl.GLContext;
+
import com.jogamp.common.util.VersionNumber;
/**
@@ -90,9 +93,11 @@ class GLVersionNumber extends VersionNumber {
// Avoid possibly confusing situations by putting some
// constraints on the upgrades we do to the major and
// minor versions
- if ((altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1) {
- val[0] = altMajor;
- val[1] = altMinor;
+ if ( (altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1 ) {
+ if( GLContext.isValidGLVersion(altMajor, altMinor) ) {
+ val[0] = altMajor;
+ val[1] = altMinor;
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
index 983f11133..ae8969d07 100644
--- a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
+++ b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
@@ -94,11 +94,7 @@ public class AWTThreadingPlugin implements ToolkitThreadingPlugin {
// QFT which is not allowed. For now, on X11 platforms,
// continue to perform this work on the EDT.
if (wait && Java2D.isOGLPipelineActive() && !ThreadingImpl.isX11()) {
- if(wait) {
- Java2D.invokeWithOGLContextCurrent(null, r);
- } else {
-
- }
+ Java2D.invokeWithOGLContextCurrent(null, r);
} else {
AWTEDTExecutor.singleton.invoke(wait, r);
}
diff --git a/src/jogl/classes/jogamp/opengl/awt/Java2D.java b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
index 3dbfefb19..edf9e89f8 100644
--- a/src/jogl/classes/jogamp/opengl/awt/Java2D.java
+++ b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
@@ -69,6 +69,7 @@ public class Java2D {
private static boolean DEBUG = Debug.debug("Java2D");
private static boolean isHeadless;
private static boolean isOGLPipelineActive;
+ private static boolean isOGLPipelineResourceCompatible;
private static Method invokeWithOGLContextCurrentMethod;
private static Method isQueueFlusherThreadMethod;
private static Method getOGLViewportMethod;
@@ -124,19 +125,37 @@ public class Java2D {
isHeadless = true;
// Figure out whether the default graphics configuration is an
// OpenGL graphics configuration
- GraphicsConfiguration cfg =
- GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().
- getDefaultConfiguration();
+ final GraphicsConfiguration cfg;
+ final String cfgName;
+ final boolean java2dOGLDisabledByOS = Platform.OS_TYPE == Platform.OSType.MACOS;
+ final boolean java2dOGLDisabledByProp;
+ {
+ boolean enabled = true;
+ final String sVal = System.getProperty("sun.java2d.opengl");
+ if( null != sVal ) {
+ enabled = Boolean.valueOf(sVal);
+ }
+ java2dOGLDisabledByProp = !enabled;
+ }
+ if( !java2dOGLDisabledByProp && !java2dOGLDisabledByOS ) {
+ cfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ cfgName = cfg.getClass().getName();
+ } else {
+ if (DEBUG) {
+ System.err.println("Java2D support disabled: by Property "+java2dOGLDisabledByProp+", by OS "+java2dOGLDisabledByOS);
+ }
+ cfg = null;
+ cfgName = "nil";
+ }
// If we get here, we aren't running in headless mode
isHeadless = false;
- String name = cfg.getClass().getName();
if (DEBUG) {
- System.err.println("Java2D support: default GraphicsConfiguration = " + name);
+ System.err.println("Java2D support: default GraphicsConfiguration = " + cfgName);
}
- isOGLPipelineActive = Platform.OS_TYPE != Platform.OSType.MACOS &&
- (name.startsWith("sun.java2d.opengl"));
-
+ isOGLPipelineActive = cfgName.startsWith("sun.java2d.opengl");
+ isOGLPipelineResourceCompatible = isOGLPipelineActive;
+
if (isOGLPipelineActive) {
try {
// Try to get methods we need to integrate
@@ -152,99 +171,101 @@ public class Java2D {
new Class[] {});
isQueueFlusherThreadMethod.setAccessible(true);
- getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
- new Class[] {
- Graphics.class,
- Integer.TYPE,
- Integer.TYPE
- });
- getOGLViewportMethod.setAccessible(true);
-
- getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
- new Class[] {
- Graphics.class
- });
- getOGLScissorBoxMethod.setAccessible(true);
-
- getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ if( isOGLPipelineResourceCompatible ) {
+ getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
+ new Class[] {
+ Graphics.class,
+ Integer.TYPE,
+ Integer.TYPE
+ });
+ getOGLViewportMethod.setAccessible(true);
+
+ getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLScissorBoxMethod.setAccessible(true);
+
+ getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceIdentifierMethod.setAccessible(true);
+
+ // Try to get additional methods required for proper FBO support
+ fbObjectSupportInitialized = true;
+ try {
+ invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
+ new Class[] {
+ GraphicsConfiguration.class,
+ Runnable.class
+ });
+ invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
+
+ getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
new Class[] {
Graphics.class
});
- getOGLSurfaceIdentifierMethod.setAccessible(true);
-
- // Try to get additional methods required for proper FBO support
- fbObjectSupportInitialized = true;
- try {
- invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
- new Class[] {
- GraphicsConfiguration.class,
- Runnable.class
- });
- invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
-
- getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
- new Class[] {
- Graphics.class
- });
- getOGLSurfaceTypeMethod.setAccessible(true);
- } catch (Exception e) {
- fbObjectSupportInitialized = false;
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: Disabling Java2D/JOGL FBO support");
- }
- }
-
- // Try to get an additional method for FBO support in recent Mustang builds
- try {
- getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
- new Class[] {
- Graphics.class
- });
- getOGLTextureTypeMethod.setAccessible(true);
- } catch (Exception e) {
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled");
- }
- }
-
- // Try to set up APIs for enabling the bridge on OS X,
- // where it isn't possible to create generalized
- // external GLDrawables
- Class<?> cglSurfaceData = null;
- try {
- cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
- } catch (Exception e) {
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
- }
- }
- if (cglSurfaceData != null) {
- // FIXME: for now, assume that FBO support is not enabled on OS X
- fbObjectSupportInitialized = false;
-
- // We need to find these methods in order to make the bridge work on OS X
- createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
- new Class[] {
- Graphics.class,
- Long.TYPE
- });
- createOGLContextOnSurfaceMethod.setAccessible(true);
-
- makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
- new Class[] {
- Graphics.class,
- Long.TYPE
- });
- makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
-
- destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
- new Class[] {
- Long.TYPE
- });
- destroyOGLContextMethod.setAccessible(true);
+ getOGLSurfaceTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ fbObjectSupportInitialized = false;
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: Disabling Java2D/JOGL FBO support");
+ }
+ }
+
+ // Try to get an additional method for FBO support in recent Mustang builds
+ try {
+ getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLTextureTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled");
+ }
+ }
+
+ // Try to set up APIs for enabling the bridge on OS X,
+ // where it isn't possible to create generalized
+ // external GLDrawables
+ Class<?> cglSurfaceData = null;
+ try {
+ cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
+ }
+ }
+ if (cglSurfaceData != null) {
+ // FIXME: for now, assume that FBO support is not enabled on OS X
+ fbObjectSupportInitialized = false;
+
+ // We need to find these methods in order to make the bridge work on OS X
+ createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ createOGLContextOnSurfaceMethod.setAccessible(true);
+
+ makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
+
+ destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
+ new Class[] {
+ Long.TYPE
+ });
+ destroyOGLContextMethod.setAccessible(true);
+ }
}
} catch (Exception e) {
catched = e;
@@ -252,6 +273,7 @@ public class Java2D {
System.err.println("Info: Disabling Java2D/JOGL integration");
}
isOGLPipelineActive = false;
+ isOGLPipelineResourceCompatible = false;
}
}
} catch (HeadlessException e) {
@@ -265,7 +287,7 @@ public class Java2D {
if(null != catched) {
catched.printStackTrace();
}
- System.err.println("JOGL/Java2D integration " + (isOGLPipelineActive ? "enabled" : "disabled"));
+ System.err.println("JOGL/Java2D OGL Pipeline active " + isOGLPipelineActive + ", resourceCompatible "+isOGLPipelineResourceCompatible);
}
return null;
}
@@ -275,6 +297,10 @@ public class Java2D {
public static boolean isOGLPipelineActive() {
return isOGLPipelineActive;
}
+
+ public static boolean isOGLPipelineResourceCompatible() {
+ return isOGLPipelineResourceCompatible;
+ }
public static boolean isFBOEnabled() {
return fbObjectSupportInitialized;
@@ -330,7 +356,7 @@ public class Java2D {
false if the passed GraphicsConfiguration was not an OpenGL
GraphicsConfiguration. */
public static boolean invokeWithOGLSharedContextCurrent(GraphicsConfiguration g, Runnable r) throws GLException {
- checkActive();
+ checkCompatible();
try {
AWTUtil.lockToolkit();
@@ -355,7 +381,7 @@ public class Java2D {
public static Rectangle getOGLViewport(Graphics g,
int componentWidth,
int componentHeight) {
- checkActive();
+ checkCompatible();
try {
return (Rectangle) getOGLViewportMethod.invoke(null, new Object[] {g,
@@ -375,7 +401,7 @@ public class Java2D {
passed to a call to glScissor(). Should only be called from the
Queue Flusher Thread. */
public static Rectangle getOGLScissorBox(Graphics g) {
- checkActive();
+ checkCompatible();
try {
return (Rectangle) getOGLScissorBoxMethod.invoke(null, new Object[] {g});
@@ -393,7 +419,7 @@ public class Java2D {
created (and the old ones destroyed). Should only be called from
the Queue Flusher Thread.*/
public static Object getOGLSurfaceIdentifier(Graphics g) {
- checkActive();
+ checkCompatible();
try {
return getOGLSurfaceIdentifierMethod.invoke(null, new Object[] {g});
@@ -408,7 +434,7 @@ public class Java2D {
object. This indicates, in particular, whether Java2D is
currently rendering into a pbuffer or FBO. */
public static int getOGLSurfaceType(Graphics g) {
- checkActive();
+ checkCompatible();
try {
// FIXME: fallback path for pre-b73 (?) Mustang builds -- remove
@@ -429,7 +455,7 @@ public class Java2D {
object assuming it is rendering to an FBO. Returns either
GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB. */
public static int getOGLTextureType(Graphics g) {
- checkActive();
+ checkCompatible();
if (getOGLTextureTypeMethod == null) {
return GL.GL_TEXTURE_2D;
@@ -483,7 +509,7 @@ public class Java2D {
associated with the given Graphics object, sharing textures and
display lists with the specified (CGLContextObj) share context. */
public static long createOGLContextOnSurface(Graphics g, long shareCtx) {
- checkActive();
+ checkCompatible();
try {
return ((Long) createOGLContextOnSurfaceMethod.invoke(null, new Object[] { g, new Long(shareCtx) })).longValue();
@@ -497,7 +523,7 @@ public class Java2D {
/** (Mac OS X-specific) Makes the given OpenGL context current on
the surface associated with the given Graphics object. */
public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
- checkActive();
+ checkCompatible();
try {
return ((Boolean) makeOGLContextCurrentOnSurfaceMethod.invoke(null, new Object[] { g, new Long(ctx) })).booleanValue();
@@ -510,7 +536,7 @@ public class Java2D {
/** (Mac OS X-specific) Destroys the given OpenGL context. */
public static void destroyOGLContext(long ctx) {
- checkActive();
+ checkCompatible();
try {
destroyOGLContextMethod.invoke(null, new Object[] { new Long(ctx) });
@@ -527,7 +553,13 @@ public class Java2D {
private static void checkActive() {
if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
+ throw new GLException("Java2D OpenGL pipeline not active");
+ }
+ }
+
+ private static void checkCompatible() {
+ if ( !isOGLPipelineResourceCompatible() ) {
+ throw new GLException("Java2D OpenGL pipeline not resource compatible");
}
}
@@ -562,7 +594,7 @@ public class Java2D {
// Note 2: the first execution of this method must not be from the
// Java2D Queue Flusher Thread.
- if (isOGLPipelineActive() &&
+ if (isOGLPipelineResourceCompatible() &&
isFBOEnabled() &&
!initializedJ2DFBOShareContext) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 838a0387d..3825f855c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -74,6 +74,7 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
@@ -687,13 +688,33 @@ public abstract class MacOSXCGLContext extends GLContextImpl
} else {
gl3ShaderProgramName = 0;
}
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
- nsOpenGLLayerPFmt = 0; // NSOpenGLLayer will release pfmt
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+
+ /**
+ * Perform NSOpenGLLayer creation and attaching on main-thread,
+ * hence release the lock on our context - which will be used to
+ * create a shared context within NSOpenGLLayer.
+ */
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final boolean ctxUnlocked = CGL.kCGLNoError == CGL.CGLUnlockContext(cglCtx);
+ try {
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ nsOpenGLLayerPFmt = 0; // NSOpenGLLayer will release pfmt
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
+ } finally {
+ if( ctxUnlocked ) {
+ if( CGL.kCGLNoError != CGL.CGLLockContext(cglCtx) ) {
+ throw new InternalError("Could not re-lock CGLContext for: "+this);
+ }
+ }
}
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
+ backingLayerHost.layoutSurfaceLayer();
} else {
lastWidth = drawable.getWidth();
lastHeight = drawable.getHeight();
@@ -773,7 +794,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean release(long ctx) {
try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) {
+ gl.glFlush();
+ }
} catch (GLException gle) {
if(DEBUG) {
System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
@@ -953,7 +976,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean release(long ctx) {
try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) {
+ gl.glFlush();
+ }
} catch (GLException gle) {
if(DEBUG) {
System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index e76c39805..9f034adb1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -346,7 +346,7 @@ public class WindowsWGLContext extends GLContextImpl {
if(glCaps.getGLProfile().isGL3()) {
WGL.wglMakeCurrent(0, 0);
WGL.wglDeleteContext(temp_ctx);
- throw new GLException("WindowsWGLContext.createContext ctx !ARB, context > GL2 requested "+getGLVersion());
+ throw new GLException(getThreadName()+": WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2 requested (OpenGL >= 3.0.1). Requested: "+glCaps.getGLProfile()+", current: "+getGLVersion());
}
if(DEBUG) {
System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion());
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index feda64f30..575ff51b8 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -166,7 +166,7 @@ public abstract class X11GLXContext extends GLContextImpl {
throw new InternalError("Given readDrawable but no driver support");
}
} catch (RuntimeException re) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName()+": Warning: X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+
"dpy "+toHexString(dpy)+
", write "+toHexString(writeDrawable)+
@@ -374,7 +374,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if(glp.isGL3()) {
glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, temp_ctx);
- throw new GLException(getThreadName()+": X11GLXContext.createContextImpl ctx !ARB, context > GL2 requested - requested: "+glp+", current: "+getGLVersion()+", ");
+ throw new GLException(getThreadName()+": X11GLXContext.createContextImpl ctx !ARB, profile > GL2 requested (OpenGL >= 3.0.1). Requested: "+glp+", current: "+getGLVersion());
}
if(DEBUG) {
System.err.println(getThreadName()+": X11GLXContext.createContextImpl failed, fall back to !ARB context "+getGLVersion());
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index b37930587..2cf74380c 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -1,6 +1,7 @@
#import "MacOSXWindowSystemInterface.h"
#import <QuartzCore/QuartzCore.h>
#import <pthread.h>
+#import "NativeWindowProtocols.h"
#include "timespec.h"
#import <OpenGL/glext.h>
@@ -41,6 +42,8 @@ extern GLboolean glIsVertexArray (GLuint array);
//
// #define DBG_PERF 1
+// #define DBG_LIFECYCLE 1
+
/**
* Capture setView(NULL), which produces a 'invalid drawable' message
*
@@ -52,6 +55,10 @@ extern GLboolean glIsVertexArray (GLuint array);
- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share;
- (void)setView:(NSView *)view;
- (void)update;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
- (void)dealloc;
@end
@@ -69,8 +76,11 @@ extern GLboolean glIsVertexArray (GLuint array);
- (void)setView:(NSView *)view
{
DBG_PRINT("MyNSOpenGLContext.setView: this.0 %p, view %p\n", self, view);
+ // NSLog(@"MyNSOpenGLContext::setView: %@",[NSThread callStackSymbols]);
if(NULL != view) {
[super setView:view];
+ } else {
+ [self clearDrawable];
}
DBG_PRINT("MyNSOpenGLContext.setView.X\n");
}
@@ -82,19 +92,47 @@ extern GLboolean glIsVertexArray (GLuint array);
DBG_PRINT("MyNSOpenGLContext.update.X\n");
}
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLContext::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLContext::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLContext::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLContext::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLContext::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
- (void)dealloc
{
- DBG_PRINT("MyNSOpenGLContext.dealloc: this.0 %p\n", self);
+ CGLContextObj cglCtx = [self CGLContextObj];
+
+ DBG_PRINT("MyNSOpenGLContext::dealloc.0 %p (refcnt %d) - CGL-Ctx %p\n", self, (int)[self retainCount], cglCtx);
+ [self clearDrawable];
+ if( NULL != cglCtx ) {
+ CGLDestroyContext( cglCtx );
+ }
[super dealloc];
- DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
+ // DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
}
@end
-@interface MyNSOpenGLLayer: NSOpenGLLayer
+@interface MyNSOpenGLLayer: NSOpenGLLayer <NWDedicatedSize>
{
@private
GLfloat gl_texCoords[8];
+ NSOpenGLContext* myCtx;
+ Bool isGLEnabled;
@protected
NSOpenGLContext* parentCtx;
@@ -106,8 +144,8 @@ extern GLboolean glIsVertexArray (GLuint array);
NSOpenGLPixelFormat* parentPixelFmt;
int texWidth;
int texHeight;
- int newTexWidth;
- int newTexHeight;
+ int dedicatedWidth;
+ int dedicatedHeight;
volatile NSOpenGLPixelBuffer* pbuffer;
volatile GLuint textureID;
volatile NSOpenGLPixelBuffer* newPBuffer;
@@ -136,7 +174,17 @@ extern GLboolean glIsVertexArray (GLuint array);
texWidth: (int) texWidth
texHeight: (int) texHeight;
-- (Bool) validateTexSizeWithNewSize;
+- (void)releaseLayer;
+- (void)deallocPBuffer;
+- (void)disableAnimation;
+- (void)pauseAnimation:(Bool)pause;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+- (void)waitUntilRenderSignal: (long) to_micros;
+- (Bool)isGLSourceValid;
+
+- (void) setGLEnabled: (Bool) enable;
+- (Bool) validateTexSizeWithDedicatedSize;
- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight;
- (void) setTextureID: (int) _texID;
@@ -144,17 +192,22 @@ extern GLboolean glIsVertexArray (GLuint array);
- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
- (void) applyNewPBuffer;
+- (void)setDedicatedSize:(CGSize)size; // @NWDedicatedSize
+- (CGRect)fixMyFrame;
+- (CGRect)fixSuperPosition;
+- (id<CAAction>)actionForKey:(NSString *)key ;
- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
-- (void)disableAnimation;
-- (void)pauseAnimation:(Bool)pause;
-- (void)deallocPBuffer;
-- (void)releaseLayer;
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
- (void)dealloc;
-- (void)setSwapInterval:(int)interval;
-- (void)tick;
-- (void)waitUntilRenderSignal: (long) to_micros;
-- (Bool)isGLSourceValid;
@end
@@ -209,6 +262,7 @@ static const GLfloat gl_verts[] = {
pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
pthread_cond_init(&renderSignal, NULL); // no attribute
+ myCtx = NULL;
{
int i;
for(i=0; i<8; i++) {
@@ -226,9 +280,10 @@ static const GLfloat gl_verts[] = {
swapIntervalCounter = 0;
timespec_now(&lastWaitTime);
shallDraw = NO;
- newTexWidth = _texWidth;
- newTexHeight = _texHeight;
- [self validateTexSizeWithNewSize];
+ isGLEnabled = YES;
+ dedicatedWidth = _texWidth;
+ dedicatedHeight = _texHeight;
+ [self validateTexSizeWithDedicatedSize];
[self setTextureID: texID];
newPBuffer = NULL;
@@ -265,13 +320,6 @@ static const GLfloat gl_verts[] = {
}
}
if(NULL != displayLink) {
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [parentCtx CGLContextObj], [parentPixelFmt 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);
@@ -302,9 +350,15 @@ static const GLfloat gl_verts[] = {
return self;
}
-- (Bool) validateTexSizeWithNewSize
+- (void) setGLEnabled: (Bool) enable
{
- return [self validateTexSize: newTexWidth texHeight: newTexHeight];
+ DBG_PRINT("MyNSOpenGLLayer::setGLEnabled: %p, %d -> %d\n", self, (int)isGLEnabled, (int)enable);
+ isGLEnabled = enable;
+}
+
+- (Bool) validateTexSizeWithDedicatedSize
+{
+ return [self validateTexSize: dedicatedWidth texHeight: dedicatedHeight];
}
- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight
@@ -312,12 +366,14 @@ static const GLfloat gl_verts[] = {
if(_texHeight != texHeight || _texWidth != texWidth) {
texWidth = _texWidth;
texHeight = _texHeight;
+ /**
CGRect lRect = [self bounds];
lRect.origin.x = 0;
lRect.origin.y = 0;
lRect.size.width = texWidth;
lRect.size.height = texHeight;
- [self setFrame: lRect];
+ [self setFrame: lRect]; */
+ CGRect lRect = [self fixMyFrame];
GLfloat texCoordWidth, texCoordHeight;
if(NULL != pbuffer) {
@@ -339,8 +395,14 @@ static const GLfloat gl_verts[] = {
gl_texCoords[5] = texCoordHeight;
gl_texCoords[4] = texCoordWidth;
gl_texCoords[6] = texCoordWidth;
+#ifdef VERBOSE_ON
+ DBG_PRINT("MyNSOpenGLLayer::validateTexSize %p -> tex %dx%d, bounds: %lf/%lf %lfx%lf\n",
+ self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+#endif
return YES;
} else {
+ [self fixMyFrame];
return NO;
}
}
@@ -407,26 +469,9 @@ static const GLfloat gl_verts[] = {
}
}
-- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
-{
- DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
- self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
- return parentPixelFmt;
-}
-
-- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
-{
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p\n",
- self, (int)[self retainCount], pixelFormat, parentCtx);
- NSOpenGLContext * nctx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", nctx);
- return nctx;
-}
-
- (void)disableAnimation
{
- DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
- pthread_mutex_lock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.0: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
[self setAsynchronous: NO];
if(NULL != displayLink) {
#ifdef HAS_CADisplayLink
@@ -438,35 +483,60 @@ static const GLfloat gl_verts[] = {
#endif
displayLink = NULL;
}
- pthread_mutex_unlock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.X: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
}
- (void)releaseLayer
{
DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_lock(&renderLock);
[self disableAnimation];
+ pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
- [[self openGLContext] release];
+ // [[self openGLContext] release];
+ if( NULL != myCtx ) {
+ [myCtx release];
+ myCtx = NULL;
+ }
+ parentCtx = NULL;
[parentPixelFmt release];
- [self release];
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
pthread_mutex_unlock(&renderLock);
+ [self release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p\n", self);
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLLayer::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLLayer::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
}
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLLayer::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::release: %@",[NSThread callStackSymbols]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLLayer::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
- (void)dealloc
{
DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
// NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
-
- pthread_mutex_lock(&renderLock);
[self disableAnimation];
+ pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
pthread_mutex_unlock(&renderLock);
pthread_cond_destroy(&renderSignal);
pthread_mutex_destroy(&renderLock);
[super dealloc];
- DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+ // DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
}
- (Bool)isGLSourceValid
@@ -474,26 +544,114 @@ static const GLfloat gl_verts[] = {
return NULL != pbuffer || NULL != newPBuffer || 0 != textureID ;
}
-- (void)resizeWithOldSuperlayerSize:(CGSize)size
- {
- CGRect lRectS = [[self superlayer] bounds];
+// @NWDedicatedSize
+- (void)setDedicatedSize:(CGSize)size {
+ DBG_PRINT("MyNSOpenGLLayer::setDedicatedSize: %p, texSize %dx%d <- %lfx%lf\n",
+ self, texWidth, texHeight, size.width, size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ dedicatedWidth = size.width;
+ dedicatedHeight = size.height;
- DBG_PRINT("MyNSOpenGLLayer::resizeWithOldSuperlayerSize: %p, texSize %dx%d, bounds: %lfx%lf -> %lfx%lf (refcnt %d)\n",
- self, texWidth, texHeight, size.width, size.height, lRectS.size.width, lRectS.size.height, (int)[self retainCount]);
+ CGRect rect = CGRectMake(0, 0, dedicatedWidth, dedicatedHeight);
+ [self setFrame: rect];
- newTexWidth = lRectS.size.width;
- newTexHeight = lRectS.size.height;
- shallDraw = [self isGLSourceValid];
- SYNC_PRINT("<SZ %dx%d>", newTexWidth, newTexHeight);
+ [CATransaction commit];
+}
- [super resizeWithOldSuperlayerSize: size];
+- (void) setFrame:(CGRect) frame {
+ CGRect rect = CGRectMake(0, 0, dedicatedWidth, dedicatedHeight);
+ [super setFrame: rect];
+}
+
+- (CGRect)fixMyFrame
+{
+ CGRect lRect = [self frame];
+
+ // With Java7 our root CALayer's frame gets off-limit -> force 0/0 origin!
+ if( lRect.origin.x!=0 || lRect.origin.y!=0 || lRect.size.width!=texWidth || lRect.size.height!=texHeight) {
+ DBG_PRINT("MyNSOpenGLLayer::fixMyFrame: %p, 0/0 texSize %dx%d -> Frame[%lf/%lf %lfx%lf]\n",
+ self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width=texWidth;
+ lRect.size.height=texHeight;
+ [self setFrame: lRect];
+
+ [CATransaction commit];
+ }
+ return lRect;
+}
+
+- (CGRect)fixSuperPosition
+{
+ CALayer * superL = [self superlayer];
+ CGRect lRect = [superL frame];
+
+ // With Java7 our root CALayer's frame gets off-limit -> force 0/0 origin!
+ if( lRect.origin.x!=0 || lRect.origin.y!=0 ) {
+ DBG_PRINT("MyNSOpenGLLayer::fixSuperPosition: %p, 0/0 -> Super Frame[%lf/%lf %lfx%lf]\n",
+ self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ [superL setPosition: lRect.origin];
+
+ [CATransaction commit];
+ }
+ return lRect;
+}
+
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ DBG_PRINT("MyNSOpenGLLayer::actionForKey.0 %p key %s -> NIL\n", self, [key UTF8String]);
+ return nil;
+ // return [super actionForKey: key];
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
+ self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
+ // We simply take over ownership of parent PixelFormat ..
+ return parentPixelFmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p, DisplayLink %p\n",
+ self, (int)[self retainCount], pixelFormat, parentCtx, displayLink);
+ // NSLog(@"MyNSOpenGLLayer::openGLContextForPixelFormat: %@",[NSThread callStackSymbols]);
+ myCtx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+#ifndef HAS_CADisplayLink
+ if(NULL != displayLink) {
+ CVReturn cvres;
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [myCtx CGLContextObj], [pixelFormat CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ }
+ }
+#endif
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", myCtx);
+ return myCtx;
}
- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
- SYNC_PRINT("<? %d>", (int)shallDraw);
- return shallDraw;
+ SYNC_PRINT("<? %d, %d>", (int)shallDraw, (int)isGLEnabled);
+ return shallDraw && isGLEnabled;
}
- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
@@ -503,7 +661,7 @@ static const GLfloat gl_verts[] = {
SYNC_PRINT("<* ");
// NSLog(@"MyNSOpenGLLayer::DRAW: %@",[NSThread callStackSymbols]);
- if( shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
+ if( isGLEnabled && shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
[context makeCurrentContext];
if( NULL != newPBuffer ) { // volatile OK
@@ -512,7 +670,7 @@ static const GLfloat gl_verts[] = {
GLenum textureTarget;
- Bool texSizeChanged = [self validateTexSizeWithNewSize];
+ Bool texSizeChanged = [self validateTexSizeWithDedicatedSize];
if( NULL != pbuffer ) {
if( texSizeChanged && 0 != textureID ) {
@@ -752,32 +910,34 @@ static const GLfloat gl_verts[] = {
@end
NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, 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 texIDArg: (GLuint)texID
- // opaque: opaque texWidth: texWidth texHeight: texHeight];
-
return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
opaque: opaque texWidth: texWidth texHeight: texHeight];
}
+
+void setNSOpenGLLayerEnabled(NSOpenGLLayer* layer, Bool enable) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ [l setGLEnabled: enable];
+ [pool release];
+}
void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
[l setSwapInterval: interval];
[pool release];
}
void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
[l waitUntilRenderSignal: to_micros];
[pool release];
}
void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
Bool shallDraw;
// volatile OK
@@ -799,8 +959,8 @@ void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
}
void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
Bool shallDraw;
if( NO == [l isSamePBuffer: p] ) {
@@ -825,16 +985,10 @@ void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuff
}
void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
-
- if ( [NSThread isMainThread] == YES ) {
- [l releaseLayer];
- } else {
- [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
- }
-
+ [l releaseLayer];
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
[pool release];
}
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index e8925f8e8..f8faeb8d0 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -575,7 +575,6 @@ void setContextView(NSOpenGLContext* ctx, NSView* view) {
[ctx setView:view];
}
[pool release];
- return ctx;
}
Bool makeCurrentContext(NSOpenGLContext* ctx) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
index d78b4ac15..e3f85b948 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTWindowClosingProtocol.java
@@ -33,22 +33,31 @@ import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
+
import javax.media.nativewindow.WindowClosingProtocol;
+import jogamp.common.awt.AWTEDTExecutor;
import jogamp.nativewindow.awt.AWTMisc;
public class AWTWindowClosingProtocol implements WindowClosingProtocol {
private Component comp;
- private Runnable closingOperation;
- private volatile boolean closingListenerSet = false;
+ private Runnable closingOperationClose;
+ private Runnable closingOperationNOP;
+ private boolean closingListenerSet = false;
private Object closingListenerLock = new Object();
private WindowClosingMode defaultCloseOperation = WindowClosingMode.DISPOSE_ON_CLOSE;
private boolean defaultCloseOperationSetByUser = false;
- public AWTWindowClosingProtocol(Component comp, Runnable closingOperation) {
+ /**
+ * @param comp mandatory AWT component which AWT Window is being queried by parent traversal
+ * @param closingOperationClose mandatory closing operation, triggered if windowClosing and {@link WindowClosingMode#DISPOSE_ON_CLOSE}
+ * @param closingOperationNOP optional closing operation, triggered if windowClosing and {@link WindowClosingMode#DO_NOTHING_ON_CLOSE}
+ */
+ public AWTWindowClosingProtocol(Component comp, Runnable closingOperationClose, Runnable closingOperationNOP) {
this.comp = comp;
- this.closingOperation = closingOperation;
+ this.closingOperationClose = closingOperationClose;
+ this.closingOperationNOP = closingOperationNOP;
}
class WindowClosingAdapter extends WindowAdapter {
@@ -59,54 +68,56 @@ public class AWTWindowClosingProtocol implements WindowClosingProtocol {
if( WindowClosingMode.DISPOSE_ON_CLOSE == op ) {
// we have to issue this call right away,
// otherwise the window gets destroyed
- closingOperation.run();
+ closingOperationClose.run();
+ } else if( null != closingOperationNOP ){
+ closingOperationNOP.run();
}
}
}
WindowListener windowClosingAdapter = new WindowClosingAdapter();
- final boolean addClosingListenerImpl() {
- Window w = AWTMisc.getWindow(comp);
- if(null!=w) {
- w.addWindowListener(windowClosingAdapter);
- return true;
- }
- return false;
- }
-
/**
- * Adds this closing listener to the components Window if exist and only one time.<br>
- * Hence you may call this method every time to ensure it has been set,
- * ie in case the Window parent is not available yet.
+ * Adds this closing listener to the components Window if exist and only one time.
+ * <p>
+ * If the closing listener is already added, and {@link IllegalStateException} is thrown.
+ * </p>
*
- * @return
+ * @return true if added, otherwise false.
+ * @throws IllegalStateException
*/
- public final boolean addClosingListenerOneShot() {
- if(!closingListenerSet) { // volatile: ok
+ public final boolean addClosingListener() throws IllegalStateException {
synchronized(closingListenerLock) {
- if(!closingListenerSet) {
- closingListenerSet=addClosingListenerImpl();
- return closingListenerSet;
- }
+ if(closingListenerSet) {
+ throw new IllegalStateException("WindowClosingListener already set");
+ }
+ final Window w = AWTMisc.getWindow(comp);
+ if(null!=w) {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
+ w.addWindowListener(windowClosingAdapter);
+ } } );
+ closingListenerSet = true;
+ return true;
+ }
}
- }
- return false;
+ return false;
}
public final boolean removeClosingListener() {
- if(closingListenerSet) { // volatile: ok
synchronized(closingListenerLock) {
- if(closingListenerSet) {
- Window w = AWTMisc.getWindow(comp);
- if(null!=w) {
- w.removeWindowListener(windowClosingAdapter);
- closingListenerSet = false;
- return true;
- }
- }
+ if(closingListenerSet) {
+ final Window w = AWTMisc.getWindow(comp);
+ if(null!=w) {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
+ w.removeWindowListener(windowClosingAdapter);
+ } } );
+ closingListenerSet = false;
+ return true;
+ }
+ }
}
- }
- return false;
+ return false;
}
/**
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 8527a0200..d65f8c231 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -130,7 +130,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
if(changed) {
if(DEBUG) {
System.err.println("JAWTWindow.updateBounds: "+bounds+" -> "+jb);
- Thread.dumpStack();
+ // Thread.dumpStack();
}
bounds.setX(jawtBounds.getX());
bounds.setY(jawtBounds.getY());
@@ -205,7 +205,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
try {
if(DEBUG) {
- System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle) + ", bounds "+bounds);
+ System.err.println("JAWTWindow.attachSurfaceHandle: "+toHexString(layerHandle) + ", bounds "+bounds);
}
attachSurfaceLayerImpl(layerHandle);
offscreenSurfaceLayer = layerHandle;
@@ -216,6 +216,17 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected abstract void attachSurfaceLayerImpl(final long layerHandle);
@Override
+ public void layoutSurfaceLayer() throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new NativeWindowException("Not an offscreen layer surface");
+ }
+ if( 0 != offscreenSurfaceLayer) {
+ layoutSurfaceLayerImpl();
+ }
+ }
+ protected void layoutSurfaceLayerImpl() {}
+
+ @Override
public final void detachSurfaceLayer() throws NativeWindowException {
if( !isOffscreenLayerSurfaceEnabled() ) {
throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
@@ -229,7 +240,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
try {
if(DEBUG) {
- System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(offscreenSurfaceLayer));
+ System.err.println("JAWTWindow.detachSurfaceHandle(): osh "+toHexString(offscreenSurfaceLayer));
}
detachSurfaceLayerImpl(offscreenSurfaceLayer);
offscreenSurfaceLayer = 0;
@@ -341,7 +352,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
if(LOCK_SUCCESS == res && drawable_old != drawable) {
res = LOCK_SURFACE_CHANGED;
if(DEBUG) {
- System.err.println("JAWTWindow: surface change 0x"+Long.toHexString(drawable_old)+" -> 0x"+Long.toHexString(drawable));
+ System.err.println("JAWTWindow: surface change "+toHexString(drawable_old)+" -> "+toHexString(drawable));
// Thread.dumpStack();
}
}
@@ -549,8 +560,8 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
StringBuilder sb = new StringBuilder();
sb.append("JAWT-Window["+
- "windowHandle 0x"+Long.toHexString(getWindowHandle())+
- ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
+ "windowHandle "+toHexString(getWindowHandle())+
+ ", surfaceHandle "+toHexString(getSurfaceHandle())+
", bounds "+bounds+", insets "+insets+
", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface);
if(null!=component) {
@@ -566,4 +577,8 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return sb.toString();
}
+
+ protected final String toHexString(long l) {
+ return "0x"+Long.toHexString(l);
+ }
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 2b49f6745..5c4fd82d2 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -38,7 +38,6 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowFactory;
@@ -49,7 +48,6 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
-import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.nativewindow.x11.X11Lib;
@@ -484,6 +482,23 @@ public class SWTAccessor {
}
}
+ /**
+ * Runs the specified action on the SWT UI thread.
+ * <p>
+ * If <code>display</code> is disposed or the current thread is the SWT UI thread
+ * {@link #invoke(boolean, Runnable)} is being used.
+ * @see #invoke(boolean, Runnable)
+ */
+ public static void invoke(org.eclipse.swt.widgets.Display display, boolean wait, Runnable runnable) {
+ if( display.isDisposed() || Thread.currentThread() == display.getThread() ) {
+ invoke(wait, runnable);
+ } else if( wait ) {
+ display.syncExec(runnable);
+ } else {
+ display.asyncExec(runnable);
+ }
+ }
+
//
// Specific X11 GTK ChildWindow - Using plain X11 native parenting (works well)
//
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
index 12e202975..a740ebbe0 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
@@ -54,8 +54,7 @@ import javax.media.nativewindow.util.Point;
public interface NativeWindow extends NativeSurface {
/**
- * destroys the window and releases
- * windowing related resources.
+ * Destroys this window incl. releasing all related resources.
*/
public void destroy();
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
index f6bc5822b..4885d5a4c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -33,11 +33,34 @@ package javax.media.nativewindow;
public interface OffscreenLayerSurface {
/**
* Attach the offscreen layer to this offscreen layer surface.
+ * <p>
+ * Implementation may realize all required resources at this point.
+ * </p>
+ * <p>
+ * It is mandatory that any related resources, e.g. a shared context,
+ * are not locked while calling this method.
+ * </p>
+ *
* @see #isOffscreenLayerSurfaceEnabled()
* @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
*/
public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+ /**
+ * Layout the offscreen layer according to the implementing class's constraints.
+ * <p>
+ * This method allows triggering a re-layout of the offscreen surface
+ * in case the implementation requires it.
+ * </p>
+ * <p>
+ * Call this method if any parent or ancestor's layout has been changed,
+ * which could affects the layout of this surface.
+ * </p>
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void layoutSurfaceLayer() throws NativeWindowException;
+
/**
* Detaches a previously attached offscreen layer from this offscreen layer surface.
* @see #attachSurfaceLayer(long)
diff --git a/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java
index 884c916e4..02f68f442 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java
@@ -37,6 +37,10 @@ package javax.media.nativewindow;
* this protocol default behavior {@link WindowClosingMode#DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.</p>
*/
public interface WindowClosingProtocol {
+
+ /**
+ * Window closing mode if triggered by toolkit close operation.
+ */
public enum WindowClosingMode {
/**
* Do nothing on native window close operation.<br>
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 9e270d403..3ec54ca78 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -51,6 +51,7 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
+import com.jogamp.common.util.Function;
import com.jogamp.nativewindow.awt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT;
@@ -70,11 +71,40 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
protected void invalidateNative() {
+ if(DEBUG) {
+ System.err.println("MacOSXJAWTWindow.invalidateNative(): osh-enabled "+isOffscreenLayerSurfaceEnabled()+
+ ", osh-set "+offscreenSurfaceHandleSet+
+ ", osh "+toHexString(offscreenSurfaceHandle)+
+ ", rsh "+toHexString(rootSurfaceLayerHandle)+
+ ", wh "+toHexString(windowHandle));
+ }
offscreenSurfaceHandle=0;
offscreenSurfaceHandleSet=false;
- if(isOffscreenLayerSurfaceEnabled()) {
+ if( isOffscreenLayerSurfaceEnabled() ) {
if(0 != rootSurfaceLayerHandle) {
+ final JAWT jawt = getJAWT();
+ if( null != jawt ) {
+ final JAWT_DrawingSurface ds = jawt.GetDrawingSurface(component);
+ if (ds != null) {
+ if ( 0 == ( ds.Lock() & JAWTFactory.JAWT_LOCK_ERROR ) ) {
+ JAWT_DrawingSurfaceInfo dsi = null;
+ try {
+ dsi = ds.GetDrawingSurfaceInfo();
+ if(! UnsetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ System.err.println("Error clearing JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayerHandle));
+ }
+ } finally {
+ if ( null != dsi ) {
+ ds.FreeDrawingSurfaceInfo(dsi);
+ }
+ ds.Unlock();
+ }
+ }
+ jawt.FreeDrawingSurface(ds);
+ }
+ }
OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
+
rootSurfaceLayerHandle = 0;
}
if(0 != windowHandle) {
@@ -88,10 +118,20 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle);
}
+ protected void layoutSurfaceLayerImpl() {
+ final long osl = getAttachedSurfaceLayer();
+ final int w = getWidth();
+ final int h = getHeight();
+ if(DEBUG) {
+ System.err.println("JAWTWindow.fixSurfaceLayerLayout: "+toHexString(osl) + ", bounds "+bounds+", "+w+"x"+h);
+ }
+ OSXUtil.FixCALayerLayout(rootSurfaceLayerHandle, osl, w, h);
+ }
+
protected void detachSurfaceLayerImpl(final long layerHandle) {
OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
}
-
+
@Override
public final long getWindowHandle() {
return windowHandle;
@@ -107,7 +147,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
throw new java.lang.UnsupportedOperationException("Not using CALAYER");
}
if(DEBUG) {
- System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): "+toHexString(surfaceHandle));
}
this.offscreenSurfaceHandle = surfaceHandle;
this.offscreenSurfaceHandleSet = true;
@@ -117,6 +157,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
// use offscreen if supported and [ applet or requested ]
return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
}
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SURFACE_NOT_READY;
ds = getJAWT().GetDrawingSurface(component);
@@ -189,7 +230,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
} else {
drawable = OSXUtil.GetNSView(windowHandle);
if(0 == drawable) {
- errMsg = "Null NSView of NSWindow 0x"+Long.toHexString(windowHandle);
+ errMsg = "Null NSView of NSWindow "+toHexString(windowHandle);
}
}
if(null == errMsg) {
@@ -204,8 +245,8 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
if(0 == rootSurfaceLayerHandle) {
errMsg = "Could not create root CALayer";
- } else if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
- errMsg = "Could not set JAWT rootSurfaceLayerHandle 0x"+Long.toHexString(rootSurfaceLayerHandle);
+ } else if(!SetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayerHandle);
}
}
}
@@ -265,9 +306,23 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
return getLocationOnScreenNonBlocking(storage, component);
}
protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
+
+ private static boolean SetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
+ return OSXUtil.RunOnMainThread(true, new Function<Boolean, Object>() {
+ public Boolean eval(Object... args) {
+ return Boolean.valueOf( SetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer) );
+ } } ).booleanValue();
+ }
+
+ private static boolean UnsetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
+ return OSXUtil.RunOnMainThread(true, new Function<Boolean, Object>() {
+ public Boolean eval(Object... args) {
+ return Boolean.valueOf( UnsetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer) );
+ } } ).booleanValue();
+ }
private static native boolean SetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
- // private static native boolean UnsetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+ private static native boolean UnsetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index f06f97064..aa44e2d64 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -32,6 +32,8 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
+import com.jogamp.common.util.Function;
+import com.jogamp.common.util.FunctionTask;
import com.jogamp.common.util.RunnableTask;
import jogamp.nativewindow.Debug;
@@ -134,26 +136,94 @@ public class OSXUtil implements ToolkitProperties {
return GetNSWindow0(nsView);
}
- public static long CreateCALayer(int x, int y, int width, int height) {
- return CreateCALayer0(x, y, width, height);
+ /**
+ * Create a CALayer suitable to act as a root CALayer on the main-thread.
+ * @see #DestroyCALayer(long)
+ * @see #AddCASublayer(long, long)
+ */
+ public static long CreateCALayer(final int x, final int y, final int width, final int height) {
+ return OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
+ public Long eval(Object... args) {
+ return Long.valueOf( CreateCALayer0(x, y, width, height) );
+ } } ).longValue();
}
- public static void AddCASublayer(long rootCALayer, long subCALayer) {
+
+ /**
+ * Attach a sub CALayer to the root CALayer on the main-thread w/ blocking.
+ * <p>
+ * Method will trigger a <code>display</code>
+ * call to the CALayer hierarchy to enforce resource creation if required, e.g. an NSOpenGLContext.
+ * </p>
+ * <p>
+ * It is mandatory that any related resources, e.g. a shared NSOpenGLContext,
+ * are not locked while calling this method.
+ * </p>
+ * @see #CreateCALayer(int, int, int, int)
+ * @see #RemoveCASublayer(long, long)
+ */
+ public static void AddCASublayer(final long rootCALayer, final long subCALayer) {
if(0==rootCALayer || 0==subCALayer) {
throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
}
- AddCASublayer0(rootCALayer, subCALayer);
+ RunOnMainThread(true, new Runnable() {
+ public void run() {
+ AddCASublayer0(rootCALayer, subCALayer);
+ }
+ });
+ }
+
+ /**
+ * Fix root and sub CALayer position to 0/0 and size on the main-thread w/o blocking.
+ * <p>
+ * If the sub CALayer implements the Objective-C NativeWindow protocol NWDedicatedSize (e.g. JOGL's MyNSOpenGLLayer),
+ * the dedicated size is passed to the layer, which propagates it appropriately.
+ * </p>
+ * <p>
+ * On OSX/Java7 our root CALayer's frame position and size gets corrupted by its NSView,
+ * hence we have created the NWDedicatedSize protocol.
+ * </p>
+ *
+ * @param rootCALayer the root surface layer, maybe null.
+ * @param subCALayer the client surface layer, maybe null.
+ * @param width the expected width
+ * @param height the expected height
+ */
+ public static void FixCALayerLayout(final long rootCALayer, final long subCALayer, final int width, final int height) {
+ if( 0==rootCALayer && 0==subCALayer ) {
+ return;
+ }
+ RunOnMainThread(false, new Runnable() {
+ public void run() {
+ FixCALayerLayout0(rootCALayer, subCALayer, width, height);
+ }
+ });
}
- public static void RemoveCASublayer(long rootCALayer, long subCALayer) {
+
+ /**
+ * Detach a sub CALayer from the root CALayer on the main-thread w/ blocking.
+ */
+ public static void RemoveCASublayer(final long rootCALayer, final long subCALayer) {
if(0==rootCALayer || 0==subCALayer) {
throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
}
- RemoveCASublayer0(rootCALayer, subCALayer);
+ RunOnMainThread(true, new Runnable() {
+ public void run() {
+ RemoveCASublayer0(rootCALayer, subCALayer);
+ } } );
}
- public static void DestroyCALayer(long caLayer) {
+
+ /**
+ * Destroy a CALayer on the main-thread w/ blocking.
+ * @see #CreateCALayer(int, int, int, int)
+ */
+ public static void DestroyCALayer(final long caLayer) {
if(0==caLayer) {
throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
}
- DestroyCALayer0(caLayer);
+ RunOnMainThread(true, new Runnable() {
+ public void run() {
+ DestroyCALayer0(caLayer);
+ } } );
}
/**
@@ -169,14 +239,14 @@ public class OSXUtil implements ToolkitProperties {
if( IsMainThread0() ) {
runnable.run(); // don't leave the JVM
} else {
- if( waitUntilDone ) {
- // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
- // otherwise we may freeze the OSX main thread.
- Throwable throwable = null;
- final Object sync = new Object();
- final RunnableTask rt = new RunnableTask( runnable, sync, true );
- synchronized(sync) {
- RunOnMainThread0(rt);
+ // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
+ // otherwise we may freeze the OSX main thread.
+ Throwable throwable = null;
+ final Object sync = new Object();
+ final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true );
+ synchronized(sync) {
+ RunOnMainThread0(rt);
+ if( waitUntilDone ) {
try {
sync.wait();
} catch (InterruptedException ie) {
@@ -188,10 +258,54 @@ public class OSXUtil implements ToolkitProperties {
if(null!=throwable) {
throw new RuntimeException(throwable);
}
- }
- } else {
- RunOnMainThread0(runnable);
+ }
+ }
+ }
+ }
+
+ private static Runnable _nop = new Runnable() { public void run() {}; };
+
+ /** Issues a {@link #RunOnMainThread(boolean, Runnable)} w/ an <i>NOP</i> runnable, while waiting until done. */
+ public static void WaitUntilFinish() {
+ RunOnMainThread(true, _nop);
+ }
+
+ /**
+ * Run on OSX UI main thread.
+ * <p>
+ * 'waitUntilDone' is implemented on Java site via lock/wait on {@link FunctionTask} to not freeze OSX main thread.
+ * </p>
+ *
+ * @param waitUntilDone
+ * @param func
+ */
+ public static <R,A> R RunOnMainThread(boolean waitUntilDone, Function<R,A> func, A... args) {
+ if( IsMainThread0() ) {
+ return func.eval(args); // don't leave the JVM
+ } else {
+ // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
+ // otherwise we may freeze the OSX main thread.
+ Throwable throwable = null;
+ final Object sync = new Object();
+ final FunctionTask<R,A> rt = new FunctionTask<R,A>( func, waitUntilDone ? sync : null, true );
+ synchronized(sync) {
+ rt.setArgs(args);
+ RunOnMainThread0(rt);
+ if( waitUntilDone ) {
+ try {
+ sync.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rt.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
}
+ return rt.getResult();
}
}
@@ -236,6 +350,7 @@ public class OSXUtil implements ToolkitProperties {
private static native long GetNSWindow0(long nsView);
private static native long CreateCALayer0(int x, int y, int width, int height);
private static native void AddCASublayer0(long rootCALayer, long subCALayer);
+ private static native void FixCALayerLayout0(long rootCALayer, long subCALayer, int width, int height);
private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(Runnable runnable);
diff --git a/src/nativewindow/native/macosx/NativeWindowProtocols.h b/src/nativewindow/native/macosx/NativeWindowProtocols.h
new file mode 100644
index 000000000..b91a50dfd
--- /dev/null
+++ b/src/nativewindow/native/macosx/NativeWindowProtocols.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#import <Foundation/NSGeometry.h>
+
+@protocol NWDedicatedSize
+- (void)setDedicatedSize:(CGSize)size;
+@end
+
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 72bb2338c..c74d6cc58 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -32,13 +32,14 @@
#include <stdarg.h>
#include <unistd.h>
#include <AppKit/AppKit.h>
+#import <QuartzCore/QuartzCore.h>
+#import "NativeWindowProtocols.h"
#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
//
@@ -49,6 +50,16 @@
#define DBG_PRINT(...)
#endif
+// #define VERBOSE2 1
+//
+#ifdef VERBOSE2
+ #define DBG_PRINT2(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT2(...)
+#endif
+
+// #define DBG_LIFECYCLE 1
+
static const char * const ClazzNameRunnable = "java/lang/Runnable";
static jmethodID runnableRunID = NULL;
@@ -313,6 +324,71 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
return res;
}
+/**
+ * Track lifecycle via DBG_PRINT messages, if VERBOSE is enabled!
+ */
+@interface MyCALayer: CALayer
+{
+}
+- (id)init;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+- (void)dealloc;
+#endif
+- (id<CAAction>)actionForKey:(NSString *)key ;
+
+@end
+
+@implementation MyCALayer
+
+- (id)init
+{
+ DBG_PRINT("MyCALayer.0\n");
+ MyCALayer * o = [super init];
+ DBG_PRINT("MyNSOpenGLContext.init.X: new %p\n", o);
+ DBG_PRINT("MyCALayer.0\n");
+ return o;
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyCALayer::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyCALayer::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyCALayer::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::release: %@",[NSThread callStackSymbols]);
+ [super release];
+ // DBG_PRINT("MyCALayer::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyCALayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::dealloc: %@",[NSThread callStackSymbols]);
+ [super dealloc];
+ // DBG_PRINT("MyCALayer.dealloc.X: %p\n", self);
+}
+
+#endif
+
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ DBG_PRINT("MyCALayer::actionForKey.0 %p key %s -> NIL\n", self, [key UTF8String]);
+ return nil;
+ // return [super actionForKey: key];
+}
+
+@end
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: CreateCALayer0
@@ -323,8 +399,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- CALayer* layer = [[CALayer alloc] init];
- DBG_PRINT("CALayer::CreateCALayer.0: %p %d/%d %dx%d (refcnt %d)\n", layer, (int)x, (int)y, (int)width, (int)height, (int)[layer retainCount]);
+ MyCALayer* layer = [[MyCALayer alloc] init];
+ DBG_PRINT("CALayer::CreateCALayer.0: root %p %d/%d %dx%d (refcnt %d)\n", layer, (int)x, (int)y, (int)width, (int)height, (int)[layer retainCount]);
// avoid zero size
if(0 == width) { width = 32; }
if(0 == height) { height = 32; }
@@ -339,12 +415,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[layer removeAllAnimations];
+ // [layer addAnimation:nil forKey:kCATransition];
[layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[layer setNeedsDisplayOnBoundsChange: YES];
- DBG_PRINT("CALayer::CreateCALayer.1: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
- DBG_PRINT("CALayer::CreateCALayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
-
+ DBG_PRINT("CALayer::CreateCALayer.1: root %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
[pool release];
+ DBG_PRINT("CALayer::CreateCALayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
return (jlong) ((intptr_t) layer);
}
@@ -357,41 +433,105 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer);
CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+ [subLayer retain]; // Pairs w/ RemoveCASublayer
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
CGRect lRectRoot = [rootLayer frame];
- DBG_PRINT("CALayer::AddCASublayer0.0: Origin %p frame0: %lf/%lf %lfx%lf\n",
+ DBG_PRINT("CALayer::AddCASublayer0.0: Origin %p frame0: %lf/%lf %lfx%lf\n",
rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
if(lRectRoot.origin.x!=0 || lRectRoot.origin.y!=0) {
lRectRoot.origin.x = 0;
lRectRoot.origin.y = 0;
- [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
- [rootLayer setFrame: lRectRoot];
- }];
+ [rootLayer setFrame: lRectRoot];
DBG_PRINT("CALayer::AddCASublayer0.1: Origin %p frame*: %lf/%lf %lfx%lf\n",
rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
}
- DBG_PRINT("CALayer::AddCASublayer0.2: %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:^(){
- // simple 1:1 layout !
- [subLayer setFrame:lRectRoot];
- [rootLayer addSublayer:subLayer];
-
- // no animations for add/remove/swap sublayers etc
- // doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
- [rootLayer removeAllAnimations];
- [rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
- [rootLayer setNeedsDisplayOnBoundsChange: YES];
- [subLayer removeAllAnimations];
- [subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
- [subLayer setNeedsDisplayOnBoundsChange: YES];
- }];
- DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
- JNF_COCOA_EXIT(env);
+ DBG_PRINT("CALayer::AddCASublayer0.2: root %p (refcnt %d) .sub %p %lf/%lf %lfx%lf (refcnt %d)\n",
+ rootLayer, (int)[rootLayer retainCount],
+ subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]);
+
+ // simple 1:1 layout !
+ [subLayer setFrame:lRectRoot];
+ [rootLayer addSublayer:subLayer];
+
+ // no animations for add/remove/swap sublayers etc
+ // doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
+ [rootLayer removeAllAnimations];
+ // [rootLayer addAnimation:nil forKey:kCATransition]; // JAU
+ [rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [rootLayer setNeedsDisplayOnBoundsChange: YES];
+ [subLayer removeAllAnimations];
+ // [subLayer addAnimation:nil forKey:kCATransition]; // JAU
+ [subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [subLayer setNeedsDisplayOnBoundsChange: YES];
+
+ // Trigger display and hence ctx creation.
+ // The latter is essential since since the parent-context lock is cleared
+ // only for this window of time (method call).
+ [rootLayer setNeedsDisplay];
+ [rootLayer displayIfNeeded];
+
+ [CATransaction commit];
+
+ [pool release];
+ DBG_PRINT("CALayer::AddCASublayer0.X: root %p (refcnt %d) .sub %p (refcnt %d)\n",
+ rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: FixCALayerLayout0
+ * Signature: (JJII)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_FixCALayerLayout0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ if( NULL != rootLayer ) {
+ CGRect lRect = [rootLayer frame];
+ if(lRect.origin.x!=0 || lRect.origin.y!=0 || lRect.size.width!=width || lRect.size.height!=height) {
+ DBG_PRINT("CALayer::FixCALayerLayout0.0: Root %p exp 0/0 %dx%d -> frame0: %lf/%lf %lfx%lf\n",
+ rootLayer, (int)width, (int)height, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = width;
+ lRect.size.height = height;
+ [rootLayer setFrame: lRect];
+ }
+ }
+ if( NULL != subLayer ) {
+ CGRect lRect = [subLayer frame];
+ if(lRect.origin.x!=0 || lRect.origin.y!=0 || lRect.size.width!=width || lRect.size.height!=height) {
+ DBG_PRINT("CALayer::FixCALayerLayout0.0: SubL %p exp 0/0 %dx%d -> frame0: %lf/%lf %lfx%lf\n",
+ subLayer, (int)width, (int)height, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = width;
+ lRect.size.height = height;
+ if( [subLayer conformsToProtocol:@protocol(NWDedicatedSize)] ) {
+ CALayer <NWDedicatedSize> * subLayerDS = (CALayer <NWDedicatedSize> *) subLayer;
+ [subLayerDS setDedicatedSize: lRect.size];
+ } else {
+ [subLayer setFrame: lRect];
+ }
+ }
+ }
+
+ [CATransaction commit];
+
+ [pool release];
}
/*
@@ -402,18 +542,26 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* rootLayer = (MyCALayer*) ((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\n", rootLayer, subLayer);
- JNF_COCOA_EXIT(env);
+ DBG_PRINT("CALayer::RemoveCASublayer0.0: root %p (refcnt %d) .sub %p (refcnt %d)\n",
+ rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ [subLayer removeFromSuperlayer];
+ [subLayer release]; // Pairs w/ AddCASublayer
+
+ [CATransaction commit];
+
+ [pool release];
+ DBG_PRINT("CALayer::RemoveCASublayer0.X: root %p (refcnt %d) .sub %p (refcnt %d)\n",
+ rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
}
/*
@@ -424,15 +572,13 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* layer = (MyCALayer*) ((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\n", layer);
- JNF_COCOA_EXIT(env);
+ DBG_PRINT("CALayer::DestroyCALayer0.0: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ [layer release]; // Trigger release of root CALayer
+ [pool release];
+ DBG_PRINT("CALayer::DestroyCALayer0.X: root %p\n", layer);
}
/*
@@ -443,20 +589,18 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
- JNF_COCOA_ENTER(env);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
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::SetJAWTRootSurfaceLayer.0: %p -> %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
- surfaceLayers.layer = layer; // already incr. retain count
- DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
- }];
- JNF_COCOA_EXIT(env);
+ MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: pre %p -> root %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
+ surfaceLayers.layer = [layer retain]; // Pairs w/ Unset
+ [pool release];
+ DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
return JNI_TRUE;
}
@@ -464,33 +608,29 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
* Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
* Method: UnsetJAWTRootSurfaceLayer0
* Signature: (JJ)Z
+ */
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
- JNF_COCOA_ENTER(env);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
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;
- {
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- if(layer != surfaceLayers.layer) {
- NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
- return JNI_FALSE;
- }
+ MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ if(layer != surfaceLayers.layer) {
+ NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
+ return JNI_FALSE;
}
- // [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- DBG_PRINT("CALayer::detachJAWTSurfaceLayer: (%p) %p -> NULL\n", layer, surfaceLayers.layer);
- surfaceLayers.layer = NULL;
- [layer release];
- // }];
- JNF_COCOA_EXIT(env);
+ DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.0: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
+ [layer release]; // Pairs w/ Set
+ surfaceLayers.layer = NULL;
+ [pool release];
+ DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.X: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
return JNI_TRUE;
}
- */
@interface MainRunnable : NSObject
@@ -503,6 +643,13 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers;
- (void) jRun;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+- (void)dealloc;
+#endif
+
+
@end
@implementation MainRunnable
@@ -519,20 +666,47 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
{
int shallBeDetached = 0;
JNIEnv* env = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
- DBG_PRINT("MainRunnable.0 env: %d\n", (int)(NULL!=env));
+ DBG_PRINT2("MainRunnable.1 env: %d\n", (int)(NULL!=env));
if(NULL!=env) {
- DBG_PRINT("MainRunnable.1.0\n");
+ DBG_PRINT2("MainRunnable.1.0\n");
(*env)->CallVoidMethod(env, runnableObj, runnableRunID);
- DBG_PRINT("MainRunnable.1.1\n");
+ DBG_PRINT2("MainRunnable.1.1\n");
+ (*env)->DeleteGlobalRef(env, runnableObj);
if (shallBeDetached) {
- DBG_PRINT("MainRunnable.1.2\n");
+ DBG_PRINT2("MainRunnable.1.3\n");
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
}
- DBG_PRINT("MainRunnable.X\n");
+ DBG_PRINT2("MainRunnable.X\n");
}
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT2("MainRunnable::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ id o = [super retain];
+ DBG_PRINT2("MainRunnable::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT2("MainRunnable::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super release];
+ // DBG_PRINT2("MainRunnable::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT2("MainRunnable::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super dealloc];
+ // DBG_PRINT2("MainRunnable.dealloc.X: %p\n", self);
+}
+
+#endif
+
@end
@@ -546,11 +720,11 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- DBG_PRINT( "RunOnMainThread0: isMainThread %d, NSApp %d, NSApp-isRunning %d\n",
+ DBG_PRINT2( "RunOnMainThread0: isMainThread %d, NSApp %d, NSApp-isRunning %d\n",
(int)([NSThread isMainThread]), (int)(NULL!=NSApp), (int)([NSApp isRunning]));
if ( NO == [NSThread isMainThread] ) {
- jobject runnableGlob = (*env)->NewGlobalRef(env, runnable);
+ jobject runnableObj = (*env)->NewGlobalRef(env, runnable);
JavaVM *jvmHandle = NULL;
int jvmVersion = 0;
@@ -561,18 +735,18 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
jvmVersion = (*env)->GetVersion(env);
}
- DBG_PRINT( "RunOnMainThread0.1.0\n");
- MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableGlob jvmHandle: jvmHandle jvmVersion: jvmVersion];
+ DBG_PRINT2( "RunOnMainThread0.1.0\n");
+ MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj jvmHandle: jvmHandle jvmVersion: jvmVersion];
[mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:NO];
+ DBG_PRINT2( "RunOnMainThread0.1.1\n");
[mr release];
- DBG_PRINT( "RunOnMainThread0.1.1\n");
+ DBG_PRINT2( "RunOnMainThread0.1.2\n");
- (*env)->DeleteGlobalRef(env, runnableGlob);
} else {
- DBG_PRINT( "RunOnMainThread0.2\n");
+ DBG_PRINT2( "RunOnMainThread0.2\n");
(*env)->CallVoidMethod(env, runnable, runnableRunID);
}
- DBG_PRINT( "RunOnMainThread0.X\n");
+ DBG_PRINT2( "RunOnMainThread0.X\n");
[pool release];
}
@@ -625,8 +799,7 @@ JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshR
(JNIEnv *env, jclass unused, jint scrn_idx)
{
int res = 0;
- JNF_COCOA_ENTER(env);
- // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
DBG_PRINT("GetScreenRefreshRate.0: screen %p\n", (void *)screen);
if(NULL != screen) {
@@ -644,9 +817,8 @@ JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshR
if(0 == res) {
res = 60; // default .. (experienced on OSX 10.6.8)
}
- DBG_PRINT(stderr, "GetScreenRefreshRate.X: %d\n", (int)res);
- // [pool release];
- JNF_COCOA_EXIT(env);
+ DBG_PRINT("GetScreenRefreshRate.X: %d\n", (int)res);
+ [pool release];
return res;
}
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index cc42465f1..ab1eef308 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -28,12 +28,15 @@
package com.jogamp.newt;
+import com.jogamp.newt.event.WindowEvent;
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 jogamp.newt.WindowImpl;
+
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
@@ -104,14 +107,26 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
CapabilitiesImmutable getChosenCapabilities();
/**
- * Destroy the Window and it's children, incl. native destruction.<br>
- * The Window can be recreate via {@link #setVisible(boolean) setVisible(true)}.
- * <p>Visibility is set to false.</p>
+ * {@inheritDoc}
+ * <p>
+ * Also iterates through this window's children and destroys them.
+ * </p>
+ * <p>
+ * Visibility is set to false.
+ * </p>
+ * <p>
+ * Method sends out {@link WindowEvent#EVENT_WINDOW_DESTROY_NOTIFY pre-} and
+ * {@link WindowEvent#EVENT_WINDOW_DESTROYED post-} destruction events
+ * to all of it's {@link WindowListener}.
+ * </p>
* <p>
* This method invokes {@link Screen#removeReference()} after it's own destruction,<br>
* which will issue {@link Screen#destroy()} if the reference count becomes 0.<br>
* This destruction sequence shall end up in {@link Display#destroy()}, if all reference counts become 0.
* </p>
+ * <p>
+ * The Window can be recreate via {@link #setVisible(boolean) setVisible(true)}.
+ * </p>
* @see #destroy()
* @see #setVisible(boolean)
*/
@@ -119,6 +134,16 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
void destroy();
/**
+ * Set a custom action handling destruction issued by a {@link WindowImpl#windowDestroyNotify(boolean) toolkit triggered window destroy}
+ * replacing the default {@link #destroy()} action.
+ * <p>
+ * The custom action shall call {@link #destroy()}
+ * but may perform further tasks before and after.
+ * </p>
+ */
+ void setWindowDestroyNotifyAction(Runnable r);
+
+ /**
* <code>setVisible</code> makes the window and children visible if <code>visible</code> is true,
* otherwise the window and children becomes invisible.
* <p>
@@ -383,10 +408,13 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
// WindowListener
//
+ /**
+ * Send a {@link WindowEvent} to all {@link WindowListener}.
+ * @param eventType a {@link WindowEvent} type, e.g. {@link WindowEvent#EVENT_WINDOW_REPAINT}.
+ */
public void sendWindowEvent(int eventType);
/**
- *
* Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
* the list.
*/
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 89a749c51..3c10859bf 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -34,6 +34,7 @@ import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
+import java.beans.Beans;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Method;
@@ -50,6 +51,7 @@ import javax.swing.MenuSelectionManager;
import jogamp.nativewindow.awt.AWTMisc;
import jogamp.newt.Debug;
+import jogamp.newt.WindowImpl;
import jogamp.newt.awt.NewtFactoryAWT;
import jogamp.newt.awt.event.AWTParentWindowAdapter;
import jogamp.newt.driver.DriverClearFocus;
@@ -58,9 +60,9 @@ import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.nativewindow.awt.JAWTWindow;
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.NEWTEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
@@ -84,18 +86,25 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private JAWTWindow jawtWindow = null;
private boolean shallUseOffscreenLayer = false;
private Window newtChild = null;
+ private boolean newtChildAttached = false;
private boolean isOnscreen = true;
private WindowClosingMode newtChildCloseOp;
- private AWTAdapter awtAdapter = null;
+ private AWTParentWindowAdapter awtAdapter = null;
private AWTAdapter awtMouseAdapter = null;
private AWTAdapter awtKeyAdapter = null;
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
public void run() {
- NewtCanvasAWT.this.destroy();
+ NewtCanvasAWT.this.destroyImpl(false /* removeNotify */, true /* windowClosing */);
}
- });
+ }, new Runnable() {
+ public void run() {
+ if( newtChild != null ) {
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+ }
+ }
+ } );
/**
* Instantiates a NewtCanvas without a NEWT child.<br>
@@ -181,6 +190,10 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() {
@Override
+ public void windowResized(WindowEvent e) {
+ updateLayoutSize();
+ }
+ @Override
public void windowGainedFocus(WindowEvent arg0) {
if( isParent() && !isFullscreen() ) {
MenuSelectionManager.defaultManager().clearSelectedPath();
@@ -203,7 +216,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
public void keyTyped(KeyEvent e) {
if(suppress) {
- e.setAttachment(InputEvent.consumedTag);
+ e.setAttachment(NEWTEvent.consumedTag);
suppress = false; // reset
}
}
@@ -233,7 +246,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
if(suppress) {
- evt.setAttachment(InputEvent.consumedTag);
+ evt.setAttachment(NEWTEvent.consumedTag);
}
if(DEBUG) {
System.err.println("NewtCanvasAWT.focusKey: XXX: "+ks);
@@ -292,16 +305,26 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
final java.awt.Container cont = AWTMisc.getContainer(this);
// remove old one
if(null != newtChild) {
- reparentWindow( false, cont );
+ detachNewtChild( cont );
newtChild = null;
}
// add new one, reparent only if ready
newtChild = newChild;
- if( isDisplayable() && null != newChild) {
- reparentWindow( true, cont );
- }
+
+ updateLayoutSize();
+ // will be done later at paint/display/..: attachNewtChild(cont);
+
return prevChild;
}
+
+ private final void updateLayoutSize() {
+ if( null != newtChild ) {
+ // use NEWT child's size for min/pref size!
+ java.awt.Dimension minSize = new java.awt.Dimension(newtChild.getWidth(), newtChild.getHeight());
+ setMinimumSize(minSize);
+ setPreferredSize(minSize);
+ }
+ }
/** @return the current NEWT child */
public Window getNEWTChild() {
@@ -320,149 +343,44 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
return awtWindowClosingProtocol.setDefaultCloseOperation(op);
}
- /* package */ void configureNewtChild(boolean attach) {
- if(null!=awtAdapter) {
- awtAdapter.removeFrom(this);
- awtAdapter=null;
- }
- if(null!=awtMouseAdapter) {
- awtMouseAdapter.removeFrom(this);
- awtMouseAdapter = null;
- }
- if(null!=awtKeyAdapter) {
- awtKeyAdapter.removeFrom(this);
- awtKeyAdapter = null;
- }
- if(null != keyboardFocusManager) {
- keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
- keyboardFocusManager = null;
- }
-
- if( null != newtChild ) {
- newtChild.setKeyboardFocusHandler(null);
- if(attach) {
- if(null == jawtWindow.getGraphicsConfiguration()) {
- throw new InternalError("XXX");
- }
- isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
- awtAdapter = new AWTParentWindowAdapter(jawtWindow, newtChild).addTo(this);
- newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
- newtChild.setFocusAction(focusAction); // enable AWT focus traversal
- newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingMode.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);
- newtChild.setDefaultCloseOperation(newtChildCloseOp);
- awtWindowClosingProtocol.removeClosingListener();
- }
- }
- }
-
@Override
public void addNotify() {
-
- // before native peer is valid: X11
- disableBackgroundErase();
-
- // creates the native peer
- super.addNotify();
-
- // after native peer is valid: Windows
- disableBackgroundErase();
-
- java.awt.Container cont = AWTMisc.getContainer(this);
- if(DEBUG) {
- // if ( isShowing() == false ) -> Container was not visible yet.
- // if ( isShowing() == true ) -> Container is already visible.
- System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+
- ", displayable "+isDisplayable()+" -> "+cont);
+ if( Beans.isDesignTime() ) {
+ super.addNotify();
+ } else {
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
+ // creates the native peer
+ super.addNotify();
+
+ // after native peer is valid: Windows
+ disableBackgroundErase();
+
+ jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+
+ if(DEBUG) {
+ // if ( isShowing() == false ) -> Container was not visible yet.
+ // if ( isShowing() == true ) -> Container is already visible.
+ System.err.println("NewtCanvasAWT.addNotify: win "+newtWinHandleToHexString(newtChild)+
+ ", comp "+this+", visible "+isVisible()+", showing "+isShowing()+
+ ", displayable "+isDisplayable()+", cont "+AWTMisc.getContainer(this));
+ }
}
- reparentWindow(true, cont);
+ awtWindowClosingProtocol.addClosingListener();
}
@Override
public void removeNotify() {
- java.awt.Container cont = AWTMisc.getContainer(this);
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont);
- }
- final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(newtChild, true);
- if(null != ols && ols.isSurfaceLayerAttached()) {
- ols.detachSurfaceLayer();
- }
- reparentWindow(false, cont);
+ awtWindowClosingProtocol.removeClosingListener();
- if(null != jawtWindow) {
- NewtFactoryAWT.destroyNativeWindow(jawtWindow);
- jawtWindow=null;
+ if( Beans.isDesignTime() ) {
+ super.removeNotify();
+ } else {
+ destroyImpl(true /* removeNotify */, false /* windowClosing */);
+ super.removeNotify();
}
-
- super.removeNotify();
- }
-
- void reparentWindow(boolean add, java.awt.Container cont) {
- if(null==newtChild) {
- return; // nop
- }
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
- }
-
- newtChild.setFocusAction(null); // no AWT focus traversal ..
- if(add) {
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.reparentWindow: newtChild: "+newtChild);
- }
- if(null == jawtWindow) {
- jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
- jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
- }
- 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
-
- // force this AWT Canvas to be focus-able,
- // since this it is completely covered by the newtChild (z-order).
- setFocusable(true);
- } else {
- configureNewtChild(false);
- newtChild.setVisible(false);
- newtChild.reparentWindow(null);
- }
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
- }
}
/**
@@ -472,46 +390,68 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
* <li> Disconnects the NEWT Child from this Canvas NativeWindow, reparent to NULL </li>
* <li> Issues <code>destroy()</code> on the NEWT Child</li>
* <li> Remove reference to the NEWT Child</li>
- * <li> Remove this Canvas from it's parent.</li>
* </ul>
* @see Window#destroy()
*/
public final void destroy() {
- if(null!=newtChild) {
+ destroyImpl(false /* removeNotify */, false /* windowClosing */);
+ }
+
+ private final void destroyImpl(boolean removeNotify, boolean windowClosing) {
+ if( null !=newtChild ) {
java.awt.Container cont = AWTMisc.getContainer(this);
if(DEBUG) {
- System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont);
- }
- configureNewtChild(false);
- if(null!=jawtWindow) {
- NewtFactoryAWT.destroyNativeWindow(jawtWindow);
- jawtWindow=null;
- }
- newtChild.setVisible(false);
- newtChild.reparentWindow(null);
- newtChild.destroy();
- newtChild=null;
- if(null!=cont) {
- cont.remove(this);
+ System.err.println("NewtCanvasAWT.destroy(removeNotify "+removeNotify+", windowClosing "+windowClosing+"): nw "+newtWinHandleToHexString(newtChild)+", from "+cont);
}
+ detachNewtChild(cont);
+
+ if( !removeNotify ) {
+ final Window cWin = newtChild;
+ final Window dWin = cWin.getDelegatedWindow();
+ newtChild=null;
+ if( windowClosing && dWin instanceof WindowImpl ) {
+ ((WindowImpl)dWin).windowDestroyNotify(true);
+ } else {
+ cWin.destroy();
+ }
+ }
}
- }
-
+ if( ( removeNotify || windowClosing ) && null!=jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
+ }
+
@Override
public void paint(Graphics g) {
- awtWindowClosingProtocol.addClosingListenerOneShot();
- if(null!=newtChild) {
+ if( validateComponent(true, null) ) {
newtChild.windowRepaint(0, 0, getWidth(), getHeight());
}
}
@Override
public void update(Graphics g) {
- awtWindowClosingProtocol.addClosingListenerOneShot();
- if(null!=newtChild) {
+ if( validateComponent(true, null) ) {
newtChild.windowRepaint(0, 0, getWidth(), getHeight());
}
}
+ @SuppressWarnings("deprecation")
+ @Override
+ public void reshape(int x, int y, int width, int height) {
+ synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape
+ super.reshape(x, y, width, height);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reshape: "+x+"/"+y+" "+width+"x"+height);
+ }
+ if( validateComponent(true, null) ) {
+ // newtChild.setSize(width, height);
+ if(null != jawtWindow && jawtWindow.isOffscreenLayerSurfaceEnabled() ) {
+ jawtWindow.layoutSurfaceLayer();
+ }
+ }
+ }
+ }
+
private final void requestFocusNEWTChild() {
if(null!=newtChild) {
newtChild.setFocusAction(null);
@@ -556,6 +496,140 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
return res;
}
+ private final boolean validateComponent(boolean attachNewtChild, java.awt.Container cont) {
+ if( Beans.isDesignTime() || !isDisplayable() ) {
+ return false;
+ }
+ if ( null == newtChild || null == jawtWindow ) {
+ return false;
+ }
+ if( null == cont ) {
+ cont = AWTMisc.getContainer(this);
+ }
+ if( 0 >= getWidth() || 0 >= getHeight() ) {
+ return false;
+ }
+
+ if( attachNewtChild && !newtChildAttached && null != newtChild ) {
+ attachNewtChild(cont);
+ }
+
+ return true;
+ }
+
+ private final void configureNewtChild(boolean attach) {
+ if(null!=awtAdapter) {
+ awtAdapter.removeFrom(this);
+ awtAdapter=null;
+ }
+ if(null!=awtMouseAdapter) {
+ awtMouseAdapter.removeFrom(this);
+ awtMouseAdapter = null;
+ }
+ if(null!=awtKeyAdapter) {
+ awtKeyAdapter.removeFrom(this);
+ awtKeyAdapter = null;
+ }
+ if(null != keyboardFocusManager) {
+ keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ keyboardFocusManager = null;
+ }
+
+ if( null != newtChild ) {
+ newtChild.setKeyboardFocusHandler(null);
+ if(attach) {
+ if(null == jawtWindow.getGraphicsConfiguration()) {
+ throw new InternalError("XXX");
+ }
+ isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ awtAdapter = (AWTParentWindowAdapter) new AWTParentWindowAdapter(jawtWindow, newtChild).addTo(this);
+ awtAdapter.removeWindowClosingFrom(this); // we utilize AWTWindowClosingProtocol triggered destruction!
+ newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
+ newtChild.setFocusAction(focusAction); // enable AWT focus traversal
+ newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
+ 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);
+ newtChild.setDefaultCloseOperation(newtChildCloseOp);
+ }
+ }
+ }
+
+ private final void attachNewtChild(java.awt.Container cont) {
+ if( null == newtChild || null == jawtWindow || newtChildAttached ) {
+ return; // nop
+ }
+ if(DEBUG) {
+ // if ( isShowing() == false ) -> Container was not visible yet.
+ // if ( isShowing() == true ) -> Container is already visible.
+ System.err.println("NewtCanvasAWT.attachNewtChild.0: win "+newtWinHandleToHexString(newtChild)+
+ ", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+
+ ", comp "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()+
+ ", cont "+cont);
+ }
+
+ newtChildAttached = true;
+ newtChild.setFocusAction(null); // no AWT focus traversal ..
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.attachNewtChild.1: newtChild: "+newtChild);
+ }
+ final int w = getWidth();
+ final int h = getHeight();
+ System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+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
+
+ // force this AWT Canvas to be focus-able,
+ // since this it is completely covered by the newtChild (z-order).
+ setFocusable(true);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.attachNewtChild.X: win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+", comp "+this);
+ }
+ }
+
+ private final void detachNewtChild(java.awt.Container cont) {
+ if( null == newtChild || null == jawtWindow || !newtChildAttached ) {
+ return; // nop
+ }
+ if(DEBUG) {
+ // if ( isShowing() == false ) -> Container was not visible yet.
+ // if ( isShowing() == true ) -> Container is already visible.
+ System.err.println("NewtCanvasAWT.detachNewtChild.0: win "+newtWinHandleToHexString(newtChild)+
+ ", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+
+ ", comp "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()+
+ ", cont "+cont);
+ }
+
+ newtChildAttached = false;
+ newtChild.setFocusAction(null); // no AWT focus traversal ..
+ configureNewtChild(false);
+ newtChild.setVisible(false);
+
+ // Detach OLS early..
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(newtChild, true);
+ if(null != ols && ols.isSurfaceLayerAttached()) {
+ ols.detachSurfaceLayer();
+ }
+ newtChild.reparentWindow(null); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer (if still attached)
+
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.detachNewtChild.X: win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+", comp "+this);
+ }
+ }
+
// Disables the AWT's erasing of this Canvas's background on Windows
// in Java SE 6. This internal API is not available in previous
// releases, but the system property
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 07004503e..c3ad51c96 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
@@ -300,9 +300,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
glWindow.reparentWindow(awtParent);
} else {
glWindow.reparentWindow(null);
- if(glClosable) {
- glWindow.setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE);
- }
+ glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE );
}
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index ad77ec79f..4920b59ea 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -81,12 +81,7 @@ public abstract class InputEvent extends NEWTEvent
return 0;
}
- /** 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) {
+ protected InputEvent(short eventType, Object source, long when, int modifiers) {
super(eventType, source, when);
this.modifiers=modifiers;
}
@@ -154,16 +149,16 @@ public abstract class InputEvent extends NEWTEvent
* @return Array of pressed mouse buttons [{@link MouseEvent#BUTTON1} .. {@link MouseEvent#BUTTON6}].
* If none is down, the resulting array is of length 0.
*/
- public final int[] getButtonsDown() {
+ public final short[] getButtonsDown() {
int len = 0;
for(int i=1; i<=MouseEvent.BUTTON_NUMBER; i++) {
- if(isButtonDown(i)) { len++; }
+ if( isButtonDown(i) ) { len++; }
}
- int[] res = new int[len];
+ short[] res = new short[len];
int j = 0;
for(int i=1; i<=MouseEvent.BUTTON_NUMBER; i++) {
- if(isButtonDown(i)) { res[j++] = ( MouseEvent.BUTTON1 - 1 ) + i; }
+ if( isButtonDown(i) ) { res[j++] = (short) ( ( MouseEvent.BUTTON1 - 1 ) + i ); }
}
return res;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index ff67b7f57..f626fec38 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -36,68 +36,123 @@ package com.jogamp.newt.event;
/**
* Key events are delivered in the following order:
- * <ol>
- * <li>{@link #EVENT_KEY_PRESSED}</li>
- * <li>{@link #EVENT_KEY_RELEASED}</li>
- * <li>{@link #EVENT_KEY_TYPED}</li>
- * </ol>
+ * <p>
+ * <table border="0">
+ * <tr><th>#</th><th>Event Type</th> <th>Constraints</th> <th>Notes</th></tr>
+ * <tr><td>1</td><td>{@link #EVENT_KEY_PRESSED} </td><td> <i> excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys</i></td><td></td></tr>
+ * <tr><td>2</td><td>{@link #EVENT_KEY_RELEASED} </td><td> <i> excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys</i></td><td></td></tr>
+ * <tr><td>3</td><td>{@link #EVENT_KEY_TYPED} </td><td> <i>only for {@link #isPrintableKey() printable} and non {@link #isAutoRepeat() auto-repeat} keys</i></td><td><b>Deprecated</b>: Use {@link #EVENT_KEY_RELEASED} and apply constraints.</td></tr>
+ * </table>
+ * </p>
* In case the native platform does not
* deliver keyboard events in the above order or skip events,
* the NEWT driver will reorder and inject synthetic events if required.
* <p>
* Besides regular modifiers like {@link InputEvent#SHIFT_MASK} etc.,
- * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected.
+ * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected, following above constraints.
* </p>
* <p>
* Auto-Repeat shall behave as follow:
* <pre>
- D = pressed, U = released, T = typed
+ P = pressed, R = released, T = typed
0 = normal, 1 = auto-repeat
- D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ P(0), [ R(1), P(1), R(1), ..], R(0) T(0)
* </pre>
* The idea is if you mask out auto-repeat in your event listener
- * you just get one long pressed key D/U/T triple.
+ * or catch {@link #EVENT_KEY_TYPED typed} events only,
+ * you just get one long pressed P/R/T triple for {@link #isPrintableKey() printable} keys.
+ * {@link #isActionKey() Action} keys would produce one long pressed P/R tuple in case you mask out auto-repeat .
+ * </p>
+ * <p>
+ * {@link #isActionKey() Action} keys will produce {@link #EVENT_KEY_PRESSED pressed}
+ * and {@link #EVENT_KEY_RELEASED released} events including {@link #isAutoRepeat() auto-repeat}.
+ * </p>
+ * <p>
+ * {@link #isPrintableKey() Printable} keys will produce {@link #EVENT_KEY_PRESSED pressed},
+ * {@link #EVENT_KEY_RELEASED released} and {@link #EVENT_KEY_TYPED typed} events, the latter is excluded for {@link #isAutoRepeat() auto-repeat} events.
* </p>
* <p>
- * {@link #isModifierKey() Modifiers keys} will produce regular events (pressed, released and typed),
- * however they will not produce Auto-Repeat events itself.
+ * {@link #isModifierKey() Modifier} keys will produce {@link #EVENT_KEY_PRESSED pressed}
+ * and {@link #EVENT_KEY_RELEASED released} events excluding {@link #isAutoRepeat() auto-repeat}.
+ * They will also influence subsequent event's {@link #getModifiers() modifier} bits while pressed.
* </p>
*/
@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
{
- public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
+ public KeyEvent(short eventType, Object source, long when, int modifiers, short keyCode, short keySym, char keyChar) {
super(eventType, source, when, modifiers);
this.keyCode=keyCode;
+ this.keySym=keySym;
this.keyChar=keyChar;
+ { // cache modifier and action flags
+ byte _flags = 0;
+ if( isModifierKey(keySym) ) {
+ _flags |= F_MODIFIER_MASK;
+ }
+ if( isActionKey(keySym) ) {
+ _flags |= F_ACTION_MASK;
+ }
+ flags = _flags;
+ }
}
/**
- * Returns the character matching the {@link #getKeyCode() virtual key code}.
+ * Returns the <i>UTF-16</i> character reflecting the {@link #getKeySymbol() key symbol}.
+ * @see #getKeySymbol()
+ * @see #getKeyCode()
*/
- public char getKeyChar() {
+ public final char getKeyChar() {
return keyChar;
}
- /** Returns the virtual key code. */
- public int getKeyCode() {
+ /**
+ * Returns the virtual <i>key symbol</i> reflecting the current <i>keyboard layout</i>.
+ * @see #getKeyChar()
+ * @see #getKeyCode()
+ */
+ public final short getKeySymbol() {
+ return keySym;
+ }
+
+ /**
+ * Returns the virtual <i>key code</i> using a fixed mapping to the <i>US keyboard layout</i>.
+ * <p>
+ * In contrast to {@link #getKeySymbol() key symbol}, <i>key code</i>
+ * uses a fixed <i>US keyboard layout</i> and therefore is keyboard layout independent.
+ * </p>
+ * <p>
+ * E.g. <i>virtual key code</i> {@link #VK_Y} denotes the same physical key
+ * regardless whether <i>keyboard layout</i> <code>QWERTY</code> or
+ * <code>QWERTZ</code> is active. The {@link #getKeySymbol() key symbol} of the former is
+ * {@link #VK_Y}, where the latter produces {@link #VK_Y}.
+ * </p>
+ * <p>
+ * <b>Disclaimer</b>: In case <i>key code</i> is not implemented on your platform (OSX, ..)
+ * the {@link #getKeySymbol() key symbol} is returned.
+ * </p>
+ * @see #getKeyChar()
+ * @see #getKeySymbol()
+ */
+ public final short getKeyCode() {
return keyCode;
}
- public String toString() {
+ public final String toString() {
return toString(null).toString();
}
- public StringBuilder toString(StringBuilder sb) {
+ public final StringBuilder toString(StringBuilder sb) {
if(null == sb) {
sb = new StringBuilder();
}
- sb.append("KeyEvent[").append(getEventTypeString(getEventType())).append(", code ").append(keyCode).append("(").append(toHexString(keyCode)).append("), char '").append(keyChar).append("' (").append(toHexString((int)keyChar)).append("), isActionKey ").append(isActionKey()).append(", ");
+ sb.append("KeyEvent[").append(getEventTypeString(getEventType())).append(", code ").append(toHexString(keyCode)).append(", sym ").append(toHexString(keySym)).append(", char '").append(keyChar).append("' (").append(toHexString((short)keyChar))
+ .append("), isModifierKey ").append(isModifierKey()).append(", isActionKey ").append(isActionKey()).append(", ");
return super.toString(sb).append("]");
}
- public static String getEventTypeString(int type) {
+ public static String getEventTypeString(short type) {
switch(type) {
case EVENT_KEY_PRESSED: return "EVENT_KEY_PRESSED";
case EVENT_KEY_RELEASED: return "EVENT_KEY_RELEASED";
@@ -107,13 +162,13 @@ public class KeyEvent extends InputEvent
}
/**
- * Returns true if the given <code>keyCode</code> represents a non-printable modifier key.
+ * Returns <code>true</code> if the given <code>virtualKey</code> represents a modifier key, otherwise <code>false</code>.
* <p>
* A modifier key is one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}.
* </p>
*/
- public static boolean isModifierKey(int keyCode) {
- switch (keyCode) {
+ public static boolean isModifierKey(short vKey) {
+ switch (vKey) {
case VK_SHIFT:
case VK_CONTROL:
case VK_ALT:
@@ -126,31 +181,36 @@ public class KeyEvent extends InputEvent
}
/**
- * Returns true if {@link #getKeyCode()} represents a non-printable modifier key.
+ * Returns <code>true</code> if {@link #getKeySymbol() key symbol} represents a modifier key,
+ * otherwise <code>false</code>.
+ * <p>
+ * See {@link #isModifierKey(short)} for details.
+ * </p>
* <p>
- * See {@link #isModifierKey(int)} for details.
+ * Note: Implementation uses a cached value.
* </p>
*/
- public boolean isModifierKey() {
- return isModifierKey(keyCode);
+ public final boolean isModifierKey() {
+ return 0 != ( F_MODIFIER_MASK & flags ) ;
}
/**
- * Returns true if the given <code>keyCode</code> represents a non-printable action key, which is not a {@link #isModifierKey(int) modifier key}.
+ * Returns <code>true</code> if the given <code>virtualKey</code> represents a non-printable and
+ * non-{@link #isModifierKey(short) modifier} action key, otherwise <code>false</code>.
* <p>
* An action key is one of {@link #VK_HOME}, {@link #VK_END}, {@link #VK_PAGE_UP}, {@link #VK_PAGE_DOWN}, {@link #VK_UP}, {@link #VK_PAGE_DOWN},
* {@link #VK_LEFT}, {@link #VK_RIGHT}, {@link #VK_F1}-{@link #VK_F24}, {@link #VK_PRINTSCREEN}, {@link #VK_CAPS_LOCK}, {@link #VK_PAUSE},
* {@link #VK_INSERT}, {@link #VK_HELP}, {@link #VK_WINDOWS}, etc ...
* </p>
*/
- public static boolean isActionKey(int keyCode) {
- if( ( VK_F1 <= keyCode && keyCode <= VK_F24 ) ||
- ( VK_ALL_CANDIDATES <= keyCode && keyCode <= VK_INPUT_METHOD_ON_OFF ) ||
- ( VK_CUT <= keyCode && keyCode <= VK_STOP ) ) {
+ public static boolean isActionKey(short vKey) {
+ if( ( VK_F1 <= vKey && vKey <= VK_F24 ) ||
+ ( VK_ALL_CANDIDATES <= vKey && vKey <= VK_INPUT_METHOD_ON_OFF ) ||
+ ( VK_CUT <= vKey && vKey <= VK_STOP ) ) {
return true;
}
- switch (keyCode) {
+ switch (vKey) {
case VK_CANCEL:
case VK_CLEAR:
case VK_PAUSE:
@@ -208,600 +268,614 @@ public class KeyEvent extends InputEvent
}
/**
- * Returns true if {@link #getKeyCode() keyCode} represents a non-printable action key, which is not a {@link #isModifierKey(int) modifier key}.
+ * Returns <code>true</code> if {@link #getKeySymbol() key symbol} represents a non-printable and
+ * non-{@link #isModifierKey(short) modifier} action key, otherwise <code>false</code>.
* <p>
- * See {@link #isActionKey(int)} for details.
+ * See {@link #isActionKey(short)} for details.
* </p>
*/
- public boolean isActionKey() {
- return isActionKey(keyCode);
+ public final boolean isActionKey() {
+ return 0 != ( F_ACTION_MASK & flags ) ;
}
/**
- * Returns true if given <code>keyKode</code> represents a printable character, which is neither a {@link #isModifierKey(int) modifier key}
- * nor an {@link #isActionKey(int) action key}.
+ * Returns <code>true</code> if given <code>virtualKey</code> represents a printable character,
+ * i.e. neither a {@link #isModifierKey(short) modifier key}
+ * nor an {@link #isActionKey(short) action key}.
* Otherwise returns <code>false</code>.
*/
- public static boolean isPrintableKey(int keyCode) {
- return !isModifierKey(keyCode) && !isActionKey(keyCode);
+ public static boolean isPrintableKey(short vKey) {
+ return !isModifierKey(vKey) && !isActionKey(vKey);
}
/**
- * Returns true if {@link #getKeyCode() keyCode} represents a printable character, which is neither a {@link #isModifierKey(int) modifier key}
- * nor an {@link #isActionKey(int) action key}.
+ * Returns <code>true</code> if {@link #getKeySymbol() key symbol} represents a printable character,
+ * i.e. neither a {@link #isModifierKey(short) modifier key}
+ * nor an {@link #isActionKey(short) action key}.
* Otherwise returns <code>false</code>.
*/
- public boolean isPrintableKey() {
- return isPrintableKey(keyCode);
+ public final boolean isPrintableKey() {
+ return 0 == ( F_NON_PRINT_MASK & flags ) ;
}
- private final int keyCode;
+ private final short keyCode;
+ private final short keySym;
private final char keyChar;
-
- public static final int EVENT_KEY_PRESSED = 300;
- public static final int EVENT_KEY_RELEASED= 301;
- public static final int EVENT_KEY_TYPED = 302;
+ private final byte flags;
+ private static final byte F_MODIFIER_MASK = 1 << 0;
+ private static final byte F_ACTION_MASK = 1 << 1;
+ private static final byte F_NON_PRINT_MASK = F_MODIFIER_MASK | F_ACTION_MASK ;
+
+ /** A key has been pressed, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. */
+ public static final short EVENT_KEY_PRESSED = 300;
+ /** A key has been released, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. */
+ public static final short EVENT_KEY_RELEASED= 301;
+ /**
+ * A {@link #isPrintableKey() printable} key has been typed (pressed and released), excluding {@link #isAutoRepeat() auto-repeat}.
+ * @deprecated Redundant, will be removed soon. Use {@link #EVENT_KEY_RELEASED} and exclude non {@link #isPrintableKey() printable} keys and {@link #isAutoRepeat() auto-repeat}.
+ */
+ public static final short EVENT_KEY_TYPED = 302;
/* Virtual key codes. */
- public static final int VK_CANCEL = 0x03;
- public static final int VK_BACK_SPACE = 0x08; // '\b'
- public static final int VK_TAB = 0x09; // '\t'
- public static final int VK_ENTER = 0x0A; // '\n'
- public static final int VK_CLEAR = 0x0C;
- public static final int VK_SHIFT = 0x10;
- public static final int VK_CONTROL = 0x11;
- public static final int VK_ALT = 0x12;
- public static final int VK_PAUSE = 0x13;
- public static final int VK_CAPS_LOCK = 0x14;
- public static final int VK_ESCAPE = 0x1B;
- public static final int VK_SPACE = 0x20;
- public static final int VK_PAGE_UP = 0x21;
- public static final int VK_PAGE_DOWN = 0x22;
- public static final int VK_END = 0x23;
- public static final int VK_HOME = 0x24;
+ public static final short VK_CANCEL = (short) 0x03;
+ public static final short VK_BACK_SPACE = (short) 0x08; // '\b'
+ public static final short VK_TAB = (short) 0x09; // '\t'
+ public static final short VK_ENTER = (short) 0x0A; // '\n'
+ public static final short VK_CLEAR = (short) 0x0C;
+ public static final short VK_SHIFT = (short) 0x10;
+ public static final short VK_CONTROL = (short) 0x11;
+ public static final short VK_ALT = (short) 0x12;
+ public static final short VK_PAUSE = (short) 0x13;
+ public static final short VK_CAPS_LOCK = (short) 0x14;
+ public static final short VK_ESCAPE = (short) 0x1B;
+ public static final short VK_SPACE = (short) 0x20;
+ public static final short VK_PAGE_UP = (short) 0x21;
+ public static final short VK_PAGE_DOWN = (short) 0x22;
+ public static final short VK_END = (short) 0x23;
+ public static final short VK_HOME = (short) 0x24;
/**
* Constant for the non-numpad <b>left</b> arrow key.
* @see #VK_KP_LEFT
*/
- public static final int VK_LEFT = 0x25;
+ public static final short VK_LEFT = (short) 0x25;
/**
* Constant for the non-numpad <b>up</b> arrow key.
* @see #VK_KP_UP
*/
- public static final int VK_UP = 0x26;
+ public static final short VK_UP = (short) 0x26;
/**
* Constant for the non-numpad <b>right</b> arrow key.
* @see #VK_KP_RIGHT
*/
- public static final int VK_RIGHT = 0x27;
+ public static final short VK_RIGHT = (short) 0x27;
/**
* Constant for the non-numpad <b>down</b> arrow key.
* @see #VK_KP_DOWN
*/
- public static final int VK_DOWN = 0x28;
+ public static final short VK_DOWN = (short) 0x28;
/**
* Constant for the comma key, ","
*/
- public static final int VK_COMMA = 0x2C;
+ public static final short VK_COMMA = (short) 0x2C;
/**
* Constant for the minus key, "-"
* @since 1.2
*/
- public static final int VK_MINUS = 0x2D;
+ public static final short VK_MINUS = (short) 0x2D;
/**
* Constant for the period key, "."
*/
- public static final int VK_PERIOD = 0x2E;
+ public static final short VK_PERIOD = (short) 0x2E;
/**
* Constant for the forward slash key, "/"
*/
- public static final int VK_SLASH = 0x2F;
+ public static final short VK_SLASH = (short) 0x2F;
/** VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
- public static final int VK_0 = 0x30;
- public static final int VK_1 = 0x31;
- public static final int VK_2 = 0x32;
- public static final int VK_3 = 0x33;
- public static final int VK_4 = 0x34;
- public static final int VK_5 = 0x35;
- public static final int VK_6 = 0x36;
- public static final int VK_7 = 0x37;
- public static final int VK_8 = 0x38;
- public static final int VK_9 = 0x39;
+ public static final short VK_0 = (short) 0x30;
+ public static final short VK_1 = (short) 0x31;
+ public static final short VK_2 = (short) 0x32;
+ public static final short VK_3 = (short) 0x33;
+ public static final short VK_4 = (short) 0x34;
+ public static final short VK_5 = (short) 0x35;
+ public static final short VK_6 = (short) 0x36;
+ public static final short VK_7 = (short) 0x37;
+ public static final short VK_8 = (short) 0x38;
+ public static final short VK_9 = (short) 0x39;
/**
* Constant for the semicolon key, ";"
*/
- public static final int VK_SEMICOLON = 0x3B;
+ public static final short VK_SEMICOLON = (short) 0x3B;
/**
* Constant for the equals key, "="
*/
- public static final int VK_EQUALS = 0x3D;
+ public static final short VK_EQUALS = (short) 0x3D;
/** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
- public static final int VK_A = 0x41;
- public static final int VK_B = 0x42;
- public static final int VK_C = 0x43;
- public static final int VK_D = 0x44;
- public static final int VK_E = 0x45;
- public static final int VK_F = 0x46;
- public static final int VK_G = 0x47;
- public static final int VK_H = 0x48;
- public static final int VK_I = 0x49;
- public static final int VK_J = 0x4A;
- public static final int VK_K = 0x4B;
- public static final int VK_L = 0x4C;
- public static final int VK_M = 0x4D;
- public static final int VK_N = 0x4E;
- public static final int VK_O = 0x4F;
- public static final int VK_P = 0x50;
- public static final int VK_Q = 0x51;
- public static final int VK_R = 0x52;
- public static final int VK_S = 0x53;
- public static final int VK_T = 0x54;
- public static final int VK_U = 0x55;
- public static final int VK_V = 0x56;
- public static final int VK_W = 0x57;
- public static final int VK_X = 0x58;
- public static final int VK_Y = 0x59;
- public static final int VK_Z = 0x5A;
+ public static final short VK_A = (short) 0x41;
+ public static final short VK_B = (short) 0x42;
+ public static final short VK_C = (short) 0x43;
+ public static final short VK_D = (short) 0x44;
+ public static final short VK_E = (short) 0x45;
+ public static final short VK_F = (short) 0x46;
+ public static final short VK_G = (short) 0x47;
+ public static final short VK_H = (short) 0x48;
+ public static final short VK_I = (short) 0x49;
+ public static final short VK_J = (short) 0x4A;
+ public static final short VK_K = (short) 0x4B;
+ public static final short VK_L = (short) 0x4C;
+ public static final short VK_M = (short) 0x4D;
+ public static final short VK_N = (short) 0x4E;
+ public static final short VK_O = (short) 0x4F;
+ public static final short VK_P = (short) 0x50;
+ public static final short VK_Q = (short) 0x51;
+ public static final short VK_R = (short) 0x52;
+ public static final short VK_S = (short) 0x53;
+ public static final short VK_T = (short) 0x54;
+ public static final short VK_U = (short) 0x55;
+ public static final short VK_V = (short) 0x56;
+ public static final short VK_W = (short) 0x57;
+ public static final short VK_X = (short) 0x58;
+ public static final short VK_Y = (short) 0x59;
+ public static final short VK_Z = (short) 0x5A;
/**
* Constant for the open bracket key, "["
*/
- public static final int VK_OPEN_BRACKET = 0x5B;
+ public static final short VK_OPEN_BRACKET = (short) 0x5B;
/**
* Constant for the back slash key, "\"
*/
- public static final int VK_BACK_SLASH = 0x5C;
+ public static final short VK_BACK_SLASH = (short) 0x5C;
/**
* Constant for the close bracket key, "]"
*/
- public static final int VK_CLOSE_BRACKET = 0x5D;
-
- public static final int VK_NUMPAD0 = 0x60;
- public static final int VK_NUMPAD1 = 0x61;
- public static final int VK_NUMPAD2 = 0x62;
- public static final int VK_NUMPAD3 = 0x63;
- public static final int VK_NUMPAD4 = 0x64;
- public static final int VK_NUMPAD5 = 0x65;
- public static final int VK_NUMPAD6 = 0x66;
- public static final int VK_NUMPAD7 = 0x67;
- public static final int VK_NUMPAD8 = 0x68;
- public static final int VK_NUMPAD9 = 0x69;
- public static final int VK_MULTIPLY = 0x6A;
- public static final int VK_ADD = 0x6B;
+ public static final short VK_CLOSE_BRACKET = (short) 0x5D;
+
+ public static final short VK_NUMPAD0 = (short) 0x60;
+ public static final short VK_NUMPAD1 = (short) 0x61;
+ public static final short VK_NUMPAD2 = (short) 0x62;
+ public static final short VK_NUMPAD3 = (short) 0x63;
+ public static final short VK_NUMPAD4 = (short) 0x64;
+ public static final short VK_NUMPAD5 = (short) 0x65;
+ public static final short VK_NUMPAD6 = (short) 0x66;
+ public static final short VK_NUMPAD7 = (short) 0x67;
+ public static final short VK_NUMPAD8 = (short) 0x68;
+ public static final short VK_NUMPAD9 = (short) 0x69;
+ public static final short VK_MULTIPLY = (short) 0x6A;
+ public static final short VK_ADD = (short) 0x6B;
/**
* Constant for the Numpad Separator key.
*/
- public static final int VK_SEPARATOR = 0x6C;
+ public static final short VK_SEPARATOR = (short) 0x6C;
- public static final int VK_SUBTRACT = 0x6D;
- public static final int VK_DECIMAL = 0x6E;
- public static final int VK_DIVIDE = 0x6F;
- public static final int VK_DELETE = 0x7F; /* ASCII DEL */
- public static final int VK_NUM_LOCK = 0x90;
- public static final int VK_SCROLL_LOCK = 0x91;
+ public static final short VK_SUBTRACT = (short) 0x6D;
+ public static final short VK_DECIMAL = (short) 0x6E;
+ public static final short VK_DIVIDE = (short) 0x6F;
+ public static final short VK_DELETE = (short) 0x7F; /* ASCII DEL */
+ public static final short VK_NUM_LOCK = (short) 0x90;
+ public static final short VK_SCROLL_LOCK = (short) 0x91;
/** Constant for the F1 function key. */
- public static final int VK_F1 = 0x70;
+ public static final short VK_F1 = (short) 0x70;
/** Constant for the F2 function key. */
- public static final int VK_F2 = 0x71;
+ public static final short VK_F2 = (short) 0x71;
/** Constant for the F3 function key. */
- public static final int VK_F3 = 0x72;
+ public static final short VK_F3 = (short) 0x72;
/** Constant for the F4 function key. */
- public static final int VK_F4 = 0x73;
+ public static final short VK_F4 = (short) 0x73;
/** Constant for the F5 function key. */
- public static final int VK_F5 = 0x74;
+ public static final short VK_F5 = (short) 0x74;
/** Constant for the F6 function key. */
- public static final int VK_F6 = 0x75;
+ public static final short VK_F6 = (short) 0x75;
/** Constant for the F7 function key. */
- public static final int VK_F7 = 0x76;
+ public static final short VK_F7 = (short) 0x76;
/** Constant for the F8 function key. */
- public static final int VK_F8 = 0x77;
+ public static final short VK_F8 = (short) 0x77;
/** Constant for the F9 function key. */
- public static final int VK_F9 = 0x78;
+ public static final short VK_F9 = (short) 0x78;
/** Constant for the F10 function key. */
- public static final int VK_F10 = 0x79;
+ public static final short VK_F10 = (short) 0x79;
/** Constant for the F11 function key. */
- public static final int VK_F11 = 0x7A;
+ public static final short VK_F11 = (short) 0x7A;
/** Constant for the F12 function key. */
- public static final int VK_F12 = 0x7B;
+ public static final short VK_F12 = (short) 0x7B;
/**
* Constant for the F13 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F13 = 0xF000;
+ public static final short VK_F13 = (short) 0xF000;
/**
* Constant for the F14 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F14 = 0xF001;
+ public static final short VK_F14 = (short) 0xF001;
/**
* Constant for the F15 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F15 = 0xF002;
+ public static final short VK_F15 = (short) 0xF002;
/**
* Constant for the F16 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F16 = 0xF003;
+ public static final short VK_F16 = (short) 0xF003;
/**
* Constant for the F17 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F17 = 0xF004;
+ public static final short VK_F17 = (short) 0xF004;
/**
* Constant for the F18 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F18 = 0xF005;
+ public static final short VK_F18 = (short) 0xF005;
/**
* Constant for the F19 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F19 = 0xF006;
+ public static final short VK_F19 = (short) 0xF006;
/**
* Constant for the F20 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F20 = 0xF007;
+ public static final short VK_F20 = (short) 0xF007;
/**
* Constant for the F21 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F21 = 0xF008;
+ public static final short VK_F21 = (short) 0xF008;
/**
* Constant for the F22 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F22 = 0xF009;
+ public static final short VK_F22 = (short) 0xF009;
/**
* Constant for the F23 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F23 = 0xF00A;
+ public static final short VK_F23 = (short) 0xF00A;
/**
* Constant for the F24 function key.
* <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- public static final int VK_F24 = 0xF00B;
+ public static final short VK_F24 = (short) 0xF00B;
- public static final int VK_PRINTSCREEN = 0x9A;
- public static final int VK_INSERT = 0x9B;
- public static final int VK_HELP = 0x9C;
- public static final int VK_META = 0x9D;
+ public static final short VK_PRINTSCREEN = (short) 0x9A;
+ public static final short VK_INSERT = (short) 0x9B;
+ public static final short VK_HELP = (short) 0x9C;
+ public static final short VK_META = (short) 0x9D;
- public static final int VK_BACK_QUOTE = 0xC0;
- public static final int VK_QUOTE = 0xDE;
+ public static final short VK_BACK_QUOTE = (short) 0xC0;
+ public static final short VK_QUOTE = (short) 0xDE;
/**
* Constant for the numeric keypad <b>up</b> arrow key.
* @see #VK_UP
*/
- public static final int VK_KP_UP = 0xE0;
+ public static final short VK_KP_UP = (short) 0xE0;
/**
* Constant for the numeric keypad <b>down</b> arrow key.
* @see #VK_DOWN
*/
- public static final int VK_KP_DOWN = 0xE1;
+ public static final short VK_KP_DOWN = (short) 0xE1;
/**
* Constant for the numeric keypad <b>left</b> arrow key.
* @see #VK_LEFT
*/
- public static final int VK_KP_LEFT = 0xE2;
+ public static final short VK_KP_LEFT = (short) 0xE2;
/**
* Constant for the numeric keypad <b>right</b> arrow key.
* @see #VK_RIGHT
*/
- public static final int VK_KP_RIGHT = 0xE3;
+ public static final short VK_KP_RIGHT = (short) 0xE3;
/** For European keyboards */
- public static final int VK_DEAD_GRAVE = 0x80;
+ public static final short VK_DEAD_GRAVE = (short) 0x80;
/** For European keyboards */
- public static final int VK_DEAD_ACUTE = 0x81;
+ public static final short VK_DEAD_ACUTE = (short) 0x81;
/** For European keyboards */
- public static final int VK_DEAD_CIRCUMFLEX = 0x82;
+ public static final short VK_DEAD_CIRCUMFLEX = (short) 0x82;
/** For European keyboards */
- public static final int VK_DEAD_TILDE = 0x83;
+ public static final short VK_DEAD_TILDE = (short) 0x83;
/** For European keyboards */
- public static final int VK_DEAD_MACRON = 0x84;
+ public static final short VK_DEAD_MACRON = (short) 0x84;
/** For European keyboards */
- public static final int VK_DEAD_BREVE = 0x85;
+ public static final short VK_DEAD_BREVE = (short) 0x85;
/** For European keyboards */
- public static final int VK_DEAD_ABOVEDOT = 0x86;
+ public static final short VK_DEAD_ABOVEDOT = (short) 0x86;
/** For European keyboards */
- public static final int VK_DEAD_DIAERESIS = 0x87;
+ public static final short VK_DEAD_DIAERESIS = (short) 0x87;
/** For European keyboards */
- public static final int VK_DEAD_ABOVERING = 0x88;
+ public static final short VK_DEAD_ABOVERING = (short) 0x88;
/** For European keyboards */
- public static final int VK_DEAD_DOUBLEACUTE = 0x89;
+ public static final short VK_DEAD_DOUBLEACUTE = (short) 0x89;
/** For European keyboards */
- public static final int VK_DEAD_CARON = 0x8a;
+ public static final short VK_DEAD_CARON = (short) 0x8a;
/** For European keyboards */
- public static final int VK_DEAD_CEDILLA = 0x8b;
+ public static final short VK_DEAD_CEDILLA = (short) 0x8b;
/** For European keyboards */
- public static final int VK_DEAD_OGONEK = 0x8c;
+ public static final short VK_DEAD_OGONEK = (short) 0x8c;
/** For European keyboards */
- public static final int VK_DEAD_IOTA = 0x8d;
+ public static final short VK_DEAD_IOTA = (short) 0x8d;
/** For European keyboards */
- public static final int VK_DEAD_VOICED_SOUND = 0x8e;
+ public static final short VK_DEAD_VOICED_SOUND = (short) 0x8e;
/** For European keyboards */
- public static final int VK_DEAD_SEMIVOICED_SOUND = 0x8f;
+ public static final short VK_DEAD_SEMIVOICED_SOUND = (short) 0x8f;
/** For European keyboards */
- public static final int VK_AMPERSAND = 0x96;
+ public static final short VK_AMPERSAND = (short) 0x96;
/** For European keyboards */
- public static final int VK_ASTERISK = 0x97;
+ public static final short VK_ASTERISK = (short) 0x97;
/** For European keyboards */
- public static final int VK_QUOTEDBL = 0x98;
+ public static final short VK_QUOTEDBL = (short) 0x98;
/** For European keyboards */
- public static final int VK_LESS = 0x99;
+ public static final short VK_LESS = (short) 0x99;
/** For European keyboards */
- public static final int VK_GREATER = 0xa0;
+ public static final short VK_GREATER = (short) 0xa0;
/** For European keyboards */
- public static final int VK_BRACELEFT = 0xa1;
+ public static final short VK_BRACELEFT = (short) 0xa1;
/** For European keyboards */
- public static final int VK_BRACERIGHT = 0xa2;
+ public static final short VK_BRACERIGHT = (short) 0xa2;
/**
* Constant for the "@" key.
*/
- public static final int VK_AT = 0x0200;
+ public static final short VK_AT = (short) 0x0200;
/**
* Constant for the ":" key.
*/
- public static final int VK_COLON = 0x0201;
+ public static final short VK_COLON = (short) 0x0201;
/**
* Constant for the "^" key.
*/
- public static final int VK_CIRCUMFLEX = 0x0202;
+ public static final short VK_CIRCUMFLEX = (short) 0x0202;
/**
* Constant for the "$" key.
*/
- public static final int VK_DOLLAR = 0x0203;
+ public static final short VK_DOLLAR = (short) 0x0203;
/**
* Constant for the Euro currency sign key.
*/
- public static final int VK_EURO_SIGN = 0x0204;
+ public static final short VK_EURO_SIGN = (short) 0x0204;
/**
* Constant for the "!" key.
*/
- public static final int VK_EXCLAMATION_MARK = 0x0205;
+ public static final short VK_EXCLAMATION_MARK = (short) 0x0205;
/**
* Constant for the inverted exclamation mark key.
*/
- public static final int VK_INVERTED_EXCLAMATION_MARK = 0x0206;
+ public static final short VK_INVERTED_EXCLAMATION_MARK = (short) 0x0206;
/**
* Constant for the "(" key.
*/
- public static final int VK_LEFT_PARENTHESIS = 0x0207;
+ public static final short VK_LEFT_PARENTHESIS = (short) 0x0207;
/**
* Constant for the "#" key.
*/
- public static final int VK_NUMBER_SIGN = 0x0208;
+ public static final short VK_NUMBER_SIGN = (short) 0x0208;
/**
* Constant for the "+" key.
*/
- public static final int VK_PLUS = 0x0209;
+ public static final short VK_PLUS = (short) 0x0209;
/**
* Constant for the ")" key.
*/
- public static final int VK_RIGHT_PARENTHESIS = 0x020A;
+ public static final short VK_RIGHT_PARENTHESIS = (short) 0x020A;
/**
* Constant for the "_" key.
*/
- public static final int VK_UNDERSCORE = 0x020B;
+ public static final short VK_UNDERSCORE = (short) 0x020B;
/**
* Constant for the Microsoft Windows "Windows" key.
* It is used for both the left and right version of the key.
*/
- public static final int VK_WINDOWS = 0x020C;
+ public static final short VK_WINDOWS = (short) 0x020C;
/**
* Constant for the Microsoft Windows Context Menu key.
*/
- public static final int VK_CONTEXT_MENU = 0x020D;
+ public static final short VK_CONTEXT_MENU = (short) 0x020D;
/* for input method support on Asian Keyboards */
/* not clear what this means - listed in Microsoft Windows API */
- public static final int VK_FINAL = 0x0018;
+ public static final short VK_FINAL = (short) 0x0018;
/** Constant for the Convert function key. */
/* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */
- public static final int VK_CONVERT = 0x001C;
+ public static final short VK_CONVERT = (short) 0x001C;
/** Constant for the Don't Convert function key. */
/* Japanese PC 106 keyboard: muhenkan */
- public static final int VK_NONCONVERT = 0x001D;
+ public static final short VK_NONCONVERT = (short) 0x001D;
/** Constant for the Accept or Commit function key. */
/* Japanese Solaris keyboard: kakutei */
- public static final int VK_ACCEPT = 0x001E;
+ public static final short VK_ACCEPT = (short) 0x001E;
/* not clear what this means - listed in Microsoft Windows API */
- public static final int VK_MODECHANGE = 0x001F;
+ public static final short VK_MODECHANGE = (short) 0x001F;
/* replaced by VK_KANA_LOCK for Microsoft Windows and Solaris;
might still be used on other platforms */
- public static final int VK_KANA = 0x0015;
+ public static final short VK_KANA = (short) 0x0015;
/* replaced by VK_INPUT_METHOD_ON_OFF for Microsoft Windows and Solaris;
might still be used for other platforms */
- public static final int VK_KANJI = 0x0019;
+ public static final short VK_KANJI = (short) 0x0019;
/**
* Constant for the Alphanumeric function key.
*/
/* Japanese PC 106 keyboard: eisuu */
- public static final int VK_ALPHANUMERIC = 0x00F0;
+ public static final short VK_ALPHANUMERIC = (short) 0x00F0;
/**
* Constant for the Katakana function key.
*/
/* Japanese PC 106 keyboard: katakana */
- public static final int VK_KATAKANA = 0x00F1;
+ public static final short VK_KATAKANA = (short) 0x00F1;
/**
* Constant for the Hiragana function key.
*/
/* Japanese PC 106 keyboard: hiragana */
- public static final int VK_HIRAGANA = 0x00F2;
+ public static final short VK_HIRAGANA = (short) 0x00F2;
/**
* Constant for the Full-Width Characters function key.
*/
/* Japanese PC 106 keyboard: zenkaku */
- public static final int VK_FULL_WIDTH = 0x00F3;
+ public static final short VK_FULL_WIDTH = (short) 0x00F3;
/**
* Constant for the Half-Width Characters function key.
*/
/* Japanese PC 106 keyboard: hankaku */
- public static final int VK_HALF_WIDTH = 0x00F4;
+ public static final short VK_HALF_WIDTH = (short) 0x00F4;
/**
* Constant for the Roman Characters function key.
*/
/* Japanese PC 106 keyboard: roumaji */
- public static final int VK_ROMAN_CHARACTERS = 0x00F5;
+ public static final short VK_ROMAN_CHARACTERS = (short) 0x00F5;
/**
* Constant for the All Candidates function key.
*/
/* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */
- public static final int VK_ALL_CANDIDATES = 0x0100;
+ public static final short VK_ALL_CANDIDATES = (short) 0x0100;
/**
* Constant for the Previous Candidate function key.
*/
/* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */
- public static final int VK_PREVIOUS_CANDIDATE = 0x0101;
+ public static final short VK_PREVIOUS_CANDIDATE = (short) 0x0101;
/**
* Constant for the Code Input function key.
*/
/* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */
- public static final int VK_CODE_INPUT = 0x0102;
+ public static final short VK_CODE_INPUT = (short) 0x0102;
/**
* Constant for the Japanese-Katakana function key.
* This key switches to a Japanese input method and selects its Katakana input mode.
*/
/* Japanese Macintosh keyboard - VK_JAPANESE_HIRAGANA + SHIFT */
- public static final int VK_JAPANESE_KATAKANA = 0x0103;
+ public static final short VK_JAPANESE_KATAKANA = (short) 0x0103;
/**
* Constant for the Japanese-Hiragana function key.
* This key switches to a Japanese input method and selects its Hiragana input mode.
*/
/* Japanese Macintosh keyboard */
- public static final int VK_JAPANESE_HIRAGANA = 0x0104;
+ public static final short VK_JAPANESE_HIRAGANA = (short) 0x0104;
/**
* Constant for the Japanese-Roman function key.
* This key switches to a Japanese input method and selects its Roman-Direct input mode.
*/
/* Japanese Macintosh keyboard */
- public static final int VK_JAPANESE_ROMAN = 0x0105;
+ public static final short VK_JAPANESE_ROMAN = (short) 0x0105;
/**
* Constant for the locking Kana function key.
* This key locks the keyboard into a Kana layout.
*/
/* Japanese PC 106 keyboard with special Windows driver - eisuu + Control; Japanese Solaris keyboard: kana */
- public static final int VK_KANA_LOCK = 0x0106;
+ public static final short VK_KANA_LOCK = (short) 0x0106;
/**
* Constant for the input method on/off key.
*/
/* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */
- public static final int VK_INPUT_METHOD_ON_OFF = 0x0107;
+ public static final short VK_INPUT_METHOD_ON_OFF = (short) 0x0107;
/* for Sun keyboards */
- public static final int VK_CUT = 0xFFD1;
- public static final int VK_COPY = 0xFFCD;
- public static final int VK_PASTE = 0xFFCF;
- public static final int VK_UNDO = 0xFFCB;
- public static final int VK_AGAIN = 0xFFC9;
- public static final int VK_FIND = 0xFFD0;
- public static final int VK_PROPS = 0xFFCA;
- public static final int VK_STOP = 0xFFC8;
+ public static final short VK_CUT = (short) 0xFFD1;
+ public static final short VK_COPY = (short) 0xFFCD;
+ public static final short VK_PASTE = (short) 0xFFCF;
+ public static final short VK_UNDO = (short) 0xFFCB;
+ public static final short VK_AGAIN = (short) 0xFFC9;
+ public static final short VK_FIND = (short) 0xFFD0;
+ public static final short VK_PROPS = (short) 0xFFCA;
+ public static final short VK_STOP = (short) 0xFFC8;
/**
* Constant for the Compose function key.
*/
- public static final int VK_COMPOSE = 0xFF20;
+ public static final short VK_COMPOSE = (short) 0xFF20;
/**
* Constant for the AltGraph function key.
*/
- public static final int VK_ALT_GRAPH = 0xFF7E;
+ public static final short VK_ALT_GRAPH = (short) 0xFF7E;
/**
* Constant for the Begin key.
*/
- public static final int VK_BEGIN = 0xFF58;
+ public static final short VK_BEGIN = (short) 0xFF58;
/**
* This value is used to indicate that the keyCode is unknown.
* KEY_TYPED events do not have a keyCode value; this value
* is used instead.
*/
- public static final int VK_UNDEFINED = 0x0;
+ public static final short VK_UNDEFINED = (short) 0x0;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyListener.java b/src/newt/classes/com/jogamp/newt/event/KeyListener.java
index dae343d80..5bca733d3 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyListener.java
@@ -34,10 +34,22 @@
package com.jogamp.newt.event;
+/**
+ * Listener for {@link KeyEvent}s.
+ *
+ * @see KeyEvent
+ */
public interface KeyListener extends NEWTEventListener
{
- public void keyPressed(KeyEvent e);
- public void keyReleased(KeyEvent e);
- public void keyTyped(KeyEvent e) ;
+ /** A key has been {@link KeyEvent#EVENT_KEY_PRESSED pressed}, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. See {@link KeyEvent}. */
+ public void keyPressed(KeyEvent e);
+ /** A key has been {@link KeyEvent#EVENT_KEY_RELEASED released}, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. See {@link KeyEvent}. */
+ public void keyReleased(KeyEvent e);
+
+ /**
+ * A {@link #isPrintableKey() printable} key has been {@link KeyEvent#EVENT_KEY_TYPED typed} (pressed and released), excluding {@link #isAutoRepeat() auto-repeat}. See {@link KeyEvent}.
+ * @deprecated Redundant, will be removed soon. Use {@link #keyReleased(KeyEvent)} and exclude non {@link #isPrintableKey() printable} keys and {@link #isAutoRepeat() auto-repeat}.
+ */
+ public void keyTyped(KeyEvent e) ;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index e6b3d8a24..23549533e 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -38,47 +38,47 @@ package com.jogamp.newt.event;
public class MouseEvent extends InputEvent
{
/** ID for button 1, value <code>1</code> */
- public static final int BUTTON1 = 1;
+ public static final short BUTTON1 = 1;
/** ID for button 2, value <code>2</code> */
- public static final int BUTTON2 = 2;
+ public static final short BUTTON2 = 2;
/** ID for button 3, value <code>3</code> */
- public static final int BUTTON3 = 3;
+ public static final short BUTTON3 = 3;
/** ID for button 4, value <code>4</code> */
- public static final int BUTTON4 = 4;
+ public static final short BUTTON4 = 4;
/** ID for button 5, value <code>5</code> */
- public static final int BUTTON5 = 5;
+ public static final short BUTTON5 = 5;
/** ID for button 6, value <code>6</code> */
- public static final int BUTTON6 = 6;
+ public static final short BUTTON6 = 6;
/** ID for button 6, value <code>7</code> */
- public static final int BUTTON7 = 7;
+ public static final short BUTTON7 = 7;
/** ID for button 6, value <code>8</code> */
- public static final int BUTTON8 = 8;
+ public static final short BUTTON8 = 8;
/** ID for button 6, value <code>9</code> */
- public static final int BUTTON9 = 9;
+ public static final short BUTTON9 = 9;
/** Maximum number of buttons, value <code>16</code> */
- public static final int BUTTON_NUMBER = 16;
+ public static final short BUTTON_NUMBER = 16;
- public static final int getClickTimeout() {
+ public static final short getClickTimeout() {
return 300;
}
- public MouseEvent(int eventType, Object source, long when,
- int modifiers, int x, int y, int clickCount, int button,
+ public MouseEvent(short eventType, Object source, long when,
+ int modifiers, int x, int y, short clickCount, short button,
float rotation)
{
super(eventType, source, when, modifiers);
this.x = new int[]{x};
this.y = new int[]{y};
this.pressure = new float[]{0};
- this.pointerids = new int[]{-1};
+ this.pointerids = new short[]{-1};
this.clickCount=clickCount;
this.button=button;
this.wheelRotation = rotation;
}
- public MouseEvent(int eventType, Object source, long when,
- int modifiers, int[] x, int[] y, float[] pressure, int[] pointerids, int clickCount, int button,
+ public MouseEvent(short eventType, Object source, long when,
+ int modifiers, int[] x, int[] y, float[] pressure, short[] pointerids, short clickCount, short button,
float rotation)
{
super(eventType, source, when, modifiers);
@@ -107,17 +107,17 @@ public class MouseEvent extends InputEvent
* @return the pointer id for the data at index.
* return -1 if index not available.
*/
- public int getPointerId(int index) {
+ public short getPointerId(int index) {
if(index >= pointerids.length)
return -1;
return pointerids[index];
}
- public int getButton() {
+ public short getButton() {
return button;
}
- public int getClickCount() {
+ public short getClickCount() {
return clickCount;
}
public int getX() {
@@ -208,7 +208,7 @@ public class MouseEvent extends InputEvent
return super.toString(sb).append("]");
}
- public static String getEventTypeString(int type) {
+ public static String getEventTypeString(short type) {
switch(type) {
case EVENT_MOUSE_CLICKED: return "EVENT_MOUSE_CLICKED";
case EVENT_MOUSE_ENTERED: return "EVENT_MOUSE_ENTERED";
@@ -221,17 +221,18 @@ public class MouseEvent extends InputEvent
default: return "unknown (" + type + ")";
}
}
- private final int x[], y[], clickCount, button;
+ private final int x[], y[];;
+ private final short clickCount, button;
private final float wheelRotation;
private final float pressure[];
- private final int pointerids[];
+ private final short pointerids[];
- public static final int EVENT_MOUSE_CLICKED = 200;
- public static final int EVENT_MOUSE_ENTERED = 201;
- public static final int EVENT_MOUSE_EXITED = 202;
- public static final int EVENT_MOUSE_PRESSED = 203;
- public static final int EVENT_MOUSE_RELEASED = 204;
- public static final int EVENT_MOUSE_MOVED = 205;
- public static final int EVENT_MOUSE_DRAGGED = 206;
- public static final int EVENT_MOUSE_WHEEL_MOVED = 207;
+ public static final short EVENT_MOUSE_CLICKED = 200;
+ public static final short EVENT_MOUSE_ENTERED = 201;
+ public static final short EVENT_MOUSE_EXITED = 202;
+ public static final short EVENT_MOUSE_PRESSED = 203;
+ public static final short EVENT_MOUSE_RELEASED = 204;
+ public static final short EVENT_MOUSE_MOVED = 205;
+ public static final short EVENT_MOUSE_DRAGGED = 206;
+ public static final short EVENT_MOUSE_WHEEL_MOVED = 207;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 9d8d92ff6..6f4561ce6 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -48,81 +48,27 @@ package com.jogamp.newt.event;
*/
@SuppressWarnings("serial")
public class NEWTEvent extends java.util.EventObject {
- private final boolean isSystemEvent;
- private final int eventType;
+ /**
+ * Object when attached via {@link #setAttachment(Object)} marks the event consumed,
+ * ie. stops propagating the event any further to the <i>other</i> event listener.
+ */
+ public static final Object consumedTag = new Object();
+
+ private final short eventType;
private final long when;
private Object attachment;
static final boolean DEBUG = false;
- // 0: NEWTEvent.java
- // 1: InputEvent.java
- // 2: KeyEvent.java
- // 3: com.jogamp.newt.Window
- // 3: com.jogamp.newt.event.awt.AWTNewtEventFactory
- // 2: MouseEvent.java
- // 3: com.jogamp.newt.Window
- // 3: com.jogamp.newt.event.awt.AWTNewtEventFactory
- // 1: WindowEvent.java
- // 2: com.jogamp.newt.Window
- // 2: com.jogamp.newt.event.awt.AWTNewtEventFactory
- //
- // FIXME: verify the isSystemEvent evaluation
- //
- static final String WindowClazzName = "com.jogamp.newt.Window" ;
- static final String AWTNewtEventFactoryClazzName = "com.jogamp.newt.event.awt.AWTNewtEventFactory" ;
-
- /**
- static final boolean evaluateIsSystemEvent(NEWTEvent event, Throwable t) {
- StackTraceElement[] stack = t.getStackTrace();
- if(stack.length==0 || null==stack[0]) {
- return false;
- }
- if(DEBUG) {
- for (int i = 0; i < stack.length && i<5; i++) {
- System.err.println(i+": " + stack[i].getClassName()+ "." + stack[i].getMethodName());
- }
- }
-
- String clazzName = null;
-
- if( event instanceof com.jogamp.newt.event.WindowEvent ) {
- if ( stack.length > 2 ) {
- clazzName = stack[2].getClassName();
- }
- } else if( (event instanceof com.jogamp.newt.event.MouseEvent) ||
- (event instanceof com.jogamp.newt.event.KeyEvent) ) {
- if ( stack.length > 3 ) {
- clazzName = stack[3].getClassName();
- }
- }
-
- boolean res = null!=clazzName && (
- clazzName.equals(WindowClazzName) ||
- clazzName.equals(AWTNewtEventFactoryClazzName) ) ;
- if(DEBUG) {
- System.err.println("system: "+res);
- }
- return res;
- } */
-
- protected NEWTEvent(int eventType, Object source, long when) {
+ protected NEWTEvent(short eventType, Object source, long when) {
super(source);
- // this.isSystemEvent = evaluateIsSystemEvent(this, new Throwable());
- this.isSystemEvent = false; // FIXME: Need a more efficient way to determine system events
this.eventType = eventType;
this.when = when;
this.attachment=null;
}
- /** Indicates whether this event was produced by the system or
- generated by user code. */
- public final boolean isSystemEvent() {
- return isSystemEvent;
- }
-
/** Returns the event type of this event. */
- public final int getEventType() {
+ public final short getEventType() {
return eventType;
}
@@ -158,10 +104,10 @@ public class NEWTEvent extends java.util.EventObject {
if(null == sb) {
sb = new StringBuilder();
}
- return sb.append("NEWTEvent[sys:").append(isSystemEvent()).append(", source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
+ return sb.append("NEWTEvent[source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
}
- static String toHexString(int hex) {
- return "0x" + Integer.toHexString(hex);
+ static String toHexString(short hex) {
+ return "0x" + Integer.toHexString( (int)hex & 0x0000FFFF );
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
index 163b51439..24b3b380a 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
@@ -41,19 +41,19 @@ package com.jogamp.newt.event;
*/
@SuppressWarnings("serial")
public class WindowEvent extends NEWTEvent {
- public static final int EVENT_WINDOW_RESIZED = 100;
- public static final int EVENT_WINDOW_MOVED = 101;
- public static final int EVENT_WINDOW_DESTROY_NOTIFY = 102;
- public static final int EVENT_WINDOW_GAINED_FOCUS = 103;
- public static final int EVENT_WINDOW_LOST_FOCUS = 104;
- public static final int EVENT_WINDOW_REPAINT = 105;
- public static final int EVENT_WINDOW_DESTROYED = 106;
+ public static final short EVENT_WINDOW_RESIZED = 100;
+ public static final short EVENT_WINDOW_MOVED = 101;
+ public static final short EVENT_WINDOW_DESTROY_NOTIFY = 102;
+ public static final short EVENT_WINDOW_GAINED_FOCUS = 103;
+ public static final short EVENT_WINDOW_LOST_FOCUS = 104;
+ public static final short EVENT_WINDOW_REPAINT = 105;
+ public static final short EVENT_WINDOW_DESTROYED = 106;
- public WindowEvent(int eventType, Object source, long when) {
+ public WindowEvent(short eventType, Object source, long when) {
super(eventType, source, when);
}
- public static String getEventTypeString(int type) {
+ public static String getEventTypeString(short type) {
switch(type) {
case EVENT_WINDOW_RESIZED: return "WINDOW_RESIZED";
case EVENT_WINDOW_MOVED: return "WINDOW_MOVED";
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
index 011e1f654..dde182510 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
@@ -36,6 +36,7 @@ package com.jogamp.newt.event;
import javax.media.nativewindow.WindowClosingProtocol;
+/** NEWT {@link WindowEvent} listener. */
public interface WindowListener extends NEWTEventListener {
/** Window is resized, your application shall respect the new window dimension. A repaint is recommended. */
public void windowResized(WindowEvent e);
@@ -53,7 +54,9 @@ public interface WindowListener extends NEWTEventListener {
**/
public void windowDestroyNotify(WindowEvent e);
- /** Window has been destroyed.*/
+ /**
+ * Window has been destroyed.
+ */
public void windowDestroyed(WindowEvent e);
/** Window gained focus. */
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
index e3f0373ec..a0f6e2cb4 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
@@ -34,7 +34,7 @@ import javax.media.nativewindow.util.Rectangle;
public class WindowUpdateEvent extends WindowEvent {
final Rectangle bounds;
- public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
+ public WindowUpdateEvent(short eventType, Object source, long when, Rectangle bounds)
{
super(eventType, source, when);
this.bounds = bounds;
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java
index 8991203d5..6de2eee45 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java
@@ -181,8 +181,13 @@ public abstract class AWTAdapter implements java.util.EventListener
/** @see #addTo(java.awt.Component) */
public abstract AWTAdapter removeFrom(java.awt.Component awtComponent);
+ /**
+ * Enqueues the event to the {@link #getNewtWindow()} is not null.
+ */
void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- newtWindow.enqueueEvent(wait, event);
+ if( null != newtWindow ) {
+ newtWindow.enqueueEvent(wait, event);
+ }
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java
index 64071eed6..1edef347b 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java
@@ -72,14 +72,11 @@ public class AWTKeyAdapter extends AWTAdapter implements java.awt.event.KeyListe
@Override
public void keyReleased(java.awt.event.KeyEvent e) {
com.jogamp.newt.event.KeyEvent keyReleaseEvt = AWTNewtEventFactory.createKeyEvent(com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED, e, newtWindow);
- com.jogamp.newt.event.KeyEvent keyTypedEvt = AWTNewtEventFactory.createKeyEvent(com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED, e, newtWindow);
if(null!=newtListener) {
final com.jogamp.newt.event.KeyListener newtKeyListener = (com.jogamp.newt.event.KeyListener)newtListener;
newtKeyListener.keyReleased(keyReleaseEvt);
- newtKeyListener.keyTyped(keyTypedEvt);
} else {
enqueueEvent(false, keyReleaseEvt);
- enqueueEvent(false, keyTypedEvt);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
index 2d63ca455..e91bb2f82 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -66,13 +66,18 @@ public class AWTWindowAdapter
return this;
}
- public AWTAdapter removeFrom(java.awt.Component awtComponent) {
- awtComponent.removeFocusListener(this);
- awtComponent.removeComponentListener(this);
+ public AWTAdapter removeWindowClosingFrom(java.awt.Component awtComponent) {
java.awt.Window win = getWindow(awtComponent);
if( null != win && null != windowClosingListener ) {
win.removeWindowListener(windowClosingListener);
}
+ return this;
+ }
+
+ public AWTAdapter removeFrom(java.awt.Component awtComponent) {
+ awtComponent.removeFocusListener(this);
+ awtComponent.removeComponentListener(this);
+ removeWindowClosingFrom(awtComponent);
if(awtComponent instanceof java.awt.Window) {
((java.awt.Window)awtComponent).removeWindowListener(this);
}
@@ -220,9 +225,16 @@ public class AWTWindowAdapter
enqueueEvent(true, event);
}
}
+ public void windowClosed(java.awt.event.WindowEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowDestroyed(event);
+ } else {
+ enqueueEvent(true, event);
+ }
+ }
public void windowActivated(java.awt.event.WindowEvent e) { }
- public void windowClosed(java.awt.event.WindowEvent e) { }
public void windowDeactivated(java.awt.event.WindowEvent e) { }
public void windowDeiconified(java.awt.event.WindowEvent e) { }
public void windowIconified(java.awt.event.WindowEvent e) { }
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 7fccb6622..ce50d95dd 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -100,7 +100,10 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
protected GLWindow(Window window) {
super(null, null, false /* always handle device lifecycle ourselves */);
this.window = (WindowImpl) window;
- this.window.setHandleDestroyNotify(false);
+ this.window.setWindowDestroyNotifyAction( new Runnable() {
+ public void run() {
+ defaultWindowDestroyNotifyOp();
+ } } );
window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
@@ -112,10 +115,6 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
defaultWindowResizedOp(getWidth(), getHeight());
}
- @Override
- public void windowDestroyNotify(WindowEvent e) {
- defaultWindowDestroyNotifyOp();
- }
});
this.window.setLifecycleHook(new GLLifecycleHook());
}
@@ -390,6 +389,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@Override
+ public void setWindowDestroyNotifyAction(Runnable r) {
+ window.setWindowDestroyNotifyAction(r);
+ }
+
+ @Override
public final void setVisible(boolean visible) {
window.setVisible(visible);
}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index 20b915cae..d4842ba2f 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -370,15 +370,8 @@ public abstract class DisplayImpl extends Display {
DisplayImpl.this.dispatchMessages();
} };
- final void dispatchMessage(final NEWTEventTask eventTask) {
- final NEWTEvent event = eventTask.get();
+ final void dispatchMessage(final NEWTEvent event) {
try {
- if(null == event) {
- // Ooops ?
- System.err.println("Warning: event of eventTask is NULL");
- Thread.dumpStack();
- return;
- }
final Object source = event.getSource();
if(source instanceof NEWTEventConsumer) {
final NEWTEventConsumer consumer = (NEWTEventConsumer) source ;
@@ -396,6 +389,21 @@ public abstract class DisplayImpl extends Display {
} else {
re = new RuntimeException(t);
}
+ throw re;
+ }
+ }
+
+ final void dispatchMessage(final NEWTEventTask eventTask) {
+ final NEWTEvent event = eventTask.get();
+ try {
+ if(null == event) {
+ // Ooops ?
+ System.err.println("Warning: event of eventTask is NULL");
+ Thread.dumpStack();
+ return;
+ }
+ dispatchMessage(event);
+ } catch (RuntimeException re) {
if( eventTask.isCallerWaiting() ) {
// propagate exception to caller
eventTask.setException(re);
@@ -451,7 +459,7 @@ public abstract class DisplayImpl extends Display {
// can't wait if we are on EDT or NEDT -> consume right away
if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) {
- dispatchMessage(new NEWTEventTask(e, null));
+ dispatchMessage(e);
return;
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index cb43fae32..66ca3e07d 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -110,7 +110,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean pointerConfined = false;
private LifecycleHook lifecycleHook = null;
- private boolean handleDestroyNotify = true;
+ private Runnable windowDestroyNotifyAction = null;
private FocusRunnable focusAction = null;
private KeyListener keyboardFocusHandler = null;
@@ -121,10 +121,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private ArrayList<NativeWindow> childWindows = new ArrayList<NativeWindow>();
private ArrayList<MouseListener> mouseListeners = new ArrayList<MouseListener>();
- private int mouseButtonPressed = 0; // current pressed mouse button number
- private int mouseButtonModMask = 0; // current pressed mouse button modifier mask
+ private short mouseButtonPressed = (short)0; // current pressed mouse button number
+ private int mouseButtonModMask = 0; // current pressed mouse button modifier mask
private long lastMousePressed = 0; // last time when a mouse button was pressed
- private int lastMouseClickCount = 0; // last mouse button click count
+ private short lastMouseClickCount = (short)0; // last mouse button click count
private boolean mouseInWindow = false;// mouse entered window - is inside the window (may be synthetic)
private Point lastMousePosition = new Point();
@@ -527,9 +527,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected void setTitleImpl(String title) {}
/**
- * Return screen coordinates of the given coordinates
- * or null, in which case a NativeWindow traversal shall being used
+ * Translates the given window client-area coordinates with top-left origin
+ * to screen coordinates.
+ * <p>
+ * Since the position reflects the client area, it does not include the insets.
+ * </p>
+ * <p>
+ * May return <code>null</code>, in which case the caller shall traverse through the NativeWindow tree
* as demonstrated in {@link #getLocationOnScreen(javax.media.nativewindow.util.Point)}.
+ * </p>
*
* @return if not null, the screen location of the given coordinates
*/
@@ -644,14 +650,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// public final void destroy() - see below
+ @Override
public final NativeWindow getParent() {
return parentWindow;
}
+ @Override
public final long getWindowHandle() {
return windowHandle;
}
+ @Override
public Point getLocationOnScreen(Point storage) {
if(isNativeValid()) {
Point d;
@@ -688,14 +697,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Window
//
+ @Override
public final boolean isNativeValid() {
return 0 != windowHandle ;
}
+ @Override
public final Screen getScreen() {
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));
}
@@ -778,7 +789,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
runOnEDTIfAvail(wait, new VisibleAction(visible));
}
-
+
+ @Override
public void setVisible(boolean visible) {
setVisible(true, visible);
}
@@ -830,9 +842,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void setSize(int width, int height) {
runOnEDTIfAvail(true, new SetSizeAction(width, height));
}
+ @Override
public void setTopLevelSize(int width, int height) {
setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
}
@@ -850,8 +864,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
_lock.lock();
try {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window DestroyAction() "+getThreadName());
+ System.err.println("Window DestroyAction() hasScreen "+(null != screen)+", isNativeValid "+isNativeValid()+" - "+getThreadName());
}
+
+ // send synced destroy-notify notification
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+
// Childs first ..
synchronized(childWindowsLock) {
if(childWindows.size()>0) {
@@ -861,8 +879,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
while( clonedChildWindows.size() > 0 ) {
NativeWindow nw = clonedChildWindows.remove(0);
if(nw instanceof WindowImpl) {
- ((WindowImpl)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
- ((WindowImpl)nw).destroy();
+ ((WindowImpl)nw).windowDestroyNotify(true);
} else {
nw.destroy();
}
@@ -932,6 +949,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private final DestroyAction destroyAction = new DestroyAction();
+ @Override
public void destroy() {
visible = false; // Immediately mark synchronized visibility flag, avoiding possible recreation
runOnEDTIfAvail(true, destroyAction);
@@ -1253,6 +1271,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private final ReparentActionRecreate reparentActionRecreate = new ReparentActionRecreate();
+ @Override
public final ReparentOperation reparentWindow(NativeWindow newParent) {
return reparentWindow(newParent, false);
}
@@ -1263,16 +1282,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return reparentAction.getOp();
}
+ @Override
public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
CapabilitiesChooser old = this.capabilitiesChooser;
this.capabilitiesChooser = chooser;
return old;
}
+ @Override
public final CapabilitiesImmutable getChosenCapabilities() {
return getGraphicsConfiguration().getChosenCapabilities();
}
+ @Override
public final CapabilitiesImmutable getRequestedCapabilities() {
return capsRequested;
}
@@ -1312,10 +1334,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void setUndecorated(boolean value) {
runOnEDTIfAvail(true, new DecorationAction(value));
}
+ @Override
public final boolean isUndecorated() {
return 0 != parentWindowHandle || undecorated || fullscreen ;
}
@@ -1355,17 +1379,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public final void setAlwaysOnTop(boolean value) {
runOnEDTIfAvail(true, new AlwaysOnTopAction(value));
}
+ @Override
public final boolean isAlwaysOnTop() {
return alwaysOnTop;
}
+ @Override
public String getTitle() {
return title;
}
+ @Override
public void setTitle(String title) {
if (title == null) {
title = "";
@@ -1376,9 +1404,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public boolean isPointerVisible() {
return pointerVisible;
}
+ @Override
public void setPointerVisible(boolean pointerVisible) {
if(this.pointerVisible != pointerVisible) {
boolean setVal = 0 == getWindowHandle();
@@ -1390,10 +1420,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
}
+ @Override
public boolean isPointerConfined() {
return pointerConfined;
}
+ @Override
public void confinePointer(boolean confine) {
if(this.pointerConfined != confine) {
boolean setVal = 0 == getWindowHandle();
@@ -1417,12 +1449,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void warpPointer(int x, int y) {
if(0 != getWindowHandle()) {
warpPointerImpl(x, y);
}
}
+ @Override
public final InsetsImmutable getInsets() {
if(isUndecorated()) {
return Insets.getZero();
@@ -1431,18 +1465,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return insets;
}
+ @Override
public final int getWidth() {
return width;
}
+ @Override
public final int getHeight() {
return height;
}
+ @Override
public final int getX() {
return x;
}
+ @Override
public final int getY() {
return y;
}
@@ -1468,10 +1506,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
this.width = width; this.height = height;
}
+ @Override
public final boolean isVisible() {
return visible;
}
+ @Override
public final boolean isFullscreen() {
return fullscreen;
}
@@ -1480,6 +1520,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Window
//
+ @Override
+ public final Window getDelegatedWindow() {
+ return this;
+ }
+
+ //----------------------------------------------------------------------
+ // WindowImpl
+ //
+
/**
* If the implementation is capable of detecting a device change
* return true and clear the status/reason of the change.
@@ -1503,23 +1552,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(boolean)} implementation.<br>
- * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify(boolean)}.
- */
- public void setHandleDestroyNotify(boolean b) {
- handleDestroyNotify = b;
- }
- //----------------------------------------------------------------------
- // WindowImpl
- //
+ @Override
+ public void setWindowDestroyNotifyAction(Runnable r) {
+ windowDestroyNotifyAction = r;
+ }
/**
* Returns the non delegated {@link AbstractGraphicsConfiguration},
@@ -1976,17 +2013,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// MouseListener/Event Support
//
- public void sendMouseEvent(int eventType, int modifiers,
- int x, int y, int button, float rotation) {
+ public void sendMouseEvent(short eventType, int modifiers,
+ int x, int y, short button, float rotation) {
doMouseEvent(false, false, eventType, modifiers, x, y, button, rotation);
}
- public void enqueueMouseEvent(boolean wait, int eventType, int modifiers,
- int x, int y, int button, float rotation) {
+ public void enqueueMouseEvent(boolean wait, short eventType, int modifiers,
+ int x, int y, short button, float rotation) {
doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation);
}
- protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
- int x, int y, int button, float rotation) {
+ protected void doMouseEvent(boolean enqueue, boolean wait, short eventType, int modifiers,
+ int x, int y, short button, float rotation) {
if( eventType == MouseEvent.EVENT_MOUSE_ENTERED || eventType == MouseEvent.EVENT_MOUSE_EXITED ) {
if( eventType == MouseEvent.EVENT_MOUSE_EXITED && x==-1 && y==-1 ) {
x = lastMousePosition.getX();
@@ -1996,9 +2033,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
x = Math.min(Math.max(x, 0), getWidth()-1);
y = Math.min(Math.max(y, 0), getHeight()-1);
mouseInWindow = eventType == MouseEvent.EVENT_MOUSE_ENTERED;
- lastMousePressed = 0; // clear state
- mouseButtonPressed = 0; // clear state
- mouseButtonModMask = 0; // clear state
+ // clear states
+ lastMousePressed = 0;
+ lastMouseClickCount = (short)0;
+ mouseButtonPressed = 0;
+ mouseButtonModMask = 0;
}
if( x < 0 || y < 0 || x >= getWidth() || y >= getHeight() ) {
return; // .. invalid ..
@@ -2013,10 +2052,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(!mouseInWindow) {
mouseInWindow = true;
eEntered = new MouseEvent(MouseEvent.EVENT_MOUSE_ENTERED, this, when,
- modifiers, x, y, lastMouseClickCount, button, 0);
- lastMousePressed = 0; // clear state
- mouseButtonPressed = 0; // clear state
- mouseButtonModMask = 0; // clear state
+ modifiers, x, y, (short)0, (short)0, (short)0);
+ // clear states
+ lastMousePressed = 0;
+ lastMouseClickCount = (short)0;
+ mouseButtonPressed = 0;
+ mouseButtonModMask = 0;
} else if( lastMousePosition.getX() == x && lastMousePosition.getY()==y ) {
if(DEBUG_MOUSE_EVENT) {
System.err.println("doMouseEvent: skip EVENT_MOUSE_MOVED w/ same position: "+lastMousePosition);
@@ -2046,7 +2087,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( when - lastMousePressed < MouseEvent.getClickTimeout() ) {
lastMouseClickCount++;
} else {
- lastMouseClickCount=1;
+ lastMouseClickCount=(short)1;
}
lastMousePressed = when;
mouseButtonPressed = button;
@@ -2060,7 +2101,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
eClicked = new MouseEvent(MouseEvent.EVENT_MOUSE_CLICKED, this, when,
modifiers, x, y, lastMouseClickCount, button, 0);
} else {
- lastMouseClickCount = 0;
+ lastMouseClickCount = (short)0;
lastMousePressed = 0;
}
mouseButtonPressed = 0;
@@ -2068,15 +2109,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else if( MouseEvent.EVENT_MOUSE_MOVED == eventType ) {
if ( mouseButtonPressed > 0 ) {
e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when,
- modifiers, x, y, 1, mouseButtonPressed, 0);
+ modifiers, x, y, (short)1, mouseButtonPressed, 0);
} else {
e = new MouseEvent(eventType, this, when,
- modifiers, x, y, 0, button, 0);
+ modifiers, x, y, (short)0, button, (short)0);
}
} else if( MouseEvent.EVENT_MOUSE_WHEEL_MOVED == eventType ) {
- e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, rotation);
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, (short)0, button, rotation);
} else {
- e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0);
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, (short)0, button, 0);
}
if( null != eEntered ) {
if(DEBUG_MOUSE_EVENT) {
@@ -2169,7 +2210,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
default:
throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
}
- consumed = InputEvent.consumedTag == e.getAttachment();
+ consumed = NEWTEvent.consumedTag == e.getAttachment();
}
}
@@ -2203,23 +2244,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return 0 <= keyCode && keyCode < keyRepeatState.capacity();
}
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- doKeyEvent(false, false, eventType, modifiers, keyCode, keyChar);
+ public void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ // Always add currently pressed mouse buttons to modifier mask
+ consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers | mouseButtonModMask, keyCode, keySym, keyChar) );
}
- public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- doKeyEvent(true, wait, eventType, modifiers, keyCode, keyChar);
+ public void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ // Always add currently pressed mouse buttons to modifier mask
+ enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers | mouseButtonModMask, keyCode, keySym, keyChar) );
}
- protected void doKeyEvent(boolean enqueue, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- modifiers |= mouseButtonModMask; // Always add currently pressed mouse buttons to modifier mask
- if( enqueue ) {
- enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
- } else {
- consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
- }
- }
-
public void addKeyListener(KeyListener l) {
addKeyListener(-1, l);
}
@@ -2290,6 +2324,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return keyListeners.toArray(new KeyListener[keyListeners.size()]);
}
+ @SuppressWarnings("deprecation")
private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) {
switch(e.getEventType()) {
case KeyEvent.EVENT_KEY_PRESSED:
@@ -2304,24 +2339,52 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
default:
throw new NativeWindowException("Unexpected key event type " + e.getEventType());
}
- return InputEvent.consumedTag == e.getAttachment();
+ return NEWTEvent.consumedTag == e.getAttachment();
}
+ @SuppressWarnings("deprecation")
protected void consumeKeyEvent(KeyEvent e) {
- boolean consumed;
+ boolean consumedE = false, consumedTyped = false;
+ if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) {
+ throw new InternalError("Deprecated KeyEvent.EVENT_KEY_TYPED is synthesized - don't send/enqueue it!");
+ }
+
+ // Synthesize deprecated event KeyEvent.EVENT_KEY_TYPED
+ final KeyEvent eTyped;
+ if( KeyEvent.EVENT_KEY_RELEASED == e.getEventType() && e.isPrintableKey() && !e.isAutoRepeat() ) {
+ eTyped = new KeyEvent(KeyEvent.EVENT_KEY_TYPED, e.getSource(), e.getWhen(), e.getModifiers(), e.getKeyCode(), e.getKeySymbol(), e.getKeyChar());
+ } else {
+ eTyped = null;
+ }
if(null != keyboardFocusHandler) {
- consumed = propagateKeyEvent(e, keyboardFocusHandler);
+ consumedE = propagateKeyEvent(e, keyboardFocusHandler);
if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumed);
+ System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumedE);
}
- } else {
- consumed = false;
- if(DEBUG_KEY_EVENT) {
+ if( null != eTyped ) {
+ consumedTyped = propagateKeyEvent(eTyped, keyboardFocusHandler);
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+eTyped+", keyboardFocusHandler consumed: "+consumedTyped);
+ }
+ }
+ }
+ if(DEBUG_KEY_EVENT) {
+ if( !consumedE ) {
System.err.println("consumeKeyEvent: "+e);
}
}
- for(int i = 0; !consumed && i < keyListeners.size(); i++ ) {
- consumed = propagateKeyEvent(e, keyListeners.get(i));
+ for(int i = 0; !consumedE && i < keyListeners.size(); i++ ) {
+ consumedE = propagateKeyEvent(e, keyListeners.get(i));
+ }
+ if( null != eTyped ) {
+ if(DEBUG_KEY_EVENT) {
+ if( !consumedTyped ) {
+ System.err.println("consumeKeyEvent: "+eTyped);
+ }
+ }
+ for(int i = 0; !consumedTyped && i < keyListeners.size(); i++ ) {
+ consumedTyped = propagateKeyEvent(eTyped, keyListeners.get(i));
+ }
}
}
@@ -2329,11 +2392,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// WindowListener/Event Support
//
public void sendWindowEvent(int eventType) {
- consumeWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ consumeWindowEvent( new WindowEvent((short)eventType, this, System.currentTimeMillis()) ); // FIXME
}
public void enqueueWindowEvent(boolean wait, int eventType) {
- enqueueEvent( wait, new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ enqueueEvent( wait, new WindowEvent((short)eventType, this, System.currentTimeMillis()) ); // FIXME
}
public void addWindowListener(WindowListener l) {
@@ -2382,7 +2445,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(DEBUG_IMPLEMENTATION) {
System.err.println("consumeWindowEvent: "+e+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight());
}
- for(int i = 0; i < windowListeners.size(); i++ ) {
+ boolean consumed = false;
+ for(int i = 0; !consumed && i < windowListeners.size(); i++ ) {
WindowListener l = windowListeners.get(i);
switch(e.getEventType()) {
case WindowEvent.EVENT_WINDOW_RESIZED:
@@ -2411,6 +2475,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
new NativeWindowException("Unexpected window event type "
+ e.getEventType());
}
+ consumed = NEWTEvent.consumedTag == e.getAttachment();
}
}
@@ -2551,32 +2616,45 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/**
- * Triggered by implementation's WM events or programmatically
+ * Triggered by implementation's WM events or programmatic while respecting {@link #getDefaultCloseOperation()}.
*
* @param force if true, overrides {@link #setDefaultCloseOperation(WindowClosingMode)} with {@link WindowClosingProtocol#DISPOSE_ON_CLOSE}
* and hence force destruction. Otherwise is follows the user settings.
* @return true if this window is no more valid and hence has been destroyed, otherwise false.
*/
- protected boolean windowDestroyNotify(boolean force) {
+ public boolean windowDestroyNotify(boolean force) {
+ final WindowClosingMode defMode = getDefaultCloseOperation();
+ final WindowClosingMode mode = force ? WindowClosingMode.DISPOSE_ON_CLOSE : defMode;
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyNotify(force: "+force+") START "+getThreadName()+": "+this);
+ System.err.println("Window.windowDestroyNotify(force: "+force+", mode "+defMode+" -> "+mode+") "+getThreadName()+": "+this);
}
- if(force) {
- setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE);
- }
-
- // send synced destroy notifications
- enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
-
- if(handleDestroyNotify && WindowClosingMode.DISPOSE_ON_CLOSE == getDefaultCloseOperation()) {
- destroy();
+
+ if( WindowClosingMode.DISPOSE_ON_CLOSE == mode ) {
+ if(force) {
+ setDefaultCloseOperation(mode);
+ }
+ try {
+ if( null == windowDestroyNotifyAction ) {
+ destroy();
+ } else {
+ windowDestroyNotifyAction.run();
+ }
+ } finally {
+ if(force) {
+ setDefaultCloseOperation(defMode);
+ }
+ }
+ } else {
+ // send synced destroy notifications
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
}
final boolean destroyed = !isNativeValid();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyNotify(force: "+force+") END "+getThreadName()+": destroyed "+destroyed+", "+this);
- }
+ System.err.println("Window.windowDestroyNotify(force: "+force+", mode "+mode+") END "+getThreadName()+": destroyed "+destroyed+", "+this);
+ }
+
return destroyed;
}
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java
index e11d79ddc..b90c2106e 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java
@@ -28,8 +28,6 @@
package jogamp.newt.awt.event;
-import com.jogamp.common.util.IntIntHashMap;
-
/**
*
* <a name="AWTEventModifierMapping"><h5>AWT Event Modifier Mapping</h5></a>
@@ -76,47 +74,10 @@ import com.jogamp.common.util.IntIntHashMap;
*/
public class AWTNewtEventFactory {
- protected static final IntIntHashMap eventTypeAWT2NEWT;
-
/** zero-based AWT button mask array filled by {@link #getAWTButtonDownMask(int)}, allowing fast lookup. */
private static int awtButtonDownMasks[] ;
static {
- IntIntHashMap map = new IntIntHashMap();
- map.setKeyNotFoundValue(0xFFFFFFFF);
- // n/a map.put(java.awt.event.WindowEvent.WINDOW_OPENED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED);
- map.put(java.awt.event.WindowEvent.WINDOW_CLOSING, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
- map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROYED);
- // n/a map.put(java.awt.event.WindowEvent.WINDOW_ICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED);
- // n/a map.put(java.awt.event.WindowEvent.WINDOW_DEICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED);
- map.put(java.awt.event.WindowEvent.WINDOW_ACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
- map.put(java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
- map.put(java.awt.event.FocusEvent.FOCUS_GAINED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
- map.put(java.awt.event.WindowEvent.WINDOW_DEACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
- map.put(java.awt.event.WindowEvent.WINDOW_LOST_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
- map.put(java.awt.event.FocusEvent.FOCUS_LOST, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
- // n/a map.put(java.awt.event.WindowEvent.WINDOW_STATE_CHANGED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_STATE_CHANGED);
-
- map.put(java.awt.event.ComponentEvent.COMPONENT_MOVED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_MOVED);
- map.put(java.awt.event.ComponentEvent.COMPONENT_RESIZED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_RESIZED);
- // n/a map.put(java.awt.event.ComponentEvent.COMPONENT_SHOWN, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_SHOWN);
- // n/a map.put(java.awt.event.ComponentEvent.COMPONENT_HIDDEN, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_HIDDEN);
-
- map.put(java.awt.event.MouseEvent.MOUSE_CLICKED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED);
- map.put(java.awt.event.MouseEvent.MOUSE_PRESSED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED);
- map.put(java.awt.event.MouseEvent.MOUSE_RELEASED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED);
- map.put(java.awt.event.MouseEvent.MOUSE_MOVED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED);
- map.put(java.awt.event.MouseEvent.MOUSE_ENTERED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED);
- map.put(java.awt.event.MouseEvent.MOUSE_EXITED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED);
- map.put(java.awt.event.MouseEvent.MOUSE_DRAGGED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED);
- map.put(java.awt.event.MouseEvent.MOUSE_WHEEL, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED);
-
- map.put(java.awt.event.KeyEvent.KEY_PRESSED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED);
- map.put(java.awt.event.KeyEvent.KEY_RELEASED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED);
- map.put(java.awt.event.KeyEvent.KEY_TYPED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED);
-
- eventTypeAWT2NEWT = map;
-
// There is an assumption in awtModifiers2Newt(int,int,boolean)
// that the awtButtonMasks and newtButtonMasks are peers, i.e.
// a given index refers to the same button in each array.
@@ -135,6 +96,41 @@ public class AWTNewtEventFactory {
}
}
+ public static final short eventTypeAWT2NEWT(int awtType) {
+ switch( awtType ) {
+ // n/a case java.awt.event.WindowEvent.WINDOW_OPENED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED;
+ case java.awt.event.WindowEvent.WINDOW_CLOSING: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY;
+ case java.awt.event.WindowEvent.WINDOW_CLOSED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROYED;
+ // n/a case java.awt.event.WindowEvent.WINDOW_ICONIFIED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED;
+ // n/a case java.awt.event.WindowEvent.WINDOW_DEICONIFIED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED;
+ case java.awt.event.WindowEvent.WINDOW_ACTIVATED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS;
+ case java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS;
+ case java.awt.event.FocusEvent.FOCUS_GAINED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS;
+ case java.awt.event.WindowEvent.WINDOW_DEACTIVATED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS;
+ case java.awt.event.WindowEvent.WINDOW_LOST_FOCUS: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS;
+ case java.awt.event.FocusEvent.FOCUS_LOST: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS;
+ // n/a case java.awt.event.WindowEvent.WINDOW_STATE_CHANGED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_STATE_CHANGED;
+
+ case java.awt.event.ComponentEvent.COMPONENT_MOVED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_MOVED;
+ case java.awt.event.ComponentEvent.COMPONENT_RESIZED: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_RESIZED;
+ // n/a case java.awt.event.ComponentEvent.COMPONENT_SHOWN: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_SHOWN;
+ // n/a case java.awt.event.ComponentEvent.COMPONENT_HIDDEN: return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_HIDDEN;
+
+ case java.awt.event.MouseEvent.MOUSE_CLICKED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED;
+ case java.awt.event.MouseEvent.MOUSE_PRESSED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
+ case java.awt.event.MouseEvent.MOUSE_RELEASED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
+ case java.awt.event.MouseEvent.MOUSE_MOVED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED;
+ case java.awt.event.MouseEvent.MOUSE_ENTERED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED;
+ case java.awt.event.MouseEvent.MOUSE_EXITED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED;
+ case java.awt.event.MouseEvent.MOUSE_DRAGGED: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED;
+ case java.awt.event.MouseEvent.MOUSE_WHEEL: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
+
+ case java.awt.event.KeyEvent.KEY_PRESSED: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED;
+ case java.awt.event.KeyEvent.KEY_RELEASED: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED;
+ }
+ return (short)0;
+ }
+
private static int getAWTButtonDownMaskImpl(int button) {
/**
* java.awt.event.InputEvent.getMaskForButton(button);
@@ -227,48 +223,48 @@ public class AWTNewtEventFactory {
return newtMods;
}
- public static final int awtButton2Newt(int awtButton) {
+ public static final short awtButton2Newt(int awtButton) {
if( 0 < awtButton && awtButton <= com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER ) {
- return awtButton;
+ return (short)awtButton;
} else {
- return 0;
+ return (short)0;
}
}
public static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.WindowEvent event, com.jogamp.newt.Window newtSource) {
- final int newtType = eventTypeAWT2NEWT.get(event.getID());
- if(0xFFFFFFFF != newtType) {
+ final short newtType = eventTypeAWT2NEWT(event.getID());
+ if( (short)0 != newtType ) {
return new com.jogamp.newt.event.WindowEvent(newtType, ((null==newtSource)?(Object)event.getComponent():(Object)newtSource), System.currentTimeMillis());
}
return null; // no mapping ..
}
public static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.ComponentEvent event, com.jogamp.newt.Window newtSource) {
- final int newtType = eventTypeAWT2NEWT.get(event.getID());
- if(0xFFFFFFFF != newtType) {
+ final short newtType = eventTypeAWT2NEWT(event.getID());
+ if( (short)0 != newtType ) {
return new com.jogamp.newt.event.WindowEvent(newtType, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, System.currentTimeMillis());
}
return null; // no mapping ..
}
public static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.FocusEvent event, com.jogamp.newt.Window newtSource) {
- final int newtType = eventTypeAWT2NEWT.get(event.getID());
- if(0xFFFFFFFF != newtType) {
+ final short newtType = eventTypeAWT2NEWT(event.getID());
+ if( (short)0 != newtType ) {
return new com.jogamp.newt.event.WindowEvent(newtType, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, System.currentTimeMillis());
}
return null; // no mapping ..
}
public static final com.jogamp.newt.event.MouseEvent createMouseEvent(java.awt.event.MouseEvent event, com.jogamp.newt.Window newtSource) {
- final int newtType = eventTypeAWT2NEWT.get(event.getID());
- if(0xFFFFFFFF != newtType) {
+ final short newtType = eventTypeAWT2NEWT(event.getID());
+ if( (short)0 != newtType ) {
float rotation = 0;
if (event instanceof java.awt.event.MouseWheelEvent) {
// AWT/NEWT rotation is reversed - AWT +1 is down, NEWT +1 is up.
rotation = -1f * ((java.awt.event.MouseWheelEvent)event).getWheelRotation();
}
- final int newtButton = awtButton2Newt(event.getButton());
+ final short newtButton = awtButton2Newt(event.getButton());
int mods = awtModifiers2Newt(event.getModifiers(), event.getModifiersEx());
mods |= com.jogamp.newt.event.InputEvent.getButtonMask(newtButton); // always include NEWT BUTTON_MASK
if(null!=newtSource) {
@@ -281,25 +277,25 @@ public class AWTNewtEventFactory {
}
return new com.jogamp.newt.event.MouseEvent(
newtType, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, event.getWhen(),
- mods, event.getX(), event.getY(), event.getClickCount(),
+ mods, event.getX(), event.getY(), (short)event.getClickCount(),
newtButton, rotation);
}
return null; // no mapping ..
}
public static final com.jogamp.newt.event.KeyEvent createKeyEvent(java.awt.event.KeyEvent event, com.jogamp.newt.Window newtSource) {
- return createKeyEvent(eventTypeAWT2NEWT.get(event.getID()), event, newtSource);
+ return createKeyEvent(eventTypeAWT2NEWT(event.getID()), event, newtSource);
}
- public static final com.jogamp.newt.event.KeyEvent createKeyEvent(int newtType, java.awt.event.KeyEvent event, com.jogamp.newt.Window newtSource) {
- if(0xFFFFFFFF != newtType) {
+ public static final com.jogamp.newt.event.KeyEvent createKeyEvent(short newtType, java.awt.event.KeyEvent event, com.jogamp.newt.Window newtSource) {
+ if( (short)0 != newtType ) {
+ final short keyCode = (short)event.getKeyCode();
return new com.jogamp.newt.event.KeyEvent(
newtType, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, event.getWhen(),
awtModifiers2Newt(event.getModifiers(), event.getModifiersEx()),
- event.getKeyCode(), event.getKeyChar());
+ keyCode, keyCode, event.getKeyChar());
}
return null; // no mapping ..
}
}
-
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index 747e2368e..b348220d6 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -42,9 +42,7 @@ import com.jogamp.newt.event.awt.AWTWindowAdapter;
* Specialized parent/client adapter,
* where the NEWT child window really gets resized,
* and the parent move window event gets discarded. */
-public class AWTParentWindowAdapter
- extends AWTWindowAdapter
- implements java.awt.event.HierarchyListener
+public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt.event.HierarchyListener
{
NativeWindow downstreamParent;
@@ -98,7 +96,7 @@ public class AWTParentWindowAdapter
public void run() {
int cw = comp.getWidth();
int ch = comp.getHeight();
- if( 0 < cw * ch ) {
+ if( 0 < cw && 0 < ch ) {
if( newtWindow.getWidth() != cw || newtWindow.getHeight() != ch ) {
newtWindow.setSize(cw, ch);
if(comp.isVisible() != newtWindow.isVisible()) {
diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
index 55fbbe603..4f19e9c4d 100644
--- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
+++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
@@ -42,78 +42,62 @@ public class AndroidNewtEventFactory {
/** API Level 12: {@link android.view.MotionEvent#ACTION_SCROLL} = {@value} */
private static final int ACTION_SCROLL = 8;
- private static final int aMotionEventType2Newt(int aType) {
- final int nType;
+ private static final short aMotionEventType2Newt(int aType) {
switch( aType ) {
case android.view.MotionEvent.ACTION_DOWN:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
case android.view.MotionEvent.ACTION_UP:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
case android.view.MotionEvent.ACTION_MOVE:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED;
case android.view.MotionEvent.ACTION_CANCEL:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
case android.view.MotionEvent.ACTION_OUTSIDE:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED;
- break;
- //
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED;
case android.view.MotionEvent.ACTION_POINTER_DOWN:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
case android.view.MotionEvent.ACTION_POINTER_UP:
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
// case ACTION_HOVER_MOVE
case ACTION_SCROLL: // API Level 12 !
- nType = com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
- break;
+ return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
// case ACTION_HOVER_ENTER
// case ACTION_HOVER_EXIT
- default:
- nType = 0xFFFFFFFF;
}
- return nType;
+ return (short)0;
}
- private static final int aAccessibilityEventType2Newt(int aType) {
- final int nType;
+ private static final short aAccessibilityEventType2Newt(int aType) {
switch( aType ) {
case android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED:
- nType = com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS; break;
- default:
- nType = 0xFFFFFFFF;
+ return com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS;
}
- return nType;
+ return (short)0;
}
- private static final int aKeyEventType2NewtEventType(int androidKeyAction) {
+ private static final short aKeyEventType2NewtEventType(int androidKeyAction) {
switch(androidKeyAction) {
case android.view.KeyEvent.ACTION_DOWN:
case android.view.KeyEvent.ACTION_MULTIPLE:
return com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED;
case android.view.KeyEvent.ACTION_UP:
return com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED;
- default:
- return 0;
}
+ return (short)0;
}
- private static final int aKeyCode2NewtKeyCode(int androidKeyCode) {
+ private static final short aKeyCode2NewtKeyCode(int androidKeyCode) {
if(android.view.KeyEvent.KEYCODE_0 <= androidKeyCode && androidKeyCode <= android.view.KeyEvent.KEYCODE_9) {
- return com.jogamp.newt.event.KeyEvent.VK_0 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_0 ) ;
+ return (short) ( com.jogamp.newt.event.KeyEvent.VK_0 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_0 ) );
}
if(android.view.KeyEvent.KEYCODE_A <= androidKeyCode && androidKeyCode <= android.view.KeyEvent.KEYCODE_Z) {
- return com.jogamp.newt.event.KeyEvent.VK_A + ( androidKeyCode - android.view.KeyEvent.KEYCODE_A ) ;
+ return (short) ( com.jogamp.newt.event.KeyEvent.VK_A + ( androidKeyCode - android.view.KeyEvent.KEYCODE_A ) );
}
if(android.view.KeyEvent.KEYCODE_F1 <= androidKeyCode && androidKeyCode <= android.view.KeyEvent.KEYCODE_F12) {
- return com.jogamp.newt.event.KeyEvent.VK_F1 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_F1 ) ;
+ return (short) ( com.jogamp.newt.event.KeyEvent.VK_F1 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_F1 ) );
}
if(android.view.KeyEvent.KEYCODE_NUMPAD_0 <= androidKeyCode && androidKeyCode <= android.view.KeyEvent.KEYCODE_NUMPAD_9) {
- return com.jogamp.newt.event.KeyEvent.VK_NUMPAD0 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_NUMPAD_0 ) ;
+ return (short) ( com.jogamp.newt.event.KeyEvent.VK_NUMPAD0 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_NUMPAD_0 ) );
}
switch(androidKeyCode) {
case android.view.KeyEvent.KEYCODE_COMMA: return com.jogamp.newt.event.KeyEvent.VK_COMMA;
@@ -144,7 +128,7 @@ public class AndroidNewtEventFactory {
case android.view.KeyEvent.KEYCODE_CTRL_LEFT: return com.jogamp.newt.event.KeyEvent.VK_CONTROL;
case android.view.KeyEvent.KEYCODE_CTRL_RIGHT: return com.jogamp.newt.event.KeyEvent.VK_CONTROL; // ??
}
- return 0;
+ return (short)0;
}
private static final int aKeyModifiers2Newt(int androidMods) {
@@ -170,38 +154,29 @@ public class AndroidNewtEventFactory {
public com.jogamp.newt.event.WindowEvent createWindowEvent(android.view.accessibility.AccessibilityEvent event, com.jogamp.newt.Window newtSource) {
final int aType = event.getEventType();
- final int nType = aAccessibilityEventType2Newt(aType);
+ final short nType = aAccessibilityEventType2Newt(aType);
- if(0xFFFFFFFF != nType) {
+ if( (short)0 != nType) {
return new com.jogamp.newt.event.WindowEvent(nType, ((null==newtSource)?null:(Object)newtSource), event.getEventTime());
}
return null; // no mapping ..
}
- public com.jogamp.newt.event.KeyEvent[] createKeyEvents(int keyCode, android.view.KeyEvent event, com.jogamp.newt.Window newtSource) {
- final int type = aKeyEventType2NewtEventType(event.getAction());
+ public com.jogamp.newt.event.KeyEvent createKeyEvent(int keyCode, android.view.KeyEvent event, com.jogamp.newt.Window newtSource) {
+ final short type = aKeyEventType2NewtEventType(event.getAction());
if(Window.DEBUG_MOUSE_EVENT) {
System.err.println("createKeyEvent: type 0x"+Integer.toHexString(type)+", keyCode 0x"+Integer.toHexString(keyCode)+", "+event);
}
- if(0xFFFFFFFF != type) {
- final int newtKeyCode = aKeyCode2NewtKeyCode(keyCode);
- if(0 != newtKeyCode) {
+ if( (short)0 != type) {
+ final short newtKeyCode = aKeyCode2NewtKeyCode(keyCode);
+ if( (short)0 != newtKeyCode ) {
final Object src = (null==newtSource)?null:(Object)newtSource;
final long unixTime = System.currentTimeMillis() + ( event.getEventTime() - android.os.SystemClock.uptimeMillis() );
final int newtMods = aKeyModifiers2Newt(event.getMetaState());
- final com.jogamp.newt.event.KeyEvent ke1 = new com.jogamp.newt.event.KeyEvent(
- type, src, unixTime, newtMods, newtKeyCode, (char) event.getUnicodeChar());
-
- if( com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED == type ) {
- return new com.jogamp.newt.event.KeyEvent[] { ke1,
- new com.jogamp.newt.event.KeyEvent(
- com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED,
- src, unixTime, newtMods, newtKeyCode, (char) event.getUnicodeChar()) };
- } else {
- return new com.jogamp.newt.event.KeyEvent[] { ke1 };
- }
+ return new com.jogamp.newt.event.KeyEvent(
+ type, src, unixTime, newtMods, newtKeyCode, newtKeyCode, (char) event.getUnicodeChar());
}
}
return null;
@@ -218,7 +193,8 @@ public class AndroidNewtEventFactory {
//
// Prefilter Android Event (Gesture, ..) and determine final type
//
- final int aType, nType;
+ final int aType;
+ final short nType;
float[] rotationXY = null;
int rotationSource = 0; // 1 - Gesture, 2 - ACTION_SCROLL
{
@@ -265,8 +241,8 @@ public class AndroidNewtEventFactory {
}
}
- if(0xFFFFFFFF != nType) {
- final int clickCount = 1;
+ if( (short)0 != nType ) {
+ final short clickCount = 1;
int modifiers = 0;
if( null == rotationXY && AndroidVersion.SDK_INT >= 12 && ACTION_SCROLL == aType ) { // API Level 12
@@ -299,7 +275,7 @@ public class AndroidNewtEventFactory {
//
final int pCount;
final int pIndex;
- final int button;
+ final short button;
switch( aType ) {
case android.view.MotionEvent.ACTION_POINTER_DOWN:
case android.view.MotionEvent.ACTION_POINTER_UP: {
@@ -307,7 +283,7 @@ public class AndroidNewtEventFactory {
pCount = 1;
final int b = event.getPointerId(pIndex) + 1; // FIXME: Assumption that Pointer-ID starts w/ 0 !
if( com.jogamp.newt.event.MouseEvent.BUTTON1 <= b && b <= com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER ) {
- button = b;
+ button = (short)b;
} else {
button = com.jogamp.newt.event.MouseEvent.BUTTON1;
}
@@ -326,7 +302,7 @@ public class AndroidNewtEventFactory {
final int[] x = new int[pCount];
final int[] y = new int[pCount];
final float[] pressure = new float[pCount];
- final int[] pointerIds = new int[pCount];
+ final short[] pointerIds = new short[pCount];
{
if(Window.DEBUG_MOUSE_EVENT) {
System.err.println("createMouseEvent: collect ptr-data ["+pIndex+".."+(pIndex+pCount-1)+", "+pCount+"], aType "+aType+", button "+button+", gestureScrollPointerDown "+gestureScrollPointerDown);
@@ -337,7 +313,7 @@ public class AndroidNewtEventFactory {
x[j] = (int)event.getX(i);
y[j] = (int)event.getY(i);
pressure[j] = event.getPressure(i);
- pointerIds[j] = event.getPointerId(i);
+ pointerIds[j] = (short)event.getPointerId(i);
if(Window.DEBUG_MOUSE_EVENT) {
System.err.println("createMouseEvent: ptr-data["+i+" -> "+j+"] "+x[j]+"/"+y[j]+", pressure "+pressure[j]+", id "+pointerIds[j]);
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java
index ee0c8f8b1..2d972f752 100644
--- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java
+++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java
@@ -38,11 +38,9 @@ public class AndroidNewtEventTranslator implements View.OnKeyListener, View.OnTo
@Override
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
- final com.jogamp.newt.event.KeyEvent[] newtEvents = factory.createKeyEvents(keyCode, event, newtWindow);
- if(null != newtEvents) {
- for(int i=0; i<newtEvents.length; i++) {
- newtWindow.enqueueEvent(false, newtEvents[i]);
- }
+ final com.jogamp.newt.event.KeyEvent newtEvent = factory.createKeyEvent(keyCode, event, newtWindow);
+ if(null != newtEvent) {
+ newtWindow.enqueueEvent(false, newtEvent);
return true;
}
return false;
diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index bee43a95e..0172309fb 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -256,10 +256,7 @@ public class WindowDriver extends WindowImpl {
}
@Override
public void windowDestroyed(WindowEvent e) {
- if(isNativeValid()) {
- WindowDriver.this.windowDestroyNotify(true);
- }
-
+ // Not fwd by AWTWindowAdapter, synthesized by NEWT
}
@Override
public void windowGainedFocus(WindowEvent e) {
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
index 5efce2524..2c0e6d3dd 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
@@ -210,9 +210,9 @@ public class LinuxEventDeviceTracker implements WindowListener {
short code;
int value;
- int keyCode=KeyEvent.VK_UNDEFINED;
+ short keyCode=KeyEvent.VK_UNDEFINED;
char keyChar=' ';
- int eventType=0;
+ short eventType=0;
int modifiers=0;
loop:
@@ -263,24 +263,20 @@ public class LinuxEventDeviceTracker implements WindowListener {
case 0:
modifiers=0;
eventType=KeyEvent.EVENT_KEY_RELEASED;
- focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
- //Send syntetic typed
- focusedWindow.sendKeyEvent(KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, (char) keyChar);
+ focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar);
break;
case 1:
eventType=KeyEvent.EVENT_KEY_PRESSED;
- focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar);
break;
case 2:
eventType=KeyEvent.EVENT_KEY_PRESSED;
modifiers=InputEvent.AUTOREPEAT_MASK;
//Send syntetic autorepeat release
- focusedWindow.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar);
- //Send syntetic typed
- focusedWindow.sendKeyEvent(KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
+ focusedWindow.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyCode, keyChar);
- focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar);
break;
}
break;
@@ -314,14 +310,15 @@ public class LinuxEventDeviceTracker implements WindowListener {
stop=true;
}
- private char NewtVKey2Unicode(int VK){
- if(KeyEvent.isPrintableKey(VK)){
+ private char NewtVKey2Unicode(short VK){
+ if( KeyEvent.isPrintableKey(VK) ){
return (char)VK;
}
return 0;
}
- private char LinuxEVKey2Unicode(short EVKey) {
+ @SuppressWarnings("unused")
+ private char LinuxEVKey2Unicode(short EVKey) {
// This is the stuff normally mapped by a system keymap
switch(EVKey){
@@ -377,9 +374,8 @@ public class LinuxEventDeviceTracker implements WindowListener {
return 0;
}
- private int LinuxEVKey2NewtVKey(short EVKey) {
- char vkCode = KeyEvent.VK_UNDEFINED;
-
+ private short LinuxEVKey2NewtVKey(short EVKey) {
+
switch(EVKey) {
case 1: // ESC
return KeyEvent.VK_ESCAPE;
@@ -886,8 +882,9 @@ public class LinuxEventDeviceTracker implements WindowListener {
if(Window.DEBUG_KEY_EVENT) {
System.out.println("LinuxEVKey2NewtVKey: Unmapped EVKey "+EVKey);
- }
- return vkCode;
+ }
+
+ return KeyEvent.VK_UNDEFINED;
}
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
index b8a326a6c..0d6278bfb 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -65,10 +65,10 @@ public class LinuxMouseTracker implements WindowListener {
private volatile boolean stop = false;
private int x = 0;
private int y = 0;
- private int buttonDown = 0;
+ private short buttonDown = 0;
private int old_x = 0;
private int old_y = 0;
- private int old_buttonDown = 0;
+ private short old_buttonDown = 0;
private WindowImpl focusedWindow = null;
private MouseDevicePoller mouseDevicePoller = new MouseDevicePoller();
@@ -183,19 +183,15 @@ public class LinuxMouseTracker implements WindowListener {
if(old_x != x || old_y != y) {
// mouse moved
- focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, 0, 0 );
+ focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, (short)0, 0 );
}
if(old_buttonDown != buttonDown) {
// press/release
if( 0 != buttonDown ) {
- focusedWindow.sendMouseEvent(
- MouseEvent.EVENT_MOUSE_PRESSED,
- 0, wx, wy, buttonDown, 0 );
+ focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_PRESSED, 0, wx, wy, buttonDown, 0 );
} else {
- focusedWindow.sendMouseEvent(
- MouseEvent.EVENT_MOUSE_RELEASED,
- 0, wx, wy, old_buttonDown, 0 );
+ focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_RELEASED, 0, wx, wy, old_buttonDown, 0 );
}
}
} else {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
index 5966bd30f..c07576901 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -31,56 +31,129 @@ 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;
+ //
+ // KeyCodes (Layout Dependent)
+ //
+ private static final short kVK_ANSI_A = 0x00;
+ private static final short kVK_ANSI_S = 0x01;
+ private static final short kVK_ANSI_D = 0x02;
+ private static final short kVK_ANSI_F = 0x03;
+ private static final short kVK_ANSI_H = 0x04;
+ private static final short kVK_ANSI_G = 0x05;
+ private static final short kVK_ANSI_Z = 0x06;
+ private static final short kVK_ANSI_X = 0x07;
+ private static final short kVK_ANSI_C = 0x08;
+ private static final short kVK_ANSI_V = 0x09;
+ private static final short kVK_ANSI_B = 0x0B;
+ private static final short kVK_ANSI_Q = 0x0C;
+ private static final short kVK_ANSI_W = 0x0D;
+ private static final short kVK_ANSI_E = 0x0E;
+ private static final short kVK_ANSI_R = 0x0F;
+ private static final short kVK_ANSI_Y = 0x10;
+ private static final short kVK_ANSI_T = 0x11;
+ private static final short kVK_ANSI_1 = 0x12;
+ private static final short kVK_ANSI_2 = 0x13;
+ private static final short kVK_ANSI_3 = 0x14;
+ private static final short kVK_ANSI_4 = 0x15;
+ private static final short kVK_ANSI_6 = 0x16;
+ private static final short kVK_ANSI_5 = 0x17;
+ private static final short kVK_ANSI_Equal = 0x18;
+ private static final short kVK_ANSI_9 = 0x19;
+ private static final short kVK_ANSI_7 = 0x1A;
+ private static final short kVK_ANSI_Minus = 0x1B;
+ private static final short kVK_ANSI_8 = 0x1C;
+ private static final short kVK_ANSI_0 = 0x1D;
+ private static final short kVK_ANSI_RightBracket = 0x1E;
+ private static final short kVK_ANSI_O = 0x1F;
+ private static final short kVK_ANSI_U = 0x20;
+ private static final short kVK_ANSI_LeftBracket = 0x21;
+ private static final short kVK_ANSI_I = 0x22;
+ private static final short kVK_ANSI_P = 0x23;
+ private static final short kVK_ANSI_L = 0x25;
+ private static final short kVK_ANSI_J = 0x26;
+ private static final short kVK_ANSI_Quote = 0x27;
+ private static final short kVK_ANSI_K = 0x28;
+ private static final short kVK_ANSI_Semicolon = 0x29;
+ private static final short kVK_ANSI_Backslash = 0x2A;
+ private static final short kVK_ANSI_Comma = 0x2B;
+ private static final short kVK_ANSI_Slash = 0x2C;
+ private static final short kVK_ANSI_N = 0x2D;
+ private static final short kVK_ANSI_M = 0x2E;
+ private static final short kVK_ANSI_Period = 0x2F;
+ private static final short kVK_ANSI_Grave = 0x32;
+ private static final short kVK_ANSI_KeypadDecimal = 0x41;
+ private static final short kVK_ANSI_KeypadMultiply = 0x43;
+ private static final short kVK_ANSI_KeypadPlus = 0x45;
+ private static final short kVK_ANSI_KeypadClear = 0x47;
+ private static final short kVK_ANSI_KeypadDivide = 0x4B;
+ private static final short kVK_ANSI_KeypadEnter = 0x4C;
+ private static final short kVK_ANSI_KeypadMinus = 0x4E;
+ private static final short kVK_ANSI_KeypadEquals = 0x51;
+ private static final short kVK_ANSI_Keypad0 = 0x52;
+ private static final short kVK_ANSI_Keypad1 = 0x53;
+ private static final short kVK_ANSI_Keypad2 = 0x54;
+ private static final short kVK_ANSI_Keypad3 = 0x55;
+ private static final short kVK_ANSI_Keypad4 = 0x56;
+ private static final short kVK_ANSI_Keypad5 = 0x57;
+ private static final short kVK_ANSI_Keypad6 = 0x58;
+ private static final short kVK_ANSI_Keypad7 = 0x59;
+ private static final short kVK_ANSI_Keypad8 = 0x5B;
+ private static final short kVK_ANSI_Keypad9 = 0x5C;
+
+ //
+ // KeyCodes (Layout Independent)
+ //
+ private static final short kVK_Return = 0x24;
+ private static final short kVK_Tab = 0x30;
+ private static final short kVK_Space = 0x31;
+ private static final short kVK_Delete = 0x33;
+ private static final short kVK_Escape = 0x35;
+ private static final short kVK_Command = 0x37;
+ private static final short kVK_Shift = 0x38;
+ private static final short kVK_CapsLock = 0x39;
+ private static final short kVK_Option = 0x3A;
+ private static final short kVK_Control = 0x3B;
+ private static final short kVK_RightShift = 0x3C;
+ private static final short kVK_RightOption = 0x3D;
+ private static final short kVK_RightControl = 0x3E;
+ // private static final short kVK_Function = 0x3F;
+ private static final short kVK_F17 = 0x40;
+ // private static final short kVK_VolumeUp = 0x48;
+ // private static final short kVK_VolumeDown = 0x49;
+ // private static final short kVK_Mute = 0x4A;
+ private static final short kVK_F18 = 0x4F;
+ private static final short kVK_F19 = 0x50;
+ private static final short kVK_F20 = 0x5A;
+ private static final short kVK_F5 = 0x60;
+ private static final short kVK_F6 = 0x61;
+ private static final short kVK_F7 = 0x62;
+ private static final short kVK_F3 = 0x63;
+ private static final short kVK_F8 = 0x64;
+ private static final short kVK_F9 = 0x65;
+ private static final short kVK_F11 = 0x67;
+ private static final short kVK_F13 = 0x69;
+ private static final short kVK_F16 = 0x6A;
+ private static final short kVK_F14 = 0x6B;
+ private static final short kVK_F10 = 0x6D;
+ private static final short kVK_F12 = 0x6F;
+ private static final short kVK_F15 = 0x71;
+ private static final short kVK_Help = 0x72;
+ private static final short kVK_Home = 0x73;
+ private static final short kVK_PageUp = 0x74;
+ private static final short kVK_ForwardDelete = 0x75;
+ private static final short kVK_F4 = 0x76;
+ private static final short kVK_End = 0x77;
+ private static final short kVK_F2 = 0x78;
+ private static final short kVK_PageDown = 0x79;
+ private static final short kVK_F1 = 0x7A;
+ private static final short kVK_LeftArrow = 0x7B;
+ private static final short kVK_RightArrow = 0x7C;
+ private static final short kVK_DownArrow = 0x7D;
+ private static final short 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;
@@ -109,6 +182,7 @@ public class MacKeyUtil {
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;
@@ -120,6 +194,7 @@ public class MacKeyUtil {
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;
@@ -130,10 +205,11 @@ public class MacKeyUtil {
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 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;
@@ -153,10 +229,83 @@ public class MacKeyUtil {
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) {
+ static short validateKeyCode(short keyCode, char keyChar) {
// OS X Virtual Keycodes
switch(keyCode) {
+ //
+ // KeyCodes (Layout Dependent)
+ //
+ case kVK_ANSI_A: return KeyEvent.VK_A;
+ case kVK_ANSI_S: return KeyEvent.VK_S;
+ case kVK_ANSI_D: return KeyEvent.VK_D;
+ case kVK_ANSI_F: return KeyEvent.VK_F;
+ case kVK_ANSI_H: return KeyEvent.VK_H;
+ case kVK_ANSI_G: return KeyEvent.VK_G;
+ case kVK_ANSI_Z: return KeyEvent.VK_Z;
+ case kVK_ANSI_X: return KeyEvent.VK_X;
+ case kVK_ANSI_C: return KeyEvent.VK_C;
+ case kVK_ANSI_V: return KeyEvent.VK_V;
+ case kVK_ANSI_B: return KeyEvent.VK_B;
+ case kVK_ANSI_Q: return KeyEvent.VK_Q;
+ case kVK_ANSI_W: return KeyEvent.VK_W;
+ case kVK_ANSI_E: return KeyEvent.VK_E;
+ case kVK_ANSI_R: return KeyEvent.VK_R;
+ case kVK_ANSI_Y: return KeyEvent.VK_Y;
+ case kVK_ANSI_T: return KeyEvent.VK_T;
+ case kVK_ANSI_1: return KeyEvent.VK_1;
+ case kVK_ANSI_2: return KeyEvent.VK_2;
+ case kVK_ANSI_3: return KeyEvent.VK_3;
+ case kVK_ANSI_4: return KeyEvent.VK_4;
+ case kVK_ANSI_6: return KeyEvent.VK_6;
+ case kVK_ANSI_5: return KeyEvent.VK_5;
+ case kVK_ANSI_Equal: return KeyEvent.VK_EQUALS;
+ case kVK_ANSI_9: return KeyEvent.VK_9;
+ case kVK_ANSI_7: return KeyEvent.VK_7;
+ case kVK_ANSI_Minus: return KeyEvent.VK_MINUS;
+ case kVK_ANSI_8: return KeyEvent.VK_8;
+ case kVK_ANSI_0: return KeyEvent.VK_0;
+ case kVK_ANSI_RightBracket: return KeyEvent.VK_CLOSE_BRACKET;
+ case kVK_ANSI_O: return KeyEvent.VK_O;
+ case kVK_ANSI_U: return KeyEvent.VK_U;
+ case kVK_ANSI_LeftBracket: return KeyEvent.VK_OPEN_BRACKET;
+ case kVK_ANSI_I: return KeyEvent.VK_I;
+ case kVK_ANSI_P: return KeyEvent.VK_P;
+ case kVK_ANSI_L: return KeyEvent.VK_L;
+ case kVK_ANSI_J: return KeyEvent.VK_J;
+ case kVK_ANSI_Quote: return KeyEvent.VK_QUOTE;
+ case kVK_ANSI_K: return KeyEvent.VK_K;
+ case kVK_ANSI_Semicolon: return KeyEvent.VK_SEMICOLON;
+ case kVK_ANSI_Backslash: return KeyEvent.VK_BACK_SLASH;
+ case kVK_ANSI_Comma: return KeyEvent.VK_COMMA;
+ case kVK_ANSI_Slash: return KeyEvent.VK_SLASH;
+ case kVK_ANSI_N: return KeyEvent.VK_N;
+ case kVK_ANSI_M: return KeyEvent.VK_M;
+ case kVK_ANSI_Period: return KeyEvent.VK_PERIOD;
+ case kVK_ANSI_Grave: return KeyEvent.VK_BACK_QUOTE; // KeyEvent.VK_DEAD_GRAVE
+ case kVK_ANSI_KeypadDecimal: return KeyEvent.VK_DECIMAL;
+ case kVK_ANSI_KeypadMultiply: return KeyEvent.VK_MULTIPLY;
+ case kVK_ANSI_KeypadPlus: return KeyEvent.VK_PLUS;
+ case kVK_ANSI_KeypadClear: return KeyEvent.VK_CLEAR;
+ case kVK_ANSI_KeypadDivide: return KeyEvent.VK_DIVIDE;
+ case kVK_ANSI_KeypadEnter: return KeyEvent.VK_ENTER;
+ case kVK_ANSI_KeypadMinus: return KeyEvent.VK_MINUS;
+ case kVK_ANSI_KeypadEquals: return KeyEvent.VK_EQUALS;
+ case kVK_ANSI_Keypad0: return KeyEvent.VK_0;
+ case kVK_ANSI_Keypad1: return KeyEvent.VK_1;
+ case kVK_ANSI_Keypad2: return KeyEvent.VK_2;
+ case kVK_ANSI_Keypad3: return KeyEvent.VK_3;
+ case kVK_ANSI_Keypad4: return KeyEvent.VK_4;
+ case kVK_ANSI_Keypad5: return KeyEvent.VK_5;
+ case kVK_ANSI_Keypad6: return KeyEvent.VK_6;
+ case kVK_ANSI_Keypad7: return KeyEvent.VK_7;
+ case kVK_ANSI_Keypad8: return KeyEvent.VK_8;
+ case kVK_ANSI_Keypad9: return KeyEvent.VK_9;
+
+ //
+ // KeyCodes (Layout Independent)
+ //
case kVK_Return: return KeyEvent.VK_ENTER;
case kVK_Tab: return KeyEvent.VK_TAB;
case kVK_Space: return KeyEvent.VK_SPACE;
@@ -270,15 +419,8 @@ public class MacKeyUtil {
// NSFindFunctionKey
// NSHelpFunctionKey
// NSModeSwitchFunctionKey
- case 0x60: return KeyEvent.VK_BACK_QUOTE; // `
- case 0x27: return KeyEvent.VK_QUOTE; // '
- case '\r': return KeyEvent.VK_ENTER;
- }
-
- 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)
+ return (short) keyChar; // let's hope for the best (compatibility of keyChar/keyCode's)
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 5755bdf11..6e9335f08 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -41,7 +41,6 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
-import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
@@ -50,6 +49,7 @@ import jogamp.newt.WindowImpl;
import jogamp.newt.driver.DriverClearFocus;
import jogamp.newt.driver.DriverUpdatePosition;
+import com.jogamp.common.util.Function;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
@@ -86,7 +86,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
sscSurfaceHandle = 0;
isOffscreenInstance = false;
if (0 != handle) {
- close0(handle);
+ OSXUtil.RunOnMainThread(true, new Runnable() {
+ public void run() {
+ close0( handle );
+ } } );
}
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -140,6 +143,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
setTitle0(getWindowHandle(), title);
}
+ @Override
protected void requestFocusImpl(boolean force) {
if(!isOffscreenInstance) {
requestFocus0(getWindowHandle(), force);
@@ -148,6 +152,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
}
+ @Override
public final void clearFocus() {
if(DEBUG_IMPLEMENTATION) {
System.err.println("MacWindow: clearFocus(), isOffscreenInstance "+isOffscreenInstance);
@@ -159,29 +164,59 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
}
+ @Override
public void updatePosition() {
- final Point pS = getTopLevelLocationOnScreen(getX(), getY());
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow: updatePosition() - isOffscreenInstance "+isOffscreenInstance+", new abs pos: pS "+pS);
+ final long handle = getWindowHandle();
+ if( 0 != handle && !isOffscreenInstance ) {
+ final Point pS = getLocationOnScreenImpl(0, 0);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: updatePosition() -> abs child-client-pos: "+pS);
+ }
+ setWindowClientTopLeftPoint0(handle, pS.getX(), pS.getY());
+ // no native event (fullscreen, some reparenting)
+ positionChanged(true, pS.getX(), pS.getY());
}
- if( !isOffscreenInstance ) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
- } // else no offscreen position
- // no native event (fullscreen, some reparenting)
- super.positionChanged(true, getX(), getY());
- }
-
+ }
+ @Override
+ protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
+ final long handle = getWindowHandle();
+ if( 0 != handle && !isOffscreenInstance ) {
+ final NativeWindow parent = getParent();
+ final boolean useParent = null != parent && 0 != parent.getWindowHandle() ;
+ if( useParent && ( getWidth() != newWidth || getHeight() != newHeight ) ) {
+ final Point p0S = getLocationOnScreenImpl(0, 0);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: sizeChanged() "+newWidth+"x"+newHeight+" -> abs child-client-pos "+p0S);
+ }
+ setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY());
+ }
+ }
+ super.sizeChanged(defer, newWidth, newHeight, force);
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
- final PointImmutable pS = isOffscreenInstance ? new Point(0, 0) : getTopLevelLocationOnScreen(x, y);
+ final PointImmutable pClientLevelOnSreen;
+ if( isOffscreenInstance ) {
+ pClientLevelOnSreen = new Point(0, 0);
+ } else {
+ final NativeWindow parent = getParent();
+ final boolean useParent = null != parent && 0 != parent.getWindowHandle() ;
+ if( useParent ) {
+ pClientLevelOnSreen = getLocationOnScreenImpl(x, y);
+ } else {
+ pClientLevelOnSreen = new Point(x, y);
+ }
+ }
if(DEBUG_IMPLEMENTATION) {
final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
final NativeWindow pWin = getParent();
final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
- System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
+ System.err.println("MacWindow reconfig.0: "+x+"/"+y+" -> clientPos "+pClientLevelOnSreen+" - "+width+"x"+height+
",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
",\n\t this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+
@@ -189,6 +224,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
", ioi: "+_isOffscreenInstance+
") -> "+isOffscreenInstance+
"\n\t, "+getReconfigureFlagsAsString(null, flags));
+ Thread.dumpStack();
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
@@ -203,25 +239,20 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
0 != ( FLAG_CHANGE_PARENTING & flags) ||
0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
if(isOffscreenInstance) {
- createWindow(true, 0 != getWindowHandle(), pS, 64, 64, false);
+ createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, false);
} else {
- createWindow(false, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
}
if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
}
- if(x>=0 && y>=0) {
- if( !isOffscreenInstance ) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
- } // else no offscreen position
- // no native event (fullscreen, some reparenting)
- super.positionChanged(true, x, y);
- }
- if(width>0 && height>0) {
+ if( width>0 && height>0 && x>=0 && y>=0 ) {
if( !isOffscreenInstance ) {
- setContentSize0(getWindowHandle(), width, height);
+ // setContentSize0(getWindowHandle(), width, height);
+ setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height);
} // else offscreen size is realized via recreation
// no native event (fullscreen, some reparenting)
- sizeChanged(true, width, height, false); // incl. validation (incl. repositioning)
+ positionChanged(true, x, y);
+ sizeChanged(true, width, height, false);
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) {
if( !isOffscreenInstance ) {
@@ -233,9 +264,13 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
if( !isOffscreenInstance ) {
setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow reconfig.X: clientPos "+pClientLevelOnSreen+", "+width+"x"+height+" -> clientPos "+getLocationOnScreenImpl(0, 0)+", insets: "+getInsets());
+ }
return true;
}
+ @Override
protected Point getLocationOnScreenImpl(int x, int y) {
final NativeWindow parent = getParent();
final boolean useParent = null != parent && 0 != parent.getWindowHandle() ;
@@ -253,39 +288,28 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
return p;
}
-
- private Point getTopLevelLocationOnScreen(int x, int y) {
- final InsetsImmutable _insets = getInsets(); // zero if undecorated
- // client position -> top-level window position
- x -= _insets.getLeftWidth() ;
- y -= _insets.getTopHeight() ;
- return getLocationOnScreenImpl(x, y);
- }
-
+
+ @Override
protected void updateInsetsImpl(Insets insets) {
// nop - using event driven insetsChange(..)
}
- @Override
- protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
- if(getWidth() != newWidth || getHeight() != newHeight) {
- final Point p0S = getTopLevelLocationOnScreen(getX(), getY());
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), p0S.getX(), p0S.getY());
- }
- super.sizeChanged(defer, newWidth, newHeight, force);
- }
-
- @Override
- protected void positionChanged(boolean defer, int newX, int newY) {
+ /** Callback for native screen position change event of the client area. */
+ protected void screenPositionChanged(boolean defer, int newX, int newY) {
// passed coordinates are in screen position of the client area
- if(getWindowHandle()!=0) {
- // screen position -> window position
- Point absPos = new Point(newX, newY);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow.positionChanged (Screen Pos): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY);
+ }
+ if(getWindowHandle()!=0) {
final NativeWindow parent = getParent();
- if(null != parent) {
+ if(null == parent) {
+ positionChanged(defer, newX, newY);
+ } else {
+ // screen position -> rel child window position
+ Point absPos = new Point(newX, newY);
absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) );
+ positionChanged(defer, absPos.getX(), absPos.getY());
}
- super.positionChanged(defer, absPos.getX(), absPos.getY());
}
}
@@ -312,20 +336,21 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
} // else may need offscreen solution ? FIXME
}
- private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- if( send ) {
- super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
- } else {
- super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
- }
+ @Override
+ public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
}
-
- private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int _keyCode, char keyChar) {
+
+ @Override
+ public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short _keyCode, short keySym, char keyChar) {
// 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
- final int keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
- // final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
- // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", key 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+", mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+ final short keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
+ /* {
+ final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+ System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", key 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+", mods "+toHexString(modifiers)+
+ ", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+ } */
// 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED
// Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE and TYPED keys _before_ PRESSED
@@ -342,25 +367,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
// key was already pressed
keyRepeatState.put(keyCode, true); // prev == false -> AR in
modifiers |= InputEvent.AUTOREPEAT_MASK;
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar); // RELEASED
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED
+ super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyCode, keyChar); // RELEASED
}
}
break;
- case KeyEvent.EVENT_KEY_TYPED:
- break;
}
- emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
- }
-
- @Override
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
- }
-
- @Override
- public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyCode, keyChar);
}
//----------------------------------------------------------------------
@@ -378,24 +390,36 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
try {
if(0!=getWindowHandle()) {
// save the view .. close the window
- surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
+ surfaceHandle = OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
+ public Long eval(Object... args) {
+ return Long.valueOf(
+ changeContentView0(getParentWindowHandle(), getWindowHandle(), 0) );
+ } } ).longValue();
if(recreate && 0==surfaceHandle) {
throw new NativeWindowException("Internal Error - recreate, window but no view");
}
- close0(getWindowHandle());
+ OSXUtil.RunOnMainThread(true, new Runnable() {
+ public void run() {
+ close0( getWindowHandle() );
+ } } );
setWindowHandle(0);
} else {
surfaceHandle = 0;
}
- setWindowHandle(createWindow0(getParentWindowHandle(),
- pS.getX(), pS.getY(), width, height,
- (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance),
- fullscreen,
- ((isUndecorated() || offscreenInstance) ?
- NSBorderlessWindowMask :
- NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
- NSBackingStoreBuffered,
- getScreen().getIndex(), surfaceHandle));
+
+ setWindowHandle( OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
+ public Long eval(Object... args) {
+ return Long.valueOf(
+ createWindow0( getParentWindowHandle(),
+ pS.getX(), pS.getY(), width, height,
+ (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance),
+ fullscreen,
+ ( (isUndecorated() || offscreenInstance) ? NSBorderlessWindowMask :
+ NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask ),
+ NSBackingStoreBuffered,
+ getScreen().getIndex(), surfaceHandle) );
+ } } ).longValue() );
+
if (getWindowHandle() == 0) {
throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
}
@@ -411,6 +435,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
protected static native boolean initIDs0();
+ /** Must be called on Main-Thread */
private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h,
boolean opaque, boolean fullscreen, int windowStyle,
int backingStoreType,
@@ -422,12 +447,14 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
/** in case of a child window, it actually only issues orderBack(..) */
private native void orderOut0(long window);
private native void orderFront0(long window);
+ /** Must be called on Main-Thread */
private native void close0(long window);
private native void setTitle0(long window, String title);
private native long contentView0(long window);
+ /** Must be called on Main-Thread */
private native long changeContentView0(long parentWindowOrViewHandle, long window, long view);
- private native void setContentSize0(long window, int w, int h);
- private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y);
+ private native void setWindowClientTopLeftPointAndSize0(long window, int x, int y, int w, int h);
+ private native void setWindowClientTopLeftPoint0(long window, int x, int y);
private native void setAlwaysOnTop0(long window, boolean atop);
private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y);
private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible);
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 650958f25..475687eb4 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -46,7 +46,6 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
-import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseAdapter;
@@ -261,87 +260,55 @@ public class WindowDriver extends WindowImpl {
// nop - using event driven insetsChange(..)
}
- private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- if( send ) {
- super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
- } else {
- super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
- }
+ private final boolean handlePressTypedAutoRepeat(boolean isModifierKey, int modifiers, short keyCode, short keySym, char keyChar) {
+ if( isKeyCodeTracked(keyCode) && keyPressedState.put(keyCode, true) ) {
+ final boolean preKeyRepeatState = keyRepeatState.put(keyCode, true);
+ if( !isModifierKey ) {
+ // AR: Key was already pressed: Either [enter | within] AR mode
+ modifiers |= InputEvent.AUTOREPEAT_MASK;
+ if( preKeyRepeatState ) {
+ // AR: Within AR mode
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keySym, keyChar);
+ } // else { AR: Enter AR mode - skip already send PRESSED ; or ALT }
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar);
+ }
+ return true;
+ }
+ return false;
}
- /** FIXME: We have to store the keyChar for typed events, since keyChar from pressed/released may be wrong (Uppercase: SHIFT-1, etc ..). */
- private IntIntHashMap typedKeyCode2KeyChar = new IntIntHashMap(KeyEvent.VK_CONTEXT_MENU+1);
-
- private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- final boolean isPrintableKey = KeyEvent.isPrintableKey(keyCode);
- final boolean isModifierKey = KeyEvent.isModifierKey(keyCode);
- // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", printableKey "+isPrintableKey+" [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis());
+ @Override
+ public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ final boolean isModifierKey = KeyEvent.isModifierKey(keySym);
+ // System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+
+ // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", printableKey "+KeyEvent.isPrintableKey(keyCode)+" [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis());
// Reorder: WINDOWS delivery order is PRESSED (t0), TYPED (t0) and RELEASED (t1) -> NEWT order: PRESSED (t0), RELEASED (t1) and TYPED (t1)
// Auto-Repeat: WINDOWS delivers only PRESSED (t0) and TYPED (t0).
switch(eventType) {
case KeyEvent.EVENT_KEY_RELEASED:
- final int keyCharTyped = typedKeyCode2KeyChar.put(keyCode, 0);
- if( 0 != keyCharTyped ) {
- keyChar = (char)keyCharTyped;
- }
if( isKeyCodeTracked(keyCode) ) {
if( keyRepeatState.put(keyCode, false) && !isModifierKey ) {
// AR out - send out missing PRESSED
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keySym, keyChar);
}
keyPressedState.put(keyCode, false);
}
- emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar);
break;
case KeyEvent.EVENT_KEY_PRESSED:
- // TYPED is delivered right after PRESSED for printable keys and contains the key-char information,
- // hence we only deliver non printable keys (action and modifier keys) here.
- // Modifier keys shall not AR.
- if( !isPrintableKey ) {
- if( !handlePressTypedAutoRepeat(isModifierKey, send, wait, modifiers, keyCode, keyChar) ) {
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keyChar);
- }
- }
- break;
- case KeyEvent.EVENT_KEY_TYPED:
- if( isPrintableKey ) {
- typedKeyCode2KeyChar.put(keyCode, keyChar);
- if( !handlePressTypedAutoRepeat(isModifierKey, send, wait, modifiers, keyCode, keyChar) ) {
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keyChar);
- }
+ if( !handlePressTypedAutoRepeat(isModifierKey, modifiers, keyCode, keySym, keyChar) ) {
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keySym, keyChar);
}
break;
+ // case KeyEvent.EVENT_KEY_TYPED:
+ // break;
}
}
- private final boolean handlePressTypedAutoRepeat(boolean isModifierKey, boolean send, boolean wait, int modifiers, int keyCode, char keyChar) {
- if( isKeyCodeTracked(keyCode) && keyPressedState.put(keyCode, true) ) {
- final boolean preKeyRepeatState = keyRepeatState.put(keyCode, true);
- if( !isModifierKey ) {
- // AR: Key was already pressed: Either [enter | within] AR mode
- modifiers |= InputEvent.AUTOREPEAT_MASK;
- if( preKeyRepeatState ) {
- // AR: Within AR mode
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keyChar);
- } // else { AR: Enter AR mode - skip already send PRESSED ; or ALT }
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar);
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
- }
- return true;
- }
- return false;
- }
-
- @Override
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
- }
-
@Override
- public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
+ public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index c55fddd07..8d33d4d73 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.util.Point;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseEvent;
public class WindowDriver extends WindowImpl {
@@ -227,8 +228,8 @@ public class WindowDriver extends WindowImpl {
}
@Override
- protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
- int x, int y, int button, float rotation) {
+ protected final void doMouseEvent(boolean enqueue, boolean wait, short eventType, int modifiers,
+ int x, int y, short button, float rotation) {
switch(eventType) {
case MouseEvent.EVENT_MOUSE_PRESSED:
switch(button) {
@@ -270,6 +271,34 @@ public class WindowDriver extends WindowImpl {
super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotation);
}
+ @Override
+ public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ // handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
+ final boolean isModifierKey = KeyEvent.isModifierKey(keyCode);
+ final boolean isAutoRepeat = 0 != ( KeyEvent.AUTOREPEAT_MASK & modifiers );
+ // System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+
+ // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isAutoRepeat+", [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis());
+
+ if( !isAutoRepeat || !isModifierKey ) { // ! ( isModifierKey && isAutoRepeat )
+ switch(eventType) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keySym, keyChar);
+ break;
+
+ case KeyEvent.EVENT_KEY_RELEASED:
+ super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar);
+ break;
+
+ // case KeyEvent.EVENT_KEY_TYPED:
+ // break;
+ }
+ }
+ }
+
+ @Override
+ public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
+ throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
+ }
//----------------------------------------------------------------------
// Internals only
diff --git a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
index 0fc487e91..1ebb714fa 100644
--- a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
+++ b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
@@ -32,7 +32,6 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
-import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.event.InputEvent;
/**
@@ -43,26 +42,22 @@ import com.jogamp.newt.event.InputEvent;
*/
public class SWTNewtEventFactory {
- protected static final IntIntHashMap eventTypeSWT2NEWT;
+ public static final short eventTypeSWT2NEWT(int swtType) {
+ switch( swtType ) {
+ // case SWT.MouseXXX: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED;
+ case SWT.MouseDown: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED;
+ case SWT.MouseUp: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED;
+ case SWT.MouseMove: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED;
+ case SWT.MouseEnter: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED;
+ case SWT.MouseExit: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED;
+ // case SWT.MouseXXX: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED;
+ case SWT.MouseVerticalWheel: return com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
- static {
- IntIntHashMap map = new IntIntHashMap();
- map.setKeyNotFoundValue(0xFFFFFFFF);
-
- // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED);
- map.put(SWT.MouseDown, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED);
- map.put(SWT.MouseUp, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED);
- map.put(SWT.MouseMove, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED);
- map.put(SWT.MouseEnter, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED);
- map.put(SWT.MouseExit, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED);
- // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED);
- map.put(SWT.MouseVerticalWheel, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED);
-
- map.put(SWT.KeyDown, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED);
- map.put(SWT.KeyUp, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED);
- // map.put(SWT.KeyXXX, com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED);
-
- eventTypeSWT2NEWT = map;
+ case SWT.KeyDown: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED;
+ case SWT.KeyUp: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED;
+ // case SWT.KeyXXX: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED;
+ }
+ return (short)0;
}
public static final int swtModifiers2Newt(int awtMods, boolean mouseHint) {
@@ -93,8 +88,8 @@ public class SWTNewtEventFactory {
default:
return null;
}
- int type = eventTypeSWT2NEWT.get(event.type);
- if(0xFFFFFFFF != type) {
+ final short type = eventTypeSWT2NEWT(event.type);
+ if( (short)0 != type ) {
float rotation = 0;
if (SWT.MouseVerticalWheel == event.type) {
// SWT/NEWT rotation is reversed - AWT +1 is down, NEWT +1 is up.
@@ -116,7 +111,7 @@ public class SWTNewtEventFactory {
return new com.jogamp.newt.event.MouseEvent(
type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time),
- mods, event.x, event.y, event.count, event.button, rotation);
+ mods, event.x, event.y, (short)event.count, (short)event.button, rotation);
}
return null; // no mapping ..
}
@@ -129,12 +124,12 @@ public class SWTNewtEventFactory {
default:
return null;
}
- int type = eventTypeSWT2NEWT.get(event.type);
- if(0xFFFFFFFF != type) {
+ final short type = eventTypeSWT2NEWT(event.type);
+ if( (short)0 != type ) {
return new com.jogamp.newt.event.KeyEvent(
type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time),
swtModifiers2Newt(event.stateMask, false),
- event.keyCode, event.character);
+ (short)event.keyCode, (short)event.keyCode, event.character);
}
return null; // no mapping ..
}
@@ -143,7 +138,7 @@ public class SWTNewtEventFactory {
//
//
- int dragButtonDown = 0;
+ short dragButtonDown = 0;
public SWTNewtEventFactory() {
resetButtonsDown();
@@ -159,7 +154,7 @@ public class SWTNewtEventFactory {
if(null != l) {
switch(event.type) {
case SWT.MouseDown:
- dragButtonDown = event.button;
+ dragButtonDown = (short) event.button;
l.mousePressed(res); break;
case SWT.MouseUp:
dragButtonDown = 0;
@@ -214,7 +209,6 @@ public class SWTNewtEventFactory {
break;
case SWT.KeyUp:
l.keyReleased(res);
- l.keyTyped(res);
break;
}
}
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 3d059c336..cfec60dc1 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -161,14 +161,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
if(KD_INPUT_POINTER_SELECT==ptr->index) {
DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y);
(*env)->CallVoidMethod(env, javaWindow, sendMouseEventID,
- (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED,
+ (ptr->select==0) ? (jshort) EVENT_MOUSE_RELEASED : (jshort) EVENT_MOUSE_PRESSED,
(jint) 0,
- (jint) ptr->x, (jint) ptr->y, 1, 0.0f);
+ (jint) ptr->x, (jint) ptr->y, (short)1, 0.0f);
} else {
DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y);
- (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
0,
- (jint) ptr->x, (jint) ptr->y, 0, 0.0f);
+ (jint) ptr->x, (jint) ptr->y, (jshort)0, 0.0f);
}
}
break;
@@ -193,8 +193,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_WindowDriver_initIDs
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIIF)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
if (windowCreatedID == NULL ||
sizeChangedID == NULL ||
visibleChangedID == NULL ||
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index b9c339285..1895b98a5 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -62,14 +62,25 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
return str;
}
-static void setFrameTopLeftPoint(NSWindow* pWin, NewtMacWindow* mWin, jint x, jint y) {
- NSPoint pS = [mWin newtScreenWinPos2OSXScreenPos: NSMakePoint(x, y)];
+static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y) {
+ NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)];
[mWin setFrameOrigin: pS];
NSView* mView = [mWin contentView];
[mWin invalidateCursorRectsForView: mView];
}
+static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height) {
+ NSSize sz = NSMakeSize(width, height);
+ NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: sz];
+ NSRect rect = { pS, sz };
+ [mWin setFrame: rect display:YES];
+
+ // -> display:YES
+ // NSView* mView = [mWin contentView];
+ // [mWin invalidateCursorRectsForView: mView];
+}
+
#ifdef VERBOSE_ON
static int getRetainCount(NSObject * obj) {
return ( NULL == obj ) ? -1 : (int)([obj retainCount]) ;
@@ -553,7 +564,9 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
return (jboolean) res;
}
-/*
+/**
+ * Method is called on Main-Thread, hence no special invocation required inside method.
+ *
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: createWindow0
* Signature: (JIIIIZIIIJ)J
@@ -573,21 +586,21 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
if(screen_idx<0) screen_idx=0;
if(screen_idx>=[screens count]) screen_idx=0;
NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx];
- NSRect rect;
+ NSRect rectWin;
if (fullscreen) {
styleMask = NSBorderlessWindowMask;
- rect = [myScreen frame];
+ rectWin = [myScreen frame];
x = 0;
y = 0;
- w = (jint) (rect.size.width);
- h = (jint) (rect.size.height);
+ w = (jint) (rectWin.size.width);
+ h = (jint) (rectWin.size.height);
} else {
- rect = NSMakeRect(x, y, w, h);
+ rectWin = NSMakeRect(x, y, w, h);
}
// Allocate the window
- NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rect
+ NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rectWin
styleMask: (NSUInteger) styleMask
backing: (NSBackingStoreType) bufferingType
defer: NO
@@ -644,7 +657,8 @@ NS_ENDHANDLER
// Use given NewtView or allocate an NewtView if NULL
if(NULL == myView) {
- myView = [[NewtView alloc] initWithFrame: rect] ;
+ NSRect rectView = NSMakeRect(0, 0, w, h);
+ myView = [[NewtView alloc] initWithFrame: rectView] ;
DBG_PRINT( "createWindow0.%d - use new view: %p,%d\n", dbgIdx++, myView, getRetainCount(myView));
} else {
DBG_PRINT( "createWindow0.%d - use given view: %p,%d\n", dbgIdx++, myView, getRetainCount(myView));
@@ -664,7 +678,7 @@ NS_ENDHANDLER
}
// Immediately re-position the window based on an upper-left coordinate system
- setFrameTopLeftPoint(parentWindow, myWindow, x, y);
+ setWindowClientTopLeftPoint(myWindow, x, y);
// force surface creation
[myView lockFocus];
@@ -706,19 +720,10 @@ NS_ENDHANDLER
return (jlong) ((intptr_t) myWindow);
}
-// Footnote: Our view handling produces random 'Assertion failure' even w/o parenting:
-//
-// [NSThemeFrame lockFocus], /SourceCache/AppKit/AppKit-1138.23/AppKit.subproj/NSView.m:6053
-// [NSThemeFrame(0x7fe94bc72c80) lockFocus] failed with window=0x7fe94bc445a0, windowNumber=9425, [self isHiddenOrHasHiddenAncestor]=0
-// ..
-// AppKit 0x00007fff89621001 -[NSView lockFocus] + 250
-// AppKit 0x00007fff8961eafa -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 3780
-// AppKit 0x00007fff8961793e -[NSView displayIfNeeded] + 1676
-// AppKit 0x00007fff8961707d _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 648
-//
-
-/*
+/**
+ * Method is called on Main-Thread, hence no special invocation required inside method.
+ *
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: close0
* Signature: (J)V
@@ -761,8 +766,6 @@ NS_DURING
[mView exitFullScreenModeWithOptions: NULL];
}
// Note: mWin's release will also release it's mView!
- // [mWin setContentView: nil];
- // [mView release];
}
NS_HANDLER
NS_ENDHANDLER
@@ -770,7 +773,8 @@ NS_ENDHANDLER
if(NULL!=pWin) {
[mWin detachFromParent: pWin];
}
- [mWin performSelectorOnMainThread:@selector(orderOut:) withObject:mWin waitUntilDone:NO];
+ // [mWin performSelectorOnMainThread:@selector(orderOut:) withObject:mWin waitUntilDone:NO];
+ [mWin orderOut: mWin];
DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
@@ -778,7 +782,8 @@ NS_ENDHANDLER
// Only release window, if release is not yet in process.
// E.g. destroyNotifySent:=true set by NewtMacWindow::windowWillClose(), i.e. window-close was clicked.
if(!destroyNotifySent) {
- [mWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
+ // [mWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
+ [mWin release];
}
DBG_PRINT( "windowClose.X - %p,%d, released %d, view %p,%d, parent %p\n",
@@ -960,7 +965,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0
return res;
}
-/*
+/**
+ * Method is called on Main-Thread, hence no special invocation required inside method.
+ *
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: changeContentView
* Signature: (J)J
@@ -1005,50 +1012,40 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeConten
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setContentSize
- * Signature: (JII)V
+ * Method: setWindowClientTopLeftPointAndSize0
+ * Signature: (JIIII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setContentSize0
- (JNIEnv *env, jobject unused, jlong window, jint w, jint h)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) window);
+ NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- DBG_PRINT( "setContentSize0 - window: %p (START)\n", win);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
- NSSize sz = NSMakeSize(w, h);
- [win setContentSize: sz];
+ setWindowClientTopLeftPointAndSize(mWin, x, y, w, h);
- DBG_PRINT( "setContentSize0 - window: %p (END)\n", win);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
[pool release];
}
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setFrameTopLeftPoint
- * Signature: (JJII)V
+ * Method: setWindowClientTopLeftPoint0
+ * Signature: (JII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setFrameTopLeftPoint0
- (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- NSObject *nsParentObj = (NSObject*) ((intptr_t) parent);
- NSWindow* pWin = NULL;
- if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) {
- pWin = (NSWindow*) nsParentObj;
- } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) {
- NSView* pView = (NSView*) nsParentObj;
- pWin = [pView window];
- }
-
- DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (START)\n", mWin, pWin);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
- setFrameTopLeftPoint(pWin, mWin, x, y);
+ setWindowClientTopLeftPoint(mWin, x, y);
- DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (END)\n", mWin, pWin);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
[pool release];
}
@@ -1134,6 +1131,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMousePosition: [mWin newtClientWinPos2OSXScreenPos: NSMakePoint(x, y)]];
+ [mWin setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 29b646fbf..6d1bcca00 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -134,8 +134,9 @@
- (void) attachToParent: (NSWindow*) parent;
- (void) detachFromParent: (NSWindow*) parent;
-- (NSPoint) newtScreenWinPos2OSXScreenPos: (NSPoint) p;
-- (NSPoint) newtClientWinPos2OSXScreenPos: (NSPoint) p;
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p;
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz;
+- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p;
- (NSPoint) getLocationOnScreen: (NSPoint) p;
- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
@@ -145,9 +146,9 @@
- (void) setMouseConfined:(BOOL)v;
- (void) setMousePosition:(NSPoint)p;
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType;
-- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType;
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType;
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
+- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
- (void) focusChanged: (BOOL) gained;
- (BOOL) becomeFirstResponder;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 5b826566b..282c13fd3 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -107,6 +107,7 @@ static jmethodID windowRepaintID = NULL;
- (id)initWithFrame:(NSRect)frameRect
{
+ id res = [super initWithFrame:frameRect];
javaWindowObject = NULL;
jvmHandle = NULL;
@@ -129,28 +130,35 @@ static jmethodID windowRepaintID = NULL;
*/
myCursor = NULL;
- return [super initWithFrame:frameRect];
+ DBG_PRINT("NewtView::create: %p (refcnt %d)\n", res, (int)[res retainCount]);
+ return res;
}
- (void) release
{
+ DBG_PRINT("NewtView::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
#ifdef VERBOSE_ON
- NSLog(@"NewtView::release\n");
- NSLog(@"%@",[NSThread callStackSymbols]);
+ // NSLog(@"%@",[NSThread callStackSymbols]);
#endif
[super release];
}
- (void) dealloc
{
+ DBG_PRINT("NewtView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag);
if(softLocked) {
NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
+ if(0 != ptrTrackingTag) {
+ // [self removeCursorRect: ptrRect cursor: myCursor];
+ [self removeTrackingRect: ptrTrackingTag];
+ ptrTrackingTag = 0;
+ }
pthread_mutex_destroy(&softLockSync);
#ifdef VERBOSE_ON
- NSLog(@"NewtView::dealloc\n");
- NSLog(@"%@",[NSThread callStackSymbols]);
+ //NSLog(@"%@",[NSThread callStackSymbols]);
#endif
+ DBG_PRINT("NewtView::dealloc.X: %p\n", self);
[super dealloc];
}
@@ -341,14 +349,14 @@ static jmethodID windowRepaintID = NULL;
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
{
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIIF)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIIF)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+ enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
+ enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISSC)V");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
+ positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
@@ -390,25 +398,31 @@ static jmethodID windowRepaintID = NULL;
mouseInside = NO;
cursorIsHidden = NO;
realized = YES;
+ DBG_PRINT("NewtWindow::create: %p (refcnt %d)\n", res, (int)[res retainCount]);
return res;
}
- (void) release
{
+ DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
#ifdef VERBOSE_ON
- NSLog(@"NewtWindow::release\n");
- NSLog(@"%@",[NSThread callStackSymbols]);
+ // NSLog(@"%@",[NSThread callStackSymbols]);
#endif
[super release];
}
- (void) dealloc
{
+ DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
#ifdef VERBOSE_ON
- NSLog(@"NewtWindow::dealloc\n");
- NSLog(@"%@",[NSThread callStackSymbols]);
+ // NSLog(@"%@",[NSThread callStackSymbols]);
#endif
+ NewtView* mView = (NewtView *)[self contentView];
+ if( NULL != mView ) {
+ [mView release];
+ }
[super dealloc];
+ DBG_PRINT("NewtWindow::dealloc.X: %p\n", self);
}
- (void) setUnrealized
@@ -470,19 +484,28 @@ static jmethodID windowRepaintID = NULL;
}
/**
- * p abs screen position w/ top-left origin
+ * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize
* returns: abs screen position w/ bottom-left origin
*/
-- (NSPoint) newtScreenWinPos2OSXScreenPos: (NSPoint) p
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p
{
NSView* mView = [self contentView];
NSRect mViewFrame = [mView frame];
- int totalHeight = mViewFrame.size.height + cachedInsets[2] + cachedInsets[3]; // height + insets[top+bottom]
+ return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size];
+}
+
+/**
+ * p abs screen position of client-area pos w/ top-left origin, using given client NSSize
+ * returns: abs screen position w/ bottom-left origin
+ */
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz
+{
+ int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom
NSScreen* screen = [self screen];
NSRect screenFrame = [screen frame];
- return NSMakePoint(screenFrame.origin.x + p.x + cachedInsets[0],
+ return NSMakePoint(screenFrame.origin.x + p.x,
screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight);
}
@@ -490,7 +513,7 @@ static jmethodID windowRepaintID = NULL;
* p rel client window position w/ top-left origin
* returns: abs screen position w/ bottom-left origin
*/
-- (NSPoint) newtClientWinPos2OSXScreenPos: (NSPoint) p
+- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p
{
NSRect winFrame = [self frame];
@@ -612,15 +635,15 @@ static jint mods2JavaMods(NSUInteger mods)
return javaMods;
}
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType
{
- jint keyCode = (jint) [event keyCode];
+ jshort keyCode = (jshort) [event keyCode];
NSString* chars = [event charactersIgnoringModifiers];
NSUInteger mods = [event modifierFlags];
[self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
}
-- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType
{
NSView* nsview = [self contentView];
if( ! [nsview isMemberOfClass:[NewtView class]] ) {
@@ -654,10 +677,10 @@ static jint mods2JavaMods(NSUInteger mods)
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
- evType, javaMods, keyCode, keyChar);
+ evType, javaMods, keyCode, keyCode, keyChar);
#else
(*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyChar);
+ evType, javaMods, keyCode, keyCode, keyChar);
#endif
}
} else {
@@ -668,10 +691,10 @@ static jint mods2JavaMods(NSUInteger mods)
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
- evType, javaMods, keyCode, keyChar);
+ evType, javaMods, keyCode, keyCode, keyChar);
#else
(*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyChar);
+ evType, javaMods, keyCode, keyCode, keyChar);
#endif
}
@@ -680,7 +703,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
}
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType
+- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
{
NSView* nsview = [self contentView];
if( ! [nsview isMemberOfClass:[NewtView class]] ) {
@@ -704,7 +727,7 @@ static jint mods2JavaMods(NSUInteger mods)
// convert to 1-based button number (or use zero if no button is involved)
// TODO: detect mouse button when mouse wheel scrolled
- jint javaButtonNum = 0;
+ jshort javaButtonNum = 0;
jfloat scrollDeltaY = 0.0f;
switch ([event type]) {
case NSScrollWheel: {
@@ -836,13 +859,12 @@ static jint mods2JavaMods(NSUInteger mods)
- (void) keyDown: (NSEvent*) theEvent
{
- [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED];
+ [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
}
- (void) keyUp: (NSEvent*) theEvent
{
- [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED];
- [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED];
+ [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
}
#define kVK_Shift 0x38
@@ -854,11 +876,10 @@ static jint mods2JavaMods(NSUInteger mods)
{
if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) {
modsDown[keyIdx] = YES;
- [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_PRESSED];
+ [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED];
} else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) {
modsDown[keyIdx] = NO;
- [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_RELEASED];
- [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_TYPED];
+ [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED];
}
}
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 24d513c68..05953cb86 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -132,9 +132,7 @@ static jmethodID focusChangedID = NULL;
static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
@@ -146,345 +144,294 @@ typedef struct {
} WindowUserData;
typedef struct {
- UINT javaKey;
- UINT windowsKey;
+ USHORT javaKey;
+ USHORT windowsKey;
+ USHORT windowsScanCodeUS;
} KeyMapEntry;
// Static table, arranged more or less spatially.
static KeyMapEntry keyMapTable[] = {
// Modifier keys
- {J_VK_CAPS_LOCK, VK_CAPITAL},
- {J_VK_SHIFT, VK_SHIFT},
- {J_VK_CONTROL, VK_CONTROL},
- {J_VK_ALT, VK_MENU},
- {J_VK_NUM_LOCK, VK_NUMLOCK},
+ {J_VK_CAPS_LOCK, VK_CAPITAL, 0},
+ {J_VK_SHIFT, VK_SHIFT, 0},
+ {J_VK_SHIFT, VK_LSHIFT, 0},
+ {J_VK_SHIFT, VK_RSHIFT, 0},
+ {J_VK_CONTROL, VK_CONTROL, 0},
+ {J_VK_CONTROL, VK_LCONTROL, 0},
+ {J_VK_CONTROL, VK_RCONTROL, 0},
+ {J_VK_ALT, VK_MENU, 0},
+ {J_VK_ALT, VK_LMENU, 0},
+ {J_VK_ALT, VK_RMENU, 0},
+ {J_VK_NUM_LOCK, VK_NUMLOCK, 0},
// Miscellaneous Windows keys
- {J_VK_WINDOWS, VK_LWIN},
- {J_VK_WINDOWS, VK_RWIN},
- {J_VK_CONTEXT_MENU, VK_APPS},
+ {J_VK_WINDOWS, VK_LWIN, 0},
+ {J_VK_WINDOWS, VK_RWIN, 0},
+ {J_VK_CONTEXT_MENU, VK_APPS, 0},
// Alphabet
- {J_VK_A, 'A'},
- {J_VK_B, 'B'},
- {J_VK_C, 'C'},
- {J_VK_D, 'D'},
- {J_VK_E, 'E'},
- {J_VK_F, 'F'},
- {J_VK_G, 'G'},
- {J_VK_H, 'H'},
- {J_VK_I, 'I'},
- {J_VK_J, 'J'},
- {J_VK_K, 'K'},
- {J_VK_L, 'L'},
- {J_VK_M, 'M'},
- {J_VK_N, 'N'},
- {J_VK_O, 'O'},
- {J_VK_P, 'P'},
- {J_VK_Q, 'Q'},
- {J_VK_R, 'R'},
- {J_VK_S, 'S'},
- {J_VK_T, 'T'},
- {J_VK_U, 'U'},
- {J_VK_V, 'V'},
- {J_VK_W, 'W'},
- {J_VK_X, 'X'},
- {J_VK_Y, 'Y'},
- {J_VK_Z, 'Z'},
- {J_VK_0, '0'},
- {J_VK_1, '1'},
- {J_VK_2, '2'},
- {J_VK_3, '3'},
- {J_VK_4, '4'},
- {J_VK_5, '5'},
- {J_VK_6, '6'},
- {J_VK_7, '7'},
- {J_VK_8, '8'},
- {J_VK_9, '9'},
- {J_VK_ENTER, VK_RETURN},
- {J_VK_SPACE, VK_SPACE},
- {J_VK_BACK_SPACE, VK_BACK},
- {J_VK_TAB, VK_TAB},
- {J_VK_ESCAPE, VK_ESCAPE},
- {J_VK_INSERT, VK_INSERT},
- {J_VK_DELETE, VK_DELETE},
- {J_VK_HOME, VK_HOME},
- {J_VK_END, VK_END},
- {J_VK_PAGE_UP, VK_PRIOR},
- {J_VK_PAGE_DOWN, VK_NEXT},
- {J_VK_CLEAR, VK_CLEAR}, // NumPad 5
+ {J_VK_A, 'A', 0},
+ {J_VK_B, 'B', 0},
+ {J_VK_C, 'C', 0},
+ {J_VK_D, 'D', 0},
+ {J_VK_E, 'E', 0},
+ {J_VK_F, 'F', 0},
+ {J_VK_G, 'G', 0},
+ {J_VK_H, 'H', 0},
+ {J_VK_I, 'I', 0},
+ {J_VK_J, 'J', 0},
+ {J_VK_K, 'K', 0},
+ {J_VK_L, 'L', 0},
+ {J_VK_M, 'M', 0},
+ {J_VK_N, 'N', 0},
+ {J_VK_O, 'O', 0},
+ {J_VK_P, 'P', 0},
+ {J_VK_Q, 'Q', 0},
+ {J_VK_R, 'R', 0},
+ {J_VK_S, 'S', 0},
+ {J_VK_T, 'T', 0},
+ {J_VK_U, 'U', 0},
+ {J_VK_V, 'V', 0},
+ {J_VK_W, 'W', 0},
+ {J_VK_X, 'X', 0},
+ {J_VK_Y, 'Y', 0},
+ {J_VK_Z, 'Z', 0},
+ {J_VK_0, '0', 0},
+ {J_VK_1, '1', 0},
+ {J_VK_2, '2', 0},
+ {J_VK_3, '3', 0},
+ {J_VK_4, '4', 0},
+ {J_VK_5, '5', 0},
+ {J_VK_6, '6', 0},
+ {J_VK_7, '7', 0},
+ {J_VK_8, '8', 0},
+ {J_VK_9, '9', 0},
+ {J_VK_ENTER, VK_RETURN, 0},
+ {J_VK_SPACE, VK_SPACE, 0},
+ {J_VK_BACK_SPACE, VK_BACK, 0},
+ {J_VK_TAB, VK_TAB, 0},
+ {J_VK_ESCAPE, VK_ESCAPE, 0},
+ {J_VK_INSERT, VK_INSERT, 0},
+ {J_VK_DELETE, VK_DELETE, 0},
+ {J_VK_HOME, VK_HOME, 0},
+ {J_VK_END, VK_END, 0},
+ {J_VK_PAGE_UP, VK_PRIOR, 0},
+ {J_VK_PAGE_DOWN, VK_NEXT, 0},
+ {J_VK_CLEAR, VK_CLEAR, 0}, // NumPad 5
// NumPad with NumLock off & extended arrows block (triangular)
- {J_VK_LEFT, VK_LEFT},
- {J_VK_RIGHT, VK_RIGHT},
- {J_VK_UP, VK_UP},
- {J_VK_DOWN, VK_DOWN},
+ {J_VK_LEFT, VK_LEFT, 0},
+ {J_VK_RIGHT, VK_RIGHT, 0},
+ {J_VK_UP, VK_UP, 0},
+ {J_VK_DOWN, VK_DOWN, 0},
// NumPad with NumLock on: numbers
- {J_VK_NUMPAD0, VK_NUMPAD0},
- {J_VK_NUMPAD1, VK_NUMPAD1},
- {J_VK_NUMPAD2, VK_NUMPAD2},
- {J_VK_NUMPAD3, VK_NUMPAD3},
- {J_VK_NUMPAD4, VK_NUMPAD4},
- {J_VK_NUMPAD5, VK_NUMPAD5},
- {J_VK_NUMPAD6, VK_NUMPAD6},
- {J_VK_NUMPAD7, VK_NUMPAD7},
- {J_VK_NUMPAD8, VK_NUMPAD8},
- {J_VK_NUMPAD9, VK_NUMPAD9},
+ {J_VK_NUMPAD0, VK_NUMPAD0, 0},
+ {J_VK_NUMPAD1, VK_NUMPAD1, 0},
+ {J_VK_NUMPAD2, VK_NUMPAD2, 0},
+ {J_VK_NUMPAD3, VK_NUMPAD3, 0},
+ {J_VK_NUMPAD4, VK_NUMPAD4, 0},
+ {J_VK_NUMPAD5, VK_NUMPAD5, 0},
+ {J_VK_NUMPAD6, VK_NUMPAD6, 0},
+ {J_VK_NUMPAD7, VK_NUMPAD7, 0},
+ {J_VK_NUMPAD8, VK_NUMPAD8, 0},
+ {J_VK_NUMPAD9, VK_NUMPAD9, 0},
// NumPad with NumLock on
- {J_VK_MULTIPLY, VK_MULTIPLY},
- {J_VK_ADD, VK_ADD},
- {J_VK_SEPARATOR, VK_SEPARATOR},
- {J_VK_SUBTRACT, VK_SUBTRACT},
- {J_VK_DECIMAL, VK_DECIMAL},
- {J_VK_DIVIDE, VK_DIVIDE},
+ {J_VK_MULTIPLY, VK_MULTIPLY, 0},
+ {J_VK_ADD, VK_ADD, 0},
+ {J_VK_SEPARATOR, VK_SEPARATOR, 0},
+ {J_VK_SUBTRACT, VK_SUBTRACT, 0},
+ {J_VK_DECIMAL, VK_DECIMAL, 0},
+ {J_VK_DIVIDE, VK_DIVIDE, 0},
// Functional keys
- {J_VK_F1, VK_F1},
- {J_VK_F2, VK_F2},
- {J_VK_F3, VK_F3},
- {J_VK_F4, VK_F4},
- {J_VK_F5, VK_F5},
- {J_VK_F6, VK_F6},
- {J_VK_F7, VK_F7},
- {J_VK_F8, VK_F8},
- {J_VK_F9, VK_F9},
- {J_VK_F10, VK_F10},
- {J_VK_F11, VK_F11},
- {J_VK_F12, VK_F12},
- {J_VK_F13, VK_F13},
- {J_VK_F14, VK_F14},
- {J_VK_F15, VK_F15},
- {J_VK_F16, VK_F16},
- {J_VK_F17, VK_F17},
- {J_VK_F18, VK_F18},
- {J_VK_F19, VK_F19},
- {J_VK_F20, VK_F20},
- {J_VK_F21, VK_F21},
- {J_VK_F22, VK_F22},
- {J_VK_F23, VK_F23},
- {J_VK_F24, VK_F24},
-
- {J_VK_PRINTSCREEN, VK_SNAPSHOT},
- {J_VK_SCROLL_LOCK, VK_SCROLL},
- {J_VK_PAUSE, VK_PAUSE},
- {J_VK_CANCEL, VK_CANCEL},
- {J_VK_HELP, VK_HELP},
+ {J_VK_F1, VK_F1, 0},
+ {J_VK_F2, VK_F2, 0},
+ {J_VK_F3, VK_F3, 0},
+ {J_VK_F4, VK_F4, 0},
+ {J_VK_F5, VK_F5, 0},
+ {J_VK_F6, VK_F6, 0},
+ {J_VK_F7, VK_F7, 0},
+ {J_VK_F8, VK_F8, 0},
+ {J_VK_F9, VK_F9, 0},
+ {J_VK_F10, VK_F10, 0},
+ {J_VK_F11, VK_F11, 0},
+ {J_VK_F12, VK_F12, 0},
+ {J_VK_F13, VK_F13, 0},
+ {J_VK_F14, VK_F14, 0},
+ {J_VK_F15, VK_F15, 0},
+ {J_VK_F16, VK_F16, 0},
+ {J_VK_F17, VK_F17, 0},
+ {J_VK_F18, VK_F18, 0},
+ {J_VK_F19, VK_F19, 0},
+ {J_VK_F20, VK_F20, 0},
+ {J_VK_F21, VK_F21, 0},
+ {J_VK_F22, VK_F22, 0},
+ {J_VK_F23, VK_F23, 0},
+ {J_VK_F24, VK_F24, 0},
+
+ {J_VK_PRINTSCREEN, VK_SNAPSHOT, 0},
+ {J_VK_SCROLL_LOCK, VK_SCROLL, 0},
+ {J_VK_PAUSE, VK_PAUSE, 0},
+ {J_VK_CANCEL, VK_CANCEL, 0},
+ {J_VK_HELP, VK_HELP, 0},
+
+ // Since we unify mappings via US kbd layout .. this is valid:
+ {J_VK_SEMICOLON, VK_OEM_1, 0}, // US only ';:'
+ {J_VK_EQUALS, VK_OEM_PLUS, 0}, // '=+'
+ {J_VK_COMMA, VK_OEM_COMMA, 0}, // ',<'
+ {J_VK_MINUS, VK_OEM_MINUS, 0}, // '-_'
+ {J_VK_PERIOD, VK_OEM_PERIOD, 0}, // '.>'
+ {J_VK_SLASH, VK_OEM_2, 0}, // US only '/?'
+ {J_VK_BACK_QUOTE, VK_OEM_3, 0}, // US only '`~'
+ {J_VK_OPEN_BRACKET, VK_OEM_4, 0}, // US only '[}'
+ {J_VK_BACK_SLASH, VK_OEM_5, 0}, // US only '\|'
+ {J_VK_CLOSE_BRACKET, VK_OEM_6, 0}, // US only ']}'
+ {J_VK_QUOTE, VK_OEM_7, 0}, // US only ''"'
+ // {J_VK_????, VK_OEM_8, 0}, // varies ..
+ // {J_VK_????, VK_OEM_102, 0}, // angle-bracket or backslash key on RT 102-key kbd
// Japanese
/*
- {J_VK_CONVERT, VK_CONVERT},
- {J_VK_NONCONVERT, VK_NONCONVERT},
- {J_VK_INPUT_METHOD_ON_OFF, VK_KANJI},
- {J_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC},
- {J_VK_KATAKANA, VK_DBE_KATAKANA},
- {J_VK_HIRAGANA, VK_DBE_HIRAGANA},
- {J_VK_FULL_WIDTH, VK_DBE_DBCSCHAR},
- {J_VK_HALF_WIDTH, VK_DBE_SBCSCHAR},
- {J_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN},
+ {J_VK_CONVERT, VK_CONVERT, 0},
+ {J_VK_NONCONVERT, VK_NONCONVERT, 0},
+ {J_VK_INPUT_METHOD_ON_OFF, VK_KANJI, 0},
+ {J_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC, 0},
+ {J_VK_KATAKANA, VK_DBE_KATAKANA, 0},
+ {J_VK_HIRAGANA, VK_DBE_HIRAGANA, 0},
+ {J_VK_FULL_WIDTH, VK_DBE_DBCSCHAR, 0},
+ {J_VK_HALF_WIDTH, VK_DBE_SBCSCHAR, 0},
+ {J_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN, 0},
*/
- {J_VK_UNDEFINED, 0}
+ {J_VK_UNDEFINED, 0, 0}
};
-/*
-Dynamic mapping table for OEM VK codes. This table is refilled
-by BuildDynamicKeyMapTable when keyboard layout is switched.
-(see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values).
-*/
-typedef struct {
- // OEM VK codes known in advance
- UINT windowsKey;
- // depends on input langauge (kbd layout)
- UINT javaKey;
-} DynamicKeyMapEntry;
-
-static DynamicKeyMapEntry dynamicKeyMapTable[] = {
- {0x00BA, J_VK_UNDEFINED}, // VK_OEM_1
- {0x00BB, J_VK_UNDEFINED}, // VK_OEM_PLUS
- {0x00BC, J_VK_UNDEFINED}, // VK_OEM_COMMA
- {0x00BD, J_VK_UNDEFINED}, // VK_OEM_MINUS
- {0x00BE, J_VK_UNDEFINED}, // VK_OEM_PERIOD
- {0x00BF, J_VK_UNDEFINED}, // VK_OEM_2
- {0x00C0, J_VK_UNDEFINED}, // VK_OEM_3
- {0x00DB, J_VK_UNDEFINED}, // VK_OEM_4
- {0x00DC, J_VK_UNDEFINED}, // VK_OEM_5
- {0x00DD, J_VK_UNDEFINED}, // VK_OEM_6
- {0x00DE, J_VK_UNDEFINED}, // VK_OEM_7
- {0x00DF, J_VK_UNDEFINED}, // VK_OEM_8
- {0x00E2, J_VK_UNDEFINED}, // VK_OEM_102
- {0, 0}
-};
+#ifndef KLF_ACTIVATE
+ #define KLF_ACTIVATE 0x00000001
+#endif
+#ifndef MAPVK_VK_TO_VSC
+ #define MAPVK_VK_TO_VSC 0
+#endif
+#ifndef MAPVK_VSC_TO_VK
+ #define MAPVK_VSC_TO_VK 1
+#endif
+#ifndef MAPVK_VK_TO_CHAR
+ #define MAPVK_VK_TO_CHAR 2
+#endif
+#ifndef MAPVK_VSC_TO_VK_EX
+ #define MAPVK_VSC_TO_VK_EX 3
+#endif
+#ifndef MAPVK_VK_TO_VSC_EX
+ #define MAPVK_VK_TO_VSC_EX 4
+#endif
-// Auxiliary tables used to fill the above dynamic table. We first
-// find the character for the OEM VK code using ::MapVirtualKey and
-// then go through these auxiliary tables to map it to Java VK code.
+static HKL kbdLayoutUS = 0;
+static const LPCSTR US_LAYOUT_NAME = "00000409";
-typedef struct {
- WCHAR c;
- UINT javaKey;
-} CharToVKEntry;
-
-static const CharToVKEntry charToVKTable[] = {
- {L'!', J_VK_EXCLAMATION_MARK},
- {L'"', J_VK_QUOTEDBL},
- {L'#', J_VK_NUMBER_SIGN},
- {L'$', J_VK_DOLLAR},
- {L'&', J_VK_AMPERSAND},
- {L'\'', J_VK_QUOTE},
- {L'(', J_VK_LEFT_PARENTHESIS},
- {L')', J_VK_RIGHT_PARENTHESIS},
- {L'*', J_VK_ASTERISK},
- {L'+', J_VK_PLUS},
- {L',', J_VK_COMMA},
- {L'-', J_VK_MINUS},
- {L'.', J_VK_PERIOD},
- {L'/', J_VK_SLASH},
- {L':', J_VK_COLON},
- {L';', J_VK_SEMICOLON},
- {L'<', J_VK_LESS},
- {L'=', J_VK_EQUALS},
- {L'>', J_VK_GREATER},
- {L'@', J_VK_AT},
- {L'[', J_VK_OPEN_BRACKET},
- {L'\\', J_VK_BACK_SLASH},
- {L']', J_VK_CLOSE_BRACKET},
- {L'^', J_VK_CIRCUMFLEX},
- {L'_', J_VK_UNDERSCORE},
- {L'`', J_VK_BACK_QUOTE},
- {L'{', J_VK_BRACELEFT},
- {L'}', J_VK_BRACERIGHT},
- {0x00A1, J_VK_INVERTED_EXCLAMATION_MARK},
- {0x20A0, J_VK_EURO_SIGN}, // ????
- {0,0}
-};
+static BYTE kbdState[256];
+static USHORT spaceScanCode;
-// For dead accents some layouts return ASCII punctuation, while some
-// return spacing accent chars, so both should be listed. NB: MS docs
-// say that conversion routings return spacing accent character, not
-// combining.
-static const CharToVKEntry charToDeadVKTable[] = {
- {L'`', J_VK_DEAD_GRAVE},
- {L'\'', J_VK_DEAD_ACUTE},
- {0x00B4, J_VK_DEAD_ACUTE},
- {L'^', J_VK_DEAD_CIRCUMFLEX},
- {L'~', J_VK_DEAD_TILDE},
- {0x02DC, J_VK_DEAD_TILDE},
- {0x00AF, J_VK_DEAD_MACRON},
- {0x02D8, J_VK_DEAD_BREVE},
- {0x02D9, J_VK_DEAD_ABOVEDOT},
- {L'"', J_VK_DEAD_DIAERESIS},
- {0x00A8, J_VK_DEAD_DIAERESIS},
- {0x02DA, J_VK_DEAD_ABOVERING},
- {0x02DD, J_VK_DEAD_DOUBLEACUTE},
- {0x02C7, J_VK_DEAD_CARON}, // aka hacek
- {L',', J_VK_DEAD_CEDILLA},
- {0x00B8, J_VK_DEAD_CEDILLA},
- {0x02DB, J_VK_DEAD_OGONEK},
- {0x037A, J_VK_DEAD_IOTA}, // ASCII ???
- {0x309B, J_VK_DEAD_VOICED_SOUND},
- {0x309C, J_VK_DEAD_SEMIVOICED_SOUND},
- {0,0}
-};
+static void InitKeyMapTableScanCode(JNIEnv *env) {
+ HKL hkl = GetKeyboardLayout(0);
+ int i;
-// ANSI CP identifiers are no longer than this
-#define MAX_ACP_STR_LEN 7
+ kbdLayoutUS = LoadKeyboardLayout( US_LAYOUT_NAME, 0 /* ? KLF_ACTIVATE ? */ );
+ if( 0 == kbdLayoutUS ) {
+ int lastError = (int) GetLastError();
+ kbdLayoutUS = hkl; // use prev. layout .. well
+ STD_PRINT("Warning: NEWT Windows: LoadKeyboardLayout(US, ..) failed: winErr 0x%X %d\n", lastError, lastError);
+ }
+ ActivateKeyboardLayout(hkl, 0);
+
+ spaceScanCode = MapVirtualKeyEx(VK_SPACE, MAPVK_VK_TO_VSC, hkl);
+
+ // Setup keyMapTable's windowsScanCodeUS
+ for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
+ USHORT scancode = (USHORT) MapVirtualKeyEx(keyMapTable[i].windowsKey, MAPVK_VK_TO_VSC_EX, kbdLayoutUS);
+ #ifdef DEBUG_KEYS
+ if( 0 == scancode ) {
+ int lastError = (int) GetLastError();
+ STD_PRINT("*** WindowsWindow: InitKeyMapTableScanCode: No ScanCode for windows vkey 0x%X (item %d), winErr 0x%X %d\n",
+ keyMapTable[i].windowsKey, i, lastError, lastError);
+ }
+ STD_PRINT("*** WindowsWindow: InitKeyMapTableScanCode: %3.3d windows vkey 0x%X -> scancode 0x%X\n",
+ i, keyMapTable[i].windowsKey, scancode);
+ #endif
+ keyMapTable[i].windowsScanCodeUS = scancode;
+ }
+}
+
+static void ParseWmVKeyAndScanCode(USHORT winVKey, BYTE winScanCode, BYTE flags, USHORT *outJavaVKeyUS, USHORT *outJavaVKeyXX, USHORT *outUTF16Char) {
+ wchar_t uniChars[2] = { L'\0', L'\0' }; // uint16_t
+ USHORT winVKeyUS = 0;
+ int nUniChars, i, j;
+ USHORT javaVKeyUS = J_VK_UNDEFINED;
+ USHORT javaVKeyXX = J_VK_UNDEFINED;
-static void BuildDynamicKeyMapTable()
-{
HKL hkl = GetKeyboardLayout(0);
- // Will need this to reset layout after dead keys.
- UINT spaceScanCode = MapVirtualKeyEx(VK_SPACE, 0, hkl);
- DynamicKeyMapEntry *dynamic;
-
- LANGID idLang = LOWORD(GetKeyboardLayout(0));
- UINT codePage;
- TCHAR strCodePage[MAX_ACP_STR_LEN];
- // use the LANGID to create a LCID
- LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);
- // get the ANSI code page associated with this locale
- if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE,
- strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
- {
- codePage = _ttoi(strCodePage);
- } else {
- codePage = GetACP();
+
+ //
+ // winVKey, winScanCode -> UTF16 w/ current KeyboardLayout
+ //
+ GetKeyboardState(kbdState);
+ kbdState[winVKey] |= 0x80;
+ nUniChars = ToUnicodeEx(winVKey, winScanCode, kbdState, uniChars, 2, 0, hkl);
+ kbdState[winVKey] &= ~0x80;
+
+ *outUTF16Char = (USHORT)(uniChars[0]); // Note: Even dead key are written in uniChar's ..
+
+ if ( 0 > nUniChars ) { // Dead key
+ char junkbuf[2] = { '\0', '\0'};
+
+ // We need to reset layout so that next translation
+ // is unaffected by the dead status. We do this by
+ // translating <SPACE> key.
+ kbdState[VK_SPACE] |= 0x80;
+ ToAsciiEx(VK_SPACE, spaceScanCode, kbdState, (WORD*)junkbuf, 0, hkl);
+ kbdState[VK_SPACE] &= ~0x80;
}
- // Entries in dynamic table that maps between Java VK and Windows
- // VK are built in three steps:
- // 1. Map windows VK to ANSI character (cannot map to unicode
- // directly, since ::ToUnicode is not implemented on win9x)
- // 2. Convert ANSI char to Unicode char
- // 3. Map Unicode char to Java VK via two auxilary tables.
+ // Assume extended scan code 0xE0 if extended flags is set (no 0xE1 from WM_KEYUP/WM_KEYDOWN)
+ USHORT winScanCodeExt = winScanCode;
+ if( 0 != ( 0x01 & flags ) ) {
+ winScanCodeExt |= 0xE000;
+ }
- for (dynamic = dynamicKeyMapTable; dynamic->windowsKey != 0; ++dynamic)
- {
- char cbuf[2] = { '\0', '\0'};
- WCHAR ucbuf[2] = { L'\0', L'\0' };
- int nchars;
- UINT scancode;
- const CharToVKEntry *charMap;
- int nconverted;
- WCHAR uc;
- BYTE kbdState[256];
-
- // Defaults to J_VK_UNDEFINED
- dynamic->javaKey = J_VK_UNDEFINED;
-
- GetKeyboardState(kbdState);
-
- kbdState[dynamic->windowsKey] |= 0x80; // Press the key.
-
- // Unpress modifiers, since they are most likely pressed as
- // part of the keyboard switching shortcut.
- kbdState[VK_CONTROL] &= ~0x80;
- kbdState[VK_SHIFT] &= ~0x80;
- kbdState[VK_MENU] &= ~0x80;
-
- scancode = MapVirtualKeyEx(dynamic->windowsKey, 0, hkl);
- nchars = ToAsciiEx(dynamic->windowsKey, scancode, kbdState,
- (WORD*)cbuf, 0, hkl);
-
- // Auxiliary table used to map Unicode character to Java VK.
- // Will assign a different table for dead keys (below).
- charMap = charToVKTable;
-
- if (nchars < 0) { // Dead key
- char junkbuf[2] = { '\0', '\0'};
- // Use a different table for dead chars since different layouts
- // return different characters for the same dead key.
- charMap = charToDeadVKTable;
-
- // We also need to reset layout so that next translation
- // is unaffected by the dead status. We do this by
- // translating <SPACE> key.
- kbdState[dynamic->windowsKey] &= ~0x80;
- kbdState[VK_SPACE] |= 0x80;
-
- ToAsciiEx(VK_SPACE, spaceScanCode, kbdState,
- (WORD*)junkbuf, 0, hkl);
+ //
+ // winVKey, winScanCodeExt -> javaVKeyUS w/ US KeyboardLayout
+ //
+ for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
+ if ( keyMapTable[i].windowsScanCodeUS == winScanCodeExt ) {
+ javaVKeyUS = keyMapTable[i].javaKey;
+ winVKeyUS = keyMapTable[i].windowsKey;
+ break;
}
+ }
- nconverted = MultiByteToWideChar(codePage, 0,
- cbuf, 1, ucbuf, 2);
-
- uc = ucbuf[0];
- {
- const CharToVKEntry *map;
- for (map = charMap; map->c != 0; ++map) {
- if (uc == map->c) {
- dynamic->javaKey = map->javaKey;
- break;
- }
- }
+ //
+ // winVKey -> javaVKeyXX
+ //
+ for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
+ if ( keyMapTable[i].windowsKey == winVKey ) {
+ javaVKeyXX = keyMapTable[i].javaKey;
+ break;
}
+ }
+
+ *outJavaVKeyUS = javaVKeyUS;
+ *outJavaVKeyXX = javaVKeyXX;
- } // for each VK_OEM_*
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: ParseWmVKeyAndScanCode winVKey 0x%X, winScanCode 0x%X, winScanCodeExt 0x%X, flags 0x%X -> UTF(0x%X, %c, res %d, sizeof %d), vKeys( US(win 0x%X, java 0x%X), XX(win 0x%X, java 0x%X))\n",
+ (int)winVKey, (int)winScanCode, winScanCodeExt, (int)flags,
+ *outUTF16Char, *outUTF16Char, nUniChars, sizeof(uniChars[0]),
+ winVKeyUS, javaVKeyUS, winVKey, javaVKeyXX);
+#endif
}
-static jint GetModifiers(BOOL altKeyFlagged, UINT jkey) {
+static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) {
jint modifiers = 0;
// have to do &0xFFFF to avoid runtime assert caused by compiling with
// /RTCcsu
@@ -516,121 +463,38 @@ static BOOL IsAltKeyDown(BYTE flags, BOOL system) {
return system && ( flags & (1<<5) ) != 0;
}
-UINT WindowsKeyToJavaKey(UINT windowsKey)
-{
- int i, j, javaKey = J_VK_UNDEFINED;
- // for the general case, use a bi-directional table
- for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
- if (keyMapTable[i].windowsKey == windowsKey) {
- javaKey = keyMapTable[i].javaKey;
- }
- }
- if( J_VK_UNDEFINED == javaKey ) {
- for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
- if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
- if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
- javaKey = dynamicKeyMapTable[j].javaKey;
- } else {
- break;
- }
- }
- }
- }
-
-#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: WindowsKeyToJavaKey 0x%X -> 0x%X\n", windowsKey, javaKey);
-#endif
- return javaKey;
-}
-
-#ifndef MAPVK_VSC_TO_VK
- #define MAPVK_VSC_TO_VK 1
-#endif
-#ifndef MAPVK_VK_TO_CHAR
- #define MAPVK_VK_TO_CHAR 2
-#endif
-
-static UINT WmVKey2ShiftedChar(UINT wkey, UINT modifiers) {
- UINT c = MapVirtualKey(wkey, MAPVK_VK_TO_CHAR);
- if( 0 != ( modifiers & EVENT_SHIFT_MASK ) ) {
- return islower(c) ? toupper(c) : c;
- }
- return isupper(c) ? tolower(c) : c;
-}
-
-static int WmChar(JNIEnv *env, jobject window, UINT character, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
- UINT modifiers = 0, jkey = 0, wkey = 0;
-
- wkey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK);
- jkey = WindowsKeyToJavaKey(wkey);
- modifiers = GetModifiers( IsAltKeyDown(flags, system), 0 );
-
- if (character == VK_RETURN) {
- character = J_VK_ENTER;
- }
-
- (*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jint) EVENT_KEY_TYPED,
- modifiers,
- (jint) jkey,
- (jchar) character);
- return 1;
-}
-
-static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
- UINT modifiers = 0, jkey = 0, character = 0;
+static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+ UINT modifiers = 0;
+ USHORT javaVKeyUS=0, javaVKeyXX=0, utf16Char=0;
if (wkey == VK_PROCESSKEY) {
return 1;
}
- jkey = WindowsKeyToJavaKey(wkey);
- modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
- character = WmVKey2ShiftedChar(wkey, modifiers);
+ ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char);
-/*
- character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
-*/
+ modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX );
(*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jint) EVENT_KEY_PRESSED,
- modifiers,
- (jint) jkey,
- (jchar) character);
-
- /* windows does not create a WM_CHAR for the Del key
- for some reason, so we need to create the KEY_TYPED event on the
- WM_KEYDOWN.
- */
- if (jkey == J_VK_DELETE) {
- (*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jint) EVENT_KEY_TYPED,
- modifiers,
- (jint) jkey,
- (jchar) '\177');
- }
+ (jshort) EVENT_KEY_PRESSED,
+ (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
return 0;
}
-static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
- UINT modifiers = 0, jkey = 0, character = 0;
+static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+ UINT modifiers = 0;
+ USHORT javaVKeyUS=0, javaVKeyXX=0, utf16Char=0;
if (wkey == VK_PROCESSKEY) {
return 1;
}
- jkey = WindowsKeyToJavaKey(wkey);
- modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
- character = WmVKey2ShiftedChar(wkey, modifiers);
+ ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char);
-/*
- character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
-*/
+ modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX );
(*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jint) EVENT_KEY_RELEASED,
- modifiers,
- (jint) jkey,
- (jchar) character);
+ (jshort) EVENT_KEY_RELEASED,
+ (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
return 0;
}
@@ -933,46 +797,35 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
case WM_SYSCHAR:
- repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
- repCnt = LOWORD(lParam);
-#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_SYSCHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
-#endif
- useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, TRUE);
+ useDefWindowProc = 1;
break;
case WM_SYSKEYDOWN:
repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
repCnt = LOWORD(lParam);
#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+ DBG_PRINT("*** WindowsWindow: windProc WM_SYSKEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
#endif
- useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, TRUE);
+ useDefWindowProc = WmKeyDown(env, window, (USHORT)wParam, repCnt, scanCode, flags, TRUE);
break;
case WM_SYSKEYUP:
repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
repCnt = LOWORD(lParam);
#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+ DBG_PRINT("*** WindowsWindow: windProc WM_SYSKEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
#endif
- useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, TRUE);
+ useDefWindowProc = WmKeyUp(env, window, (USHORT)wParam, repCnt, scanCode, flags, TRUE);
break;
case WM_CHAR:
- repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
- repCnt = LOWORD(lParam);
-#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_CHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
-#endif
- useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, FALSE);
+ useDefWindowProc = 1;
break;
case WM_KEYDOWN:
repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
- repCnt = LOWORD(lParam);
#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_KEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+ DBG_PRINT("*** WindowsWindow: windProc WM_KEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
#endif
useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, FALSE);
break;
@@ -981,7 +834,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
repCnt = LOWORD(lParam);
#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc WM_KEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+ DBG_PRINT("*** WindowsWindow: windProc WM_KEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
#endif
useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, FALSE);
break;
@@ -1005,19 +858,19 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n");
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_PRESSED,
+ (jshort) EVENT_MOUSE_PRESSED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 1, (jfloat) 0.0f);
+ (jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_LBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_RELEASED,
+ (jshort) EVENT_MOUSE_RELEASED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 1, (jfloat) 0.0f);
+ (jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
@@ -1025,19 +878,19 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n");
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_PRESSED,
+ (jshort) EVENT_MOUSE_PRESSED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 2, (jfloat) 0.0f);
+ (jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_MBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_RELEASED,
+ (jshort) EVENT_MOUSE_RELEASED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 2, (jfloat) 0.0f);
+ (jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
@@ -1045,36 +898,36 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n");
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_PRESSED,
+ (jshort) EVENT_MOUSE_PRESSED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 3, (jfloat) 0.0f);
+ (jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_RBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_RELEASED,
+ (jshort) EVENT_MOUSE_RELEASED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 3, (jfloat) 0.0f);
+ (jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_MOUSEMOVE:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_MOVED,
+ (jshort) EVENT_MOUSE_MOVED,
GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jint) 0, (jfloat) 0.0f);
+ (jshort) 0, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_MOUSELEAVE:
- (*env)->CallVoidMethod(env, window, enqueueMouseEventID, JNI_FALSE,
- (jint) EVENT_MOUSE_EXITED,
+ (*env)->CallVoidMethod(env, window, sendMouseEventID, JNI_FALSE,
+ (jshort) EVENT_MOUSE_EXITED,
0,
(jint) -1, (jint) -1, // fake
- (jint) 0, (jfloat) 0.0f);
+ (jshort) 0, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
// Java synthesizes EVENT_MOUSE_ENTERED
@@ -1099,10 +952,10 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
}
DBG_PRINT("*** WindowsWindow: WM_HSCROLL 0x%X, rotation %f, mods 0x%X\n", sb, rotation, modifiers);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_WHEEL_MOVED,
+ (jshort) EVENT_MOUSE_WHEEL_MOVED,
modifiers,
(jint) 0, (jint) 0,
- (jint) 1, (jfloat) rotation);
+ (jshort) 1, (jfloat) rotation);
useDefWindowProc = 1;
break;
}
@@ -1128,10 +981,10 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
(int)eventPt.x, (int)eventPt.y, rotationOrTilt, vKeys, modifiers);
}
(*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jint) EVENT_MOUSE_WHEEL_MOVED,
+ (jshort) EVENT_MOUSE_WHEEL_MOVED,
modifiers,
(jint) eventPt.x, (jint) eventPt.y,
- (jint) 1, (jfloat) rotationOrTilt);
+ (jshort) 1, (jfloat) rotationOrTilt);
useDefWindowProc = 1;
break;
}
@@ -1208,7 +1061,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMes
// DBG_PRINT("*** WindowsWindow.DispatchMessages0: thread 0x%X - gotOne %d\n", (int)GetCurrentThreadId(), (int)gotOne);
if (gotOne) {
++i;
- TranslateMessage(&msg);
+ // TranslateMessage(&msg); // No more needed: We translate V_KEY -> UTF Char manually in key up/down
DispatchMessage(&msg);
}
} while (gotOne && i < 100);
@@ -1474,10 +1327,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIIF)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIIF)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
@@ -1487,14 +1338,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
visibleChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
requestFocusID == NULL) {
return JNI_FALSE;
}
- BuildDynamicKeyMapTable();
+ InitKeyMapTableScanCode(env);
return JNI_TRUE;
}
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index 85b3a14c7..9b11ff0dd 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -28,8 +28,6 @@
#include "X11Common.h"
-#define USE_SENDIO_DIRECT 1
-
jclass X11NewtWindowClazz = NULL;
jmethodID insetsChangedID = NULL;
jmethodID visibleChangedID = NULL;
@@ -46,9 +44,7 @@ static jmethodID focusChangedID = NULL;
static jmethodID reparentNotifyID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
@@ -59,10 +55,18 @@ static jmethodID requestFocusID = NULL;
#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
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;
+ if( IS_WITHIN( keySym, XK_a, XK_z ) ) {
+ return ( keySym - XK_a ) + J_VK_A ;
+ }
+ if( IS_WITHIN( keySym, XK_0, XK_9 ) ) {
+ return ( keySym - XK_0 ) + J_VK_0 ;
+ }
+ if( IS_WITHIN( keySym, XK_KP_0, XK_KP_9 ) ) {
+ return ( keySym - XK_KP_0 ) + J_VK_NUMPAD0 ;
+ }
+ if( IS_WITHIN( keySym, XK_F1, XK_F12 ) ) {
+ return ( keySym - XK_F1 ) + J_VK_F1 ;
+ }
switch(keySym) {
case XK_Return:
@@ -154,15 +158,15 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return keySym;
}
-static jint X11InputState2NewtModifiers(unsigned int xstate, KeySym keySym) {
+static jint X11InputState2NewtModifiers(unsigned int xstate, int javaVKey) {
jint modifiers = 0;
- if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == keySym ) {
+ if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == javaVKey ) {
modifiers |= EVENT_CTRL_MASK;
}
- if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == keySym ) {
+ if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == javaVKey ) {
modifiers |= EVENT_SHIFT_MASK;
}
- if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == keySym ) {
+ if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == javaVKey ) {
modifiers |= EVENT_ALT_MASK;
}
if ( (Button1Mask & xstate) != 0 ) {
@@ -218,10 +222,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIIF)V");
- sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIIF)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
+ sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSC)V");
requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
if (displayCompletedID == NULL ||
@@ -235,9 +237,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
reparentNotifyID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
requestFocusID == NULL) {
return JNI_FALSE;
@@ -328,6 +328,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
jobject jwindow = NULL;
XEvent evt;
KeySym keySym = 0;
+ KeyCode keyCode = 0;
+ jshort javaVKeyUS = 0;
+ jshort javaVKeyNN = 0;
jint modifiers = 0;
char keyChar = 0;
char text[255];
@@ -386,18 +389,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
}
// fall through intended
- case KeyPress:
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- KeySym lower_return = 0, upper_return = 0;
- keyChar=text[0];
- XConvertCase(keySym, &lower_return, &upper_return);
- // always return upper case, set modifier masks (SHIFT, ..)
- keySym = X11KeySym2NewtVKey(upper_return);
- } else {
- keyChar=0;
- keySym = X11KeySym2NewtVKey(keySym);
+ case KeyPress: {
+ KeySym shiftedKeySym; // layout depending keySym w/ SHIFT
+
+ keyCode = evt.xkey.keycode;
+ keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */); // layout depending keySym w/o SHIFT
+
+ if( XLookupString(&evt.xkey, text, 255, &shiftedKeySym, 0) == 1 ) {
+ keyChar=text[0];
+ }
+
+ javaVKeyNN = X11KeySym2NewtVKey(keySym);
+ javaVKeyUS = javaVKeyNN; // FIXME!
+ modifiers |= X11InputState2NewtModifiers(evt.xkey.state, javaVKeyNN) | autoRepeatModifiers;
+
+ fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X (shifted: 0x%X), keyChar '%c', javaVKey[US 0x%X, NN 0x%X]\n",
+ (int)keyCode, (int)keySym, (int)shiftedKeySym, (int)keyChar, (int)javaVKeyUS, (int)javaVKeyNN);
}
- modifiers |= X11InputState2NewtModifiers(evt.xkey.state, keySym) | autoRepeatModifiers;
break;
case ButtonPress:
@@ -413,87 +421,39 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
switch(evt.type) {
case ButtonPress:
(*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0.0f /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED,
modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0.0f /*rotation*/);
- #endif
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
break;
case ButtonRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0.0f /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED,
modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0.0f /*rotation*/);
- #endif
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
break;
case MotionNotify:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0.0f /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0.0f /*rotation*/);
- #endif
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jshort) 0, 0.0f /*rotation*/);
break;
case EnterNotify:
DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0.0f /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_ENTERED,
modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0.0f /*rotation*/);
- #endif
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
break;
case LeaveNotify:
DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_EXITED,
modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0.0f /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0.0f /*rotation*/);
- #endif
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
break;
case KeyPress:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- modifiers, keySym, (jchar) keyChar);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
- modifiers, keySym, (jchar) keyChar);
- #endif
-
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED,
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar);
break;
case KeyRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- modifiers, keySym, (jchar) keyChar);
-
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
- modifiers, keySym, (jchar) keyChar);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
- modifiers, keySym, (jchar) keyChar);
-
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
- modifiers, keySym, (jchar) keyChar);
- #endif
-
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED,
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar);
break;
case DestroyNotify:
DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c
index bbddf764b..f3474ee34 100644
--- a/src/newt/native/bcm_vc_iv.c
+++ b/src/newt/native/bcm_vc_iv.c
@@ -50,8 +50,6 @@ static jmethodID windowCreatedID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
/**
* Display
@@ -117,14 +115,10 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initID
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIIF)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (windowCreatedID == NULL ||
sizeChangedID == NULL ||
visibleChangedID == NULL ||
- windowDestroyNotifyID == NULL ||
- sendMouseEventID == NULL ||
- sendKeyEventID == NULL) {
+ windowDestroyNotifyID == NULL) {
DBG_PRINT( "initIDs failed\n" );
return JNI_FALSE;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove01GLCanvasSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove01GLCanvasSwingAWT.java
new file mode 100644
index 000000000..ce8f9adc8
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove01GLCanvasSwingAWT.java
@@ -0,0 +1,241 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestAddRemove01GLCanvasSwingAWT extends UITestCase {
+ static long durationPerTest = 50;
+ static int addRemoveCount = 15;
+ static boolean noOnscreenTest = false;
+ static boolean noOffscreenTest = false;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static GLProfile glp;
+ static int width, height;
+ static boolean waitForKey = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
+ glp = GLProfile.get(GLProfile.GL2ES2);
+ Assert.assertNotNull(glp);
+ width = 640;
+ height = 480;
+ } else {
+ setTestSupported(false);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected JPanel create(final JFrame[] top, final int width, final int height, final int num)
+ throws InterruptedException, InvocationTargetException
+ {
+ final JPanel[] jPanel = new JPanel[] { null };
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jPanel[0] = new JPanel();
+ jPanel[0].setLayout(new BorderLayout());
+
+ final JFrame jFrame1 = new JFrame("JFrame #"+num);
+ // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
+ jFrame1.getContentPane().add(jPanel[0]);
+ jFrame1.setSize(width, height);
+
+ top[0] = jFrame1;
+ } } );
+ return jPanel[0];
+ }
+
+ protected void add(final Container cont, final Component comp)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ cont.add(comp, BorderLayout.CENTER);
+ } } );
+ }
+
+ protected void dispose(final GLCanvas glc)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ glc.destroy();
+ } } );
+ }
+
+ protected void setVisible(final JFrame jFrame, final boolean visible) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if( visible ) {
+ jFrame.pack();
+ jFrame.validate();
+ }
+ jFrame.setVisible(visible);
+ } } ) ;
+ }
+
+ protected void dispose(final JFrame jFrame) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame.dispose();
+ } } ) ;
+ }
+
+ protected void runTestGL(boolean onscreen, GLCapabilities caps, int addRemoveOpCount)
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+
+ for(int i=0; i<addRemoveOpCount; i++) {
+ System.err.println("Loop # "+i+" / "+addRemoveCount);
+ final GLCanvas glc = new GLCanvas(caps);
+ Assert.assertNotNull(glc);
+ if( !onscreen ) {
+ glc.setShallUseOffscreenLayer(true);
+ }
+ Dimension glc_sz = new Dimension(width, height);
+ glc.setMinimumSize(glc_sz);
+ glc.setPreferredSize(glc_sz);
+ glc.setSize(glc_sz);
+ final GearsES2 gears = new GearsES2(1);
+ gears.setVerbose(false);
+ glc.addGLEventListener(gears);
+
+ final JFrame[] top = new JFrame[] { null };
+ final Container glcCont = create(top, width, height, i);
+ add(glcCont, glc);
+
+ setVisible(top[0], true);
+
+ final long t0 = System.currentTimeMillis();
+ do {
+ glc.display();
+ Thread.sleep(10);
+ } while ( ( System.currentTimeMillis() - t0 ) < durationPerTest ) ;
+
+ System.err.println("GLCanvas isOffscreenLayerSurfaceEnabled: "+glc.isOffscreenLayerSurfaceEnabled()+": "+glc.getChosenGLCapabilities());
+
+ dispose(top[0]);
+ }
+ }
+
+ @Test
+ public void test01Onscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( noOnscreenTest || JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("No onscreen test requested or platform doesn't support onscreen rendering.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(true, caps, addRemoveCount);
+ }
+
+ @Test
+ public void test02Offscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( noOffscreenTest || !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("No offscreen test requested or platform doesn't support offscreen rendering.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(false, caps, addRemoveCount);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ durationPerTest = Long.parseLong(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-loops")) {
+ i++;
+ try {
+ addRemoveCount = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-noOnscreen")) {
+ noOnscreenTest = true;
+ } else if(args[i].equals("-noOffscreen")) {
+ noOffscreenTest = true;
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ System.err.println("waitForKey "+waitForKey);
+
+ System.err.println("addRemoveCount "+addRemoveCount);
+
+ System.err.println("noOnscreenTest "+noOnscreenTest);
+ System.err.println("noOffscreenTest "+noOffscreenTest);
+ System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ org.junit.runner.JUnitCore.main(TestAddRemove01GLCanvasSwingAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove02GLWindowNewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove02GLWindowNewtCanvasAWT.java
new file mode 100644
index 000000000..3d78943f9
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove02GLWindowNewtCanvasAWT.java
@@ -0,0 +1,246 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+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.UITestCase;
+
+public class TestAddRemove02GLWindowNewtCanvasAWT extends UITestCase {
+ static long durationPerTest = 50;
+ static int addRemoveCount = 15;
+ static boolean noOnscreenTest = false;
+ static boolean noOffscreenTest = false;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static GLProfile glp;
+ static int width, height;
+ static boolean waitForKey = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
+ glp = GLProfile.get(GLProfile.GL2ES2);
+ Assert.assertNotNull(glp);
+ width = 640;
+ height = 480;
+ } else {
+ setTestSupported(false);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected JPanel create(final JFrame[] top, final int width, final int height, final int num)
+ throws InterruptedException, InvocationTargetException
+ {
+ final JPanel[] jPanel = new JPanel[] { null };
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jPanel[0] = new JPanel();
+ jPanel[0].setLayout(new BorderLayout());
+
+ final JFrame jFrame1 = new JFrame("JFrame #"+num);
+ // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
+ jFrame1.getContentPane().add(jPanel[0]);
+ jFrame1.setSize(width, height);
+
+ top[0] = jFrame1;
+ } } );
+ return jPanel[0];
+ }
+
+ protected void add(final Container cont, final Component comp)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ cont.add(comp, BorderLayout.CENTER);
+ } } );
+ }
+
+ protected void dispose(final GLCanvas glc)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ glc.destroy();
+ } } );
+ }
+
+ protected void setVisible(final JFrame jFrame, final boolean visible) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if( visible ) {
+ jFrame.pack();
+ jFrame.validate();
+ }
+ jFrame.setVisible(visible);
+ } } ) ;
+ }
+
+ protected void dispose(final JFrame jFrame) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame.dispose();
+ } } ) ;
+ }
+
+ protected void runTestGL(boolean onscreen, GLCapabilities caps, int addRemoveOpCount)
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+
+ for(int i=0; i<addRemoveOpCount; i++) {
+ System.err.println("Loop # "+i+" / "+addRemoveCount);
+ final GLWindow glw = GLWindow.create(caps);
+ Assert.assertNotNull(glw);
+ final NewtCanvasAWT glc = new NewtCanvasAWT(glw);
+ Assert.assertNotNull(glc);
+ if( !onscreen ) {
+ glc.setShallUseOffscreenLayer(true);
+ }
+ Dimension glc_sz = new Dimension(width, height);
+ glc.setMinimumSize(glc_sz);
+ glc.setPreferredSize(glc_sz);
+ glc.setSize(glc_sz);
+ final GearsES2 gears = new GearsES2(1);
+ gears.setVerbose(false);
+ glw.addGLEventListener(gears);
+
+ final JFrame[] top = new JFrame[] { null };
+ final Container glcCont = create(top, width, height, i);
+ add(glcCont, glc);
+
+ setVisible(top[0], true);
+
+ final long t0 = System.currentTimeMillis();
+ do {
+ glw.display();
+ Thread.sleep(10);
+ } while ( ( System.currentTimeMillis() - t0 ) < durationPerTest ) ;
+
+ System.err.println("GLCanvas isOffscreenLayerSurfaceEnabled: "+glc.isOffscreenLayerSurfaceEnabled()+": "+glw.getChosenGLCapabilities());
+
+ dispose(top[0]);
+ glw.destroy();
+ }
+ }
+
+ @Test
+ public void test01Onscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( noOnscreenTest || JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("No onscreen test requested or platform doesn't support onscreen rendering.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(true, caps, addRemoveCount);
+ }
+
+ @Test
+ public void test02Offscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( noOffscreenTest || !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("No offscreen test requested or platform doesn't support offscreen rendering.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(false, caps, addRemoveCount);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ durationPerTest = Long.parseLong(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-loops")) {
+ i++;
+ try {
+ addRemoveCount = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-noOnscreen")) {
+ noOnscreenTest = true;
+ } else if(args[i].equals("-noOffscreen")) {
+ noOffscreenTest = true;
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ System.err.println("waitForKey "+waitForKey);
+
+ System.err.println("addRemoveCount "+addRemoveCount);
+
+ System.err.println("noOnscreenTest "+noOnscreenTest);
+ System.err.println("noOffscreenTest "+noOffscreenTest);
+ System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ org.junit.runner.JUnitCore.main(TestAddRemove02GLWindowNewtCanvasAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove03GLWindowNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove03GLWindowNEWT.java
new file mode 100644
index 000000000..9d7a4026b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestAddRemove03GLWindowNEWT.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestAddRemove03GLWindowNEWT extends UITestCase {
+ static long durationPerTest = 50;
+ static int addRemoveCount = 15;
+ static GLProfile glp;
+ static int width, height;
+ static boolean waitForKey = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
+ glp = GLProfile.get(GLProfile.GL2ES2);
+ Assert.assertNotNull(glp);
+ width = 640;
+ height = 480;
+ } else {
+ setTestSupported(false);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected void runTestGL(GLCapabilities caps, int addRemoveOpCount)
+ throws InterruptedException, InvocationTargetException
+ {
+
+ for(int i=0; i<addRemoveOpCount; i++) {
+ System.err.println("Loop # "+i+" / "+addRemoveCount);
+ final GLWindow glw = GLWindow.create(caps);
+ Assert.assertNotNull(glw);
+ glw.setTitle("GLWindow #"+i);
+ glw.setSize(width, height);
+ final GearsES2 gears = new GearsES2(1);
+ gears.setVerbose(false);
+ glw.addGLEventListener(gears);
+
+ glw.setVisible(true);
+
+ final long t0 = System.currentTimeMillis();
+ do {
+ glw.display();
+ Thread.sleep(10);
+ } while ( ( System.currentTimeMillis() - t0 ) < durationPerTest ) ;
+
+ System.err.println("GLWindow: "+glw.getChosenGLCapabilities());
+
+ glw.destroy();
+ }
+ }
+
+ @Test
+ public void test01Onscreen()
+ throws InterruptedException, InvocationTargetException
+ {
+ GLCapabilities caps = new GLCapabilities(glp);
+ runTestGL(caps, addRemoveCount);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ durationPerTest = Long.parseLong(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-loops")) {
+ i++;
+ try {
+ addRemoveCount = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ System.err.println("waitForKey "+waitForKey);
+
+ System.err.println("addRemoveCount "+addRemoveCount);
+
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ org.junit.runner.JUnitCore.main(TestAddRemove03GLWindowNEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
new file mode 100644
index 000000000..2729d6a5d
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
@@ -0,0 +1,160 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowUpdateEvent;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+/**
+ * Test using a NEWT {@link Window} for onscreen case.
+ * <p>
+ * Creates a {@link GLDrawable} using the
+ * {@link GLDrawableFactory#createGLDrawable(javax.media.nativewindow.NativeSurface) factory model}.
+ * The {@link GLContext} is derived {@link GLDrawable#createContext(GLContext) from the drawable}.
+ * </p>
+ * <p>
+ * Finally a {@link GLAutoDrawableDelegate} is created with the just created {@link GLDrawable} and {@link GLContext}.
+ * It is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
+ static long duration = 500; // ms
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final Window window = NewtFactory.createWindow(reqGLCaps);
+ Assert.assertNotNull(window);
+ window.setSize(640, 400);
+ window.setVisible(true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
+ System.out.println("Window: "+window.getClass().getName());
+
+ final GLDrawable drawable = factory.createGLDrawable(window);
+ Assert.assertNotNull(drawable);
+ drawable.setRealized(true);
+
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, drawable.createContext(null), window, false, null) {
+ @Override
+ protected void destroyImplInLock() {
+ super.destroyImplInLock(); // destroys drawable/context
+ window.destroy(); // destroys the actual window, incl. the device
+ }
+ };
+
+ window.setWindowDestroyNotifyAction( new Runnable() {
+ public void run() {
+ glad.windowDestroyNotifyOp();
+ } } );
+
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowRepaint(WindowUpdateEvent e) {
+ glad.windowRepaintOp();
+ }
+
+ @Override
+ public void windowResized(WindowEvent e) {
+ glad.windowResizedOp(window.getWidth(), window.getHeight());
+ }
+ });
+
+ glad.addGLEventListener(demo);
+
+ QuitAdapter quitAdapter = new QuitAdapter();
+ //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
+ //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+ window.addKeyListener(quitAdapter);
+ window.addWindowListener(quitAdapter);
+
+ Animator animator = new Animator();
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD);
+ animator.add(glad);
+ animator.start();
+ Assert.assertTrue(animator.isStarted());
+ Assert.assertTrue(animator.isAnimating());
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+ System.out.println("Fin start ...");
+
+ animator.stop();
+ Assert.assertFalse(animator.isAnimating());
+ Assert.assertFalse(animator.isStarted());
+ glad.destroy();
+ System.out.println("Fin Drawable: "+drawable);
+ System.out.println("Fin Window: "+window);
+ }
+
+ @Test
+ public void testOnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = new GLCapabilities( GLProfile.getGL2ES2() );
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
index c5b4227c2..050e596cf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
@@ -55,6 +55,7 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import jogamp.newt.WindowImpl;
/**
* Tests using a NEWT {@link Window} for on- and offscreen cases.
@@ -169,6 +170,11 @@ public class TestGLAutoDrawableDelegateOnOffscrnCapsNEWT extends UITestCase {
}
};
+ window.setWindowDestroyNotifyAction( new Runnable() {
+ public void run() {
+ glad.windowDestroyNotifyOp();
+ } } );
+
window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
@@ -179,11 +185,6 @@ public class TestGLAutoDrawableDelegateOnOffscrnCapsNEWT extends UITestCase {
public void windowResized(WindowEvent e) {
glad.windowResizedOp(window.getWidth(), window.getHeight());
}
-
- @Override
- public void windowDestroyNotify(WindowEvent e) {
- glad.windowDestroyNotifyOp();
- }
});
glad.addGLEventListener(demo);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java
index 8b1449493..cce4149ba 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java
@@ -107,6 +107,11 @@ public class TestGLContextDrawableSwitch01NEWT extends UITestCase {
}
};
+ window.setWindowDestroyNotifyAction( new Runnable() {
+ public void run() {
+ glad.windowDestroyNotifyOp();
+ } } );
+
// add basic window interaction
window.addWindowListener(new WindowAdapter() {
@Override
@@ -117,10 +122,6 @@ public class TestGLContextDrawableSwitch01NEWT extends UITestCase {
public void windowResized(WindowEvent e) {
glad.windowResizedOp(window.getWidth(), window.getHeight());
}
- @Override
- public void windowDestroyNotify(WindowEvent e) {
- glad.windowDestroyNotifyOp();
- }
});
window.addWindowListener(wl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java
index 4af9a3932..2ef797fba 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java
@@ -109,6 +109,11 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase {
}
};
+ window.setWindowDestroyNotifyAction( new Runnable() {
+ public void run() {
+ glad.windowDestroyNotifyOp();
+ } } );
+
// add basic window interaction
window.addWindowListener(new WindowAdapter() {
@Override
@@ -119,10 +124,6 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase {
public void windowResized(WindowEvent e) {
glad.windowResizedOp(window.getWidth(), window.getHeight());
}
- @Override
- public void windowDestroyNotify(WindowEvent e) {
- glad.windowDestroyNotifyOp();
- }
});
window.addWindowListener(wl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
index 90407166f..8cc094276 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
@@ -33,9 +33,7 @@ import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GLAnimatorControl;
@@ -70,6 +68,7 @@ public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
static Dimension frameSize1;
static Dimension preferredGLSize;
static long durationPerTest = 1000;
+ static boolean waitForKey = false;
@BeforeClass
public static void initClass() {
@@ -189,7 +188,10 @@ public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
Thread.sleep(durationPerTest/2);
- end(animator1, frame1, null);
+ end(animator1, frame1, null);
+ if( waitForKey ) {
+ UITestCase.waitForKey("Continue");
+ }
}
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
@@ -214,7 +216,6 @@ public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
}
public static void main(String args[]) throws IOException {
- boolean waitForKey = false;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
@@ -234,11 +235,7 @@ public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
}
}
if(waitForKey) {
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- System.err.println("Press enter to continue");
- try {
- System.err.println(stdin.readLine());
- } catch (IOException e) { }
+ UITestCase.waitForKey("Start");
}
String tstname = TestOffscreenLayer01GLCanvasAWT.class.getName();
/*
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
index e4a3bce71..2236f4b05 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
@@ -33,9 +33,7 @@ import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GLAnimatorControl;
@@ -70,6 +68,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
static Dimension frameSize1;
static Dimension preferredGLSize;
static long durationPerTest = 1000;
+ static boolean waitForKey = false;
@BeforeClass
public static void initClass() {
@@ -79,7 +78,6 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
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);
@@ -169,7 +167,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
Assert.assertEquals(true, newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
-
+
GLAnimatorControl animator1 = new Animator(glWindow1);
if(!noAnimation) {
animator1.start();
@@ -187,6 +185,9 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
Thread.sleep(durationPerTest/2);
end(animator1, frame1, glWindow1);
+ if( waitForKey ) {
+ UITestCase.waitForKey("Continue");
+ }
}
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
@@ -211,7 +212,6 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
public static void main(String args[]) throws IOException {
- boolean waitForKey = false;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
@@ -231,11 +231,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
}
if(waitForKey) {
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- System.err.println("Press enter to continue");
- try {
- System.err.println(stdin.readLine());
- } catch (IOException e) { }
+ UITestCase.waitForKey("Start");
}
String tstname = TestOffscreenLayer02NewtCanvasAWT.class.getName();
/*
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
index 7894f3e86..fbea81a54 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
@@ -68,6 +68,7 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil.WindowClosingListener;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
@@ -507,6 +508,8 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
*/
public void testContextSharingCreateVisibleDestroy(final boolean useNewt, final boolean shareContext) throws InterruptedException, InvocationTargetException {
final JFrame frame = new JFrame("Simple JOGL App for testing context sharing");
+ final WindowClosingListener awtClosingListener = AWTRobotUtil.addClosingListener(frame);
+
//
// GLDrawableFactory factory = GLDrawableFactory.getFactory(GLProfile.get(GLProfile.GL2));
// GLContext sharedContext = factory.getOrCreateSharedContext(factory.getDefaultDevice());
@@ -699,7 +702,7 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
while(animator.isAnimating() && animator.getTotalFPSDuration() < durationPerTest) {
Thread.sleep(100);
}
- AWTRobotUtil.closeWindow(frame, true);
+ AWTRobotUtil.closeWindow(frame, true, awtClosingListener);
boolean windowClosed = closingSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
Assert.assertEquals(true, windowClosed);
} catch (InterruptedException e) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java
new file mode 100644
index 000000000..d59bc2230
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
+ static long durationPerTest = 500;
+ static boolean shallUseOffscreenFBOLayer = false;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static GLProfile glp;
+ static int width, height;
+ static boolean waitForKey = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
+ glp = GLProfile.get(GLProfile.GL2ES2);
+ Assert.assertNotNull(glp);
+ width = 640;
+ height = 480;
+ } else {
+ setTestSupported(false);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected JPanel create(final JFrame[] top, final int width, final int height, final int num)
+ throws InterruptedException, InvocationTargetException
+ {
+ final JPanel[] jPanel = new JPanel[] { null };
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jPanel[0] = new JPanel();
+ jPanel[0].setLayout(new BorderLayout());
+
+ final JFrame jFrame1 = new JFrame("JFrame #"+num);
+ // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
+ jFrame1.getContentPane().add(jPanel[0]);
+ jFrame1.setSize(width, height);
+
+ top[0] = jFrame1;
+ } } );
+ return jPanel[0];
+ }
+
+ protected void add(final Container cont, final Component comp, final JFrame jFrame)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ cont.add(comp, BorderLayout.CENTER);
+ jFrame.pack();
+ jFrame.validate();
+ } } );
+ }
+
+ protected void dispose(final GLCanvas glc)
+ throws InterruptedException, InvocationTargetException
+ {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ glc.destroy();
+ } } );
+ }
+
+ protected void setFrameVisible(final JFrame jFrame, final boolean visible) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame.setVisible(visible);
+ } } ) ;
+ }
+
+ protected void setComponentVisible(final Component comp, final boolean visible) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ comp.setVisible(visible);
+ } } ) ;
+ }
+
+ protected void dispose(final JFrame jFrame) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame.dispose();
+ } } ) ;
+ }
+
+ private volatile int frameCount = 0;
+
+ protected void runTestGL(boolean onscreen, GLCapabilities caps)
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+
+ for(int i=0; i<1; i++) {
+ Animator anim = new Animator();
+ final GLCanvas glc = new GLCanvas(caps);
+ Assert.assertNotNull(glc);
+ anim.add(glc);
+ if( !onscreen ) {
+ glc.setShallUseOffscreenLayer(true);
+ }
+ Dimension glc_sz = new Dimension(width, height);
+ glc.setMinimumSize(glc_sz);
+ glc.setPreferredSize(glc_sz);
+ glc.setSize(glc_sz);
+ glc.addGLEventListener(new GLEventListener() {
+ @Override
+ public void init(GLAutoDrawable drawable) {}
+ @Override
+ public void dispose(GLAutoDrawable drawable) {}
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ frameCount++;
+ }
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
+ });
+ final GearsES2 gears = new GearsES2(1);
+ gears.setVerbose(false);
+ glc.addGLEventListener(gears);
+
+ final JFrame[] top = new JFrame[] { null };
+ final Container glcCont = create(top, width, height, i);
+ add(glcCont, glc, top[0]);
+
+ frameCount = 0;
+ setFrameVisible(top[0], true);
+ Assert.assertTrue("Component didn't become visible", AWTRobotUtil.waitForVisible(glc, true));
+ Assert.assertTrue("Component didn't become realized", AWTRobotUtil.waitForRealized(glc, true));
+
+ anim.setUpdateFPSFrames(60, null);
+ anim.start();
+ anim.resetFPSCounter();
+ System.err.println("Visible Part 1/3");
+
+ while( anim.getTotalFPSDuration() < durationPerTest ) {
+ Thread.sleep(60);
+ }
+
+ setComponentVisible(glc, false);
+ Assert.assertTrue("Component didn't become invisible", AWTRobotUtil.waitForVisible(glc, false));
+ final int frameCountT0 = frameCount;
+ anim.resetFPSCounter();
+ System.err.println("Invisible Part 2/3");
+
+ while( anim.getTotalFPSDuration() < durationPerTest ) {
+ Thread.sleep(60);
+ }
+
+ final int frameCountT1 = frameCount;
+ System.err.println("GLCanvas invisible frame count: Before "+frameCountT0+", after "+frameCountT1);
+ Assert.assertTrue("GLCanvas rendered more that 4 times while being invisible, before "+frameCountT0+", after "+frameCountT1,
+ 4 >= frameCountT1 - frameCountT0);
+
+ setComponentVisible(glc, true);
+ Assert.assertTrue("Component didn't become visible", AWTRobotUtil.waitForVisible(glc, true));
+ anim.resetFPSCounter();
+ System.err.println("Visible Part 3/3");
+
+ while( anim.getTotalFPSDuration() < durationPerTest ) {
+ Thread.sleep(60);
+ }
+
+ System.err.println("GLCanvas isOffscreenLayerSurfaceEnabled: "+glc.isOffscreenLayerSurfaceEnabled()+": "+glc.getChosenGLCapabilities());
+
+ dispose(top[0]);
+ }
+ }
+
+ @Test
+ public void test01Onscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( shallUseOffscreenFBOLayer || shallUseOffscreenPBufferLayer || JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("Offscreen test requested or platform requires it.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(true, caps);
+ }
+
+ @Test
+ public void test02Offscreen()
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ if( !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("Platform doesn't support offscreen test.");
+ return;
+ }
+ GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ runTestGL(false, caps);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ durationPerTest = Long.parseLong(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-layeredFBO")) {
+ shallUseOffscreenFBOLayer = true;
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ System.err.println("waitForKey "+waitForKey);
+
+ System.err.println("shallUseOffscreenFBOLayer "+shallUseOffscreenFBOLayer);
+ System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ org.junit.runner.JUnitCore.main(TestBug664GLCanvasSetVisibleSwingAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug675BeansInDesignTimeAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug675BeansInDesignTimeAWT.java
new file mode 100644
index 000000000..0c0975308
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug675BeansInDesignTimeAWT.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Window;
+import java.beans.Beans;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+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;
+
+public class TestBug675BeansInDesignTimeAWT extends UITestCase {
+ static boolean waitForKey = false;
+ static long durationPerTest = 200;
+
+ @Test
+ public void test01() throws InterruptedException, InvocationTargetException {
+ Beans.setDesignTime(true);
+
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ final GLCanvas glCanvas = new GLCanvas(caps);
+ final Dimension preferredGLSize = new Dimension(400,200);
+ glCanvas.setPreferredSize(preferredGLSize);
+ glCanvas.setMinimumSize(preferredGLSize);
+ glCanvas.setSize(preferredGLSize);
+
+ glCanvas.addGLEventListener(new GearsES2());
+
+ final Window window = new JFrame(this.getSimpleTestName(" - "));
+ window.setLayout(new BorderLayout());
+ window.add(glCanvas, BorderLayout.CENTER);
+
+ // trigger realization on AWT-EDT, otherwise it won't immediatly ..
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ window.pack();
+ window.validate();
+ window.setVisible(true);
+ }
+ } );
+
+ // Immediately displayable after issuing initial setVisible(true) on AWT-EDT!
+ Assert.assertTrue("GLCanvas didn't become displayable", glCanvas.isDisplayable());
+ if( !Beans.isDesignTime() ) {
+ Assert.assertTrue("GLCanvas didn't become realized", glCanvas.isRealized());
+ }
+
+ Thread.sleep(durationPerTest);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ window.dispose();
+ }
+ } );
+ }
+
+ public static void main(String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ org.junit.runner.JUnitCore.main(TestBug675BeansInDesignTimeAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
index 9f62e4a49..aca2b675c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
@@ -40,11 +40,14 @@ import com.jogamp.newt.event.TraceKeyAdapter;
import com.jogamp.newt.event.TraceWindowAdapter;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
@@ -55,25 +58,27 @@ import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
public class TestGearsES2AWT extends UITestCase {
+ public enum FrameLayout { None, TextOnBottom, BorderCenterSurrounded, DoubleBorderCenterSurrounded };
static int width, height;
static boolean forceES2 = false;
static boolean forceGL3 = false;
- static boolean shallUseOffscreenLayer = false;
+ static boolean shallUseOffscreenFBOLayer = false;
static boolean shallUseOffscreenPBufferLayer = false;
static boolean useMSAA = false;
static boolean useStencil = false;
- static boolean addComp = true;
static boolean shutdownRemoveGLCanvas = true;
static boolean shutdownDisposeFrame = true;
static boolean shutdownSystemExit = false;
static int swapInterval = 1;
static boolean exclusiveContext = false;
static Thread awtEDT;
+ static Dimension rwsize = null;
@BeforeClass
public static void initClass() {
@@ -94,25 +99,70 @@ public class TestGearsES2AWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException, InvocationTargetException {
+ static void setGLCanvasSize(final Frame frame, final GLCanvas glc, final Dimension new_sz) {
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ glc.setMinimumSize(new_sz);
+ glc.setPreferredSize(new_sz);
+ glc.setSize(new_sz);
+ if( null != frame ) {
+ frame.pack();
+ }
+ } } );
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ protected void runTestGL(GLCapabilities caps, FrameLayout frameLayout) throws InterruptedException, InvocationTargetException {
final Frame frame = new Frame("GearsES2 AWT Test");
Assert.assertNotNull(frame);
final GLCanvas glCanvas = new GLCanvas(caps);
Assert.assertNotNull(glCanvas);
- Dimension glc_sz = new Dimension(width, height);
- glCanvas.setMinimumSize(glc_sz);
- glCanvas.setPreferredSize(glc_sz);
- glCanvas.setSize(glc_sz);
- if(addComp) {
- final TextArea ta = new TextArea(2, 20);
- ta.append("0123456789");
- ta.append(Platform.getNewline());
- ta.append("Some Text");
- ta.append(Platform.getNewline());
- frame.add(ta, BorderLayout.SOUTH);
+ setGLCanvasSize(null, glCanvas, new Dimension(width, height));
+
+ switch( frameLayout) {
+ case None:
+ frame.add(glCanvas);
+ break;
+ case TextOnBottom:
+ final TextArea ta = new TextArea(2, 20);
+ ta.append("0123456789");
+ ta.append(Platform.getNewline());
+ ta.append("Some Text");
+ ta.append(Platform.getNewline());
+ frame.setLayout(new BorderLayout());
+ frame.add(ta, BorderLayout.SOUTH);
+ frame.add(glCanvas, BorderLayout.CENTER);
+ break;
+ case BorderCenterSurrounded:
+ frame.setLayout(new BorderLayout());
+ frame.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ frame.add(new Button("EAST"), BorderLayout.EAST);
+ frame.add(new Button("WEST"), BorderLayout.WEST);
+ frame.add(glCanvas, BorderLayout.CENTER);
+ break;
+ case DoubleBorderCenterSurrounded:
+ 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(glCanvas, BorderLayout.CENTER);
+
+ frame.setLayout(new BorderLayout());
+ frame.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ frame.add(new Button("EAST"), BorderLayout.EAST);
+ frame.add(new Button("WEST"), BorderLayout.WEST);
+ frame.add(c, BorderLayout.CENTER);
+ break;
}
- frame.add(glCanvas, BorderLayout.CENTER);
frame.setTitle("Gears AWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
glCanvas.addGLEventListener(new GearsES2(swapInterval));
@@ -130,13 +180,24 @@ public class TestGearsES2AWT extends UITestCase {
public void run() {
frame.pack();
frame.setVisible(true);
- }});
+ }});
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true));
+
animator.start();
Assert.assertTrue(animator.isStarted());
Assert.assertTrue(animator.isAnimating());
Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
animator.setUpdateFPSFrames(60, System.err);
+ System.err.println("canvas pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getWidth()+"x"+glCanvas.getHeight());
+
+ if( null != rwsize ) {
+ Thread.sleep(500); // 500ms delay
+ setGLCanvasSize(frame, glCanvas, rwsize);
+ System.err.println("window resize pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getWidth()+"x"+glCanvas.getHeight());
+ }
+
while(!quitAdapter.shouldQuit() /* && animator.isAnimating() */ && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
@@ -184,19 +245,21 @@ public class TestGearsES2AWT extends UITestCase {
if(useStencil) {
caps.setStencilBits(1);
}
- if(shallUseOffscreenLayer) {
+ if(shallUseOffscreenFBOLayer) {
caps.setOnscreen(false);
}
if(shallUseOffscreenPBufferLayer) {
caps.setPBuffer(true);
}
- runTestGL(caps);
+ runTestGL(caps, frameLayout);
}
static long duration = 500; // ms
-
+ static FrameLayout frameLayout = FrameLayout.None;
+
public static void main(String args[]) {
boolean waitForKey = false;
+ int rw=-1, rh=-1;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
@@ -204,6 +267,15 @@ public class TestGearsES2AWT extends UITestCase {
try {
duration = Integer.parseInt(args[i]);
} catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-rwidth")) {
+ i++;
+ rw = MiscUtils.atoi(args[i], rw);
+ } else if(args[i].equals("-rheight")) {
+ i++;
+ rh = MiscUtils.atoi(args[i], rh);
+ } else if(args[i].equals("-layout")) {
+ i++;
+ frameLayout = FrameLayout.valueOf(args[i]);
} else if(args[i].equals("-es2")) {
forceES2 = true;
} else if(args[i].equals("-gl3")) {
@@ -213,8 +285,8 @@ public class TestGearsES2AWT extends UITestCase {
swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-exclctx")) {
exclusiveContext = true;
- } else if(args[i].equals("-layered")) {
- shallUseOffscreenLayer = true;
+ } else if(args[i].equals("-layeredFBO")) {
+ shallUseOffscreenFBOLayer = true;
} else if(args[i].equals("-layeredPBuffer")) {
shallUseOffscreenPBufferLayer = true;
} else if(args[i].equals("-msaa")) {
@@ -223,8 +295,6 @@ public class TestGearsES2AWT extends UITestCase {
useStencil = true;
} else if(args[i].equals("-wait")) {
waitForKey = true;
- } else if(args[i].equals("-justGears")) {
- addComp = false;
} else if(args[i].equals("-shutdownKeepGLCanvas")) {
shutdownRemoveGLCanvas = false;
} else if(args[i].equals("-shutdownKeepFrame")) {
@@ -236,11 +306,18 @@ public class TestGearsES2AWT extends UITestCase {
shutdownSystemExit = true;
}
}
+ if( 0 < rw && 0 < rh ) {
+ rwsize = new Dimension(rw, rh);
+ }
+
+ System.err.println("resize "+rwsize);
+ System.err.println("frameLayout "+frameLayout);
System.err.println("forceES2 "+forceES2);
System.err.println("forceGL3 "+forceGL3);
System.err.println("swapInterval "+swapInterval);
System.err.println("exclusiveContext "+exclusiveContext);
- System.err.println("shallUseOffscreenLayer "+shallUseOffscreenLayer);
+ System.err.println("shallUseOffscreenFBOLayer "+shallUseOffscreenFBOLayer);
+ System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
if(waitForKey) {
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index 3910d1881..47891a8df 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -71,7 +71,7 @@ import org.junit.Test;
public class TestGearsES2NEWT extends UITestCase {
static int screenIdx = 0;
static PointImmutable wpos;
- static DimensionImmutable wsize;
+ static DimensionImmutable wsize, rwsize=null;
static long duration = 500; // ms
static boolean opaque = true;
@@ -265,6 +265,11 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+ if( null != rwsize ) {
+ Thread.sleep(500); // 500ms delay
+ glWindow.setSize(rwsize.getWidth(), rwsize.getHeight());
+ System.err.println("window resize pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+ }
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
@@ -318,7 +323,7 @@ public class TestGearsES2NEWT extends UITestCase {
public static void main(String args[]) throws IOException {
mainRun = true;
- int x=0, y=0, w=640, h=480;
+ int x=0, y=0, w=640, h=480, rw=-1, rh=-1;
boolean usePos = false;
for(int i=0; i<args.length; i++) {
@@ -369,6 +374,12 @@ public class TestGearsES2NEWT extends UITestCase {
i++;
y = MiscUtils.atoi(args[i], y);
usePos = true;
+ } else if(args[i].equals("-rwidth")) {
+ i++;
+ rw = MiscUtils.atoi(args[i], rw);
+ } else if(args[i].equals("-rheight")) {
+ i++;
+ rh = MiscUtils.atoi(args[i], rh);
} else if(args[i].equals("-screen")) {
i++;
screenIdx = MiscUtils.atoi(args[i], 0);
@@ -380,12 +391,16 @@ public class TestGearsES2NEWT extends UITestCase {
}
}
wsize = new Dimension(w, h);
+ if( 0 < rw && 0 < rh ) {
+ rwsize = new Dimension(rw, rh);
+ }
if(usePos) {
wpos = new Point(x, y);
}
System.err.println("position "+wpos);
System.err.println("size "+wsize);
+ System.err.println("resize "+rwsize);
System.err.println("screen "+screenIdx);
System.err.println("translucent "+(!opaque));
System.err.println("forceAlpha "+forceAlpha);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
index 5fca50593..ad2165301 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
@@ -29,10 +29,15 @@
package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Component;
+import java.awt.Container;
import java.awt.Frame;
+import java.awt.TextArea;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import com.jogamp.common.os.Platform;
import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
@@ -62,14 +67,18 @@ import javax.media.opengl.GLProfile;
import javax.swing.SwingUtilities;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
public class TestGearsES2NewtCanvasAWT extends UITestCase {
+ public enum FrameLayout { None, TextOnBottom, BorderBottom, BorderBottom2, BorderCenter, BorderCenterSurrounded, DoubleBorderCenterSurrounded };
+ public enum ResizeBy { GLWindow, Component, Frame };
+
static int screenIdx = 0;
static PointImmutable wpos;
- static DimensionImmutable wsize;
+ static DimensionImmutable wsize, rwsize = null;
static long duration = 500; // ms
static boolean opaque = true;
@@ -80,6 +89,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
static boolean showFPS = false;
static int loops = 1;
static boolean loop_shutdown = false;
+ static boolean shallUseOffscreenFBOLayer = false;
static boolean forceES2 = false;
static boolean forceGL3 = false;
static boolean mainRun = false;
@@ -96,7 +106,69 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException, InvocationTargetException {
+ static void setGLWindowSize(final Frame frame, final GLWindow glw, final DimensionImmutable new_sz) {
+ try {
+ glw.setSize(new_sz.getWidth(), new_sz.getHeight());
+ if( null != frame ) {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.pack();
+ } } );
+ }
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+ static void setComponentSize(final Frame frame, final Component comp, final DimensionImmutable new_sz) {
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ java.awt.Dimension d = new java.awt.Dimension(new_sz.getWidth(), new_sz.getHeight());
+ comp.setMinimumSize(d);
+ comp.setPreferredSize(d);
+ comp.setSize(d);
+ if( null != frame ) {
+ frame.pack();
+ }
+ } } );
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+ static void setFrameSize(final Frame frame, final boolean frameLayout, final DimensionImmutable new_sz) {
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ java.awt.Dimension d = new java.awt.Dimension(new_sz.getWidth(), new_sz.getHeight());
+ frame.setSize(d);
+ if( frameLayout ) {
+ frame.validate();
+ }
+ } } );
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ static void setSize(final ResizeBy resizeBy, final Frame frame, final boolean frameLayout, final Component comp, final GLWindow glw, final DimensionImmutable new_sz) {
+ switch( resizeBy ) {
+ case GLWindow:
+ setGLWindowSize(frameLayout ? frame : null, glw, new_sz);
+ break;
+ case Component:
+ setComponentSize(frameLayout ? frame : null, comp, new_sz);
+ break;
+ case Frame:
+ setFrameSize(frame, frameLayout, new_sz);
+ break;
+ }
+ }
+
+ // public enum ResizeBy { GLWindow, Component, Frame };
+ protected void runTestGL(final GLCapabilitiesImmutable caps, final ResizeBy resizeBy, final FrameLayout frameLayout) throws InterruptedException, InvocationTargetException {
System.err.println("requested: vsync "+swapInterval+", "+caps);
Display dpy = NewtFactory.createDisplay(null);
Screen screen = NewtFactory.createScreen(dpy, screenIdx);
@@ -104,13 +176,68 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
Assert.assertNotNull(glWindow);
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if ( shallUseOffscreenFBOLayer ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
+
+ final Frame frame = new Frame("AWT Parent Frame");
+
+ setSize(resizeBy, frame, false, newtCanvasAWT, glWindow, wsize);
+
+ switch( frameLayout) {
+ case None:
+ frame.add(newtCanvasAWT);
+ break;
+ case TextOnBottom:
+ final TextArea ta = new TextArea(2, 20);
+ ta.append("0123456789");
+ ta.append(Platform.getNewline());
+ ta.append("Some Text");
+ ta.append(Platform.getNewline());
+ frame.setLayout(new BorderLayout());
+ frame.add(ta, BorderLayout.SOUTH);
+ frame.add(newtCanvasAWT, BorderLayout.CENTER);
+ break;
+ case BorderBottom:
+ frame.setLayout(new BorderLayout());
+ frame.add(newtCanvasAWT, BorderLayout.SOUTH);
+ break;
+ case BorderBottom2:
+ frame.setLayout(new BorderLayout());
+ frame.add(newtCanvasAWT, BorderLayout.SOUTH);
+ frame.add(new Button("North"), BorderLayout.NORTH);
+ break;
+ case BorderCenter:
+ frame.setLayout(new BorderLayout());
+ frame.add(newtCanvasAWT, BorderLayout.CENTER);
+ break;
+ case BorderCenterSurrounded:
+ frame.setLayout(new BorderLayout());
+ frame.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ frame.add(new Button("EAST"), BorderLayout.EAST);
+ frame.add(new Button("WEST"), BorderLayout.WEST);
+ frame.add(newtCanvasAWT, BorderLayout.CENTER);
+ break;
+ case DoubleBorderCenterSurrounded:
+ 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(newtCanvasAWT, BorderLayout.CENTER);
+
+ frame.setLayout(new BorderLayout());
+ frame.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ frame.add(new Button("EAST"), BorderLayout.EAST);
+ frame.add(new Button("WEST"), BorderLayout.WEST);
+ frame.add(c, BorderLayout.CENTER);
+ break;
+ }
- final Frame frame1 = new Frame("AWT Parent Frame");
- frame1.setLayout(new BorderLayout());
- frame1.add(newtCanvasAWT, BorderLayout.CENTER);
- frame1.setSize(wsize.getWidth(), wsize.getHeight());
- frame1.setLocation(0, 0);
- frame1.setTitle("Gears NewtCanvasAWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval+", size "+wsize+", pos "+wpos);
+ frame.setTitle("Gears NewtCanvasAWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval+", size "+wsize+", pos "+wpos);
final GearsES2 demo = new GearsES2(swapInterval);
demo.setPMVUseBackingArray(pmvUseBackingArray);
@@ -158,9 +285,16 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- frame1.setVisible(true);
+ if( ResizeBy.Frame == resizeBy ) {
+ frame.validate();
+ } else {
+ frame.pack();
+ }
+ frame.setVisible(true);
}
- });
+ });
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
@@ -168,6 +302,12 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+ if( null != rwsize ) {
+ Thread.sleep(500); // 500ms delay
+ setSize(resizeBy, frame, true, newtCanvasAWT, glWindow, rwsize);
+ System.err.println("window resize "+rwsize+" -> pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+ }
+
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
@@ -179,7 +319,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
Assert.assertEquals(null, glWindow.getExclusiveContextThread());
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- frame1.dispose();
+ frame.dispose();
}
});
glWindow.destroy();
@@ -203,7 +343,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
if(-1 < forceAlpha) {
caps.setAlphaBits(forceAlpha);
}
- runTestGL(caps);
+ runTestGL(caps, resizeBy, frameLayout);
if(loop_shutdown) {
GLProfile.shutdown();
}
@@ -219,19 +359,35 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
}
final GLProfile glp = GLProfile.get(GLProfile.GL3);
final GLCapabilities caps = new GLCapabilities( glp );
- runTestGL(caps);
+ runTestGL(caps, resizeBy, frameLayout);
}
+ static FrameLayout frameLayout = FrameLayout.None;
+ static ResizeBy resizeBy = ResizeBy.Component;
+
public static void main(String args[]) throws IOException {
mainRun = true;
int x=0, y=0, w=640, h=480;
+ int rw=-1, rh=-1;
boolean usePos = false;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-rwidth")) {
+ i++;
+ rw = MiscUtils.atoi(args[i], rw);
+ } else if(args[i].equals("-rheight")) {
+ i++;
+ rh = MiscUtils.atoi(args[i], rh);
+ } else if(args[i].equals("-layout")) {
+ i++;
+ frameLayout = FrameLayout.valueOf(args[i]);
+ } else if(args[i].equals("-resizeBy")) {
+ i++;
+ resizeBy = ResizeBy.valueOf(args[i]);
} else if(args[i].equals("-translucent")) {
opaque = false;
} else if(args[i].equals("-forceAlpha")) {
@@ -244,6 +400,8 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
} else if(args[i].equals("-vsync")) {
i++;
swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-layeredFBO")) {
+ shallUseOffscreenFBOLayer = true;
} else if(args[i].equals("-exclctx")) {
exclusiveContext = true;
} else if(args[i].equals("-es2")) {
@@ -277,12 +435,19 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
}
}
wsize = new Dimension(w, h);
+ if( 0 < rw && 0 < rh ) {
+ rwsize = new Dimension(rw, rh);
+ }
if(usePos) {
wpos = new Point(x, y);
}
+
+ System.err.println("frameLayout "+frameLayout);
+ System.err.println("resizeBy "+resizeBy);
System.err.println("position "+wpos);
System.err.println("size "+wsize);
+ System.err.println("resize "+rwsize);
System.err.println("screen "+screenIdx);
System.err.println("translucent "+(!opaque));
System.err.println("forceAlpha "+forceAlpha);
@@ -290,6 +455,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
System.err.println("pmvDirect "+(!pmvUseBackingArray));
System.err.println("loops "+loops);
System.err.println("loop shutdown "+loop_shutdown);
+ System.err.println("shallUseOffscreenFBOLayer "+shallUseOffscreenFBOLayer);
System.err.println("forceES2 "+forceES2);
System.err.println("forceGL3 "+forceGL3);
System.err.println("swapInterval "+swapInterval);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
new file mode 100644
index 000000000..cb2cf064f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
@@ -0,0 +1,375 @@
+/**
+ * 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.jogl.demos.es2.newt;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.swt.NewtCanvasSWT;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
+import javax.media.nativewindow.util.DimensionImmutable;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLProfile;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestGearsES2NewtCanvasSWT extends UITestCase {
+ static int screenIdx = 0;
+ static PointImmutable wpos;
+ static DimensionImmutable wsize, rwsize = null;
+
+ static long duration = 500; // ms
+ static boolean opaque = true;
+ static int forceAlpha = -1;
+ static boolean fullscreen = false;
+ static boolean pmvUseBackingArray = true;
+ static int swapInterval = 1;
+ static boolean showFPS = false;
+ static int loops = 1;
+ static boolean loop_shutdown = false;
+ static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
+ static boolean exclusiveContext = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(null == wsize) {
+ wsize = new Dimension(640, 480);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+
+ @Before
+ public void init() {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ }});
+ display.syncExec(new Runnable() {
+ public void run() {
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }});
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ display.syncExec(new Runnable() {
+ public void run() {
+ composite.dispose();
+ shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display.dispose();
+ }});
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+
+ protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException, InvocationTargetException {
+ System.err.println("requested: vsync "+swapInterval+", "+caps);
+ com.jogamp.newt.Display dpy = NewtFactory.createDisplay(null);
+ com.jogamp.newt.Screen screen = NewtFactory.createScreen(dpy, screenIdx);
+ final GLWindow glWindow = GLWindow.create(screen, caps);
+ Assert.assertNotNull(glWindow);
+
+ final GearsES2 demo = new GearsES2(swapInterval);
+ demo.setPMVUseBackingArray(pmvUseBackingArray);
+ glWindow.addGLEventListener(demo);
+
+ Animator animator = new Animator();
+ animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD);
+ animator.setExclusiveContext(exclusiveContext);
+
+ QuitAdapter quitAdapter = new QuitAdapter();
+ //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
+ //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+ glWindow.addKeyListener(quitAdapter);
+ glWindow.addWindowListener(quitAdapter);
+
+ glWindow.addWindowListener(new WindowAdapter() {
+ public void windowResized(WindowEvent e) {
+ System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ public void windowMoved(WindowEvent e) {
+ System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ });
+
+ glWindow.addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar()=='f') {
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+ glWindow.setExclusiveContextThread(t);
+ } }.start();
+ }
+ }
+ });
+
+ animator.add(glWindow);
+ animator.start();
+ Assert.assertTrue(animator.isStarted());
+ Assert.assertTrue(animator.isAnimating());
+ Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread());
+
+ final NewtCanvasSWT canvas1 = NewtCanvasSWT.create( composite, 0, glWindow );
+ Assert.assertNotNull( canvas1 );
+
+ display.syncExec( new Runnable() {
+ public void run() {
+ shell.setText( getSimpleTestName(".") );
+ shell.setSize( wsize.getWidth(), wsize.getHeight() );
+ if( null != wpos ) {
+ shell.setLocation( wpos.getX(), wpos.getY() );
+ }
+ shell.open();
+ }
+ });
+
+ animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+
+ System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
+ System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
+ System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+
+ if( null != rwsize ) {
+ for(int i=0; i<50; i++) { // 500 ms dispatched delay
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ display.syncExec( new Runnable() {
+ public void run() {
+ shell.setSize( rwsize.getWidth(), rwsize.getHeight() );
+ }
+ });
+ System.err.println("window resize pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+ }
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+
+ Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread());
+ animator.stop();
+ Assert.assertFalse(animator.isAnimating());
+ Assert.assertFalse(animator.isStarted());
+ Assert.assertEquals(null, glWindow.getExclusiveContextThread());
+
+ canvas1.dispose();
+ glWindow.destroy();
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false));
+ }
+
+ @Test
+ public void test01GL2ES2() throws InterruptedException, InvocationTargetException {
+ for(int i=1; i<=loops; i++) {
+ System.err.println("Loop "+i+"/"+loops);
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities( glp );
+ caps.setBackgroundOpaque(opaque);
+ if(-1 < forceAlpha) {
+ caps.setAlphaBits(forceAlpha);
+ }
+ runTestGL(caps);
+ if(loop_shutdown) {
+ GLProfile.shutdown();
+ }
+ }
+ }
+
+ @Test
+ public void test02GL3() throws InterruptedException, InvocationTargetException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+
+ int x=0, y=0, w=640, h=480, rw=-1, rh=-1;
+ boolean usePos = false;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-translucent")) {
+ opaque = false;
+ } else if(args[i].equals("-forceAlpha")) {
+ i++;
+ forceAlpha = MiscUtils.atoi(args[i], 0);
+ } else if(args[i].equals("-fullscreen")) {
+ fullscreen = true;
+ } else if(args[i].equals("-pmvDirect")) {
+ pmvUseBackingArray = false;
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-exclctx")) {
+ exclusiveContext = true;
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
+ } else if(args[i].equals("-showFPS")) {
+ showFPS = true;
+ } else if(args[i].equals("-width")) {
+ i++;
+ w = MiscUtils.atoi(args[i], w);
+ } else if(args[i].equals("-height")) {
+ i++;
+ h = MiscUtils.atoi(args[i], h);
+ } else if(args[i].equals("-x")) {
+ i++;
+ x = MiscUtils.atoi(args[i], x);
+ usePos = true;
+ } else if(args[i].equals("-y")) {
+ i++;
+ y = MiscUtils.atoi(args[i], y);
+ usePos = true;
+ } else if(args[i].equals("-rwidth")) {
+ i++;
+ rw = MiscUtils.atoi(args[i], rw);
+ } else if(args[i].equals("-rheight")) {
+ i++;
+ rh = MiscUtils.atoi(args[i], rh);
+ } else if(args[i].equals("-screen")) {
+ i++;
+ screenIdx = MiscUtils.atoi(args[i], 0);
+ } else if(args[i].equals("-loops")) {
+ i++;
+ loops = MiscUtils.atoi(args[i], 1);
+ } else if(args[i].equals("-loop-shutdown")) {
+ loop_shutdown = true;
+ }
+ }
+ wsize = new Dimension(w, h);
+ if( 0 < rw && 0 < rh ) {
+ rwsize = new Dimension(rw, rh);
+ }
+
+ if(usePos) {
+ wpos = new Point(x, y);
+ }
+ System.err.println("position "+wpos);
+ System.err.println("size "+wsize);
+ System.err.println("resize "+rwsize);
+ System.err.println("screen "+screenIdx);
+ System.err.println("translucent "+(!opaque));
+ System.err.println("forceAlpha "+forceAlpha);
+ System.err.println("fullscreen "+fullscreen);
+ System.err.println("pmvDirect "+(!pmvUseBackingArray));
+ System.err.println("loops "+loops);
+ System.err.println("loop shutdown "+loop_shutdown);
+ System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
+ System.err.println("swapInterval "+swapInterval);
+ System.err.println("exclusiveContext "+exclusiveContext);
+
+ org.junit.runner.JUnitCore.main(TestGearsES2NewtCanvasSWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/swt/TestGearsES2SWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/swt/TestGearsES2SWT.java
new file mode 100644
index 000000000..c6f299e83
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/swt/TestGearsES2SWT.java
@@ -0,0 +1,340 @@
+/**
+ * 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.jogl.demos.es2.swt;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.opengl.swt.GLCanvas;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
+import javax.media.nativewindow.util.DimensionImmutable;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLProfile;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestGearsES2SWT extends UITestCase {
+ static int screenIdx = 0;
+ static PointImmutable wpos;
+ static DimensionImmutable wsize, rwsize=null;
+
+ static long duration = 500; // ms
+ static boolean opaque = true;
+ static int forceAlpha = -1;
+ static boolean fullscreen = false;
+ static boolean pmvUseBackingArray = true;
+ static int swapInterval = 1;
+ static boolean showFPS = false;
+ static int loops = 1;
+ static boolean loop_shutdown = false;
+ static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
+ static boolean exclusiveContext = false;
+
+ @BeforeClass
+ public static void initClass() {
+ if(null == wsize) {
+ wsize = new Dimension(640, 480);
+ }
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+
+ @Before
+ public void init() {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ }});
+ display.syncExec(new Runnable() {
+ public void run() {
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }});
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ display.syncExec(new Runnable() {
+ public void run() {
+ composite.dispose();
+ shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display.dispose();
+ }});
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+
+ protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException, InvocationTargetException {
+ System.err.println("requested: vsync "+swapInterval+", "+caps);
+
+ final GLCanvas canvas = GLCanvas.create( composite, 0, caps, null, null);
+ Assert.assertNotNull( canvas );
+
+ final GearsES2 demo = new GearsES2(swapInterval);
+ demo.setPMVUseBackingArray(pmvUseBackingArray);
+ canvas.addGLEventListener(demo);
+
+ Animator animator = new Animator();
+ animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD);
+ animator.setExclusiveContext(exclusiveContext);
+
+ animator.add(canvas);
+ animator.start();
+ Assert.assertTrue(animator.isStarted());
+ Assert.assertTrue(animator.isAnimating());
+ Assert.assertEquals(exclusiveContext ? animator.getThread() : null, canvas.getExclusiveContextThread());
+
+ display.syncExec( new Runnable() {
+ public void run() {
+ shell.setText( getSimpleTestName(".") );
+ shell.setSize( wsize.getWidth(), wsize.getHeight() );
+ if( null != wpos ) {
+ shell.setLocation( wpos.getX(), wpos.getY() );
+ }
+ shell.open();
+ }
+ });
+
+ animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+
+ while(animator.isAnimating() && !canvas.isRealized() && animator.getTotalFPSDuration()<duration) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ System.err.println("NW chosen: "+canvas.getDelegatedDrawable().getChosenGLCapabilities());
+ System.err.println("GL chosen: "+canvas.getChosenGLCapabilities());
+ System.err.println("window pos/siz: "+canvas.getLocation()+" "+canvas.getWidth()+"x"+canvas.getHeight());
+
+ if( null != rwsize ) {
+ for(int i=0; i<50; i++) { // 500 ms dispatched delay
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ display.syncExec( new Runnable() {
+ public void run() {
+ shell.setSize( rwsize.getWidth(), rwsize.getHeight() );
+ }
+ });
+ System.err.println("window resize pos/siz: "+canvas.getLocation()+" "+canvas.getWidth()+"x"+canvas.getHeight());
+ }
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+
+ Assert.assertEquals(exclusiveContext ? animator.getThread() : null, canvas.getExclusiveContextThread());
+ animator.stop();
+ Assert.assertFalse(animator.isAnimating());
+ Assert.assertFalse(animator.isStarted());
+ Assert.assertEquals(null, canvas.getExclusiveContextThread());
+
+ display.syncExec(new Runnable() {
+ public void run() {
+ canvas.dispose();
+ } } );
+ }
+
+ @Test
+ public void test01GL2ES2() throws InterruptedException, InvocationTargetException {
+ for(int i=1; i<=loops; i++) {
+ System.err.println("Loop "+i+"/"+loops);
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities( glp );
+ caps.setBackgroundOpaque(opaque);
+ if(-1 < forceAlpha) {
+ caps.setAlphaBits(forceAlpha);
+ }
+ runTestGL(caps);
+ if(loop_shutdown) {
+ GLProfile.shutdown();
+ }
+ }
+ }
+
+ @Test
+ public void test02GL3() throws InterruptedException, InvocationTargetException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+
+ int x=0, y=0, w=640, h=480, rw=-1, rh=-1;
+ boolean usePos = false;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-translucent")) {
+ opaque = false;
+ } else if(args[i].equals("-forceAlpha")) {
+ i++;
+ forceAlpha = MiscUtils.atoi(args[i], 0);
+ } else if(args[i].equals("-fullscreen")) {
+ fullscreen = true;
+ } else if(args[i].equals("-pmvDirect")) {
+ pmvUseBackingArray = false;
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-exclctx")) {
+ exclusiveContext = true;
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
+ } else if(args[i].equals("-showFPS")) {
+ showFPS = true;
+ } else if(args[i].equals("-width")) {
+ i++;
+ w = MiscUtils.atoi(args[i], w);
+ } else if(args[i].equals("-height")) {
+ i++;
+ h = MiscUtils.atoi(args[i], h);
+ } else if(args[i].equals("-x")) {
+ i++;
+ x = MiscUtils.atoi(args[i], x);
+ usePos = true;
+ } else if(args[i].equals("-y")) {
+ i++;
+ y = MiscUtils.atoi(args[i], y);
+ usePos = true;
+ } else if(args[i].equals("-rwidth")) {
+ i++;
+ rw = MiscUtils.atoi(args[i], rw);
+ } else if(args[i].equals("-rheight")) {
+ i++;
+ rh = MiscUtils.atoi(args[i], rh);
+ } else if(args[i].equals("-screen")) {
+ i++;
+ screenIdx = MiscUtils.atoi(args[i], 0);
+ } else if(args[i].equals("-loops")) {
+ i++;
+ loops = MiscUtils.atoi(args[i], 1);
+ } else if(args[i].equals("-loop-shutdown")) {
+ loop_shutdown = true;
+ }
+ }
+ wsize = new Dimension(w, h);
+ if( 0 < rw && 0 < rh ) {
+ rwsize = new Dimension(rw, rh);
+ }
+
+ if(usePos) {
+ wpos = new Point(x, y);
+ }
+ System.err.println("position "+wpos);
+ System.err.println("size "+wsize);
+ System.err.println("resize "+rwsize);
+ System.err.println("screen "+screenIdx);
+ System.err.println("translucent "+(!opaque));
+ System.err.println("forceAlpha "+forceAlpha);
+ System.err.println("fullscreen "+fullscreen);
+ System.err.println("pmvDirect "+(!pmvUseBackingArray));
+ System.err.println("loops "+loops);
+ System.err.println("loop shutdown "+loop_shutdown);
+ System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
+ System.err.println("swapInterval "+swapInterval);
+ System.err.println("exclusiveContext "+exclusiveContext);
+
+ org.junit.runner.JUnitCore.main(TestGearsES2SWT.class.getName());
+ }
+}
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 4ebb7dddd..d63193445 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
@@ -45,6 +45,7 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil.WindowClosingListener;
public class TestCloseNewtAWT extends UITestCase {
@@ -107,9 +108,11 @@ public class TestCloseNewtAWT extends UITestCase {
frame.setVisible(true);
}
});
- Thread.sleep(500);
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(newtWindow, true));
+ final WindowClosingListener closingListener = AWTRobotUtil.addClosingListener(frame);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true, closingListener));
}
public static void main(String[] args) {
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 5d6218df4..a87cbe0ac 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
@@ -115,7 +115,8 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
// Wrap the window in a canvas.
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
+ // newtCanvasAWT.setShallUseOffscreenLayer(true);
+
// Monitor AWT focus and keyboard events.
AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
@@ -146,7 +147,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
frame1.setVisible(true);
} } );
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
AWTRobotUtil.clearAWTFocus(robot);
Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java
index d63f0d2a7..5b7986f4d 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java
@@ -46,13 +46,14 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil.WindowClosingListener;
public class TestWindowClosingProtocol01AWT extends UITestCase {
@Test
public void testCloseFrameGLCanvas() throws InterruptedException, InvocationTargetException {
final Frame frame = new Frame("testCloseFrameGLCanvas AWT");
-
+ final WindowClosingListener closingListener = AWTRobotUtil.addClosingListener(frame);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
final GLCanvas glCanvas = new GLCanvas(caps);
@@ -74,12 +75,14 @@ public class TestWindowClosingProtocol01AWT extends UITestCase {
WindowClosingMode op = glCanvas.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DO_NOTHING_ON_CLOSE, op);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // nop
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false, closingListener)); // nop
Thread.sleep(100);
- Assert.assertEquals(true, frame.isDisplayable());
+ Assert.assertEquals(true, frame.isDisplayable());
Assert.assertEquals(true, frame.isVisible());
- Assert.assertEquals(true, glCanvas.isValid());
- Assert.assertEquals(true, glCanvas.isDisplayable());
+ Assert.assertEquals(true, glCanvas.isValid());
+ Assert.assertEquals(true, glCanvas.isDisplayable());
+ Assert.assertEquals(true, closingListener.isWindowClosing());
+ Assert.assertEquals(false, closingListener.isWindowClosed());
//
// close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose
@@ -87,11 +90,18 @@ public class TestWindowClosingProtocol01AWT extends UITestCase {
glCanvas.setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE);
op = glCanvas.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DISPOSE_ON_CLOSE, op);
+
+ Thread.sleep(300);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // no frame close
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, false));
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false, closingListener)); // no frame close, but GLCanvas's GL resources will be destroyed
+ Thread.sleep(100);
Assert.assertEquals(true, frame.isDisplayable());
Assert.assertEquals(true, frame.isVisible());
+ Assert.assertEquals(true, closingListener.isWindowClosing());
+ Assert.assertEquals(false, closingListener.isWindowClosed());
+ for (int wait=0; wait<AWTRobotUtil.POLL_DIVIDER && glCanvas.isRealized(); wait++) {
+ Thread.sleep(AWTRobotUtil.TIME_SLICE);
+ }
Assert.assertEquals(false, glCanvas.isRealized());
SwingUtilities.invokeAndWait(new Runnable() {
@@ -103,7 +113,8 @@ public class TestWindowClosingProtocol01AWT extends UITestCase {
@Test
public void testCloseJFrameGLCanvas() throws InterruptedException, InvocationTargetException {
final JFrame frame = new JFrame("testCloseJFrameGLCanvas AWT");
-
+ final WindowClosingListener closingListener = AWTRobotUtil.addClosingListener(frame);
+
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
GLCanvas glCanvas = new GLCanvas(caps);
@@ -126,7 +137,9 @@ public class TestWindowClosingProtocol01AWT extends UITestCase {
WindowClosingMode op = glCanvas.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DO_NOTHING_ON_CLOSE, op);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // nop
+ Thread.sleep(300);
+
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false, closingListener)); // nop
Thread.sleep(100);
Assert.assertEquals(true, frame.isDisplayable());
Assert.assertEquals(true, glCanvas.isValid());
@@ -147,7 +160,7 @@ public class TestWindowClosingProtocol01AWT extends UITestCase {
op = glCanvas.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DISPOSE_ON_CLOSE, op);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true, closingListener));
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, false));
Assert.assertEquals(false, frame.isDisplayable());
Assert.assertEquals(false, glCanvas.isValid());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java
index 1657fcbe9..8d32beea3 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java
@@ -52,7 +52,7 @@ public class TestWindowClosingProtocol02NEWT extends UITestCase {
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
final GLWindow glWindow = GLWindow.create(caps);
- final AWTRobotUtil.WindowClosingListener windowClosingListener = AWTRobotUtil.addClosingListener(glWindow);
+ final AWTRobotUtil.WindowClosingListener closingListener = AWTRobotUtil.addClosingListener(glWindow);
glWindow.addGLEventListener(new GearsES2());
glWindow.setSize(512, 512);
@@ -69,11 +69,13 @@ public class TestWindowClosingProtocol02NEWT extends UITestCase {
glWindow.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
op = glWindow.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DO_NOTHING_ON_CLOSE, op);
+
+ Thread.sleep(300);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, false)); // nop
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, false, closingListener)); // nop
Assert.assertEquals(true, glWindow.isNativeValid());
- Assert.assertEquals(true, windowClosingListener.isWindowClosing());
- windowClosingListener.reset();
+ Assert.assertEquals(true, closingListener.isWindowClosing());
+ closingListener.reset();
//
// close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose
@@ -82,9 +84,9 @@ public class TestWindowClosingProtocol02NEWT extends UITestCase {
op = glWindow.getDefaultCloseOperation();
Assert.assertEquals(WindowClosingMode.DISPOSE_ON_CLOSE, op);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, true));
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, true, closingListener));
Assert.assertEquals(false, glWindow.isNativeValid());
- Assert.assertEquals(true, windowClosingListener.isWindowClosing());
+ Assert.assertEquals(true, closingListener.isWindowClosing());
}
public static void main(String[] args) {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java
index 65068e9e8..b0a222a5a 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java
@@ -46,17 +46,19 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil.WindowClosingListener;
public class TestWindowClosingProtocol03NewtAWT extends UITestCase {
@Test
public void testCloseJFrameNewtCanvasAWT() throws InterruptedException, InvocationTargetException {
final JFrame frame = new JFrame("testCloseJFrameNewtCanvasAWT");
-
+ final WindowClosingListener awtClosingListener = AWTRobotUtil.addClosingListener(frame);
+
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
final GLWindow glWindow = GLWindow.create(caps);
- final AWTRobotUtil.WindowClosingListener windowClosingListener = AWTRobotUtil.addClosingListener(glWindow);
+ final AWTRobotUtil.WindowClosingListener newtClosingListener = AWTRobotUtil.addClosingListener(glWindow);
glWindow.addGLEventListener(new GearsES2());
@@ -81,18 +83,26 @@ public class TestWindowClosingProtocol03NewtAWT extends UITestCase {
//
// close with op: DO_NOTHING_ON_CLOSE -> NOP / HIDE (default)
//
- Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation());
- WindowClosingMode op = newtCanvas.getDefaultCloseOperation();
- Assert.assertEquals(WindowClosingMode.DO_NOTHING_ON_CLOSE, op);
+ {
+ Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation());
+ WindowClosingMode op = newtCanvas.getDefaultCloseOperation();
+ Assert.assertEquals(WindowClosingMode.DO_NOTHING_ON_CLOSE, op);
+ }
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false));
+ Thread.sleep(300);
+
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false, awtClosingListener));
Assert.assertEquals(true, frame.isDisplayable());
Assert.assertEquals(false, frame.isVisible());
Assert.assertEquals(true, newtCanvas.isValid());
Assert.assertEquals(true, newtCanvas.isDisplayable());
Assert.assertEquals(true, glWindow.isNativeValid());
- Assert.assertEquals(true, windowClosingListener.isWindowClosing());
- windowClosingListener.reset();
+ Assert.assertEquals(true, awtClosingListener.isWindowClosing());
+ Assert.assertEquals(false, awtClosingListener.isWindowClosed());
+ Assert.assertEquals(true, newtClosingListener.isWindowClosing());
+ Assert.assertEquals(false, newtClosingListener.isWindowClosed());
+ awtClosingListener.reset();
+ newtClosingListener.reset();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -105,18 +115,25 @@ public class TestWindowClosingProtocol03NewtAWT extends UITestCase {
//
// close with op (JFrame): DISPOSE_ON_CLOSE -- newtCanvas -- glWindow --> dispose
//
- frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation());
- op = newtCanvas.getDefaultCloseOperation();
- Assert.assertEquals(WindowClosingMode.DISPOSE_ON_CLOSE, op);
+ {
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation());
+ WindowClosingMode op = newtCanvas.getDefaultCloseOperation();
+ Assert.assertEquals(WindowClosingMode.DISPOSE_ON_CLOSE, op);
+ }
+
+ Thread.sleep(300);
- Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true, awtClosingListener));
Assert.assertEquals(false, frame.isDisplayable());
Assert.assertEquals(false, frame.isVisible());
Assert.assertEquals(false, newtCanvas.isValid());
Assert.assertEquals(false, newtCanvas.isDisplayable());
Assert.assertEquals(false, glWindow.isNativeValid());
- Assert.assertEquals(true, windowClosingListener.isWindowClosing());
+ Assert.assertEquals(true, awtClosingListener.isWindowClosing());
+ Assert.assertEquals(true, awtClosingListener.isWindowClosed());
+ Assert.assertEquals(true, newtClosingListener.isWindowClosing());
+ Assert.assertEquals(true, newtClosingListener.isWindowClosed());
}
public static void main(String[] args) {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
index 31fa11e9d..4dd3bb98a 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
@@ -33,6 +33,7 @@ import java.util.ArrayList ;
import javax.media.opengl.GLProfile ;
+import org.junit.After;
import org.junit.Assert ;
import org.junit.BeforeClass ;
import org.junit.Test ;
@@ -335,33 +336,32 @@ public abstract class BaseNewtEventModifiers extends UITestCase {
_robot.setAutoDelay( MS_ROBOT_AUTO_DELAY ) ;
{
// Make sure all the buttons and modifier keys are released.
- _releaseModifiers() ;
- _escape() ;
- eventDispatch(); eventDispatch(); eventDispatch();
- Thread.sleep( MS_ROBOT_POST_TEST_DELAY ) ;
- eventDispatch(); eventDispatch(); eventDispatch();
+ clearKeyboadAndMouse();
}
_testMouseListener.setModifierCheckEnabled( true ) ;
Throwable throwable = null;
- final Object sync = new Object();
- final RunnableTask rt = new RunnableTask( testAction, sync, true );
+ // final Object sync = new Object();
+ final RunnableTask rt = new RunnableTask( testAction, null, true );
try {
- new Thread(rt, "Test-Thread").start();
- while( !rt.isExecuted() && null == throwable ) {
- eventDispatch();
- }
- if(null==throwable) {
- throwable = rt.getThrowable();
- }
- if(null!=throwable) {
- throw new RuntimeException(throwable);
- }
+ // synchronized(sync) {
+ new Thread(rt, "Test-Thread").start();
+ int i=0;
+ while( !rt.isExecuted() && null == throwable ) {
+ System.err.println("WAIT-till-done: eventDispatch() #"+i++);
+ eventDispatch();
+ }
+ if(null==throwable) {
+ throwable = rt.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ // }
} finally {
- _testMouseListener.setModifierCheckEnabled( false ) ;
- eventDispatch(); eventDispatch(); eventDispatch();
- Thread.sleep( MS_ROBOT_POST_TEST_DELAY ) ;
- eventDispatch(); eventDispatch(); eventDispatch();
+ System.err.println("WAIT-till-done: DONE");
+ _testMouseListener.setModifierCheckEnabled( false ) ;
+ clearKeyboadAndMouse();
}
}
@@ -677,19 +677,24 @@ public abstract class BaseNewtEventModifiers extends UITestCase {
////////////////////////////////////////////////////////////////////////////
- public static void baseAfterClass() throws Exception {
-
+ public void eventDispatchedPostTestDelay() throws Exception {
+ eventDispatch(); eventDispatch(); eventDispatch();
+ Thread.sleep( MS_ROBOT_POST_TEST_DELAY ) ;
+ eventDispatch(); eventDispatch(); eventDispatch();
+ _testMouseListener.clear();
+ }
+
+ public void clearKeyboadAndMouse() throws Exception {
// Make sure all modifiers are released, otherwise the user's
// desktop can get locked up (ask me how I know this).
-
_releaseModifiers() ;
_escape() ;
- Thread.sleep( MS_ROBOT_POST_TEST_DELAY ) ;
+ eventDispatchedPostTestDelay();
}
////////////////////////////////////////////////////////////////////////////
- private static void _releaseModifiers() {
+ private void _releaseModifiers() {
if (_robot != null) {
@@ -714,7 +719,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase {
}
}
- private static void _escape() {
+ private void _escape() {
if (_robot != null) {
_robot.keyPress( java.awt.event.KeyEvent.VK_ESCAPE ) ;
_robot.keyRelease( java.awt.event.KeyEvent.VK_ESCAPE ) ;
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersAWTCanvas.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersAWTCanvas.java
index 17f81c583..a847ca671 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersAWTCanvas.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersAWTCanvas.java
@@ -62,25 +62,27 @@ public class TestNewtEventModifiersAWTCanvas extends BaseNewtEventModifiers {
_testFrame = new JFrame( "Event Modifier Test AWTCanvas" ) ;
_testFrame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE ) ;
- _testFrame.getContentPane().add( canvas ) ;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
+ _testFrame.getContentPane().add( canvas ) ;
_testFrame.setBounds( TEST_FRAME_X, TEST_FRAME_Y, TEST_FRAME_WIDTH, TEST_FRAME_HEIGHT ) ;
_testFrame.setVisible( true ) ;
}
}) ;
- Assert.assertEquals(true, AWTRobotUtil.waitForVisible(_testFrame, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(_testFrame, true));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(canvas, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(canvas, true));
+
AWTRobotUtil.assertRequestFocusAndWait(null, canvas, canvas, null, null); // programmatic
Assert.assertNotNull(_robot);
- AWTRobotUtil.requestFocus(_robot, canvas, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+ AWTRobotUtil.requestFocus(_robot, canvas, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
}
////////////////////////////////////////////////////////////////////////////
@AfterClass
public static void afterClass() throws Exception {
- baseAfterClass();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
_testFrame.dispose() ;
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNEWTWindowAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNEWTWindowAWT.java
index 5428958a0..71191c863 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNEWTWindowAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNEWTWindowAWT.java
@@ -58,7 +58,9 @@ public class TestNewtEventModifiersNEWTWindowAWT extends BaseNewtEventModifiers
_glWindow.setPosition(TEST_FRAME_X, TEST_FRAME_Y);
_glWindow.setVisible(true);
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(_glWindow, true));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(_glWindow, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(_glWindow, true));
+
AWTRobotUtil.assertRequestFocusAndWait(null, _glWindow, _glWindow, null, null); // programmatic
Assert.assertNotNull(_robot);
AWTRobotUtil.requestFocus(_robot, _glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
@@ -68,7 +70,6 @@ public class TestNewtEventModifiersNEWTWindowAWT extends BaseNewtEventModifiers
@AfterClass
public static void afterClass() throws Exception {
- baseAfterClass();
_glWindow.destroy();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasAWT.java
index 6a3f4a54b..968d1af79 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasAWT.java
@@ -82,6 +82,9 @@ public class TestNewtEventModifiersNewtCanvasAWT extends BaseNewtEventModifiers
}
} ) ;
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(_testFrame, true));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(_glWindow, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(_glWindow, true));
+
AWTRobotUtil.assertRequestFocusAndWait(null, _glWindow, _glWindow, null, null); // programmatic
Assert.assertNotNull(_robot);
AWTRobotUtil.requestFocus(_robot, _glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
@@ -93,7 +96,6 @@ public class TestNewtEventModifiersNewtCanvasAWT extends BaseNewtEventModifiers
@AfterClass
public static void afterClass() throws Exception {
- baseAfterClass();
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
_testFrame.dispose() ;
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasSWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasSWT.java
index cafc3dd46..6279b70dc 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasSWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtEventModifiersNewtCanvasSWT.java
@@ -62,22 +62,23 @@ public class TestNewtEventModifiersNewtCanvasSWT extends BaseNewtEventModifiers
////////////////////////////////////////////////////////////////////////////
- protected static void eventDispatch2xImpl() {
- eventDispatchImpl();
+ protected static void eventDispatchImpl() {
+ final int maxEvents = 10;
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
- eventDispatchImpl();
- }
-
- protected static void eventDispatchImpl() {
- if( !_display.isDisposed() ) {
- if( !_display.readAndDispatch() ) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) { }
- }
- }
+ final boolean[] res = { false };
+ int i=0;
+ do {
+ SWTAccessor.invoke(_display, true, new Runnable() {
+ public void run() {
+ if( !_display.isDisposed() ) {
+ res[0] = _display.readAndDispatch();
+ } else {
+ res[0] = false;
+ }
+ } } );
+ } while( i<maxEvents && res[0] );
}
@Override
@@ -96,7 +97,7 @@ public class TestNewtEventModifiersNewtCanvasSWT extends BaseNewtEventModifiers
}});
Assert.assertNotNull( _display );
- _display.syncExec(new Runnable() {
+ SWTAccessor.invoke(_display, true, new Runnable() {
public void run() {
_shell = new Shell( _display );
Assert.assertNotNull( _shell );
@@ -115,7 +116,7 @@ public class TestNewtEventModifiersNewtCanvasSWT extends BaseNewtEventModifiers
NewtCanvasSWT.create( _composite, SWT.NO_BACKGROUND, _glWindow ) ;
}
- _display.syncExec( new Runnable() {
+ SWTAccessor.invoke(_display, true, new Runnable() {
public void run() {
_shell.setBounds( TEST_FRAME_X, TEST_FRAME_Y, TEST_FRAME_WIDTH, TEST_FRAME_HEIGHT ) ;
_shell.open();
@@ -128,9 +129,9 @@ public class TestNewtEventModifiersNewtCanvasSWT extends BaseNewtEventModifiers
// no waiting for results ..
AWTRobotUtil.requestFocus(null, _glWindow, false); // programmatic
- eventDispatch2xImpl();
+ eventDispatchImpl();
AWTRobotUtil.requestFocus(_robot, _glWindow, INITIAL_MOUSE_X, INITIAL_MOUSE_Y);
- eventDispatch2xImpl();
+ eventDispatchImpl();
_glWindow.addMouseListener( _testMouseListener ) ;
}
@@ -139,23 +140,17 @@ public class TestNewtEventModifiersNewtCanvasSWT extends BaseNewtEventModifiers
@AfterClass
public static void afterClass() throws Exception {
- baseAfterClass();
-
_glWindow.destroy() ;
try {
- _display.syncExec(new Runnable() {
- public void run() {
- _composite.dispose();
- _shell.dispose();
- }});
-
- if(!_display.isDisposed()) {
- SWTAccessor.invoke(true, new Runnable() {
- public void run() {
+ SWTAccessor.invoke(_display, true, new Runnable() {
+ public void run() {
+ _composite.dispose();
+ _shell.dispose();
+ if(!_display.isDisposed()) {
_display.dispose();
- }});
- }
+ }
+ }});
}
catch( Throwable throwable ) {
throwable.printStackTrace();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java
index ec06379e0..08a181e10 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java
@@ -47,6 +47,8 @@ import javax.swing.JFrame;
import java.io.IOException;
+import jogamp.nativewindow.jawt.JAWTUtil;
+
import org.junit.BeforeClass;
import org.junit.Test;
@@ -61,6 +63,11 @@ import com.jogamp.opengl.test.junit.util.*;
/**
* Testing combinations of key code modifiers of key event.
+ *
+ * <p>
+ * Due to limitation of AWT Robot, the test machine needs to have US keyboard enabled,
+ * even though we do unify VK codes to US keyboard across all layouts.
+ * </p>
*/
public class TestNewtKeyCodeModifiersAWT extends UITestCase {
static int width, height;
@@ -99,12 +106,14 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase {
glWindow.destroy();
}
- @Test
- public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ private void testNewtCanvasAWT_Impl(boolean onscreen) throws AWTException, InterruptedException, InvocationTargetException {
GLWindow glWindow = GLWindow.create(glCaps);
// Wrap the window in a canvas.
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if( !onscreen ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
// Add the canvas to a frame, and make it all visible.
final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
@@ -129,42 +138,63 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
- glWindow.destroy();
+ glWindow.destroy();
+ }
+
+ @Test
+ public void test02NewtCanvasAWT_Onscreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("Platform doesn't support onscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(true);
}
- static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask) {
+ @Test
+ public void test03NewtCanvasAWT_Offsccreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("Platform doesn't support offscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(false);
+ }
+
+ @SuppressWarnings("deprecation")
+ static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask, int keyCode, char keyCharOnly, char keyCharMod) {
keyAdapter.reset();
- AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
- AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P
+ AWTRobotUtil.keyPress(0, robot, true, keyCode, 10); // press keyCode
+ AWTRobotUtil.keyPress(0, robot, false, keyCode, 100); // release+typed keyCode
robot.waitForIdle();
- for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected
+ for(int j=0; j < 40 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected
robot.delay(100);
}
AWTRobotUtil.keyPress(0, robot, true, modifierKey, 10); // press MOD
- AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
- AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 10); // release+typed P
- AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100); // release+typed MOD
+ AWTRobotUtil.keyPress(0, robot, true, keyCode, 10); // press keyCode
+ AWTRobotUtil.keyPress(0, robot, false, keyCode, 10); // release+typed keyCode
+ AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100); // release MOD
robot.waitForIdle();
- for(int j=0; j < 20 && keyAdapter.getQueueSize() < 3+6; j++) { // wait until events are collected
+ for(int j=0; j < 40 && keyAdapter.getQueueSize() < 3+5; j++) { // wait until events are collected
robot.delay(100);
}
- NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3+6, 0);
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter,
+ 3 /* press-SI */, 3 /* release-SI */, 2 /* typed-SI */,
+ 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ );
final List<EventObject> queue = keyAdapter.getQueued();
int i=0;
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, keyCode, keyCharOnly);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, keyCode, keyCharOnly);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, keyCode, keyCharOnly);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, modifierKey);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, keyCode, keyCharMod);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, keyCode, keyCharMod);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, keyCode, keyCharMod);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey, (char)0);
}
+ @SuppressWarnings("deprecation")
static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) {
final int m1k = KeyEvent.VK_ALT;
final int m1m = InputEvent.ALT_MASK;
@@ -180,32 +210,31 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase {
AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P
- AWTRobotUtil.keyPress(0, robot, false, m3k, 10); // release+typed MOD
- AWTRobotUtil.keyPress(0, robot, false, m2k, 10); // release+typed MOD
- AWTRobotUtil.keyPress(0, robot, false, m1k, 10); // release+typed MOD
+ AWTRobotUtil.keyPress(0, robot, false, m3k, 10); // release MOD
+ AWTRobotUtil.keyPress(0, robot, false, m2k, 10); // release MOD
+ AWTRobotUtil.keyPress(0, robot, false, m1k, 10); // release MOD
robot.waitForIdle();
- for(int j=0; j < 20 && keyAdapter.getQueueSize() < 3*4; j++) { // wait until events are collected
+ for(int j=0; j < 40 && keyAdapter.getQueueSize() < 4+4+1; j++) { // wait until events are collected
robot.delay(100);
}
- NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3*4, 0);
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter,
+ 4 /* press-SI */, 4 /* release-SI */, 1 /* typed-SI */,
+ 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ );
final List<EventObject> queue = keyAdapter.getQueued();
int i=0;
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m, m1k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m, m2k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, m3k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m, m1k, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m, m2k, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, m3k, (char)0);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_P);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_P, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_P, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_P, (char)0);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, m3k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m, m2k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k);
- NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m, m1k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k, (char)0);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k, (char)0);
}
void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
@@ -233,9 +262,11 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase {
AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
glWindow1KA.reset();
- testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK);
- testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK);
- testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK);
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK, KeyEvent.VK_1, '1', '!');
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK, KeyEvent.VK_Y, 'y', 'Y'); // US: Y, DE: Z
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK, KeyEvent.VK_P, 'p', 'P');
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK, KeyEvent.VK_P, 'p', (char)0);
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK, KeyEvent.VK_P, 'p', (char)0);
testKeyCodeAllModifierV1(robot, glWindow1KA);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java
index ef4b17375..b3ba71795 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java
@@ -48,10 +48,13 @@ import javax.swing.JFrame;
import java.io.IOException;
+import jogamp.nativewindow.jawt.JAWTUtil;
+
import org.junit.BeforeClass;
import org.junit.Test;
import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
@@ -99,12 +102,14 @@ public class TestNewtKeyCodesAWT extends UITestCase {
glWindow.destroy();
}
- @Test
- public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ private void testNewtCanvasAWT_Impl(boolean onscreen) throws AWTException, InterruptedException, InvocationTargetException {
GLWindow glWindow = GLWindow.create(glCaps);
// Wrap the window in a canvas.
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if( !onscreen ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
// Add the canvas to a frame, and make it all visible.
final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
@@ -131,7 +136,25 @@ public class TestNewtKeyCodesAWT extends UITestCase {
}
glWindow.destroy();
}
+
+ @Test
+ public void test02NewtCanvasAWT_Onscreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("Platform doesn't support onscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(true);
+ }
+ @Test
+ public void test03NewtCanvasAWT_Offsccreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("Platform doesn't support offscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(false);
+ }
+
static CodeSeg[] codeSegments = new CodeSeg[] {
new CodeSeg(0x008, 0x008, "bs"),
// new CodeSeg(0x009, 0x009, "tab"), // TAB functions as focus traversal key
@@ -167,14 +190,29 @@ public class TestNewtKeyCodesAWT extends UITestCase {
keyAdapter.reset();
final CodeSeg codeSeg = codeSegments[i];
// System.err.println("*** Segment "+codeSeg.description);
- for(int c=codeSeg.min; c<=codeSeg.max; c++) {
+ int eventCount = 0;
+ for(short c=codeSeg.min; c<=codeSeg.max; c++) {
// System.err.println("*** KeyCode 0x"+Integer.toHexString(c));
- AWTRobotUtil.keyPress(0, robot, true, c, 10);
- AWTRobotUtil.keyPress(0, robot, false, c, 100);
+ try {
+ AWTRobotUtil.keyPress(0, robot, true, c, 10);
+ } catch (Exception e) {
+ System.err.println("Exception @ AWT Robot.PRESS "+MiscUtils.toHexString(c)+" - "+e.getMessage());
+ break;
+ }
+ eventCount++;
+ try {
+ AWTRobotUtil.keyPress(0, robot, false, c, 100);
+ } catch (Exception e) {
+ System.err.println("Exception @ AWT Robot.RELEASE "+MiscUtils.toHexString(c)+" - "+e.getMessage());
+ break;
+ }
+ eventCount++;
+ if( KeyEvent.isPrintableKey(c) ) {
+ eventCount++;
+ }
robot.waitForIdle();
}
- final int codeCount = codeSeg.max - codeSeg.min + 1;
- for(int j=0; j < 20 && keyAdapter.getQueueSize() < 3 * codeCount; j++) { // wait until events are collected
+ for(int j=0; j < 20 && keyAdapter.getQueueSize() < eventCount; j++) { // wait until events are collected
robot.delay(100);
}
final ArrayList<EventObject> events = new ArrayList<EventObject>(keyAdapter.getQueued());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java
index 00fbc0500..d7de4e735 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java
@@ -153,6 +153,7 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
glWindow.destroy();
}
+ @SuppressWarnings("deprecation")
static void testKeyEventAutoRepeat(Robot robot, NEWTKeyAdapter keyAdapter, int loops, int pressDurationMS) {
System.err.println("KEY Event Auto-Repeat Test: "+loops);
EventObject[][] first = new EventObject[loops][3];
@@ -201,9 +202,19 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
final boolean hasAR = 0 < keyAdapter.getKeyPressedCount(true) ;
{
- final int expTotal = keyEvents.size();
- final int expAR = hasAR ? expTotal - 3 * 2 * loops : 0; // per loop: 3 for non AR events and 3 for non AR 'B'
- NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, expTotal, expAR);
+ final int perLoopSI = 2; // per loop: 1 non AR event and 1 for non AR 'B'
+ final int expSI, expAR;
+ if( hasAR ) {
+ expSI = perLoopSI * loops;
+ expAR = ( keyEvents.size() - expSI*3 ) / 2; // AR: no typed -> 2, SI: typed -> 3
+ } else {
+ expSI = keyEvents.size() / 3; // all typed events
+ expAR = 0;
+ }
+
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter,
+ expSI /* press-SI */, expSI /* release-SI */, expSI /* typed-SI */,
+ expAR /* press-AR */, expAR /* release-AR */, 0 /* typed-AR */ );
}
if( !hasAR ) {
@@ -216,7 +227,7 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
NEWTKeyUtil.dumpKeyEvents(Arrays.asList(first[i]));
System.err.println("Auto-Repeat Loop "+i+" - Tail:");
NEWTKeyUtil.dumpKeyEvents(Arrays.asList(last[i]));
- }
+ }
for(int i=0; i<loops; i++) {
KeyEvent e = (KeyEvent) first[i][0];
Assert.assertTrue("1st Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
@@ -230,7 +241,7 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
e = (KeyEvent) first[i][2];
Assert.assertTrue("3rd Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
- Assert.assertTrue("3rd Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() );
+ Assert.assertTrue("3rd Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() );
Assert.assertTrue("3rd Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
e = (KeyEvent) last[i][0];
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java
index 256536bbb..bdf932904 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java
@@ -45,6 +45,8 @@ import javax.swing.JFrame;
import java.io.IOException;
+import jogamp.nativewindow.jawt.JAWTUtil;
+
import org.junit.BeforeClass;
import org.junit.Test;
@@ -104,12 +106,14 @@ public class TestNewtKeyEventOrderAWT extends UITestCase {
glWindow.destroy();
}
- @Test
- public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ private void testNewtCanvasAWT_Impl(boolean onscreen) throws AWTException, InterruptedException, InvocationTargetException {
GLWindow glWindow = GLWindow.create(glCaps);
// Wrap the window in a canvas.
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if( !onscreen ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
// Add the canvas to a frame, and make it all visible.
final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
@@ -137,6 +141,24 @@ public class TestNewtKeyEventOrderAWT extends UITestCase {
glWindow.destroy();
}
+ @Test
+ public void test02NewtCanvasAWT_Onscreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("Platform doesn't support onscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(true);
+ }
+
+ @Test
+ public void test03NewtCanvasAWT_Offsccreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("Platform doesn't support offscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(false);
+ }
+
static void testKeyEventOrder(Robot robot, NEWTKeyAdapter keyAdapter, int loops) {
System.err.println("KEY Event Order Test: "+loops);
keyAdapter.reset();
@@ -167,7 +189,11 @@ public class TestNewtKeyEventOrderAWT extends UITestCase {
NEWTKeyUtil.validateKeyEventOrder(keyAdapter.getQueued());
- NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 6*3*loops, 0);
+ final int expTotal = 6*loops; // all typed events
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter,
+ expTotal /* press-SI */, expTotal /* release-SI */, expTotal /* typed-SI */,
+ 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ );
+
}
void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
index 61579998e..2a35a15eb 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
@@ -45,6 +45,8 @@ import javax.swing.JFrame;
import java.io.IOException;
+import jogamp.nativewindow.jawt.JAWTUtil;
+
import org.junit.BeforeClass;
import org.junit.Test;
@@ -98,12 +100,14 @@ public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase {
glWindow.destroy();
}
- @Test
- public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ private void testNewtCanvasAWT_Impl(boolean onscreen) throws AWTException, InterruptedException, InvocationTargetException {
GLWindow glWindow = GLWindow.create(glCaps);
// Wrap the window in a canvas.
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if( !onscreen ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
// Add the canvas to a frame, and make it all visible.
final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
@@ -131,6 +135,24 @@ public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase {
glWindow.destroy();
}
+ @Test
+ public void test02NewtCanvasAWT_Onscreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( JAWTUtil.isOffscreenLayerRequired() ) {
+ System.err.println("Platform doesn't support onscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(true);
+ }
+
+ @Test
+ public void test03NewtCanvasAWT_Offsccreen() throws AWTException, InterruptedException, InvocationTargetException {
+ if( !JAWTUtil.isOffscreenLayerSupported() ) {
+ System.err.println("Platform doesn't support offscreen rendering.");
+ return;
+ }
+ testNewtCanvasAWT_Impl(false);
+ }
+
void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
final Robot robot = new Robot();
robot.setAutoWaitForIdle(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
index d6f1f817a..122138f6d 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
@@ -191,6 +191,7 @@ public class TestParentingFocusTraversal01AWT extends UITestCase {
frame1.setVisible(true);
}});
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
AWTRobotUtil.clearAWTFocus(robot);
Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
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 ffc42e318..8b46760e1 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -28,6 +28,7 @@
package com.jogamp.opengl.test.junit.util;
+import jogamp.common.awt.AWTEDTExecutor;
import jogamp.newt.WindowImplAccess;
import java.lang.reflect.InvocationTargetException;
@@ -41,6 +42,8 @@ import javax.media.opengl.awt.GLCanvas;
import org.junit.Assert;
+import com.jogamp.newt.event.WindowEvent;
+
public class AWTRobotUtil {
static final boolean DEBUG = false;
@@ -646,16 +649,19 @@ public class AWTRobotUtil {
*
* @param obj either an AWT Window (Frame, JFrame) or NEWT Window
* @param willClose indicating that the window will close, hence this method waits for the window to be closed
+ * @param wcl the WindowClosingListener to determine whether the AWT or NEWT widget has been closed. It should be attached
+ * to the widget ASAP before any other listener, e.g. via {@link #addClosingListener(Object)}.
+ * The WindowClosingListener will be reset before attempting to close the widget.
* @return True if the Window is closing and closed (if willClose is true), each within TIME_OUT
* @throws InterruptedException
*/
- public static boolean closeWindow(Object obj, boolean willClose) throws InterruptedException, InvocationTargetException {
- WindowClosingListener closingListener = addClosingListener(obj);
+ public static boolean closeWindow(Object obj, boolean willClose, WindowClosingListener closingListener) throws InterruptedException {
+ closingListener.reset();
if(obj instanceof java.awt.Window) {
final java.awt.Window win = (java.awt.Window) obj;
java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
final java.awt.EventQueue evtQ = tk.getSystemEventQueue();
- java.awt.EventQueue.invokeAndWait(new Runnable() {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() {
evtQ.postEvent(new java.awt.event.WindowEvent(win, java.awt.event.WindowEvent.WINDOW_CLOSING));
} });
@@ -675,12 +681,15 @@ public class AWTRobotUtil {
return wait<POLL_DIVIDER;
}
- public static WindowClosingListener addClosingListener(Object obj) throws InterruptedException {
+ public static WindowClosingListener addClosingListener(Object obj) {
WindowClosingListener cl = null;
if(obj instanceof java.awt.Window) {
- java.awt.Window win = (java.awt.Window) obj;
- AWTWindowClosingAdapter acl = new AWTWindowClosingAdapter();
- win.addWindowListener(acl);
+ final java.awt.Window win = (java.awt.Window) obj;
+ final AWTWindowClosingAdapter acl = new AWTWindowClosingAdapter();
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
+ win.addWindowListener(acl);
+ } } );
cl = acl;
} else if(obj instanceof com.jogamp.newt.Window) {
com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj;
@@ -694,53 +703,77 @@ public class AWTRobotUtil {
}
public static interface WindowClosingListener {
void reset();
+ public int getWindowClosingCount();
+ public int getWindowClosedCount();
public boolean isWindowClosing();
public boolean isWindowClosed();
}
static class AWTWindowClosingAdapter
extends java.awt.event.WindowAdapter implements WindowClosingListener
{
- volatile boolean closing = false;
- volatile boolean closed = false;
+ volatile int closing = 0;
+ volatile int closed = 0;
public void reset() {
- closing = false;
- closed = false;
+ closing = 0;
+ closed = 0;
}
- public boolean isWindowClosing() {
+ public int getWindowClosingCount() {
return closing;
}
- public boolean isWindowClosed() {
+ public int getWindowClosedCount() {
return closed;
}
+ public boolean isWindowClosing() {
+ return 0 < closing;
+ }
+ public boolean isWindowClosed() {
+ return 0 < closed;
+ }
public void windowClosing(java.awt.event.WindowEvent e) {
- closing = true;
+ closing++;
+ System.err.println("AWTWindowClosingAdapter.windowClosing: "+this);
}
public void windowClosed(java.awt.event.WindowEvent e) {
- closed = true;
+ closed++;
+ System.err.println("AWTWindowClosingAdapter.windowClosed: "+this);
+ }
+ public String toString() {
+ return "AWTWindowClosingAdapter[closing "+closing+", closed "+closed+"]";
}
}
static class NEWTWindowClosingAdapter
extends com.jogamp.newt.event.WindowAdapter implements WindowClosingListener
{
- volatile boolean closing = false;
- volatile boolean closed = false;
+ volatile int closing = 0;
+ volatile int closed = 0;
public void reset() {
- closing = false;
- closed = false;
+ closing = 0;
+ closed = 0;
}
- public boolean isWindowClosing() {
+ public int getWindowClosingCount() {
return closing;
}
- public boolean isWindowClosed() {
+ public int getWindowClosedCount() {
return closed;
}
- public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent e) {
- closing = true;
+ public boolean isWindowClosing() {
+ return 0 < closing;
+ }
+ public boolean isWindowClosed() {
+ return 0 < closed;
+ }
+ public void windowDestroyNotify(WindowEvent e) {
+ closing++;
+ System.err.println("NEWTWindowClosingAdapter.windowDestroyNotify: "+this);
+ }
+ public void windowDestroyed(WindowEvent e) {
+ closed++;
+ System.err.println("NEWTWindowClosingAdapter.windowDestroyed: "+this);
}
- public void windowDestroyed(com.jogamp.newt.event.WindowEvent e) {
- closed = true;
+ public String toString() {
+ return "NEWTWindowClosingAdapter[closing "+closing+", closed "+closed+"]";
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
index c230f0aa1..0aee0f087 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
@@ -51,6 +51,22 @@ public class MiscUtils {
return def;
}
+ public static String toHexString(byte hex) {
+ return "0x" + Integer.toHexString( (int)hex & 0x000000FF );
+ }
+
+ public static String toHexString(short hex) {
+ return "0x" + Integer.toHexString( (int)hex & 0x0000FFFF );
+ }
+
+ public static String toHexString(int hex) {
+ return "0x" + Integer.toHexString( hex );
+ }
+
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString( hex );
+ }
+
public static void assertFloatBufferEquals(String errmsg, FloatBuffer expected, FloatBuffer actual, float delta) {
if(null == expected && null == actual) {
return;
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
index e090ed4cf..d007d2424 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
@@ -38,28 +38,28 @@ import com.jogamp.newt.event.KeyEvent;
public class NEWTKeyUtil {
public static class CodeSeg {
- public final int min;
- public final int max;
+ public final short min;
+ public final short max;
public final String description;
public CodeSeg(int min, int max, String description) {
- this.min = min;
- this.max = max;
+ this.min = (short)min;
+ this.max = (short)max;
this.description = description;
}
}
public static class CodeEvent {
- public final int code;
+ public final short code;
public final String description;
public final KeyEvent event;
- public CodeEvent(int code, String description, KeyEvent event) {
+ public CodeEvent(short code, String description, KeyEvent event) {
this.code = code;
this.description = description;
this.event = event;
}
public String toString() {
- return "Code 0x"+Integer.toHexString(code)+" != "+event+" // "+description;
+ return "Code 0x"+Integer.toHexString( (int)code & 0x0000FFFF )+" != "+event+" // "+description;
}
}
@@ -90,46 +90,63 @@ public class NEWTKeyUtil {
public static boolean validateKeyCodes(List<CodeEvent> missCodes, CodeSeg codeSeg, List<EventObject> keyEvents, boolean verbose) {
final int codeCount = codeSeg.max - codeSeg.min + 1;
int misses = 0;
+ int evtIdx = 0;
for(int i=0; i<codeCount; i++) {
- final int c = codeSeg.min + i;
- final int j = i*3+0; // KEY_PRESSED
- final KeyEvent e = (KeyEvent) ( j < keyEvents.size() ? keyEvents.get(j) : null );
- if( null == e || c != e.getKeyCode() ) {
+ // evtIdx -> KEY_PRESSED !
+ final short c = (short) ( codeSeg.min + i );
+ final KeyEvent e = (KeyEvent) ( evtIdx < keyEvents.size() ? keyEvents.get(evtIdx) : null );
+ if( null == e ) {
missCodes.add(new CodeEvent(c, codeSeg.description, e));
misses++;
+ evtIdx++;
+ } else {
+ if( c != e.getKeyCode() ) {
+ missCodes.add(new CodeEvent(c, codeSeg.description, e));
+ misses++;
+ }
+ if( KeyEvent.isPrintableKey(c) ) {
+ evtIdx += 3; // w/ TYPED
+ } else {
+ evtIdx += 2;
+ }
}
}
- final boolean res = 3*codeCount == keyEvents.size() && 0 == missCodes.size();
+ final boolean res = evtIdx == keyEvents.size() && 0 == missCodes.size();
if(verbose) {
System.err.println("+++ Code Segment "+codeSeg.description+", Misses: "+misses+" / "+codeCount+", events "+keyEvents.size()+", valid "+res);
}
return res;
}
- public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode) {
- if(0 <= keyCode) {
- Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode());
- }
+ public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode, char keyChar) {
if(0 <= eventType) {
Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType());
}
if(0 <= modifier) {
Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifier)+", has "+e, modifier == e.getModifiers());
}
+ if(0 < keyCode) {
+ Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode());
+ }
+ if(0 < keyChar) {
+ Assert.assertTrue("KeyEvent char mismatch, expected 0x"+Integer.toHexString(keyChar)+", has "+e, keyChar == e.getKeyChar());
+ }
}
- public static int getNextKeyEventType(int et) {
+ @SuppressWarnings("deprecation")
+ public static short getNextKeyEventType(KeyEvent e) {
+ final int et = e.getEventType();
switch( et ) {
case KeyEvent.EVENT_KEY_PRESSED:
return KeyEvent.EVENT_KEY_RELEASED;
case KeyEvent.EVENT_KEY_RELEASED:
- return KeyEvent.EVENT_KEY_TYPED;
+ return e.isPrintableKey() && !e.isAutoRepeat() ? KeyEvent.EVENT_KEY_TYPED : KeyEvent.EVENT_KEY_PRESSED;
case KeyEvent.EVENT_KEY_TYPED:
return KeyEvent.EVENT_KEY_PRESSED;
default:
- Assert.assertTrue("Invalid event type "+et, false);
+ Assert.assertTrue("Invalid event "+e, false);
return 0;
- }
+ }
}
public static void validateKeyEventOrder(List<EventObject> keyEvents) {
@@ -141,45 +158,68 @@ public class NEWTKeyUtil {
eet = KeyEvent.EVENT_KEY_PRESSED;
}
final int et = e.getEventType();
- Assert.assertEquals("Key event not in proper order", eet, et);
- eet = getNextKeyEventType(et);
+ Assert.assertEquals("Key event not in proper order "+i+"/"+keyEvents.size()+" - event "+e, eet, et);
+ eet = getNextKeyEventType(e);
keyCode2NextEvent.put(e.getKeyCode(), eet);
}
}
/**
- *
* @param keyAdapter
- * @param expTotalCount number of key press/release/types events
- * @param expARCount number of key press/release/types Auto-Release events
+ * @param expPressedCountSI number of single key press events
+ * @param expReleasedCountSI number of single key release events
+ * @param expTypedCountSI number of single key types events
+ * @param expPressedCountAR number of auto-repeat key press events
+ * @param expReleasedCountAR number of auto-repeat key release events
+ * @param expTypedCountAR number of auto-repeat key types events
*/
- public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter, int expTotalCount, int expARCount) {
- final int keyPressed = keyAdapter.getKeyPressedCount(false);
+ public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter,
+ int expPressedCountSI, int expReleasedCountSI, int expTypedCountSI,
+ int expPressedCountAR, int expReleasedCountAR, int expTypedCountAR) {
+ final int expTotalCountSI = expPressedCountSI + expReleasedCountSI + expTypedCountSI;
+ final int expTotalCountAR = expPressedCountAR + expReleasedCountAR + expTypedCountAR;
+ final int expTotalCountALL = expTotalCountSI + expTotalCountAR;
+
+ final int keyPressedALL = keyAdapter.getKeyPressedCount(false);
final int keyPressedAR = keyAdapter.getKeyPressedCount(true);
- final int keyReleased = keyAdapter.getKeyReleasedCount(false);
+ final int keyReleasedALL = keyAdapter.getKeyReleasedCount(false);
final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true);
- final int keyTyped = keyAdapter.getKeyTypedCount(false);
+ final int keyTypedALL = keyAdapter.getKeyTypedCount(false);
final int keyTypedAR = keyAdapter.getKeyTypedCount(true);
- final int keyPressedNR = keyPressed-keyPressedAR;
- final int keyReleasedNR = keyReleased-keyReleasedAR;
- final int keyTypedNR = keyTyped-keyTypedAR;
- System.err.println("Total Press "+keyPressed +", Release "+keyReleased +", Typed "+keyTyped);
- System.err.println("AutoR Press "+keyPressedAR+", Release "+keyReleasedAR+", Typed "+keyTypedAR);
- System.err.println("No AR Press "+keyPressedNR+", Release "+keyReleasedNR+", Typed "+keyTypedNR);
+
+ final int keyPressedSI = keyPressedALL-keyPressedAR;
+ final int keyReleasedSI = keyReleasedALL-keyReleasedAR;
+ final int keyTypedSI = keyTypedALL-keyTypedAR;
+
+ final int totalCountALL = keyPressedALL + keyReleasedALL + keyTypedALL;
+ final int totalCountSI = keyPressedSI + keyReleasedSI + keyTypedSI;
+ final int totalCountAR = keyPressedAR + keyReleasedAR + keyTypedAR;
+
+ System.err.println("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI +", Typed "+expTypedCountSI +", Events "+expTotalCountSI);
+ System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR +", Typed "+expTypedCountAR +", Events "+expTotalCountAR);
+
+ System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Typed "+keyTypedSI +", Events "+totalCountSI);
+ System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Typed "+keyTypedAR +", Events "+totalCountAR);
+ System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Typed "+keyTypedALL+", Events "+totalCountALL);
+
+ Assert.assertEquals("Internal Error: totalSI != totalALL - totalAR", totalCountSI, totalCountALL - totalCountAR);
+
+ Assert.assertEquals("Invalid: Has AR Typed events", 0, keyTypedAR);
+ Assert.assertEquals("Invalid: Exp AR Typed events", 0, expTypedCountAR);
+
+ Assert.assertEquals("Key press count failure (SI)", expPressedCountSI, keyPressedSI);
+ Assert.assertEquals("Key released count failure (SI)", expReleasedCountSI, keyReleasedSI);
+ Assert.assertEquals("Key typed count failure (SI)", expTypedCountSI, keyTypedSI);
+
+ Assert.assertEquals("Key press count failure (AR)", expPressedCountAR, keyPressedAR);
+ Assert.assertEquals("Key released count failure (AR)", expReleasedCountAR, keyReleasedAR);
+
+ Assert.assertEquals("Key total count failure (SI)", expTotalCountSI, totalCountSI);
+ Assert.assertEquals("Key total count failure (AR)", expTotalCountAR, totalCountAR);
final List<EventObject> keyEvents = keyAdapter.getQueued();
- Assert.assertEquals("Key event count not multiple of 3", 0, keyEvents.size()%3);
- Assert.assertEquals("Key event count not 3 * press_release_count", expTotalCount, keyEvents.size());
- Assert.assertEquals("Key press count failure", expTotalCount/3, keyPressed);
- Assert.assertEquals("Key press count failure (AR)", expARCount/3, keyPressedAR);
- Assert.assertEquals("Key released count failure", expTotalCount/3, keyReleased);
- Assert.assertEquals("Key released count failure (AR)", expARCount/3, keyReleasedAR);
- Assert.assertEquals("Key typed count failure", expTotalCount/3, keyTyped);
- Assert.assertEquals("Key typed count failure (AR)", expARCount/3, keyTypedAR);
- // should be true - always, reaching this point - duh!
- Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyPressedNR);
- Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyReleasedNR);
- Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyTypedNR);
- }
+ Assert.assertEquals("Key total count failure (ALL) w/ list sum ", expTotalCountALL, totalCountALL);
+ Assert.assertEquals("Key total count failure (ALL) w/ list size ", expTotalCountALL, keyEvents.size());
+ }
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
index b028df377..44e2eeda7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
@@ -28,7 +28,10 @@
package com.jogamp.opengl.test.junit.util;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
@@ -141,6 +144,14 @@ public abstract class UITestCase {
System.err.println("++++ UITestCase.tearDown: "+getFullTestName(" - "));
}
+ public static void waitForKey(String preMessage) {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println(preMessage+"> Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+
static final String unsupportedTestMsg = "Test not supported on this platform.";
public String getSnapshotFilename(int sn, String postSNDetail, GLCapabilitiesImmutable caps, int width, int height, boolean sinkHasAlpha, String fileSuffix, String destPath) {