diff options
Diffstat (limited to 'src')
75 files changed, 3057 insertions, 1868 deletions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java index ba025e18c..ba025e18c 100755..100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java index 016674338..016674338 100755..100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureEmitter.java index adb1c2ae0..adb1c2ae0 100755..100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureEmitter.java diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureJavaMethodBindingEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureJavaMethodBindingEmitter.java index e98478b6e..e98478b6e 100755..100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureJavaMethodBindingEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/nativesig/NativeSignatureJavaMethodBindingEmitter.java diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index a3749788b..a3749788b 100755..100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java index 63713887b..63713887b 100755..100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java index e9e29fe2f..0cc5f5ae7 100755..100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java @@ -265,42 +265,51 @@ public class Quaternion { } /** Set this quaternion from a Sphereical interpolation - * of two param quaternion, used mostly for rotational animation + * of two param quaternion, used mostly for rotational animation. + * <p> + * Note: Method does not normalize this quaternion! + * </p> + * <p> + * See http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + * </p> * @param a initial quaternion * @param b target quaternion * @param t float between 0 and 1 representing interp. */ - public void slerp(Quaternion a,Quaternion b, float t) - { - float omega, cosom, sinom, sclp, sclq; - cosom = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; - if ((1.0f+cosom) > FloatUtil.E) { - if ((1.0f-cosom) > FloatUtil.E) { - omega = (float)FloatUtil.acos(cosom); - sinom = (float)FloatUtil.sin(omega); - sclp = (float)FloatUtil.sin((1.0f-t)*omega) / sinom; - sclq = (float)FloatUtil.sin(t*omega) / sinom; - } - else { - sclp = 1.0f - t; - sclq = t; - } - x = sclp*a.x + sclq*b.x; - y = sclp*a.y + sclq*b.y; - z = sclp*a.z + sclq*b.z; - w = sclp*a.w + sclq*b.w; + public void slerp(Quaternion a, Quaternion b, float t) { + final float cosom = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; + final float t1 = 1.0f - t; + + // if the two quaternions are close, just use linear interpolation + if (cosom >= 0.95f) { + x = a.x * t1 + b.x * t; + y = a.y * t1 + b.y * t; + z = a.z * t1 + b.z * t; + w = a.w * t1 + b.w * t; + return; } - else { - x =-a.y; - y = a.x; - z =-a.w; - w = a.z; - sclp = FloatUtil.sin((1.0f-t) * FloatUtil.PI * 0.5f); - sclq = FloatUtil.sin(t * FloatUtil.PI * 0.5f); - x = sclp*a.x + sclq*b.x; - y = sclp*a.y + sclq*b.y; - z = sclp*a.z + sclq*b.z; + + // the quaternions are nearly opposite, we can pick any axis normal to a,b + // to do the rotation + if (cosom <= -0.99f) { + x = 0.5f * (a.x + b.x); + y = 0.5f * (a.y + b.y); + z = 0.5f * (a.z + b.z); + w = 0.5f * (a.w + b.w); + return; } + + // cosom is now withion range of acos, do a SLERP + final float sinom = FloatUtil.sqrt(1.0f - cosom * cosom); + final float omega = FloatUtil.acos(cosom); + + final float scla = FloatUtil.sin(t1 * omega) / sinom; + final float sclb = FloatUtil.sin( t * omega) / sinom; + + x = a.x * scla + b.x * sclb; + y = a.y * scla + b.y * sclb; + z = a.z * scla + b.z * sclb; + w = a.w * scla + b.w * sclb; } /** Check if this quaternion is empty, ie (0,0,0,1) diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 5a75d016a..5a75d016a 100755..100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java index c5b3b3f44..ac2b24117 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java @@ -145,7 +145,7 @@ public class Animator extends AnimatorBase { public void run() { try { if(DEBUG) { - System.err.println("Animator start on " + Thread.currentThread().getName() + ": " + toString()); + System.err.println("Animator start on " + getThreadName() + ": " + toString()); } fpsCounter.resetFPSCounter(); animThread = Thread.currentThread(); @@ -265,7 +265,7 @@ public class Animator extends AnimatorBase { runnable = new MainLoop(); } fpsCounter.resetFPSCounter(); - String threadName = Thread.currentThread().getName()+"-"+baseName; + String threadName = getThreadName()+"-"+baseName; Thread thread; if(null==threadGroup) { thread = new Thread(runnable, threadName); diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java index aa0e70132..837fc84bd 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java @@ -138,7 +138,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { baseName = getBaseName(""); } if(DEBUG) { - System.err.println("Animator.initImpl: baseName "+baseName+", implClazz "+impl.getClass().getName()+" - "+toString()+" - "+Thread.currentThread().getName()); + System.err.println("Animator.initImpl: baseName "+baseName+", implClazz "+impl.getClass().getName()+" - "+toString()+" - "+getThreadName()); } } } @@ -173,7 +173,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { @Override public synchronized void add(final GLAutoDrawable drawable) { if(DEBUG) { - System.err.println("Animator add: 0x"+Integer.toHexString(drawable.hashCode())+" - "+toString()+" - "+Thread.currentThread().getName()); + System.err.println("Animator add: 0x"+Integer.toHexString(drawable.hashCode())+" - "+toString()+" - "+getThreadName()); } if( drawables.contains(drawable) ) { throw new IllegalArgumentException("Drawable already added to animator: "+this+", "+drawable); @@ -204,7 +204,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { @Override public synchronized void remove(final GLAutoDrawable drawable) { if(DEBUG) { - System.err.println("Animator remove: 0x"+Integer.toHexString(drawable.hashCode())+" - "+toString()+" - "+Thread.currentThread().getName()); + System.err.println("Animator remove: 0x"+Integer.toHexString(drawable.hashCode())+" - "+toString()+" - "+getThreadName()); } if( !drawables.contains(drawable) ) { throw new IllegalArgumentException("Drawable not added to animator: "+this+", "+drawable); @@ -539,14 +539,14 @@ public abstract class AnimatorBase implements GLAnimatorControl { } 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()); + System.err.println("finishLifecycleAction(" + waitCondition.getClass().getName() + "): ++++++ timeout reached ++++++ " + getThreadName()); } stateSync.lock(); // avoid too many lock/unlock ops try { System.err.println("finishLifecycleAction(" + waitCondition.getClass().getName() + "): OK "+(!nok)+ "- pollPeriod "+pollPeriod+", blocking "+blocking+ ", waited " + (blocking ? ( TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION - remaining ) : 0 ) + "/" + TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION + - " - " + Thread.currentThread().getName()); + " - " + getThreadName()); System.err.println(" - "+toString()); } finally { stateSync.unlock(); @@ -571,6 +571,8 @@ public abstract class AnimatorBase implements GLAnimatorControl { } } + protected static String getThreadName() { return Thread.currentThread().getName(); } + public String toString() { return getClass().getName()+"[started "+isStarted()+", animating "+isAnimating()+", paused "+isPaused()+", drawable "+drawables.size()+ ", totals[dt "+getTotalFPSDuration()+", frames "+getTotalFPSFrames()+", fps "+getTotalFPS()+ diff --git a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java index bfcab23fd..7613efec6 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java @@ -235,7 +235,7 @@ public class FPSAnimator extends AnimatorBase { if ( null != timer || null != task || isStartedImpl() ) { return false; } - timer = new Timer( Thread.currentThread().getName()+"-"+baseName+"-Timer"+(timerNo++) ); + timer = new Timer( getThreadName()+"-"+baseName+"-Timer"+(timerNo++) ); task = new MainTask(); if(DEBUG) { System.err.println("FPSAnimator.start() START: "+task+", "+ Thread.currentThread() + ": " + toString()); diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java index eceeea6db..7d110659a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java @@ -172,7 +172,10 @@ public class ShaderUtil { info.shaderBinaryFormats.add(new Integer(formats[i])); } } - } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); } + } catch (GLException gle) { + System.err.println("Catched Exception on thread "+Thread.currentThread().getName()); + gle.printStackTrace(); + } } } return info.shaderBinaryFormats; @@ -199,7 +202,10 @@ public class ShaderUtil { } info.shaderCompilerAvailable = new Boolean(v); queryOK = true; - } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); } + } catch (GLException gle) { + System.err.println("Catched Exception on thread "+Thread.currentThread().getName()); + gle.printStackTrace(); + } if(!queryOK) { info.shaderCompilerAvailable = new Boolean(true); } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 05200324d..be947e5f5 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -1559,9 +1559,7 @@ public abstract class GLContext { return needColon; } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } + protected static String getThreadName() { return Thread.currentThread().getName(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java index 95c314a48..65c8b2ea5 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java @@ -65,29 +65,31 @@ public interface GLDrawable { public GLContext createContext(GLContext shareWith); /** - * Indicates to on-screen GLDrawable implementations whether the - * underlying window has been created and can be drawn into. End - * users do not need to call this method; it is not necessary to - * call <code>setRealized</code> on a GLCanvas, a GLJPanel, or a - * GLPbuffer, as these perform the appropriate calls on their - * underlying GLDrawables internally. - * - * <P> - * + * Indicates to GLDrawable implementations whether the + * underlying {@link NativeSurface surface} has been created and can be drawn into. + * <p> + * If realized, the {@link #getHandle() drawable handle} may become + * valid while it's {@link NativeSurface surface} is being {@link NativeSurface#lockSurface() locked}. + * </p> + * <p> + * End users do not need to call this method; it is not necessary to + * call <code>setRealized</code> on a {@link GLAutoDrawable} + * as these perform the appropriate calls on their underlying GLDrawables internally. + * </p> + * <p> * Developers implementing new OpenGL components for various window * toolkits need to call this method against GLDrawables obtained - * from the GLDrawableFactory via the {@link - * GLDrawableFactory#getGLDrawable - * GLDrawableFactory.getGLDrawable()} method. It must typically be + * from the GLDrawableFactory via the + * {@link GLDrawableFactory#createGLDrawable(NativeSurface)} method. + * It must typically be * called with an argument of <code>true</code> when the component * associated with the GLDrawable is realized and with an argument * of <code>false</code> just before the component is unrealized. * For the AWT, this means calling <code>setRealized(true)</code> in * the <code>addNotify</code> method and with an argument of * <code>false</code> in the <code>removeNotify</code> method. - * - * <P> - * + * </p> + * <p> * <code>GLDrawable</code> implementations should handle multiple * cycles of <code>setRealized(true)</code> / * <code>setRealized(false)</code> calls. Most, if not all, Java @@ -101,12 +103,11 @@ public interface GLDrawable { * <code>GLDrawable</code> to re-initialize and destroy any * associated resources as the component becomes realized and * unrealized, respectively. - * - * <P> - * + * </p> + * <p> * With an argument of <code>true</code>, * the minimum implementation shall call - * {@link NativeSurface#lockSurface() NativeSurface's lockSurface()} and if successfull: + * {@link NativeSurface#lockSurface() NativeSurface's lockSurface()} and if successful: * <ul> * <li> Update the {@link GLCapabilities}, which are associated with * the attached {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.</li> @@ -115,14 +116,17 @@ public interface GLDrawable { * This is important since {@link NativeSurface#lockSurface() NativeSurface's lockSurface()} * ensures resolving the window/surface handles, and the drawable's {@link GLCapabilities} * might have changed. - * - * <P> - * + * </p> + * <p> * Calling this method has no other effects. For example, if * <code>removeNotify</code> is called on a Canvas implementation * for which a GLDrawable has been created, it is also necessary to * destroy all OpenGL contexts associated with that GLDrawable. This * is not done automatically by the implementation. + * </p> + * @see #isRealized() + * @see #getHandle() + * @see NativeSurface#lockSurface() */ public void setRealized(boolean realized); @@ -131,6 +135,7 @@ public interface GLDrawable { * <p> * A drawable can be realized and unrealized via {@link #setRealized(boolean)}. * </p> + * @see #setRealized(boolean) */ public boolean isRealized(); @@ -172,11 +177,22 @@ public interface GLDrawable { public NativeSurface getNativeSurface(); /** - * This is the GL/Windowing drawable handle.<br> - * It is usually the {@link javax.media.nativewindow.NativeSurface#getSurfaceHandle()}, - * ie the native surface handle of the underlying windowing toolkit.<br> - * However, on X11/GLX this reflects a GLXDrawable, which represents a GLXWindow, GLXPixmap, or GLXPbuffer.<br> - * On EGL, this represents the EGLSurface.<br> + * Returns the GL drawable handle, + * guaranteed to be valid after {@link #setRealized(boolean) realization} + * <i>and</i> while it's {@link NativeSurface surface} is being {@link NativeSurface#lockSurface() locked}. + * <p> + * It is usually identical to the underlying windowing toolkit {@link NativeSurface surface}'s + * {@link javax.media.nativewindow.NativeSurface#getSurfaceHandle() handle} + * or an intermediate layer to suite GL, e.g. an EGL surface. + * </p> + * <p> + * On EGL it is represented by the EGLSurface.<br> + * On X11/GLX it is represented by either the Window XID, GLXPixmap, or GLXPbuffer.<br> + * On Windows it is represented by the HDC, which may change with each {@link #lockSurface()}.<br> + * </p> + * @see #setRealized(boolean) + * @see NativeSurface#lockSurface() + * @see NativeSurface#unlockSurface() */ public long getHandle(); diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 9d5bd0524..e775afbff 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -255,6 +255,8 @@ public abstract class GLDrawableFactory { } } + protected static String getThreadName() { return Thread.currentThread().getName(); } + /** Returns true if this factory is complete, i.e. ready to be used. Otherwise return false. */ protected abstract boolean isComplete(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 2fdf18404..c1d5fb1d2 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -687,7 +687,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing if(DEBUG) { final NativeSurface ns = getNativeSurface(); final long nsH = null != ns ? ns.getSurfaceHandle() : 0; - System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(nsH)); + System.err.println("GLCanvas.sizeChanged: ("+getThreadName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(nsH)); // Thread.dumpStack(); } if( validateGLDrawable() ) { @@ -1209,9 +1209,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing return config; } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } + protected static String getThreadName() { return Thread.currentThread().getName(); } /** * A most simple JOGL AWT test entry diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index f1a2ccc7e..dfb769eb4 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -832,9 +832,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing return tmp[0]; } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } + protected static String getThreadName() { return Thread.currentThread().getName(); } //---------------------------------------------------------------------- // Implementations of the various backends diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java index 1f59b5805..1f59b5805 100755..100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java index 2884aca2f..2884aca2f 100755..100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java diff --git a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java index 610f08e21..1a862a3b7 100644 --- a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java +++ b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java @@ -247,8 +247,6 @@ final class ExtensionAvailabilityCache { private int glXExtensionCount = 0; private HashSet<String> availableExtensionCache = new HashSet<String>(50); - static String getThreadName() { - return Thread.currentThread().getName(); - } + static String getThreadName() { return Thread.currentThread().getName(); } } diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java index 1eb7c618c..705f8b94e 100644 --- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -118,7 +118,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe final boolean res = isGLStatePreservationSupported() ? true : false; if( res ) { if( DEBUG ) { - System.err.println("GLAutoDrawableBase.setPreserveGLStateAtDestroy: ("+Thread.currentThread().getName()+"): "+preserveGLELSAtDestroy+" -> "+value+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); + System.err.println("GLAutoDrawableBase.setPreserveGLStateAtDestroy: ("+getThreadName()+"): "+preserveGLELSAtDestroy+" -> "+value+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); } preserveGLELSAtDestroy = value; } @@ -200,7 +200,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe GLDrawableImpl _drawable = drawable; if( null!=_drawable ) { if(DEBUG) { - System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); + System.err.println("GLAutoDrawableBase.sizeChanged: ("+getThreadName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); } if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) { final RecursiveLock _lock = getLock(); @@ -678,6 +678,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe return null != _drawable ? _drawable.getHandle() : 0; } + protected static String getThreadName() { return Thread.currentThread().getName(); } + @Override public String toString() { return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 64ade3eff..0d8b193af 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -258,7 +258,7 @@ public abstract class GLContextImpl extends GLContext { if(DEBUG) { String sgl1 = (null!=this.gl)?this.gl.getClass().getSimpleName()+", "+this.gl.toString():"<null>"; String sgl2 = (null!=gl)?gl.getClass().getSimpleName()+", "+gl.toString():"<null>"; - Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread().getName()+", "+sgl1+" -> "+sgl2); + Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+getThreadName()+", "+sgl1+" -> "+sgl2); e.printStackTrace(); } this.gl = gl; @@ -342,18 +342,24 @@ public abstract class GLContextImpl extends GLContext { @Override public final void destroy() { + if ( null == drawable ) { + throw new GLException("Drawable is null: "+toString()); + } 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); } - if (contextHandle != 0) { + if ( 0 != contextHandle ) { final int lockRes = drawable.lockSurface(); - if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + if ( NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes ) { // this would be odd .. throw new GLException("Surface not ready to lock: "+drawable); } Throwable drawableContextRealizedException = null; try { + if ( !drawable.isRealized() ) { + throw new GLException("Drawable not realized: "+toString()); + } // Must hold the lock around the destroy operation to make sure we // don't destroy the context while another thread renders to it. lock.lock(); // holdCount++ -> 1 - n (1: not locked, 2-n: destroy while rendering) @@ -365,17 +371,18 @@ public abstract class GLContextImpl extends GLContext { } } try { - // release current context - if(lock.getHoldCount() == 1) { - // needs current context to call associateDrawable(..) and to disable debug handler - makeCurrent(); + // if not current, makeCurrent(), to call associateDrawable(..) and to disable debug handler + if ( lock.getHoldCount() == 1 ) { + if ( GLContext.CONTEXT_NOT_CURRENT == makeCurrent() ) { + throw new GLException("GLContext.makeCurrent() failed: "+toString()); + } } try { associateDrawable(false); } catch (Throwable t) { drawableContextRealizedException = t; } - if(0 != defaultVAO) { + if ( 0 != defaultVAO ) { int[] tmp = new int[] { defaultVAO }; gl.getGL2GL3().glBindVertexArray(0); gl.getGL2GL3().glDeleteVertexArrays(1, tmp, 0); @@ -492,17 +499,13 @@ public abstract class GLContextImpl extends GLContext { return CONTEXT_NOT_CURRENT; } - boolean unlockContextAndSurface = true; // Must be cleared if successful, otherwise finally block will release context and surface! + boolean unlockResources = true; // Must be cleared if successful, otherwise finally block will release context and/or surface! int res = CONTEXT_NOT_CURRENT; try { - if (0 == drawable.getHandle()) { - throw new GLException("drawable has invalid handle: "+drawable); - } - if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) { - drawable.updateHandle(); - } - if ( drawable.isRealized() ) { + if ( 0 == drawable.getHandle() ) { + throw new GLException("drawable has invalid handle: "+drawable); + } lock.lock(); try { // One context can only be current by one thread, @@ -513,7 +516,7 @@ public abstract class GLContextImpl extends GLContext { // Assume we don't need to make this context current again // For Mac OS X, however, we need to update the context to track resizes drawableUpdatedNotify(); - unlockContextAndSurface = false; // success + unlockResources = false; // success 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); } @@ -523,7 +526,7 @@ public abstract class GLContextImpl extends GLContext { } } res = makeCurrentWithinLock(lockRes); - unlockContextAndSurface = CONTEXT_NOT_CURRENT == res; // success ? + unlockResources = CONTEXT_NOT_CURRENT == res; // success ? /** * FIXME: refactor dependence on Java 2D / JOGL bridge @@ -533,10 +536,10 @@ public abstract class GLContextImpl extends GLContext { } */ } catch (RuntimeException e) { - unlockContextAndSurface = true; + unlockResources = true; throw e; } finally { - if (unlockContextAndSurface) { + if (unlockResources) { if( DEBUG_TRACE_SWITCH ) { System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.1]: Context lock.unlock() due to error, res "+makeCurrentResultToString(res)+", "+lock); } @@ -545,10 +548,10 @@ public abstract class GLContextImpl extends GLContext { } } /* if ( drawable.isRealized() ) */ } catch (RuntimeException e) { - unlockContextAndSurface = true; + unlockResources = true; throw e; } finally { - if (unlockContextAndSurface) { + if (unlockResources) { drawable.unlockSurface(); } } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 9c1cd478b..177c465da 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -887,7 +887,7 @@ public class GLDrawableHelper { final Runnable initAction) { if(null==context) { if (DEBUG) { - Exception e = new GLException(Thread.currentThread().getName()+" Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); + Exception e = new GLException(getThreadName()+" Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); e.printStackTrace(); } return; @@ -935,7 +935,7 @@ public class GLDrawableHelper { res = context.makeCurrent(); if (GLContext.CONTEXT_NOT_CURRENT != res) { if(GLContext.CONTEXT_CURRENT_NEW == res) { - throw new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context); + throw new GLException(getThreadName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context); } if( listeners.size() > 0 && null != autoDrawable ) { disposeAllGLEventListener(autoDrawable, false); @@ -950,7 +950,7 @@ public class GLDrawableHelper { } flushGLRunnables(); } catch (Exception e) { - System.err.println("Catched: "+e.getMessage()); + System.err.println("Catched Exception on thread "+getThreadName()); e.printStackTrace(); } if (lastContext != null) { @@ -1036,7 +1036,7 @@ public class GLDrawableHelper { try { context.release(); } catch (Exception e) { - System.err.println("Catched: "+e.getMessage()); + System.err.println("Catched Exception on thread "+getThreadName()); e.printStackTrace(); } } @@ -1142,7 +1142,7 @@ public class GLDrawableHelper { context.release(); ctxReleased = true; } catch (Exception e) { - System.err.println("Catched: "+e.getMessage()); + System.err.println("Catched Exception on thread "+getThreadName()); e.printStackTrace(); } } @@ -1160,5 +1160,7 @@ public class GLDrawableHelper { long td = System.currentTimeMillis() - t0; System.err.println("td0 "+td+"ms, fps "+(1.0/(td/1000.0))+", td-makeCurrent: "+tdA+"ms, td-render "+tdR+"ms, td-swap "+tdS+"ms, td-release "+tdX+"ms, ctx claimed: "+ctxClaimed+", ctx release: "+ctxReleased+", ctx destroyed "+ctxDestroyed); } + + protected static String getThreadName() { return Thread.currentThread().getName(); } } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index d0c1461a9..a2b99c7da 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -79,14 +79,11 @@ public abstract class GLDrawableImpl implements GLDrawable { if( !realized ) { // volatile OK (locked below) return; // destroyed already } - int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release] + final int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release] if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) { return; } try { - if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) { - updateHandle(); - } if( realized ) { // volatile OK final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities(); if ( caps.getDoubleBuffered() ) { @@ -145,11 +142,21 @@ public abstract class GLDrawableImpl implements GLDrawable { return surface; } - /** called with locked surface @ setRealized(false) */ + /** + * called with locked surface @ setRealized(false) or @ lockSurface(..) when surface changed + * <p> + * Must be paired w/ {@link #createHandle()}. + * </p> + */ protected void destroyHandle() {} - /** called with locked surface @ setRealized(true) or @ lockSurface(..) when surface changed */ - protected void updateHandle() {} + /** + * called with locked surface @ setRealized(true) or @ lockSurface(..) when surface changed + * <p> + * Must be paired w/ {@link #destroyHandle()}. + * </p> + */ + protected void createHandle() {} @Override public long getHandle() { @@ -174,7 +181,7 @@ public abstract class GLDrawableImpl implements GLDrawable { if(isProxySurface) { ((ProxySurface)surface).createNotify(); } - if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { + if(NativeSurface.LOCK_SURFACE_NOT_READY >= surface.lockSurface()) { throw new GLException("GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)"); } } else { @@ -185,7 +192,7 @@ public abstract class GLDrawableImpl implements GLDrawable { realized = realizedArg; if(realizedArg) { setRealizedImpl(); - updateHandle(); + createHandle(); } else { destroyHandle(); setRealizedImpl(); @@ -193,7 +200,7 @@ public abstract class GLDrawableImpl implements GLDrawable { } } finally { if(realizedArg) { - unlockSurface(); + surface.unlockSurface(); } else { aDevice.unlock(); if(isProxySurface) { @@ -276,12 +283,47 @@ public abstract class GLDrawableImpl implements GLDrawable { return surface.getHeight(); } - /** @see NativeSurface#lockSurface() */ + /** + * {@link NativeSurface#lockSurface() Locks} the underlying windowing toolkit's {@link NativeSurface surface}. + * <p> + * <i>If</i> drawable is {@link #setRealized(boolean) realized}, + * the {@link #getHandle() drawable handle} is valid after successfully {@link NativeSurface#lockSurface() locking} + * it's {@link NativeSurface surface} until being {@link #unlockSurface() unlocked}. + * </p> + * <p> + * In case the {@link NativeSurface surface} has changed as indicated by it's + * {@link NativeSurface#lockSurface() lock} result {@link NativeSurface#LOCK_SURFACE_CHANGED}, + * the implementation is required to update this information as needed within it's implementation. + * </p> + * + * @see NativeSurface#lockSurface() + * @see #getHandle() + */ public final int lockSurface() throws GLException { - return surface.lockSurface(); + final int lockRes = surface.lockSurface(); + if ( NativeSurface.LOCK_SURFACE_CHANGED == lockRes && realized ) { + // Update the drawable handle, in case the surface handle has changed. + final long _handle1 = getHandle(); + destroyHandle(); + createHandle(); + final long _handle2 = getHandle(); + if(DEBUG) { + if( _handle1 != _handle2) { + System.err.println(getThreadName() + ": Drawable handle changed: "+toHexString(_handle1)+" -> "+toHexString(_handle2)); + } + } + } + return lockRes; + } - /** @see NativeSurface#unlockSurface() */ + /** + * {@link NativeSurface#unlockSurface() Unlocks} the underlying windowing toolkit {@link NativeSurface surface}, + * which may render the {@link #getHandle() drawable handle} invalid. + * + * @see NativeSurface#unlockSurface() + * @see #getHandle() + */ public final void unlockSurface() { surface.unlockSurface(); } @@ -294,9 +336,7 @@ public abstract class GLDrawableImpl implements GLDrawable { ",\n\tSurface "+getNativeSurface()+"]"; } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } + protected static String getThreadName() { return Thread.currentThread().getName(); } protected GLDrawableFactory factory; protected NativeSurface surface; diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java index 51ec7dda6..ac10e2728 100644 --- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java @@ -546,7 +546,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { @Override public final void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException { if(DEBUG) { - System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); + System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+getThreadName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); } int lockRes = lockSurface(); if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { diff --git a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java index f7d59e127..112dfcb64 100644 --- a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java +++ b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java @@ -219,9 +219,7 @@ public class GLWorkerThread { return (Thread.currentThread() == thread); } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } + protected static String getThreadName() { return Thread.currentThread().getName(); } static class WorkerRunnable implements Runnable { public void run() { diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java index 7e050c81e..91187cc26 100644 --- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java +++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java @@ -116,17 +116,17 @@ public class SharedResourceRunner implements Runnable { if(null != thread && !thread.isAlive()) { // thread was killed unrecognized .. if (DEBUG) { - System.err.println("SharedResourceRunner.start() - dead-old-thread cleanup - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.start() - dead-old-thread cleanup - "+getThreadName()); } releaseSharedResources(); thread = null; } if(null == thread) { if (DEBUG) { - System.err.println("SharedResourceRunner.start() - start new Thread - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.start() - start new Thread - "+getThreadName()); } resetState(); - thread = new Thread(this, Thread.currentThread().getName()+"-SharedResourceRunner"); + thread = new Thread(this, getThreadName()+"-SharedResourceRunner"); thread.setDaemon(true); // Allow JVM to exit, even if this one is running thread.start(); } @@ -136,7 +136,7 @@ public class SharedResourceRunner implements Runnable { public void stop() { if(null != thread) { if (DEBUG) { - System.err.println("SharedResourceRunner.stop() - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.stop() - "+getThreadName()); } synchronized (this) { shouldRelease = true; @@ -161,14 +161,14 @@ public class SharedResourceRunner implements Runnable { if (null == sr && !getDeviceTried(connection)) { addDeviceTried(connection); if (DEBUG) { - System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": trying - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": trying - "+getThreadName()); } if ( impl.isDeviceSupported(connection) ) { doAndWait(connection, null); sr = impl.mapGet(connection); } if (DEBUG) { - System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) +" - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) +" - "+getThreadName()); } } } @@ -183,11 +183,11 @@ public class SharedResourceRunner implements Runnable { if (null != sr) { removeDeviceTried(connection); if (DEBUG) { - System.err.println("SharedResourceRunner.releaseShared() " + connection + ": trying - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.releaseShared() " + connection + ": trying - "+getThreadName()); } doAndWait(null, connection); if (DEBUG) { - System.err.println("SharedResourceRunner.releaseShared() " + connection + ": done - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.releaseShared() " + connection + ": done - "+getThreadName()); } } } @@ -197,7 +197,7 @@ public class SharedResourceRunner implements Runnable { private final void doAndWait(String initConnection, String releaseConnection) { // wait until thread becomes ready to init new device, // pass the device and release the sync - final String threadName = Thread.currentThread().getName(); + final String threadName = getThreadName(); if (DEBUG) { System.err.println("SharedResourceRunner.doAndWait() START init: " + initConnection + ", release: "+releaseConnection+" - "+threadName); } @@ -230,7 +230,7 @@ public class SharedResourceRunner implements Runnable { } public final void run() { - final String threadName = Thread.currentThread().getName(); + final String threadName = getThreadName(); if (DEBUG) { System.err.println("SharedResourceRunner.run(): STARTED - " + threadName); @@ -249,7 +249,7 @@ public class SharedResourceRunner implements Runnable { } catch (InterruptedException ex) { shouldRelease = true; if(DEBUG) { - System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+threadName); ex.printStackTrace(); } } @@ -319,10 +319,12 @@ public class SharedResourceRunner implements Runnable { try { impl.releaseSharedResource(iter.next()); } catch (Throwable t) { - System.err.println("Catched Exception: "+t.getStackTrace()+" - "+Thread.currentThread().getName()); + System.err.println("Catched Exception on thread "+getThreadName()); t.printStackTrace(); } } impl.clear(); } + + protected static String getThreadName() { return Thread.currentThread().getName(); } } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java index 167eebf3a..2edf26145 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java @@ -100,10 +100,10 @@ public abstract class EGLDrawable extends GLDrawableImpl { } @Override - protected final void updateHandle() { + protected final void createHandle() { final EGLWrappedSurface eglws = (EGLWrappedSurface) surface; if(DEBUG) { - System.err.println(getThreadName() + ": updateHandle of "+eglws); + System.err.println(getThreadName() + ": createHandle of "+eglws); } if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) { if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) { diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index b390621fa..be3729a7d 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -456,7 +456,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } } catch (Throwable t) { if(DEBUG) { - System.err.println("Catched Exception:"); + System.err.println("Catched Exception on thread "+getThreadName()); t.printStackTrace(); } success = false; @@ -597,7 +597,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } } catch (GLException gle) { if(DEBUG) { - System.err.println("Catched Exception while EGL Shared Resource initialization"); + System.err.println("Catched Exception on thread "+getThreadName()); gle.printStackTrace(); } } @@ -658,8 +658,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target)); } - static String getThreadName() { return Thread.currentThread().getName(); } - @Override protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { if (target == null) { diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index f99d89df7..a197bd51f 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -669,7 +669,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl setSwapIntervalImpl(nsOpenGLLayer, interval); // enabled per default in layered surface valid = true; if (DEBUG) { - System.err.println("NSOpenGLLayer.Attach: OK, layer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbuffer)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", drawableHandle "+toHexString(drawable.getHandle())+" - "+Thread.currentThread().getName()); + System.err.println("NSOpenGLLayer.Attach: OK, layer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbuffer)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", drawableHandle "+toHexString(drawable.getHandle())+" - "+getThreadName()); } } finally { MacOSXCGLContext.this.lock.unlock(); @@ -685,7 +685,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl if( !valid ) { // could not acquire lock, re-queue if (DEBUG) { - System.err.println("NSOpenGLLayer.Attach: Re-Queue, drawableHandle "+toHexString(drawable.getHandle())+" - "+Thread.currentThread().getName()); + System.err.println("NSOpenGLLayer.Attach: Re-Queue, drawableHandle "+toHexString(drawable.getHandle())+" - "+getThreadName()); } OSXUtil.RunLater(this, 1); } @@ -713,17 +713,17 @@ public abstract class MacOSXCGLContext extends GLContextImpl ols.detachSurfaceLayer(); } } catch(Throwable t) { - System.err.println("Catched exception @ "+Thread.currentThread().getName()+": "); + System.err.println("Catched Exception on thread "+getThreadName()); t.printStackTrace(); } CGL.releaseNSOpenGLLayer(cmd.nsOpenGLLayer); if(DEBUG) { - System.err.println("NSOpenGLLayer.Detach: OK, layer "+toHexString(cmd.nsOpenGLLayer)+" - "+Thread.currentThread().getName()); + System.err.println("NSOpenGLLayer.Detach: OK, layer "+toHexString(cmd.nsOpenGLLayer)+" - "+getThreadName()); } cmd.nsOpenGLLayer = 0; cmd.valid = false; } else if(DEBUG) { - System.err.println("NSOpenGLLayer.Detach: Skipped "+toHexString(cmd.nsOpenGLLayer)+" - "+Thread.currentThread().getName()); + System.err.println("NSOpenGLLayer.Detach: Skipped "+toHexString(cmd.nsOpenGLLayer)+" - "+getThreadName()); } } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java index 1daa892ba..910158d1f 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java @@ -152,10 +152,6 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { return getFactoryImpl().getGLDynamicLookupHelper(0); } - protected static String getThreadName() { - return Thread.currentThread().getName(); - } - // Support for "mode switching" as described in MacOSXCGLDrawable public void setOpenGLMode(GLBackendType mode) { if (mode == openGLMode) { diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index aaca7c78a..6c647108f 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -291,7 +291,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } } catch (GLException gle) { if(DEBUG) { - System.err.println("Catched Exception while MaxOSXCGL Shared Resource initialization:"); + System.err.println("Catched Exception on thread "+getThreadName()); gle.printStackTrace(); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index aea0d7973..d7d6ceab4 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -174,7 +174,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { long pid = GDI.GetCurrentProcess(); if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) { if(DEBUG) { - System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + getThreadName()); // Thread.dumpStack(); } processAffinityChanges = pid; @@ -194,7 +194,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { " this PID 0x" + Long.toHexString(pid) ); } if(DEBUG) { - System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + getThreadName()); } GDI.SetProcessAffinityMask(pid, sysMask.get(0)); } @@ -432,7 +432,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } catch (GLException gle) { if(DEBUG) { - System.err.println("Catched Exception while WindowsWGL Shared Resource initialization"); + System.err.println("Catched Exception on thread "+getThreadName()); gle.printStackTrace(); } } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index f22bbfc52..2f3940baa 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -360,7 +360,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } catch (GLException gle) { if(DEBUG) { - System.err.println("Catched Exception while X11GLX Shared Resource initialization"); + System.err.println("Catched Exception on thread "+getThreadName()); gle.printStackTrace(); } } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java index c15065cfa..6b239a43d 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java @@ -56,7 +56,7 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable { glXWindow=0; useGLXWindow=false; if(realized) { - updateHandle(); + createHandle(); } } @@ -82,7 +82,7 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable { } @Override - protected final void updateHandle() { + protected final void createHandle() { if(USE_GLXWINDOW) { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration(); if(config.getFBConfig()>=0) { diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java index d06aca039..d06aca039 100755..100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java 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 c3ad51c96..c3ad51c96 100755..100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java index 4920b59ea..b04ebc1af 100644 --- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java @@ -133,7 +133,7 @@ public abstract class InputEvent extends NEWTEvent if(isControlDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("ctrl"); } if(isMetaDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("meta"); } if(isAltDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("alt"); } - if(isAltGraphDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("altg"); } + if(isAltGraphDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("altgr"); } if(isAutoRepeat()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("repeat"); } for(int i=1; i<=MouseEvent.BUTTON_NUMBER; i++) { if(isButtonDown(i)) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("button").append(i); } diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java index 5117ffe29..45bccf964 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java @@ -34,7 +34,11 @@ package com.jogamp.newt.event; +import com.jogamp.common.util.IntBitfield; + /** + * <a name="eventDelivery"><h5>KeyEvent Delivery</h5></a> + * * Key events are delivered in the following order: * <p> * <table border="0"> @@ -77,29 +81,84 @@ package com.jogamp.newt.event; * 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> + * + * <a name="unicodeMapping"><h5>Unicode Mapping</h5></a> + * <p> + * {@link #getKeyChar() Key-chars}, as well as + * {@link #isPrintableKey() printable} {@link #getKeyCode() key-codes} and {@link #getKeySymbol() key-symbols} + * use the UTF-16 unicode space w/o collision. + * + * </p> + * <p> + * Non-{@link #isPrintableKey() printable} {@link #getKeyCode() key-codes} and {@link #getKeySymbol() key-symbols}, + * i.e. {@link #isModifierKey() modifier-} and {@link #isActionKey() action-}keys, + * are mapped to unicode's control and private range and do not collide w/ {@link #isPrintableKey() printable} unicode values + * with the following exception. + * </p> + * + * <a name="unicodeCollision"><h5>Unicode Collision</h5></a> + * <p> + * The following {@link #getKeyCode() Key-code}s and {@link #getKeySymbol() key-symbol}s collide w/ unicode space:<br/> + * <table border="1"> + * <tr><th>unicode range</th> <th>virtual key code</th> <th>unicode character</th></tr> + * <tr><td>[0x61 .. 0x78]</td> <td>[{@link #VK_F1}..{@link #VK_F24}]</td> <td>['a'..'x']</td></tr> + * </table> + * </p> + * <p> + * Collision was chosen for {@link #getKeyCode() Key-code} and {@link #getKeySymbol() key-symbol} mapping + * to allow a minimal code range, i.e. <code>[0..255]</code>. + * The reduced code range in turn allows the implementation to utilize fast and small lookup tables, + * e.g. to implement a key-press state tracker. + * </p> + * <pre> + * http://www.utf8-chartable.de/unicode-utf8-table.pl + * http://www.unicode.org/Public/5.1.0/ucd/PropList.txt + * https://en.wikipedia.org/wiki/Mapping_of_Unicode_characters + * https://en.wikipedia.org/wiki/Unicode_control_characters + * https://en.wikipedia.org/wiki/Private_Use_%28Unicode%29#Private_Use_Areas + * </pre> + * </p> */ @SuppressWarnings("serial") public class KeyEvent extends InputEvent { - public KeyEvent(short eventType, Object source, long when, int modifiers, short keyCode, short keySym, char keyChar) { - super(eventType, source, when, modifiers); + private KeyEvent(short eventType, Object source, long when, int modifiers, short keyCode, short keySym, int keySymModMask, char keyChar) { + super(eventType, source, when, modifiers | keySymModMask); 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; + if( isPrintableKey(keySym, false) && isPrintableKey((short)keyChar, true) ) { + _flags |= F_PRINTABLE_MASK; + } else { + if( 0 != keySymModMask ) { + _flags |= F_MODIFIER_MASK; + } else { + // A = U - ( P + M ) + _flags |= F_ACTION_MASK; + } } flags = _flags; + + // + // Validate flags + // + final int pma_bits = flags & ( F_PRINTABLE_MASK | F_MODIFIER_MASK | F_ACTION_MASK ) ; + final int pma_count = IntBitfield.getBitCount(pma_bits); + if ( 1 != pma_count ) { + throw new InternalError("Key must be either of type printable, modifier or action - but it is of "+pma_count+" types: "+this); + } } } + + public static KeyEvent create(short eventType, Object source, long when, int modifiers, short keyCode, short keySym, char keyChar) { + return new KeyEvent(eventType, source, when, modifiers, keyCode, keySym, getModifierMask(keySym), keyChar); + } /** - * Returns the <i>UTF-16</i> character reflecting the {@link #getKeySymbol() key symbol}. + * Returns the <i>UTF-16</i> character reflecting the {@link #getKeySymbol() key symbol} + * incl. active {@link #isModifierKey() modifiers}. * @see #getKeySymbol() * @see #getKeyCode() */ @@ -109,6 +168,12 @@ public class KeyEvent extends InputEvent /** * Returns the virtual <i>key symbol</i> reflecting the current <i>keyboard layout</i>. + * <p> + * For {@link #isPrintableKey() printable keys}, the <i>key symbol</i> is the {@link #isModifierKey() unmodified} + * representation of the UTF-16 {@link #getKeyChar() key char}.<br/> + * E.g. symbol [{@link #VK_A}, 'A'] for char 'a'. + * </p> + * @see #isPrintableKey() * @see #getKeyChar() * @see #getKeyCode() */ @@ -128,10 +193,6 @@ public class KeyEvent extends InputEvent * <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() */ @@ -148,7 +209,7 @@ public class KeyEvent extends InputEvent sb = new StringBuilder(); } 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(", "); + .append("), printable ").append(isPrintableKey()).append(", modifier ").append(isModifierKey()).append(", action ").append(isActionKey()).append(", "); return super.toString(sb).append("]"); } @@ -161,6 +222,18 @@ public class KeyEvent extends InputEvent } } + /** + * @param keyChar UTF16 value to map. It is expected that the incoming keyChar value is unshifted and unmodified, + * however, lower case a-z is mapped to {@link KeyEvent#VK_A} - {@link KeyEvent#VK_Z}. + * @return {@link KeyEvent} virtual key (VK) value. + */ + public static short utf16ToVKey(char keyChar) { + if( 'a' <= keyChar && keyChar <= 'z' ) { + return (short) ( ( keyChar - 'a' ) + KeyEvent.VK_A ); + } + return (short) keyChar; + } + /** * Returns <code>true</code> if the given <code>virtualKey</code> represents a modifier key, otherwise <code>false</code>. * <p> @@ -180,6 +253,25 @@ public class KeyEvent extends InputEvent } } + /** + * If <code>vKey</code> is a {@link #isModifierKey() modifier key}, method returns the corresponding modifier mask, + * otherwise 0. + */ + public static int getModifierMask(short vKey) { + switch (vKey) { + case VK_SHIFT: + return InputEvent.SHIFT_MASK; + case VK_CONTROL: + return InputEvent.CTRL_MASK; + case VK_ALT: + case VK_ALT_GRAPH: + return InputEvent.ALT_MASK; + case VK_META: + return InputEvent.META_MASK; + } + return 0; + } + /** * Returns <code>true</code> if {@link #getKeySymbol() key symbol} represents a modifier key, * otherwise <code>false</code>. @@ -193,109 +285,73 @@ public class KeyEvent extends InputEvent public final boolean isModifierKey() { return 0 != ( F_MODIFIER_MASK & flags ) ; } - - /** - * 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(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 (vKey) { - case VK_CANCEL: - case VK_CLEAR: - case VK_PAUSE: - case VK_CAPS_LOCK: - case VK_ESCAPE: - case VK_PAGE_UP: - case VK_PAGE_DOWN: - case VK_END: - case VK_HOME: - case VK_LEFT: - case VK_UP: - case VK_RIGHT: - case VK_DOWN: - case VK_DELETE: - case VK_NUM_LOCK: - case VK_SCROLL_LOCK: - - case VK_PRINTSCREEN: - case VK_INSERT: - case VK_HELP: - case VK_META: - case VK_KP_UP: - case VK_KP_DOWN: - case VK_KP_LEFT: - case VK_KP_RIGHT: - - case VK_DEAD_VOICED_SOUND: - case VK_DEAD_SEMIVOICED_SOUND: - - case VK_WINDOWS: - case VK_CONTEXT_MENU: - case VK_FINAL: - - case VK_CONVERT: - case VK_NONCONVERT: - case VK_ACCEPT: - case VK_MODECHANGE: - - case VK_KANA: - case VK_KANJI: - - case VK_ALPHANUMERIC: - case VK_KATAKANA: - case VK_HIRAGANA: - case VK_FULL_WIDTH: - case VK_HALF_WIDTH: - case VK_ROMAN_CHARACTERS: - - case VK_COMPOSE: - case VK_BEGIN: - - return true; - } - return false; - } /** - * 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>. + * 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(short)} for details. + * Hence it is the set A of all keys U w/o printable P and w/o modifiers M: + * <code> A = U - ( P + M ) </code> * </p> + * @see #isPrintableKey() + * @see #isModifierKey() */ public final boolean isActionKey() { return 0 != ( F_ACTION_MASK & flags ) ; } - /** - * 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}. + /** + * Returns <code>true</code> if given <code>uniChar</code> represents a printable character, + * i.e. a value other than {@link #VK_UNDEFINED} and not a control or non-printable private code. + * <p> + * A printable character is neither a {@link #isModifierKey(short) modifier key}, nor an {@link #isActionKey(short) action key}. + * </p> + * <p> * Otherwise returns <code>false</code>. + * </p> + * <p> + * Distinction of key character and virtual key code is made due to <a href="#unicodeCollision">unicode collision</a>. + * </p> + * + * @param uniChar the UTF-16 unicode value, which maybe a virtual key code or key character. + * @param isKeyChar true if <code>uniChar</code> is a key character, otherwise a virtual key code */ - public static boolean isPrintableKey(short vKey) { - return !isModifierKey(vKey) && !isActionKey(vKey); + public static boolean isPrintableKey(final short uniChar, final boolean isKeyChar) { + if( VK_UNDEFINED == uniChar ) { + return false; + } + if( !isKeyChar ) { + if( ( nonPrintableKeys[0].min <= uniChar && uniChar <= nonPrintableKeys[0].max ) || + ( nonPrintableKeys[1].min <= uniChar && uniChar <= nonPrintableKeys[1].max ) || + ( nonPrintableKeys[2].min <= uniChar && uniChar <= nonPrintableKeys[2].max ) || + ( nonPrintableKeys[3].min <= uniChar && uniChar <= nonPrintableKeys[3].max ) ) { + return false; + } + + } else { + if( ( nonPrintableKeys[0].inclKeyChar && nonPrintableKeys[0].min <= uniChar && uniChar <= nonPrintableKeys[0].max ) || + ( nonPrintableKeys[1].inclKeyChar && nonPrintableKeys[1].min <= uniChar && uniChar <= nonPrintableKeys[1].max ) || + ( nonPrintableKeys[2].inclKeyChar && nonPrintableKeys[2].min <= uniChar && uniChar <= nonPrintableKeys[2].max ) || + ( nonPrintableKeys[3].inclKeyChar && nonPrintableKeys[3].min <= uniChar && uniChar <= nonPrintableKeys[3].max ) ) { + return false; + } + } + return true; } /** - * 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}. + * Returns <code>true</code> if {@link #getKeySymbol() key symbol} and {@link #getKeyChar() key char} + * represents a printable character, i.e. a value other than {@link #VK_UNDEFINED} + * and not a control or non-printable private code. + * <p> + * A printable character is neither a {@link #isModifierKey(short) modifier key}, nor an {@link #isActionKey(short) action key}. + * </p> + * <p> * Otherwise returns <code>false</code>. + * </p> */ public final boolean isPrintableKey() { - return 0 == ( F_NON_PRINT_MASK & flags ) ; + return 0 != ( F_PRINTABLE_MASK & flags ) ; } private final short keyCode; @@ -304,7 +360,7 @@ public class KeyEvent extends InputEvent 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 ; + private static final byte F_PRINTABLE_MASK = 1 << 2; /** A key has been pressed, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. */ public static final short EVENT_KEY_PRESSED = 300; @@ -316,571 +372,599 @@ public class KeyEvent extends InputEvent */ public static final short EVENT_KEY_TYPED = 302; + /** + * This value, {@code '\0'}, is used to indicate that the keyChar is unknown or not printable. + */ + public static final char NULL_CHAR = '\0'; + /* Virtual key codes. */ - 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 class NonPrintableRange { + /** min. unicode value, inclusive */ + public short min; + /** max. unicode value, inclusive */ + public short max; + /** true if valid for keyChar values as well, otherwise only valid for keyCode and keySym due to collision. */ + public final boolean inclKeyChar; + private NonPrintableRange(short min, short max, boolean inclKeyChar) { + this.min = min; + this.max = max; + this.inclKeyChar = inclKeyChar; + } + }; + /** Non printable key ranges, currently fixed to an aray of size 4. */ + public final static NonPrintableRange[] nonPrintableKeys = { new NonPrintableRange( (short)0x0000, (short)0x001F, true ), + new NonPrintableRange( (short)0x0061, (short)0x0078, false), + new NonPrintableRange( (short)0x007F, (short)0x009F, true ), + new NonPrintableRange( (short)0xE000, (short)0xF8FF, true ) }; + + // + // Unicode: Non printable controls: [0x00 - 0x1F] + // + + /** + * This value, {@value}, is used to indicate that the keyCode is unknown. + */ + public static final short VK_UNDEFINED = (short) 0x0; + + static final short VK_FREE01 = (short) 0x01; + + /** Constant for the HOME function key. ASCII: Start Of Text. */ + public static final short VK_HOME = (short) 0x02; + + /** Constant for the END function key. ASCII: End Of Text. */ + public static final short VK_END = (short) 0x03; + + /** Constant for the END function key. ASCII: End Of Transmission. */ + public static final short VK_FINAL = (short) 0x04; + + /** Constant for the PRINT function key. ASCII: Enquiry. */ + public static final short VK_PRINTSCREEN = (short) 0x05; + + static final short VK_FREE06 = (short) 0x06; + static final short VK_FREE07 = (short) 0x07; + + /** Constant for the BACK SPACE key "\b", matching ASCII. */ + public static final short VK_BACK_SPACE = (short) 0x08; + + /** Constant for the HORIZ TAB key "\t", matching ASCII. */ + public static final short VK_TAB = (short) 0x09; + + /** Constant for the ENTER key, i.e. LINE FEED "\n", matching ASCII. */ + public static final short VK_ENTER = (short) 0x0A; + + /** Constant for the PAGE DOWN function key. ASCII: Vertical Tabulation. */ + public static final short VK_PAGE_DOWN = (short) 0x0B; + + /** Constant for the CLEAR key, i.e. FORM FEED, matching ASCII. */ public static final short VK_CLEAR = (short) 0x0C; - public static final short VK_SHIFT = (short) 0x10; + + static final short VK_FREE0D = (short) 0x0D; + static final short VK_FREE0E = (short) 0x0E; + + /** Constant for the CTRL function key. ASCII: shift-in. */ + public static final short VK_SHIFT = (short) 0x0F; + + /** Constant for the PAGE UP function key. ASCII: Data Link Escape. */ + public static final short VK_PAGE_UP = (short) 0x10; + + /** Constant for the CTRL function key. ASCII: device-ctrl-one. */ public static final short VK_CONTROL = (short) 0x11; + + /** Constant for the left ALT function key. ASCII: device-ctrl-two. */ public static final short VK_ALT = (short) 0x12; - public static final short VK_PAUSE = (short) 0x13; + + /** Constant for the ALT_GRAPH function key, i.e. right ALT key. ASCII: device-ctrl-three. */ + public static final short VK_ALT_GRAPH = (short) 0x13; + + /** Constant for the CAPS LOCK function key. ASCII: device-ctrl-four. */ public static final short VK_CAPS_LOCK = (short) 0x14; + + static final short VK_FREE15 = (short) 0x15; + + /** Constant for the PAUSE function key. ASCII: sync-idle. */ + public static final short VK_PAUSE = (short) 0x16; + + /** <b>scroll lock</b> key. ASCII: End Of Transmission Block. */ + public static final short VK_SCROLL_LOCK = (short) 0x17; + + /** Constant for the CANCEL function key. ASCII: Cancel. */ + public static final short VK_CANCEL = (short) 0x18; + + static final short VK_FREE19 = (short) 0x19; + + /** Constant for the INSERT function key. ASCII: Substitute. */ + public static final short VK_INSERT = (short) 0x1A; + + /** Constant for the ESCAPE function key. ASCII: Escape. */ 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 Convert function key, Japanese "henkan". ASCII: File Separator. */ + public static final short VK_CONVERT = (short) 0x1C; - /** - * Constant for the non-numpad <b>left</b> arrow key. - * @see #VK_KP_LEFT - */ - public static final short VK_LEFT = (short) 0x25; + /** Constant for the Don't Convert function key, Japanese "muhenkan". ASCII: Group Separator.*/ + public static final short VK_NONCONVERT = (short) 0x1D; - /** - * Constant for the non-numpad <b>up</b> arrow key. - * @see #VK_KP_UP - */ - public static final short VK_UP = (short) 0x26; + /** Constant for the Accept or Commit function key, Japanese "kakutei". ASCII: Record Separator.*/ + public static final short VK_ACCEPT = (short) 0x1E; - /** - * Constant for the non-numpad <b>right</b> arrow key. - * @see #VK_KP_RIGHT - */ - public static final short VK_RIGHT = (short) 0x27; + /** Constant for the Mode Change (?). ASCII: Unit Separator.*/ + public static final short VK_MODECHANGE = (short) 0x1F; - /** - * Constant for the non-numpad <b>down</b> arrow key. - * @see #VK_KP_DOWN - */ - public static final short VK_DOWN = (short) 0x28; + // + // Unicode: Printable [0x20 - 0x7E] + // NOTE: Collision of 'a' - 'x' [0x61 .. 0x78], used for keyCode/keySym Fn function keys + // + + /** Constant for the SPACE function key. ASCII: SPACE. */ + public static final short VK_SPACE = (short) 0x20; + + /** Constant for the "!" key. */ + public static final short VK_EXCLAMATION_MARK = (short) 0x21; - /** - * Constant for the comma key, "," - */ - public static final short VK_COMMA = (short) 0x2C; + /** Constant for the """ key. */ + public static final short VK_QUOTEDBL = (short) 0x22; + + /** Constant for the "#" key. */ + public static final short VK_NUMBER_SIGN = (short) 0x23; - /** - * Constant for the minus key, "-" - * @since 1.2 - */ + /** Constant for the "$" key. */ + public static final short VK_DOLLAR = (short) 0x24; + + /** Constant for the "%" key. */ + public static final short VK_PERCENT = (short) 0x25; + + /** Constant for the "&" key. */ + public static final short VK_AMPERSAND = (short) 0x26; + + /** Constant for the "'" key. */ + public static final short VK_QUOTE = (short) 0x27; + + /** Constant for the "(" key. */ + public static final short VK_LEFT_PARENTHESIS = (short) 0x28; + + /** Constant for the ")" key. */ + public static final short VK_RIGHT_PARENTHESIS = (short) 0x29; + + /** Constant for the "*" key */ + public static final short VK_ASTERISK = (short) 0x2A; + + /** Constant for the "+" key. */ + public static final short VK_PLUS = (short) 0x2B; + + /** Constant for the comma key, "," */ + public static final short VK_COMMA = (short) 0x2C; + + /** Constant for the minus key, "-" */ public static final short VK_MINUS = (short) 0x2D; - /** - * Constant for the period key, "." - */ + /** Constant for the period key, "." */ public static final short VK_PERIOD = (short) 0x2E; - /** - * Constant for the forward slash key, "/" - */ + /** Constant for the forward slash key, "/" */ public static final short VK_SLASH = (short) 0x2F; - /** VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ + /** VK_0 thru VK_9 are the same as UTF16/ASCII '0' thru '9' [0x30 - 0x39] */ public static final short VK_0 = (short) 0x30; + /** See {@link #VK_0}. */ public static final short VK_1 = (short) 0x31; + /** See {@link #VK_0}. */ public static final short VK_2 = (short) 0x32; + /** See {@link #VK_0}. */ public static final short VK_3 = (short) 0x33; + /** See {@link #VK_0}. */ public static final short VK_4 = (short) 0x34; + /** See {@link #VK_0}. */ public static final short VK_5 = (short) 0x35; + /** See {@link #VK_0}. */ public static final short VK_6 = (short) 0x36; + /** See {@link #VK_0}. */ public static final short VK_7 = (short) 0x37; + /** See {@link #VK_0}. */ public static final short VK_8 = (short) 0x38; + /** See {@link #VK_0}. */ public static final short VK_9 = (short) 0x39; - /** - * Constant for the semicolon key, ";" - */ + /** Constant for the ":" key. */ + public static final short VK_COLON = (short) 0x3A; + + /** Constant for the semicolon key, ";" */ public static final short VK_SEMICOLON = (short) 0x3B; - /** - * Constant for the equals key, "=" - */ + /** Constant for the equals key, "<" */ + public static final short VK_LESS = (short) 0x3C; + + /** Constant for the equals key, "=" */ public static final short VK_EQUALS = (short) 0x3D; - /** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ + /** Constant for the equals key, ">" */ + public static final short VK_GREATER = (short) 0x3E; + + /** Constant for the equals key, "?" */ + public static final short VK_QUESTIONMARK = (short) 0x3F; + + /** Constant for the equals key, "@" */ + public static final short VK_AT = (short) 0x40; + + /** VK_A thru VK_Z are the same as Capital UTF16/ASCII 'A' thru 'Z' (0x41 - 0x5A) */ public static final short VK_A = (short) 0x41; + /** See {@link #VK_A}. */ public static final short VK_B = (short) 0x42; + /** See {@link #VK_A}. */ public static final short VK_C = (short) 0x43; + /** See {@link #VK_A}. */ public static final short VK_D = (short) 0x44; + /** See {@link #VK_A}. */ public static final short VK_E = (short) 0x45; + /** See {@link #VK_A}. */ public static final short VK_F = (short) 0x46; + /** See {@link #VK_A}. */ public static final short VK_G = (short) 0x47; + /** See {@link #VK_A}. */ public static final short VK_H = (short) 0x48; + /** See {@link #VK_A}. */ public static final short VK_I = (short) 0x49; + /** See {@link #VK_A}. */ public static final short VK_J = (short) 0x4A; + /** See {@link #VK_A}. */ public static final short VK_K = (short) 0x4B; + /** See {@link #VK_A}. */ public static final short VK_L = (short) 0x4C; + /** See {@link #VK_A}. */ public static final short VK_M = (short) 0x4D; + /** See {@link #VK_A}. */ public static final short VK_N = (short) 0x4E; + /** See {@link #VK_A}. */ public static final short VK_O = (short) 0x4F; + /** See {@link #VK_A}. */ public static final short VK_P = (short) 0x50; + /** See {@link #VK_A}. */ public static final short VK_Q = (short) 0x51; + /** See {@link #VK_A}. */ public static final short VK_R = (short) 0x52; + /** See {@link #VK_A}. */ public static final short VK_S = (short) 0x53; + /** See {@link #VK_A}. */ public static final short VK_T = (short) 0x54; + /** See {@link #VK_A}. */ public static final short VK_U = (short) 0x55; + /** See {@link #VK_A}. */ public static final short VK_V = (short) 0x56; + /** See {@link #VK_A}. */ public static final short VK_W = (short) 0x57; + /** See {@link #VK_A}. */ public static final short VK_X = (short) 0x58; + /** See {@link #VK_A}. */ public static final short VK_Y = (short) 0x59; + /** See {@link #VK_A}. */ public static final short VK_Z = (short) 0x5A; - /** - * Constant for the open bracket key, "[" - */ + /** Constant for the open bracket key, "[" */ public static final short VK_OPEN_BRACKET = (short) 0x5B; - /** - * Constant for the back slash key, "\" - */ + /**Constant for the back slash key, "\" */ public static final short VK_BACK_SLASH = (short) 0x5C; - /** - * Constant for the close bracket key, "]" - */ + /** Constant for the close bracket key, "]" */ 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 "^" key. */ + public static final short VK_CIRCUMFLEX = (short) 0x5E; + /** Constant for the "_" key */ + public static final short VK_UNDERSCORE = (short) 0x5F; + + /** Constant for the "`" key */ + public static final short VK_BACK_QUOTE = (short) 0x60; + + /** Small UTF/ASCII 'a' thru 'z' (0x61 - 0x7a) - Not used for keyCode / keySym. */ + /** - * Constant for the Numpad Separator key. + * Constant for the F<i>n</i> function keys. + * <p> + * F1..F24, i.e. F<i>n</i>, are mapped from on <code>0x60+n</code> -> <code>[0x61 .. 0x78]</code>. + * </p> + * <p> + * <b>Warning:</b> The F<i>n</i> function keys <b>do collide</b> with unicode characters small 'a' thru 'x'!<br/> + * See <a href="#unicodeCollision">Unicode Collision</a> for details. + * </p> */ - public static final short VK_SEPARATOR = (short) 0x6C; + public static final short VK_F1 = (short) ( 0x60+ 1 ); - 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 F2 function key. See {@link #VK_F1}. */ + public static final short VK_F2 = (short) ( 0x60+ 2 ); - /** Constant for the F1 function key. */ - public static final short VK_F1 = (short) 0x70; + /** Constant for the F3 function key. See {@link #VK_F1}. */ + public static final short VK_F3 = (short) ( 0x60+ 3 ); - /** Constant for the F2 function key. */ - public static final short VK_F2 = (short) 0x71; + /** Constant for the F4 function key. See {@link #VK_F1}. */ + public static final short VK_F4 = (short) ( 0x60+ 4 ); - /** Constant for the F3 function key. */ - public static final short VK_F3 = (short) 0x72; + /** Constant for the F5 function key. See {@link #VK_F1}. */ + public static final short VK_F5 = (short) ( 0x60+ 5 ); - /** Constant for the F4 function key. */ - public static final short VK_F4 = (short) 0x73; + /** Constant for the F6 function key. See {@link #VK_F1}. */ + public static final short VK_F6 = (short) ( 0x60+ 6 ); - /** Constant for the F5 function key. */ - public static final short VK_F5 = (short) 0x74; + /** Constant for the F7 function key. See {@link #VK_F1}. */ + public static final short VK_F7 = (short) ( 0x60+ 7 ); - /** Constant for the F6 function key. */ - public static final short VK_F6 = (short) 0x75; + /** Constant for the F8 function key. See {@link #VK_F1}. */ + public static final short VK_F8 = (short) ( 0x60+ 8 ); - /** Constant for the F7 function key. */ - public static final short VK_F7 = (short) 0x76; + /** Constant for the F9 function key. See {@link #VK_F1}. */ + public static final short VK_F9 = (short) ( 0x60+ 9 ); - /** Constant for the F8 function key. */ - public static final short VK_F8 = (short) 0x77; + /** Constant for the F11 function key. See {@link #VK_F1}. */ + public static final short VK_F10 = (short) ( 0x60+10 ); - /** Constant for the F9 function key. */ - public static final short VK_F9 = (short) 0x78; + /** Constant for the F11 function key. See {@link #VK_F1}. */ + public static final short VK_F11 = (short) ( 0x60+11 ); - /** Constant for the F10 function key. */ - public static final short VK_F10 = (short) 0x79; + /** Constant for the F12 function key. See {@link #VK_F1}.*/ + public static final short VK_F12 = (short) ( 0x60+12 ); - /** Constant for the F11 function key. */ - public static final short VK_F11 = (short) 0x7A; + /** Constant for the F13 function key. See {@link #VK_F1}. */ + public static final short VK_F13 = (short) ( 0x60+13 ); - /** Constant for the F12 function key. */ - public static final short VK_F12 = (short) 0x7B; + /** Constant for the F14 function key. See {@link #VK_F1}. */ + public static final short VK_F14 = (short) ( 0x60+14 ); - /** - * Constant for the F13 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F13 = (short) 0xF000; + /** Constant for the F15 function key. See {@link #VK_F1}. */ + public static final short VK_F15 = (short) ( 0x60+15 ); - /** - * Constant for the F14 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F14 = (short) 0xF001; + /** Constant for the F16 function key. See {@link #VK_F1}. */ + public static final short VK_F16 = (short) ( 0x60+16 ); - /** - * Constant for the F15 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F15 = (short) 0xF002; + /** Constant for the F17 function key. See {@link #VK_F1}. */ + public static final short VK_F17 = (short) ( 0x60+17 ); - /** - * Constant for the F16 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F16 = (short) 0xF003; + /** Constant for the F18 function key. See {@link #VK_F1}. */ + public static final short VK_F18 = (short) ( 0x60+18 ); - /** - * Constant for the F17 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F17 = (short) 0xF004; + /** Constant for the F19 function key. See {@link #VK_F1}. */ + public static final short VK_F19 = (short) ( 0x60+19 ); - /** - * Constant for the F18 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - 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 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 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 short VK_F21 = (short) 0xF008; + /** Constant for the F20 function key. See {@link #VK_F1}. */ + public static final short VK_F20 = (short) ( 0x60+20 ); - /** - * Constant for the F22 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F22 = (short) 0xF009; + /** Constant for the F21 function key. See {@link #VK_F1}. */ + public static final short VK_F21 = (short) ( 0x60+21 ); - /** - * Constant for the F23 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F23 = (short) 0xF00A; + /** Constant for the F22 function key. See {@link #VK_F1}. */ + public static final short VK_F22 = (short) ( 0x60+22 ); - /** - * Constant for the F24 function key. - * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p> - */ - public static final short VK_F24 = (short) 0xF00B; + /** Constant for the F23 function key. See {@link #VK_F1}. */ + public static final short VK_F23 = (short) ( 0x60+23 ); - 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; + /** Constant for the F24 function key. See {@link #VK_F1}. */ + public static final short VK_F24 = (short) ( 0x60+24 ); - public static final short VK_BACK_QUOTE = (short) 0xC0; - public static final short VK_QUOTE = (short) 0xDE; + + /** Constant for the "{" key */ + public static final short VK_LEFT_BRACE = (short) 0x7B; + /** Constant for the "|" key */ + public static final short VK_PIPE = (short) 0x7C; + /** Constant for the "}" key */ + public static final short VK_RIGHT_BRACE = (short) 0x7D; + + /** Constant for the "~" key, matching ASCII */ + public static final short VK_TILDE = (short) 0x7E; + + // + // Unicode: Non printable controls: [0x7F - 0x9F] + // + + /** Constant for the DEL key, matching ASCII. Non printable UTF control. */ + public static final short VK_DELETE = (short) 0x7F; + + /** Numeric keypad VK_NUMPAD0 thru VK_NUMPAD9 are mapped to UTF control (0x80 - 0x89). Non printable UTF control. */ + public static final short VK_NUMPAD0 = (short) 0x80; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD1 = (short) 0x81; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD2 = (short) 0x82; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD3 = (short) 0x83; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD4 = (short) 0x84; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD5 = (short) 0x85; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD6 = (short) 0x86; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD7 = (short) 0x87; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD8 = (short) 0x88; + /** See {@link #VK_NUMPAD0}. */ + public static final short VK_NUMPAD9 = (short) 0x89; + + /** Numeric keypad <b>decimal separator</b> key. Non printable UTF control. */ + public static final short VK_DECIMAL = (short) 0x8A; + + /** Numeric keypad <b>decimal separator</b> key. Non printable UTF control. */ + public static final short VK_SEPARATOR = (short) 0x8B; + + /** Numeric keypad <b>add</b> key. Non printable UTF control. */ + public static final short VK_ADD = (short) 0x8C; - /** - * Constant for the numeric keypad <b>up</b> arrow key. - * @see #VK_UP - */ - public static final short VK_KP_UP = (short) 0xE0; + /** Numeric keypad <b>subtract</b> key. Non printable UTF control. */ + public static final short VK_SUBTRACT = (short) 0x8D; + + /** Numeric keypad <b>multiply</b> key. Non printable UTF control. */ + public static final short VK_MULTIPLY = (short) 0x8E; + + /** Numeric keypad <b>divide</b> key. Non printable UTF control. */ + public static final short VK_DIVIDE = (short) 0x8F; + + /** Numeric keypad <b>num lock</b> key. Non printable UTF control. */ + public static final short VK_NUM_LOCK = (short) 0x90; + + /** Numeric keypad <b>left</b> arrow key, for cursor pad see {@link #VK_LEFT}. Non printable UTF control. */ + public static final short VK_KP_LEFT = (short) 0x91; - /** - * Constant for the numeric keypad <b>down</b> arrow key. - * @see #VK_DOWN - */ - public static final short VK_KP_DOWN = (short) 0xE1; + /** Numeric keypad <b>up</b> arrow key, for cursor pad see {@link #VK_UP}. Non printable UTF control. */ + public static final short VK_KP_UP = (short) 0x92; - /** - * Constant for the numeric keypad <b>left</b> arrow key. - * @see #VK_LEFT - */ - public static final short VK_KP_LEFT = (short) 0xE2; + /** Constant for the numeric keypad <b>right</b> arrow key, for cursor pad see {@link #VK_RIGHT}. Non printable UTF control. */ + public static final short VK_KP_RIGHT = (short) 0x93; + + /** Numeric keypad <b>down</b> arrow key, for cursor pad see {@link #VK_DOWN}. Non printable UTF control. */ + public static final short VK_KP_DOWN = (short) 0x94; - /** - * Constant for the numeric keypad <b>right</b> arrow key. - * @see #VK_RIGHT - */ - public static final short VK_KP_RIGHT = (short) 0xE3; - - /** For European keyboards */ - public static final short VK_DEAD_GRAVE = (short) 0x80; - /** For European keyboards */ - public static final short VK_DEAD_ACUTE = (short) 0x81; - /** For European keyboards */ - public static final short VK_DEAD_CIRCUMFLEX = (short) 0x82; - /** For European keyboards */ - public static final short VK_DEAD_TILDE = (short) 0x83; - /** For European keyboards */ - public static final short VK_DEAD_MACRON = (short) 0x84; - /** For European keyboards */ - public static final short VK_DEAD_BREVE = (short) 0x85; - /** For European keyboards */ - public static final short VK_DEAD_ABOVEDOT = (short) 0x86; - /** For European keyboards */ - public static final short VK_DEAD_DIAERESIS = (short) 0x87; - /** For European keyboards */ - public static final short VK_DEAD_ABOVERING = (short) 0x88; - /** For European keyboards */ - public static final short VK_DEAD_DOUBLEACUTE = (short) 0x89; - /** For European keyboards */ - public static final short VK_DEAD_CARON = (short) 0x8a; - /** For European keyboards */ - public static final short VK_DEAD_CEDILLA = (short) 0x8b; - /** For European keyboards */ - public static final short VK_DEAD_OGONEK = (short) 0x8c; - /** For European keyboards */ - public static final short VK_DEAD_IOTA = (short) 0x8d; - /** For European keyboards */ - public static final short VK_DEAD_VOICED_SOUND = (short) 0x8e; - /** For European keyboards */ - public static final short VK_DEAD_SEMIVOICED_SOUND = (short) 0x8f; - - /** For European keyboards */ - public static final short VK_AMPERSAND = (short) 0x96; - /** For European keyboards */ - public static final short VK_ASTERISK = (short) 0x97; - /** For European keyboards */ - public static final short VK_QUOTEDBL = (short) 0x98; - /** For European keyboards */ - public static final short VK_LESS = (short) 0x99; - - /** For European keyboards */ - public static final short VK_GREATER = (short) 0xa0; - /** For European keyboards */ - public static final short VK_BRACELEFT = (short) 0xa1; - /** For European keyboards */ - public static final short VK_BRACERIGHT = (short) 0xa2; + /** Constant for the cursor-pad <b>left</b> arrow key, for numerical pad see {@link #VK_KP_LEFT}*/ + public static final short VK_LEFT = (short) 0x95; - /** - * Constant for the "@" key. - */ - public static final short VK_AT = (short) 0x0200; + /** Constant for the cursor-pad <b>left</b> arrow key, for numerical pad see {@link #VK_KP_UP}.*/ + public static final short VK_UP = (short) 0x96; - /** - * Constant for the ":" key. - */ - public static final short VK_COLON = (short) 0x0201; + /** Constant for the cursor-pad <b>left</b> arrow key, for numerical pad see {@link #VK_KP_RIGHT}.*/ + public static final short VK_RIGHT = (short) 0x97; - /** - * Constant for the "^" key. - */ - public static final short VK_CIRCUMFLEX = (short) 0x0202; + /** Constant for the cursor-pad <b>left</b> arrow key, for numerical pad see {@link #VK_KP_DOWN}.*/ + public static final short VK_DOWN = (short) 0x98; + + /** Constant for the Context Menu key. */ + public static final short VK_CONTEXT_MENU = (short) 0x99; /** - * Constant for the "$" key. + * Constant for the MS "Windows" function key. + * It is used for both the left and right version of the key. */ - public static final short VK_DOLLAR = (short) 0x0203; + public static final short VK_WINDOWS = (short) 0x9A; - /** - * Constant for the Euro currency sign key. - */ - public static final short VK_EURO_SIGN = (short) 0x0204; + /** Constant for the Meta function key. */ + public static final short VK_META = (short) 0x9B; + + /** Constant for the Help function key. */ + public static final short VK_HELP = (short) 0x9C; + + /** Constant for the Compose function key. */ + public static final short VK_COMPOSE = (short) 0x9D; - /** - * Constant for the "!" key. - */ - public static final short VK_EXCLAMATION_MARK = (short) 0x0205; + /** Constant for the Begin function key. */ + public static final short VK_BEGIN = (short) 0x9E; - /** - * Constant for the inverted exclamation mark key. - */ - public static final short VK_INVERTED_EXCLAMATION_MARK = (short) 0x0206; + /** Constant for the Stop function key. */ + public static final short VK_STOP = (short) 0x9F; + + // + // Unicode: Printable [0x00A0 - 0xDFFF] + // + + /** Constant for the inverted exclamation mark key. */ + public static final short VK_INVERTED_EXCLAMATION_MARK = (short) 0xA1; + + /** Constant for the Euro currency sign key. */ + public static final short VK_EURO_SIGN = (short) 0x20AC; - /** - * Constant for the "(" key. - */ - public static final short VK_LEFT_PARENTHESIS = (short) 0x0207; + // + // Unicode: Private 0xE000 - 0xF8FF (Marked Non-Printable) + // + + /* for Sun keyboards */ + public static final short VK_CUT = (short) 0xF879; + public static final short VK_COPY = (short) 0xF87A; + public static final short VK_PASTE = (short) 0xF87B; + public static final short VK_UNDO = (short) 0xF87C; + public static final short VK_AGAIN = (short) 0xF87D; + public static final short VK_FIND = (short) 0xF87E; + public static final short VK_PROPS = (short) 0xF87F; - /** - * Constant for the "#" key. - */ - public static final short VK_NUMBER_SIGN = (short) 0x0208; + /* for input method support on Asian Keyboards */ /** - * Constant for the "+" key. + * Constant for the input method on/off key. */ - public static final short VK_PLUS = (short) 0x0209; - + /* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */ + public static final short VK_INPUT_METHOD_ON_OFF = (short) 0xF890; + /** - * Constant for the ")" key. + * Constant for the Code Input function key. */ - public static final short VK_RIGHT_PARENTHESIS = (short) 0x020A; + /* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */ + public static final short VK_CODE_INPUT = (short) 0xF891; /** - * Constant for the "_" key. + * Constant for the Roman Characters function key. */ - public static final short VK_UNDERSCORE = (short) 0x020B; + /* Japanese PC 106 keyboard: roumaji */ + public static final short VK_ROMAN_CHARACTERS = (short) 0xF892; /** - * Constant for the Microsoft Windows "Windows" key. - * It is used for both the left and right version of the key. + * Constant for the All Candidates function key. */ - public static final short VK_WINDOWS = (short) 0x020C; + /* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */ + public static final short VK_ALL_CANDIDATES = (short) 0xF893; /** - * Constant for the Microsoft Windows Context Menu key. + * Constant for the Previous Candidate function key. */ - 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 short VK_FINAL = (short) 0x0018; - - /** Constant for the Convert function key. */ - /* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */ - public static final short VK_CONVERT = (short) 0x001C; - - /** Constant for the Don't Convert function key. */ - /* Japanese PC 106 keyboard: muhenkan */ - public static final short VK_NONCONVERT = (short) 0x001D; - - /** Constant for the Accept or Commit function key. */ - /* Japanese Solaris keyboard: kakutei */ - public static final short VK_ACCEPT = (short) 0x001E; - - /* not clear what this means - listed in Microsoft Windows API */ - 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 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 short VK_KANJI = (short) 0x0019; + /* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */ + public static final short VK_PREVIOUS_CANDIDATE = (short) 0xF894; /** * Constant for the Alphanumeric function key. */ /* Japanese PC 106 keyboard: eisuu */ - public static final short VK_ALPHANUMERIC = (short) 0x00F0; + public static final short VK_ALPHANUMERIC = (short) 0xF895; /** * Constant for the Katakana function key. */ /* Japanese PC 106 keyboard: katakana */ - public static final short VK_KATAKANA = (short) 0x00F1; + public static final short VK_KATAKANA = (short) 0xF896; /** * Constant for the Hiragana function key. */ /* Japanese PC 106 keyboard: hiragana */ - public static final short VK_HIRAGANA = (short) 0x00F2; + public static final short VK_HIRAGANA = (short) 0xF897; /** * Constant for the Full-Width Characters function key. */ /* Japanese PC 106 keyboard: zenkaku */ - public static final short VK_FULL_WIDTH = (short) 0x00F3; + public static final short VK_FULL_WIDTH = (short) 0xF898; /** * Constant for the Half-Width Characters function key. */ /* Japanese PC 106 keyboard: hankaku */ - public static final short VK_HALF_WIDTH = (short) 0x00F4; - - /** - * Constant for the Roman Characters function key. - */ - /* Japanese PC 106 keyboard: roumaji */ - 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 short VK_ALL_CANDIDATES = (short) 0x0100; - - /** - * Constant for the Previous Candidate function key. - */ - /* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */ - 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 short VK_CODE_INPUT = (short) 0x0102; + public static final short VK_HALF_WIDTH = (short) 0xF89A; /** * 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 short VK_JAPANESE_KATAKANA = (short) 0x0103; + public static final short VK_JAPANESE_KATAKANA = (short) 0xF89B; /** * 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 short VK_JAPANESE_HIRAGANA = (short) 0x0104; + public static final short VK_JAPANESE_HIRAGANA = (short) 0xF89C; /** * 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 short VK_JAPANESE_ROMAN = (short) 0x0105; + public static final short VK_JAPANESE_ROMAN = (short) 0xF89D; /** * 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 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 short VK_INPUT_METHOD_ON_OFF = (short) 0x0107; - - /* for Sun keyboards */ - 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 short VK_COMPOSE = (short) 0xFF20; - - /** - * Constant for the AltGraph function key. - */ - public static final short VK_ALT_GRAPH = (short) 0xFF7E; - - /** - * Constant for the Begin key. - */ - public static final short VK_BEGIN = (short) 0xFF58; + public static final short VK_KANA_LOCK = (short) 0xF89F; /** * Constant for Keyboard became invisible, e.g. Android's soft keyboard Back button hit while keyboard is visible. */ - public static final short VK_KEYBOARD_INVISIBLE = (short) 0xDEAD; + public static final short VK_KEYBOARD_INVISIBLE = (short) 0xF8FF; - /** - * 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 short VK_UNDEFINED = (short) 0x0; } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index e5dd783ca..01a58a305 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -2251,41 +2251,45 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // // KeyListener/Event Support // - protected IntBitfield keyPressedState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1); - protected IntBitfield keyRepeatState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1); + private static final int keyTrackingRange = 255; + private final IntBitfield keyPressedState = new IntBitfield( keyTrackingRange + 1 ); + + protected final boolean isKeyCodeTracked(final short keyCode) { + return ( 0xFFFF & (int)keyCode ) <= keyTrackingRange; + } /** - * @param keyCode - * @return 1 if pressed, 0 if not pressed, -1 if not handled. + * @param keyCode the keyCode to set pressed state + * @param pressed true if pressed, otherwise false + * @return the previus pressed value */ - protected final int isKeyPressed(int keyCode) { - if( 0 <= keyCode && keyCode < keyPressedState.capacity() ) { - return keyPressedState.get(keyCode) ? 1 : 0; + protected final boolean setKeyPressed(short keyCode, boolean pressed) { + final int v = 0xFFFF & (int)keyCode; + if( v <= keyTrackingRange ) { + return keyPressedState.put(v, pressed); } - return -1; + return false; } /** - * @param keyCode - * @return 1 if pressed, 0 if not pressed, -1 if not handled. + * @param keyCode the keyCode to test pressed state + * @return true if pressed, otherwise false */ - protected final int isKeyInAutoRepeat(int keyCode) { - if( 0 <= keyCode && keyCode < keyRepeatState.capacity() ) { - return keyRepeatState.get(keyCode) ? 1 : 0; + protected final boolean isKeyPressed(short keyCode) { + final int v = 0xFFFF & (int)keyCode; + if( v <= keyTrackingRange ) { + return keyPressedState.get(v); } - return -1; - } - protected final boolean isKeyCodeTracked(int keyCode) { - return 0 <= keyCode && keyCode < keyRepeatState.capacity(); + return false; } 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) ); + consumeKeyEvent( KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | mouseButtonModMask, keyCode, keySym, 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) ); + enqueueEvent(wait, KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | mouseButtonModMask, keyCode, keySym, keyChar) ); } @Override @@ -2400,7 +2404,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // 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()); + eTyped = KeyEvent.create(KeyEvent.EVENT_KEY_TYPED, e.getSource(), e.getWhen(), e.getModifiers(), e.getKeyCode(), e.getKeySymbol(), e.getKeyChar()); } else { eTyped = null; } diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java index b90c2106e..ccbdc07bf 100644 --- a/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java +++ b/src/newt/classes/jogamp/newt/awt/event/AWTNewtEventFactory.java @@ -176,6 +176,14 @@ public class AWTNewtEventFactory { } } + public static final short awtButton2Newt(int awtButton) { + if( 0 < awtButton && awtButton <= com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER ) { + return (short)awtButton; + } else { + return (short)0; + } + } + /** * Converts the specified set of AWT event modifiers and extended event * modifiers to the equivalent NEWT event modifiers. @@ -223,12 +231,365 @@ public class AWTNewtEventFactory { return newtMods; } - public static final short awtButton2Newt(int awtButton) { - if( 0 < awtButton && awtButton <= com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER ) { - return (short)awtButton; - } else { - return (short)0; + public static short awtKeyCode2NewtKeyCode(final int awtKeyCode) { + final short defNEWTKeyCode = (short)awtKeyCode; + switch (awtKeyCode) { + case java.awt.event.KeyEvent.VK_HOME : return com.jogamp.newt.event.KeyEvent.VK_HOME; + case java.awt.event.KeyEvent.VK_END : return com.jogamp.newt.event.KeyEvent.VK_END; + case java.awt.event.KeyEvent.VK_FINAL : return com.jogamp.newt.event.KeyEvent.VK_FINAL; + case java.awt.event.KeyEvent.VK_PRINTSCREEN : return com.jogamp.newt.event.KeyEvent.VK_PRINTSCREEN; + case java.awt.event.KeyEvent.VK_BACK_SPACE : return com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE; + case java.awt.event.KeyEvent.VK_TAB : return com.jogamp.newt.event.KeyEvent.VK_TAB; + case java.awt.event.KeyEvent.VK_ENTER : return com.jogamp.newt.event.KeyEvent.VK_ENTER; + case java.awt.event.KeyEvent.VK_PAGE_DOWN : return com.jogamp.newt.event.KeyEvent.VK_PAGE_DOWN; + case java.awt.event.KeyEvent.VK_CLEAR : return com.jogamp.newt.event.KeyEvent.VK_CLEAR; + case java.awt.event.KeyEvent.VK_SHIFT : return com.jogamp.newt.event.KeyEvent.VK_SHIFT; + case java.awt.event.KeyEvent.VK_PAGE_UP : return com.jogamp.newt.event.KeyEvent.VK_PAGE_UP; + case java.awt.event.KeyEvent.VK_CONTROL : return com.jogamp.newt.event.KeyEvent.VK_CONTROL; + case java.awt.event.KeyEvent.VK_ALT : return com.jogamp.newt.event.KeyEvent.VK_ALT; + case java.awt.event.KeyEvent.VK_ALT_GRAPH : return com.jogamp.newt.event.KeyEvent.VK_ALT_GRAPH; + case java.awt.event.KeyEvent.VK_CAPS_LOCK : return com.jogamp.newt.event.KeyEvent.VK_CAPS_LOCK; + case java.awt.event.KeyEvent.VK_PAUSE : return com.jogamp.newt.event.KeyEvent.VK_PAUSE; + case java.awt.event.KeyEvent.VK_SCROLL_LOCK : return com.jogamp.newt.event.KeyEvent.VK_SCROLL_LOCK; + case java.awt.event.KeyEvent.VK_CANCEL : return com.jogamp.newt.event.KeyEvent.VK_CANCEL; + case java.awt.event.KeyEvent.VK_INSERT : return com.jogamp.newt.event.KeyEvent.VK_INSERT; + case java.awt.event.KeyEvent.VK_ESCAPE : return com.jogamp.newt.event.KeyEvent.VK_ESCAPE; + case java.awt.event.KeyEvent.VK_CONVERT : return com.jogamp.newt.event.KeyEvent.VK_CONVERT; + case java.awt.event.KeyEvent.VK_NONCONVERT : return com.jogamp.newt.event.KeyEvent.VK_NONCONVERT; + case java.awt.event.KeyEvent.VK_ACCEPT : return com.jogamp.newt.event.KeyEvent.VK_ACCEPT; + case java.awt.event.KeyEvent.VK_MODECHANGE : return com.jogamp.newt.event.KeyEvent.VK_MODECHANGE; + case java.awt.event.KeyEvent.VK_SPACE : return com.jogamp.newt.event.KeyEvent.VK_SPACE; + case java.awt.event.KeyEvent.VK_EXCLAMATION_MARK: return com.jogamp.newt.event.KeyEvent.VK_EXCLAMATION_MARK; + case java.awt.event.KeyEvent.VK_QUOTEDBL : return com.jogamp.newt.event.KeyEvent.VK_QUOTEDBL; + case java.awt.event.KeyEvent.VK_NUMBER_SIGN : return com.jogamp.newt.event.KeyEvent.VK_NUMBER_SIGN; + case java.awt.event.KeyEvent.VK_DOLLAR : return com.jogamp.newt.event.KeyEvent.VK_DOLLAR; + // case 0x25 : return com.jogamp.newt.event.KeyEvent.VK_PERCENT; + case java.awt.event.KeyEvent.VK_AMPERSAND : return com.jogamp.newt.event.KeyEvent.VK_AMPERSAND; + case java.awt.event.KeyEvent.VK_QUOTE : return com.jogamp.newt.event.KeyEvent.VK_QUOTE; + case java.awt.event.KeyEvent.VK_LEFT_PARENTHESIS : return com.jogamp.newt.event.KeyEvent.VK_LEFT_PARENTHESIS; + case java.awt.event.KeyEvent.VK_RIGHT_PARENTHESIS: return com.jogamp.newt.event.KeyEvent.VK_RIGHT_PARENTHESIS; + case java.awt.event.KeyEvent.VK_ASTERISK : return com.jogamp.newt.event.KeyEvent.VK_ASTERISK; + case java.awt.event.KeyEvent.VK_PLUS : return com.jogamp.newt.event.KeyEvent.VK_PLUS; + case java.awt.event.KeyEvent.VK_COMMA : return com.jogamp.newt.event.KeyEvent.VK_COMMA; + case java.awt.event.KeyEvent.VK_MINUS : return com.jogamp.newt.event.KeyEvent.VK_MINUS; + case java.awt.event.KeyEvent.VK_PERIOD : return com.jogamp.newt.event.KeyEvent.VK_PERIOD; + case java.awt.event.KeyEvent.VK_SLASH : return com.jogamp.newt.event.KeyEvent.VK_SLASH; + case java.awt.event.KeyEvent.VK_0 : return com.jogamp.newt.event.KeyEvent.VK_0; + case java.awt.event.KeyEvent.VK_1 : return com.jogamp.newt.event.KeyEvent.VK_1; + case java.awt.event.KeyEvent.VK_2 : return com.jogamp.newt.event.KeyEvent.VK_2; + case java.awt.event.KeyEvent.VK_3 : return com.jogamp.newt.event.KeyEvent.VK_3; + case java.awt.event.KeyEvent.VK_4 : return com.jogamp.newt.event.KeyEvent.VK_4; + case java.awt.event.KeyEvent.VK_5 : return com.jogamp.newt.event.KeyEvent.VK_5; + case java.awt.event.KeyEvent.VK_6 : return com.jogamp.newt.event.KeyEvent.VK_6; + case java.awt.event.KeyEvent.VK_7 : return com.jogamp.newt.event.KeyEvent.VK_7; + case java.awt.event.KeyEvent.VK_8 : return com.jogamp.newt.event.KeyEvent.VK_8; + case java.awt.event.KeyEvent.VK_9 : return com.jogamp.newt.event.KeyEvent.VK_9; + case java.awt.event.KeyEvent.VK_COLON : return com.jogamp.newt.event.KeyEvent.VK_COLON; + case java.awt.event.KeyEvent.VK_SEMICOLON : return com.jogamp.newt.event.KeyEvent.VK_SEMICOLON; + case java.awt.event.KeyEvent.VK_LESS : return com.jogamp.newt.event.KeyEvent.VK_LESS; + case java.awt.event.KeyEvent.VK_EQUALS : return com.jogamp.newt.event.KeyEvent.VK_EQUALS; + case java.awt.event.KeyEvent.VK_GREATER : return com.jogamp.newt.event.KeyEvent.VK_GREATER; + case 0x3f : return com.jogamp.newt.event.KeyEvent.VK_QUESTIONMARK; + case java.awt.event.KeyEvent.VK_AT : return com.jogamp.newt.event.KeyEvent.VK_AT; + case java.awt.event.KeyEvent.VK_A : return com.jogamp.newt.event.KeyEvent.VK_A; + case java.awt.event.KeyEvent.VK_B : return com.jogamp.newt.event.KeyEvent.VK_B; + case java.awt.event.KeyEvent.VK_C : return com.jogamp.newt.event.KeyEvent.VK_C; + case java.awt.event.KeyEvent.VK_D : return com.jogamp.newt.event.KeyEvent.VK_D; + case java.awt.event.KeyEvent.VK_E : return com.jogamp.newt.event.KeyEvent.VK_E; + case java.awt.event.KeyEvent.VK_F : return com.jogamp.newt.event.KeyEvent.VK_F; + case java.awt.event.KeyEvent.VK_G : return com.jogamp.newt.event.KeyEvent.VK_G; + case java.awt.event.KeyEvent.VK_H : return com.jogamp.newt.event.KeyEvent.VK_H; + case java.awt.event.KeyEvent.VK_I : return com.jogamp.newt.event.KeyEvent.VK_I; + case java.awt.event.KeyEvent.VK_J : return com.jogamp.newt.event.KeyEvent.VK_J; + case java.awt.event.KeyEvent.VK_K : return com.jogamp.newt.event.KeyEvent.VK_K; + case java.awt.event.KeyEvent.VK_L : return com.jogamp.newt.event.KeyEvent.VK_L; + case java.awt.event.KeyEvent.VK_M : return com.jogamp.newt.event.KeyEvent.VK_M; + case java.awt.event.KeyEvent.VK_N : return com.jogamp.newt.event.KeyEvent.VK_N; + case java.awt.event.KeyEvent.VK_O : return com.jogamp.newt.event.KeyEvent.VK_O; + case java.awt.event.KeyEvent.VK_P : return com.jogamp.newt.event.KeyEvent.VK_P; + case java.awt.event.KeyEvent.VK_Q : return com.jogamp.newt.event.KeyEvent.VK_Q; + case java.awt.event.KeyEvent.VK_R : return com.jogamp.newt.event.KeyEvent.VK_R; + case java.awt.event.KeyEvent.VK_S : return com.jogamp.newt.event.KeyEvent.VK_S; + case java.awt.event.KeyEvent.VK_T : return com.jogamp.newt.event.KeyEvent.VK_T; + case java.awt.event.KeyEvent.VK_U : return com.jogamp.newt.event.KeyEvent.VK_U; + case java.awt.event.KeyEvent.VK_V : return com.jogamp.newt.event.KeyEvent.VK_V; + case java.awt.event.KeyEvent.VK_W : return com.jogamp.newt.event.KeyEvent.VK_W; + case java.awt.event.KeyEvent.VK_X : return com.jogamp.newt.event.KeyEvent.VK_X; + case java.awt.event.KeyEvent.VK_Y : return com.jogamp.newt.event.KeyEvent.VK_Y; + case java.awt.event.KeyEvent.VK_Z : return com.jogamp.newt.event.KeyEvent.VK_Z; + case java.awt.event.KeyEvent.VK_OPEN_BRACKET : return com.jogamp.newt.event.KeyEvent.VK_OPEN_BRACKET; + case java.awt.event.KeyEvent.VK_BACK_SLASH : return com.jogamp.newt.event.KeyEvent.VK_BACK_SLASH; + case java.awt.event.KeyEvent.VK_CLOSE_BRACKET : return com.jogamp.newt.event.KeyEvent.VK_CLOSE_BRACKET; + case java.awt.event.KeyEvent.VK_CIRCUMFLEX : return com.jogamp.newt.event.KeyEvent.VK_CIRCUMFLEX; + case java.awt.event.KeyEvent.VK_UNDERSCORE : return com.jogamp.newt.event.KeyEvent.VK_UNDERSCORE; + case java.awt.event.KeyEvent.VK_BACK_QUOTE : return com.jogamp.newt.event.KeyEvent.VK_BACK_QUOTE; + case java.awt.event.KeyEvent.VK_F1 : return com.jogamp.newt.event.KeyEvent.VK_F1; + case java.awt.event.KeyEvent.VK_F2 : return com.jogamp.newt.event.KeyEvent.VK_F2; + case java.awt.event.KeyEvent.VK_F3 : return com.jogamp.newt.event.KeyEvent.VK_F3; + case java.awt.event.KeyEvent.VK_F4 : return com.jogamp.newt.event.KeyEvent.VK_F4; + case java.awt.event.KeyEvent.VK_F5 : return com.jogamp.newt.event.KeyEvent.VK_F5; + case java.awt.event.KeyEvent.VK_F6 : return com.jogamp.newt.event.KeyEvent.VK_F6; + case java.awt.event.KeyEvent.VK_F7 : return com.jogamp.newt.event.KeyEvent.VK_F7; + case java.awt.event.KeyEvent.VK_F8 : return com.jogamp.newt.event.KeyEvent.VK_F8; + case java.awt.event.KeyEvent.VK_F9 : return com.jogamp.newt.event.KeyEvent.VK_F9; + case java.awt.event.KeyEvent.VK_F10 : return com.jogamp.newt.event.KeyEvent.VK_F10; + case java.awt.event.KeyEvent.VK_F11 : return com.jogamp.newt.event.KeyEvent.VK_F11; + case java.awt.event.KeyEvent.VK_F12 : return com.jogamp.newt.event.KeyEvent.VK_F12; + case java.awt.event.KeyEvent.VK_F13 : return com.jogamp.newt.event.KeyEvent.VK_F13; + case java.awt.event.KeyEvent.VK_F14 : return com.jogamp.newt.event.KeyEvent.VK_F14; + case java.awt.event.KeyEvent.VK_F15 : return com.jogamp.newt.event.KeyEvent.VK_F15; + case java.awt.event.KeyEvent.VK_F16 : return com.jogamp.newt.event.KeyEvent.VK_F16; + case java.awt.event.KeyEvent.VK_F17 : return com.jogamp.newt.event.KeyEvent.VK_F17; + case java.awt.event.KeyEvent.VK_F18 : return com.jogamp.newt.event.KeyEvent.VK_F18; + case java.awt.event.KeyEvent.VK_F19 : return com.jogamp.newt.event.KeyEvent.VK_F19; + case java.awt.event.KeyEvent.VK_F20 : return com.jogamp.newt.event.KeyEvent.VK_F20; + case java.awt.event.KeyEvent.VK_F21 : return com.jogamp.newt.event.KeyEvent.VK_F21; + case java.awt.event.KeyEvent.VK_F22 : return com.jogamp.newt.event.KeyEvent.VK_F22; + case java.awt.event.KeyEvent.VK_F23 : return com.jogamp.newt.event.KeyEvent.VK_F23; + case java.awt.event.KeyEvent.VK_F24 : return com.jogamp.newt.event.KeyEvent.VK_F24; + case java.awt.event.KeyEvent.VK_BRACELEFT : return com.jogamp.newt.event.KeyEvent.VK_LEFT_BRACE; + case 0x7c : return com.jogamp.newt.event.KeyEvent.VK_PIPE; + case java.awt.event.KeyEvent.VK_BRACERIGHT : return com.jogamp.newt.event.KeyEvent.VK_RIGHT_BRACE; + case java.awt.event.KeyEvent.VK_DEAD_TILDE : return com.jogamp.newt.event.KeyEvent.VK_TILDE; + case java.awt.event.KeyEvent.VK_DELETE : return com.jogamp.newt.event.KeyEvent.VK_DELETE; + case java.awt.event.KeyEvent.VK_NUMPAD0 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD0; + case java.awt.event.KeyEvent.VK_NUMPAD1 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD1; + case java.awt.event.KeyEvent.VK_NUMPAD2 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD2; + case java.awt.event.KeyEvent.VK_NUMPAD3 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD3; + case java.awt.event.KeyEvent.VK_NUMPAD4 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD4; + case java.awt.event.KeyEvent.VK_NUMPAD5 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD5; + case java.awt.event.KeyEvent.VK_NUMPAD6 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD6; + case java.awt.event.KeyEvent.VK_NUMPAD7 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD7; + case java.awt.event.KeyEvent.VK_NUMPAD8 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD8; + case java.awt.event.KeyEvent.VK_NUMPAD9 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD9; + case java.awt.event.KeyEvent.VK_DECIMAL : return com.jogamp.newt.event.KeyEvent.VK_DECIMAL; + case java.awt.event.KeyEvent.VK_SEPARATOR : return com.jogamp.newt.event.KeyEvent.VK_SEPARATOR; + case java.awt.event.KeyEvent.VK_ADD : return com.jogamp.newt.event.KeyEvent.VK_ADD; + case java.awt.event.KeyEvent.VK_SUBTRACT : return com.jogamp.newt.event.KeyEvent.VK_SUBTRACT; + case java.awt.event.KeyEvent.VK_MULTIPLY : return com.jogamp.newt.event.KeyEvent.VK_MULTIPLY; + case java.awt.event.KeyEvent.VK_DIVIDE : return com.jogamp.newt.event.KeyEvent.VK_DIVIDE; + case java.awt.event.KeyEvent.VK_NUM_LOCK : return com.jogamp.newt.event.KeyEvent.VK_NUM_LOCK; + case java.awt.event.KeyEvent.VK_KP_LEFT : return com.jogamp.newt.event.KeyEvent.VK_KP_LEFT; + case java.awt.event.KeyEvent.VK_KP_UP : return com.jogamp.newt.event.KeyEvent.VK_KP_UP; + case java.awt.event.KeyEvent.VK_KP_RIGHT : return com.jogamp.newt.event.KeyEvent.VK_KP_RIGHT; + case java.awt.event.KeyEvent.VK_KP_DOWN : return com.jogamp.newt.event.KeyEvent.VK_KP_DOWN; + case java.awt.event.KeyEvent.VK_LEFT : return com.jogamp.newt.event.KeyEvent.VK_LEFT; + case java.awt.event.KeyEvent.VK_UP : return com.jogamp.newt.event.KeyEvent.VK_UP; + case java.awt.event.KeyEvent.VK_RIGHT : return com.jogamp.newt.event.KeyEvent.VK_RIGHT; + case java.awt.event.KeyEvent.VK_DOWN : return com.jogamp.newt.event.KeyEvent.VK_DOWN; + case java.awt.event.KeyEvent.VK_CONTEXT_MENU : return com.jogamp.newt.event.KeyEvent.VK_CONTEXT_MENU; + case java.awt.event.KeyEvent.VK_WINDOWS : return com.jogamp.newt.event.KeyEvent.VK_WINDOWS; + case java.awt.event.KeyEvent.VK_META : return com.jogamp.newt.event.KeyEvent.VK_META; + case java.awt.event.KeyEvent.VK_HELP : return com.jogamp.newt.event.KeyEvent.VK_HELP; + case java.awt.event.KeyEvent.VK_COMPOSE : return com.jogamp.newt.event.KeyEvent.VK_COMPOSE; + case java.awt.event.KeyEvent.VK_BEGIN : return com.jogamp.newt.event.KeyEvent.VK_BEGIN; + case java.awt.event.KeyEvent.VK_STOP : return com.jogamp.newt.event.KeyEvent.VK_STOP; + case java.awt.event.KeyEvent.VK_INVERTED_EXCLAMATION_MARK: return com.jogamp.newt.event.KeyEvent.VK_INVERTED_EXCLAMATION_MARK; + case java.awt.event.KeyEvent.VK_EURO_SIGN : return com.jogamp.newt.event.KeyEvent.VK_EURO_SIGN; + case java.awt.event.KeyEvent.VK_CUT : return com.jogamp.newt.event.KeyEvent.VK_CUT; + case java.awt.event.KeyEvent.VK_COPY : return com.jogamp.newt.event.KeyEvent.VK_COPY; + case java.awt.event.KeyEvent.VK_PASTE : return com.jogamp.newt.event.KeyEvent.VK_PASTE; + case java.awt.event.KeyEvent.VK_UNDO : return com.jogamp.newt.event.KeyEvent.VK_UNDO; + case java.awt.event.KeyEvent.VK_AGAIN : return com.jogamp.newt.event.KeyEvent.VK_AGAIN; + case java.awt.event.KeyEvent.VK_FIND : return com.jogamp.newt.event.KeyEvent.VK_FIND; + case java.awt.event.KeyEvent.VK_PROPS : return com.jogamp.newt.event.KeyEvent.VK_PROPS; + case java.awt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF: return com.jogamp.newt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF; + case java.awt.event.KeyEvent.VK_CODE_INPUT : return com.jogamp.newt.event.KeyEvent.VK_CODE_INPUT; + case java.awt.event.KeyEvent.VK_ROMAN_CHARACTERS: return com.jogamp.newt.event.KeyEvent.VK_ROMAN_CHARACTERS; + case java.awt.event.KeyEvent.VK_ALL_CANDIDATES: return com.jogamp.newt.event.KeyEvent.VK_ALL_CANDIDATES; + case java.awt.event.KeyEvent.VK_PREVIOUS_CANDIDATE: return com.jogamp.newt.event.KeyEvent.VK_PREVIOUS_CANDIDATE; + case java.awt.event.KeyEvent.VK_ALPHANUMERIC : return com.jogamp.newt.event.KeyEvent.VK_ALPHANUMERIC; + case java.awt.event.KeyEvent.VK_KATAKANA : return com.jogamp.newt.event.KeyEvent.VK_KATAKANA; + case java.awt.event.KeyEvent.VK_HIRAGANA : return com.jogamp.newt.event.KeyEvent.VK_HIRAGANA; + case java.awt.event.KeyEvent.VK_FULL_WIDTH : return com.jogamp.newt.event.KeyEvent.VK_FULL_WIDTH; + case java.awt.event.KeyEvent.VK_HALF_WIDTH : return com.jogamp.newt.event.KeyEvent.VK_HALF_WIDTH; + case java.awt.event.KeyEvent.VK_JAPANESE_KATAKANA: return com.jogamp.newt.event.KeyEvent.VK_JAPANESE_KATAKANA; + case java.awt.event.KeyEvent.VK_JAPANESE_HIRAGANA: return com.jogamp.newt.event.KeyEvent.VK_JAPANESE_HIRAGANA; + case java.awt.event.KeyEvent.VK_JAPANESE_ROMAN: return com.jogamp.newt.event.KeyEvent.VK_JAPANESE_ROMAN; + case java.awt.event.KeyEvent.VK_KANA_LOCK : return com.jogamp.newt.event.KeyEvent.VK_KANA_LOCK; + } + return defNEWTKeyCode; + } + + public static int newtKeyCode2AWTKeyCode(final short newtKeyCode) { + final int defAwtKeyCode = 0xFFFF & (int)newtKeyCode; + switch (newtKeyCode) { + case com.jogamp.newt.event.KeyEvent.VK_HOME : return java.awt.event.KeyEvent.VK_HOME; + case com.jogamp.newt.event.KeyEvent.VK_END : return java.awt.event.KeyEvent.VK_END; + case com.jogamp.newt.event.KeyEvent.VK_FINAL : return java.awt.event.KeyEvent.VK_FINAL; + case com.jogamp.newt.event.KeyEvent.VK_PRINTSCREEN : return java.awt.event.KeyEvent.VK_PRINTSCREEN; + case com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE : return java.awt.event.KeyEvent.VK_BACK_SPACE; + case com.jogamp.newt.event.KeyEvent.VK_TAB : return java.awt.event.KeyEvent.VK_TAB; + case com.jogamp.newt.event.KeyEvent.VK_ENTER : return java.awt.event.KeyEvent.VK_ENTER; + case com.jogamp.newt.event.KeyEvent.VK_PAGE_DOWN : return java.awt.event.KeyEvent.VK_PAGE_DOWN; + case com.jogamp.newt.event.KeyEvent.VK_CLEAR : return java.awt.event.KeyEvent.VK_CLEAR; + case com.jogamp.newt.event.KeyEvent.VK_SHIFT : return java.awt.event.KeyEvent.VK_SHIFT; + case com.jogamp.newt.event.KeyEvent.VK_PAGE_UP : return java.awt.event.KeyEvent.VK_PAGE_UP; + case com.jogamp.newt.event.KeyEvent.VK_CONTROL : return java.awt.event.KeyEvent.VK_CONTROL; + case com.jogamp.newt.event.KeyEvent.VK_ALT : return java.awt.event.KeyEvent.VK_ALT; + // FIXME: On X11 it results to 0xff7e w/ AWTRobot, which is wrong. 0xffea Alt_R is expected AFAIK. + case com.jogamp.newt.event.KeyEvent.VK_ALT_GRAPH : return java.awt.event.KeyEvent.VK_ALT_GRAPH; + case com.jogamp.newt.event.KeyEvent.VK_CAPS_LOCK : return java.awt.event.KeyEvent.VK_CAPS_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_PAUSE : return java.awt.event.KeyEvent.VK_PAUSE; + case com.jogamp.newt.event.KeyEvent.VK_SCROLL_LOCK : return java.awt.event.KeyEvent.VK_SCROLL_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_CANCEL : return java.awt.event.KeyEvent.VK_CANCEL; + case com.jogamp.newt.event.KeyEvent.VK_INSERT : return java.awt.event.KeyEvent.VK_INSERT; + case com.jogamp.newt.event.KeyEvent.VK_ESCAPE : return java.awt.event.KeyEvent.VK_ESCAPE; + case com.jogamp.newt.event.KeyEvent.VK_CONVERT : return java.awt.event.KeyEvent.VK_CONVERT; + case com.jogamp.newt.event.KeyEvent.VK_NONCONVERT : return java.awt.event.KeyEvent.VK_NONCONVERT; + case com.jogamp.newt.event.KeyEvent.VK_ACCEPT : return java.awt.event.KeyEvent.VK_ACCEPT; + case com.jogamp.newt.event.KeyEvent.VK_MODECHANGE : return java.awt.event.KeyEvent.VK_MODECHANGE; + case com.jogamp.newt.event.KeyEvent.VK_SPACE : return java.awt.event.KeyEvent.VK_SPACE; + case com.jogamp.newt.event.KeyEvent.VK_EXCLAMATION_MARK: return java.awt.event.KeyEvent.VK_EXCLAMATION_MARK; + case com.jogamp.newt.event.KeyEvent.VK_QUOTEDBL : return java.awt.event.KeyEvent.VK_QUOTEDBL; + case com.jogamp.newt.event.KeyEvent.VK_NUMBER_SIGN : return java.awt.event.KeyEvent.VK_NUMBER_SIGN; + case com.jogamp.newt.event.KeyEvent.VK_DOLLAR : return java.awt.event.KeyEvent.VK_DOLLAR; + case com.jogamp.newt.event.KeyEvent.VK_PERCENT : return defAwtKeyCode; + case com.jogamp.newt.event.KeyEvent.VK_AMPERSAND : return java.awt.event.KeyEvent.VK_AMPERSAND; + case com.jogamp.newt.event.KeyEvent.VK_QUOTE : return java.awt.event.KeyEvent.VK_QUOTE; + case com.jogamp.newt.event.KeyEvent.VK_LEFT_PARENTHESIS : return java.awt.event.KeyEvent.VK_LEFT_PARENTHESIS; + case com.jogamp.newt.event.KeyEvent.VK_RIGHT_PARENTHESIS: return java.awt.event.KeyEvent.VK_RIGHT_PARENTHESIS; + case com.jogamp.newt.event.KeyEvent.VK_ASTERISK : return java.awt.event.KeyEvent.VK_ASTERISK; + case com.jogamp.newt.event.KeyEvent.VK_PLUS : return java.awt.event.KeyEvent.VK_PLUS; + case com.jogamp.newt.event.KeyEvent.VK_COMMA : return java.awt.event.KeyEvent.VK_COMMA; + case com.jogamp.newt.event.KeyEvent.VK_MINUS : return java.awt.event.KeyEvent.VK_MINUS; + case com.jogamp.newt.event.KeyEvent.VK_PERIOD : return java.awt.event.KeyEvent.VK_PERIOD; + case com.jogamp.newt.event.KeyEvent.VK_SLASH : return java.awt.event.KeyEvent.VK_SLASH; + case com.jogamp.newt.event.KeyEvent.VK_0 : return java.awt.event.KeyEvent.VK_0; + case com.jogamp.newt.event.KeyEvent.VK_1 : return java.awt.event.KeyEvent.VK_1; + case com.jogamp.newt.event.KeyEvent.VK_2 : return java.awt.event.KeyEvent.VK_2; + case com.jogamp.newt.event.KeyEvent.VK_3 : return java.awt.event.KeyEvent.VK_3; + case com.jogamp.newt.event.KeyEvent.VK_4 : return java.awt.event.KeyEvent.VK_4; + case com.jogamp.newt.event.KeyEvent.VK_5 : return java.awt.event.KeyEvent.VK_5; + case com.jogamp.newt.event.KeyEvent.VK_6 : return java.awt.event.KeyEvent.VK_6; + case com.jogamp.newt.event.KeyEvent.VK_7 : return java.awt.event.KeyEvent.VK_7; + case com.jogamp.newt.event.KeyEvent.VK_8 : return java.awt.event.KeyEvent.VK_8; + case com.jogamp.newt.event.KeyEvent.VK_9 : return java.awt.event.KeyEvent.VK_9; + case com.jogamp.newt.event.KeyEvent.VK_COLON : return java.awt.event.KeyEvent.VK_COLON; + case com.jogamp.newt.event.KeyEvent.VK_SEMICOLON : return java.awt.event.KeyEvent.VK_SEMICOLON; + case com.jogamp.newt.event.KeyEvent.VK_LESS : return java.awt.event.KeyEvent.VK_LESS; + case com.jogamp.newt.event.KeyEvent.VK_EQUALS : return java.awt.event.KeyEvent.VK_EQUALS; + case com.jogamp.newt.event.KeyEvent.VK_GREATER : return java.awt.event.KeyEvent.VK_GREATER; + case com.jogamp.newt.event.KeyEvent.VK_QUESTIONMARK : return defAwtKeyCode; + case com.jogamp.newt.event.KeyEvent.VK_AT : return java.awt.event.KeyEvent.VK_AT; + case com.jogamp.newt.event.KeyEvent.VK_A : return java.awt.event.KeyEvent.VK_A; + case com.jogamp.newt.event.KeyEvent.VK_B : return java.awt.event.KeyEvent.VK_B; + case com.jogamp.newt.event.KeyEvent.VK_C : return java.awt.event.KeyEvent.VK_C; + case com.jogamp.newt.event.KeyEvent.VK_D : return java.awt.event.KeyEvent.VK_D; + case com.jogamp.newt.event.KeyEvent.VK_E : return java.awt.event.KeyEvent.VK_E; + case com.jogamp.newt.event.KeyEvent.VK_F : return java.awt.event.KeyEvent.VK_F; + case com.jogamp.newt.event.KeyEvent.VK_G : return java.awt.event.KeyEvent.VK_G; + case com.jogamp.newt.event.KeyEvent.VK_H : return java.awt.event.KeyEvent.VK_H; + case com.jogamp.newt.event.KeyEvent.VK_I : return java.awt.event.KeyEvent.VK_I; + case com.jogamp.newt.event.KeyEvent.VK_J : return java.awt.event.KeyEvent.VK_J; + case com.jogamp.newt.event.KeyEvent.VK_K : return java.awt.event.KeyEvent.VK_K; + case com.jogamp.newt.event.KeyEvent.VK_L : return java.awt.event.KeyEvent.VK_L; + case com.jogamp.newt.event.KeyEvent.VK_M : return java.awt.event.KeyEvent.VK_M; + case com.jogamp.newt.event.KeyEvent.VK_N : return java.awt.event.KeyEvent.VK_N; + case com.jogamp.newt.event.KeyEvent.VK_O : return java.awt.event.KeyEvent.VK_O; + case com.jogamp.newt.event.KeyEvent.VK_P : return java.awt.event.KeyEvent.VK_P; + case com.jogamp.newt.event.KeyEvent.VK_Q : return java.awt.event.KeyEvent.VK_Q; + case com.jogamp.newt.event.KeyEvent.VK_R : return java.awt.event.KeyEvent.VK_R; + case com.jogamp.newt.event.KeyEvent.VK_S : return java.awt.event.KeyEvent.VK_S; + case com.jogamp.newt.event.KeyEvent.VK_T : return java.awt.event.KeyEvent.VK_T; + case com.jogamp.newt.event.KeyEvent.VK_U : return java.awt.event.KeyEvent.VK_U; + case com.jogamp.newt.event.KeyEvent.VK_V : return java.awt.event.KeyEvent.VK_V; + case com.jogamp.newt.event.KeyEvent.VK_W : return java.awt.event.KeyEvent.VK_W; + case com.jogamp.newt.event.KeyEvent.VK_X : return java.awt.event.KeyEvent.VK_X; + case com.jogamp.newt.event.KeyEvent.VK_Y : return java.awt.event.KeyEvent.VK_Y; + case com.jogamp.newt.event.KeyEvent.VK_Z : return java.awt.event.KeyEvent.VK_Z; + case com.jogamp.newt.event.KeyEvent.VK_OPEN_BRACKET : return java.awt.event.KeyEvent.VK_OPEN_BRACKET; + case com.jogamp.newt.event.KeyEvent.VK_BACK_SLASH : return java.awt.event.KeyEvent.VK_BACK_SLASH; + case com.jogamp.newt.event.KeyEvent.VK_CLOSE_BRACKET : return java.awt.event.KeyEvent.VK_CLOSE_BRACKET; + case com.jogamp.newt.event.KeyEvent.VK_CIRCUMFLEX : return java.awt.event.KeyEvent.VK_CIRCUMFLEX; + case com.jogamp.newt.event.KeyEvent.VK_UNDERSCORE : return java.awt.event.KeyEvent.VK_UNDERSCORE; + case com.jogamp.newt.event.KeyEvent.VK_BACK_QUOTE : return java.awt.event.KeyEvent.VK_BACK_QUOTE; + case com.jogamp.newt.event.KeyEvent.VK_F1 : return java.awt.event.KeyEvent.VK_F1; + case com.jogamp.newt.event.KeyEvent.VK_F2 : return java.awt.event.KeyEvent.VK_F2; + case com.jogamp.newt.event.KeyEvent.VK_F3 : return java.awt.event.KeyEvent.VK_F3; + case com.jogamp.newt.event.KeyEvent.VK_F4 : return java.awt.event.KeyEvent.VK_F4; + case com.jogamp.newt.event.KeyEvent.VK_F5 : return java.awt.event.KeyEvent.VK_F5; + case com.jogamp.newt.event.KeyEvent.VK_F6 : return java.awt.event.KeyEvent.VK_F6; + case com.jogamp.newt.event.KeyEvent.VK_F7 : return java.awt.event.KeyEvent.VK_F7; + case com.jogamp.newt.event.KeyEvent.VK_F8 : return java.awt.event.KeyEvent.VK_F8; + case com.jogamp.newt.event.KeyEvent.VK_F9 : return java.awt.event.KeyEvent.VK_F9; + case com.jogamp.newt.event.KeyEvent.VK_F10 : return java.awt.event.KeyEvent.VK_F10; + case com.jogamp.newt.event.KeyEvent.VK_F11 : return java.awt.event.KeyEvent.VK_F11; + case com.jogamp.newt.event.KeyEvent.VK_F12 : return java.awt.event.KeyEvent.VK_F12; + case com.jogamp.newt.event.KeyEvent.VK_F13 : return java.awt.event.KeyEvent.VK_F13; + case com.jogamp.newt.event.KeyEvent.VK_F14 : return java.awt.event.KeyEvent.VK_F14; + case com.jogamp.newt.event.KeyEvent.VK_F15 : return java.awt.event.KeyEvent.VK_F15; + case com.jogamp.newt.event.KeyEvent.VK_F16 : return java.awt.event.KeyEvent.VK_F16; + case com.jogamp.newt.event.KeyEvent.VK_F17 : return java.awt.event.KeyEvent.VK_F17; + case com.jogamp.newt.event.KeyEvent.VK_F18 : return java.awt.event.KeyEvent.VK_F18; + case com.jogamp.newt.event.KeyEvent.VK_F19 : return java.awt.event.KeyEvent.VK_F19; + case com.jogamp.newt.event.KeyEvent.VK_F20 : return java.awt.event.KeyEvent.VK_F20; + case com.jogamp.newt.event.KeyEvent.VK_F21 : return java.awt.event.KeyEvent.VK_F21; + case com.jogamp.newt.event.KeyEvent.VK_F22 : return java.awt.event.KeyEvent.VK_F22; + case com.jogamp.newt.event.KeyEvent.VK_F23 : return java.awt.event.KeyEvent.VK_F23; + case com.jogamp.newt.event.KeyEvent.VK_F24 : return java.awt.event.KeyEvent.VK_F24; + case com.jogamp.newt.event.KeyEvent.VK_LEFT_BRACE : return java.awt.event.KeyEvent.VK_BRACELEFT; + case com.jogamp.newt.event.KeyEvent.VK_PIPE : return defAwtKeyCode; + case com.jogamp.newt.event.KeyEvent.VK_RIGHT_BRACE : return java.awt.event.KeyEvent.VK_BRACERIGHT; + case com.jogamp.newt.event.KeyEvent.VK_TILDE : return java.awt.event.KeyEvent.VK_DEAD_TILDE; + case com.jogamp.newt.event.KeyEvent.VK_DELETE : return java.awt.event.KeyEvent.VK_DELETE; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD0 : return java.awt.event.KeyEvent.VK_NUMPAD0; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD1 : return java.awt.event.KeyEvent.VK_NUMPAD1; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD2 : return java.awt.event.KeyEvent.VK_NUMPAD2; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD3 : return java.awt.event.KeyEvent.VK_NUMPAD3; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD4 : return java.awt.event.KeyEvent.VK_NUMPAD4; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD5 : return java.awt.event.KeyEvent.VK_NUMPAD5; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD6 : return java.awt.event.KeyEvent.VK_NUMPAD6; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD7 : return java.awt.event.KeyEvent.VK_NUMPAD7; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD8 : return java.awt.event.KeyEvent.VK_NUMPAD8; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD9 : return java.awt.event.KeyEvent.VK_NUMPAD9; + case com.jogamp.newt.event.KeyEvent.VK_DECIMAL : return java.awt.event.KeyEvent.VK_DECIMAL; + case com.jogamp.newt.event.KeyEvent.VK_SEPARATOR : return java.awt.event.KeyEvent.VK_SEPARATOR; + case com.jogamp.newt.event.KeyEvent.VK_ADD : return java.awt.event.KeyEvent.VK_ADD; + case com.jogamp.newt.event.KeyEvent.VK_SUBTRACT : return java.awt.event.KeyEvent.VK_SUBTRACT; + case com.jogamp.newt.event.KeyEvent.VK_MULTIPLY : return java.awt.event.KeyEvent.VK_MULTIPLY; + case com.jogamp.newt.event.KeyEvent.VK_DIVIDE : return java.awt.event.KeyEvent.VK_DIVIDE; + case com.jogamp.newt.event.KeyEvent.VK_NUM_LOCK : return java.awt.event.KeyEvent.VK_NUM_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_KP_LEFT : return java.awt.event.KeyEvent.VK_KP_LEFT; + case com.jogamp.newt.event.KeyEvent.VK_KP_UP : return java.awt.event.KeyEvent.VK_KP_UP; + case com.jogamp.newt.event.KeyEvent.VK_KP_RIGHT : return java.awt.event.KeyEvent.VK_KP_RIGHT; + case com.jogamp.newt.event.KeyEvent.VK_KP_DOWN : return java.awt.event.KeyEvent.VK_KP_DOWN; + case com.jogamp.newt.event.KeyEvent.VK_LEFT : return java.awt.event.KeyEvent.VK_LEFT; + case com.jogamp.newt.event.KeyEvent.VK_UP : return java.awt.event.KeyEvent.VK_UP; + case com.jogamp.newt.event.KeyEvent.VK_RIGHT : return java.awt.event.KeyEvent.VK_RIGHT; + case com.jogamp.newt.event.KeyEvent.VK_DOWN : return java.awt.event.KeyEvent.VK_DOWN; + case com.jogamp.newt.event.KeyEvent.VK_CONTEXT_MENU : return java.awt.event.KeyEvent.VK_CONTEXT_MENU; + case com.jogamp.newt.event.KeyEvent.VK_WINDOWS : return java.awt.event.KeyEvent.VK_WINDOWS; + case com.jogamp.newt.event.KeyEvent.VK_META : return java.awt.event.KeyEvent.VK_META; + case com.jogamp.newt.event.KeyEvent.VK_HELP : return java.awt.event.KeyEvent.VK_HELP; + case com.jogamp.newt.event.KeyEvent.VK_COMPOSE : return java.awt.event.KeyEvent.VK_COMPOSE; + case com.jogamp.newt.event.KeyEvent.VK_BEGIN : return java.awt.event.KeyEvent.VK_BEGIN; + case com.jogamp.newt.event.KeyEvent.VK_STOP : return java.awt.event.KeyEvent.VK_STOP; + case com.jogamp.newt.event.KeyEvent.VK_INVERTED_EXCLAMATION_MARK: return java.awt.event.KeyEvent.VK_INVERTED_EXCLAMATION_MARK; + case com.jogamp.newt.event.KeyEvent.VK_EURO_SIGN : return java.awt.event.KeyEvent.VK_EURO_SIGN; + case com.jogamp.newt.event.KeyEvent.VK_CUT : return java.awt.event.KeyEvent.VK_CUT; + case com.jogamp.newt.event.KeyEvent.VK_COPY : return java.awt.event.KeyEvent.VK_COPY; + case com.jogamp.newt.event.KeyEvent.VK_PASTE : return java.awt.event.KeyEvent.VK_PASTE; + case com.jogamp.newt.event.KeyEvent.VK_UNDO : return java.awt.event.KeyEvent.VK_UNDO; + case com.jogamp.newt.event.KeyEvent.VK_AGAIN : return java.awt.event.KeyEvent.VK_AGAIN; + case com.jogamp.newt.event.KeyEvent.VK_FIND : return java.awt.event.KeyEvent.VK_FIND; + case com.jogamp.newt.event.KeyEvent.VK_PROPS : return java.awt.event.KeyEvent.VK_PROPS; + case com.jogamp.newt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF: return java.awt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF; + case com.jogamp.newt.event.KeyEvent.VK_CODE_INPUT : return java.awt.event.KeyEvent.VK_CODE_INPUT; + case com.jogamp.newt.event.KeyEvent.VK_ROMAN_CHARACTERS: return java.awt.event.KeyEvent.VK_ROMAN_CHARACTERS; + case com.jogamp.newt.event.KeyEvent.VK_ALL_CANDIDATES: return java.awt.event.KeyEvent.VK_ALL_CANDIDATES; + case com.jogamp.newt.event.KeyEvent.VK_PREVIOUS_CANDIDATE: return java.awt.event.KeyEvent.VK_PREVIOUS_CANDIDATE; + case com.jogamp.newt.event.KeyEvent.VK_ALPHANUMERIC : return java.awt.event.KeyEvent.VK_ALPHANUMERIC; + case com.jogamp.newt.event.KeyEvent.VK_KATAKANA : return java.awt.event.KeyEvent.VK_KATAKANA; + case com.jogamp.newt.event.KeyEvent.VK_HIRAGANA : return java.awt.event.KeyEvent.VK_HIRAGANA; + case com.jogamp.newt.event.KeyEvent.VK_FULL_WIDTH : return java.awt.event.KeyEvent.VK_FULL_WIDTH; + case com.jogamp.newt.event.KeyEvent.VK_HALF_WIDTH : return java.awt.event.KeyEvent.VK_HALF_WIDTH; + case com.jogamp.newt.event.KeyEvent.VK_JAPANESE_KATAKANA: return java.awt.event.KeyEvent.VK_JAPANESE_KATAKANA; + case com.jogamp.newt.event.KeyEvent.VK_JAPANESE_HIRAGANA: return java.awt.event.KeyEvent.VK_JAPANESE_HIRAGANA; + case com.jogamp.newt.event.KeyEvent.VK_JAPANESE_ROMAN: return java.awt.event.KeyEvent.VK_JAPANESE_ROMAN; + case com.jogamp.newt.event.KeyEvent.VK_KANA_LOCK : return java.awt.event.KeyEvent.VK_KANA_LOCK; } + return defAwtKeyCode; } public static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.WindowEvent event, com.jogamp.newt.Window newtSource) { @@ -289,11 +650,11 @@ public class AWTNewtEventFactory { 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( + final short newtKeyCode = awtKeyCode2NewtKeyCode( event.getKeyCode() ); + return com.jogamp.newt.event.KeyEvent.create( newtType, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, event.getWhen(), awtModifiers2Newt(event.getModifiers(), event.getModifiersEx()), - keyCode, keyCode, event.getKeyChar()); + newtKeyCode, newtKeyCode, event.getKeyChar()); } return null; // no mapping .. } 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 4c2ed06e8..364a348ee 100644 --- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java +++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java @@ -155,7 +155,7 @@ public class AndroidNewtEventFactory { } break; } - return (short)0; + return com.jogamp.newt.event.KeyEvent.VK_UNDEFINED; } private static final int aKeyModifiers2Newt(int androidMods) { @@ -211,12 +211,12 @@ public class AndroidNewtEventFactory { } private static com.jogamp.newt.event.KeyEvent createKeyEventImpl(android.view.KeyEvent aEvent, short newtType, short newtKeyCode, com.jogamp.newt.Window newtSource) { - if( (short)0 != newtType && (short)0 != newtKeyCode ) { + if( (short)0 != newtType && com.jogamp.newt.event.KeyEvent.VK_UNDEFINED != newtKeyCode ) { final Object src = null==newtSource ? null : newtSource; final long unixTime = System.currentTimeMillis() + ( aEvent.getEventTime() - android.os.SystemClock.uptimeMillis() ); final int newtMods = aKeyModifiers2Newt(aEvent.getMetaState()); - return new com.jogamp.newt.event.KeyEvent( + return com.jogamp.newt.event.KeyEvent.create( newtType, src, unixTime, newtMods, newtKeyCode, newtKeyCode, (char) aEvent.getUnicodeChar()); } return null; diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java index ead567d82..4139951aa 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java @@ -38,7 +38,6 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.util.EDTUtil; -import jogamp.newt.DefaultEDTUtil; import jogamp.newt.DisplayImpl; public class DisplayDriver extends DisplayImpl { diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java index 2c0e6d3dd..e68b91d82 100644 --- a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java +++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java @@ -57,21 +57,21 @@ import com.jogamp.newt.event.KeyEvent; public class LinuxEventDeviceTracker implements WindowListener { - private static final LinuxEventDeviceTracker ledt; + private static final LinuxEventDeviceTracker ledt; - static { - ledt = new LinuxEventDeviceTracker(); - final Thread t = new Thread(ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager"); - t.setDaemon(true); - t.start(); - } + static { + ledt = new LinuxEventDeviceTracker(); + final Thread t = new Thread(ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager"); + t.setDaemon(true); + t.start(); + } - public static LinuxEventDeviceTracker getSingleton() { - return ledt; - } + public static LinuxEventDeviceTracker getSingleton() { + return ledt; + } - private WindowImpl focusedWindow = null; + private WindowImpl focusedWindow = null; private EventDeviceManager eventDeviceManager = new EventDeviceManager(); /* @@ -85,61 +85,63 @@ public class LinuxEventDeviceTracker implements WindowListener { And so on up to event31. */ - private EventDevicePoller[] eventDevicePollers = new EventDevicePoller[32]; - - @Override - public void windowResized(WindowEvent e) { } - - @Override - public void windowMoved(WindowEvent e) { } - - @Override - public void windowDestroyNotify(WindowEvent e) { - Object s = e.getSource(); - if(focusedWindow == s) { - focusedWindow = null; - } - } - - @Override - public void windowDestroyed(WindowEvent e) { } - - @Override - public void windowGainedFocus(WindowEvent e) { - Object s = e.getSource(); - if(s instanceof WindowImpl) { - focusedWindow = (WindowImpl) s; - } - } - - @Override - public void windowLostFocus(WindowEvent e) { - Object s = e.getSource(); - if(focusedWindow == s) { - focusedWindow = null; - } - } - - public static void main(String[] args ){ - System.setProperty("newt.debug.Window.KeyEvent", "true"); - LinuxEventDeviceTracker.getSingleton(); - try { - Thread.sleep(30000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public void windowRepaint(WindowUpdateEvent e) { } + private EventDevicePoller[] eventDevicePollers = new EventDevicePoller[32]; + + @Override + public void windowResized(WindowEvent e) { } + + @Override + public void windowMoved(WindowEvent e) { } + + @Override + public void windowDestroyNotify(WindowEvent e) { + Object s = e.getSource(); + if(focusedWindow == s) { + focusedWindow = null; + } + } + + @Override + public void windowDestroyed(WindowEvent e) { } + + @Override + public void windowGainedFocus(WindowEvent e) { + Object s = e.getSource(); + if(s instanceof WindowImpl) { + focusedWindow = (WindowImpl) s; + } + } + + @Override + public void windowLostFocus(WindowEvent e) { + Object s = e.getSource(); + if(focusedWindow == s) { + focusedWindow = null; + } + } + + public static void main(String[] args ){ + System.setProperty("newt.debug.Window.KeyEvent", "true"); + LinuxEventDeviceTracker.getSingleton(); + try { + while(true) { + Thread.sleep(1000); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void windowRepaint(WindowUpdateEvent e) { } class EventDeviceManager implements Runnable { private volatile boolean stop = false; @Override - public void run() { + public void run() { File f = new File("/dev/input/"); int number; while(!stop){ @@ -169,7 +171,7 @@ public class LinuxEventDeviceTracker implements WindowListener { } } - class EventDevicePoller implements Runnable { + class EventDevicePoller implements Runnable { private volatile boolean stop = false; private String eventDeviceName; @@ -178,713 +180,780 @@ public class LinuxEventDeviceTracker implements WindowListener { this.eventDeviceName="/dev/input/event"+eventDeviceNumber; } - @Override - public void run() { - final byte[] b = new byte[16]; - /** - * The Linux input event interface. - * http://www.kernel.org/doc/Documentation/input/input.txt - * - * struct input_event { - * struct timeval time; - * unsigned short type; - * unsigned short code; - * unsigned int value; - * }; - */ - ByteBuffer bb = ByteBuffer.wrap(b); - StructAccessor s = new StructAccessor(bb); - final File f = new File(eventDeviceName); - f.setReadOnly(); - InputStream fis; - try { - fis = new FileInputStream(f); - } catch (FileNotFoundException e) { + @Override + public void run() { + final byte[] b = new byte[16]; + /** + * The Linux input event interface. + * http://www.kernel.org/doc/Documentation/input/input.txt + * + * struct input_event { + * struct timeval time; + * unsigned short type; + * unsigned short code; + * unsigned int value; + * }; + */ + ByteBuffer bb = ByteBuffer.wrap(b); + StructAccessor s = new StructAccessor(bb); + final File f = new File(eventDeviceName); + f.setReadOnly(); + InputStream fis; + try { + fis = new FileInputStream(f); + } catch (FileNotFoundException e) { stop=true; - return; - } + return; + } - int timeSeconds; - int timeSecondFraction; - short type; - short code; - int value; + int timeSeconds; + int timeSecondFraction; + short type; + short code; + int value; - short keyCode=KeyEvent.VK_UNDEFINED; - char keyChar=' '; - short eventType=0; - int modifiers=0; + short keyCode=KeyEvent.VK_UNDEFINED; + char keyChar=' '; + short eventType=0; + int modifiers=0; loop: - while(!stop) { - int remaining=16; - while(remaining>0) { - int read = 0; - try { - read = fis.read(b, 0, remaining); - } catch (IOException e) { - stop = true; - break loop; - } - if(read<0) { - stop = true; // EOF of event device file !? - break loop; - } else { - remaining -= read; - } - } - - timeSeconds = s.getIntAt(0); - timeSecondFraction = s.getShortAt(4); - type = s.getShortAt(8); - code = s.getShortAt(10); - value = s.getIntAt(12); - - if(null != focusedWindow) { - /* - * Linux sends Keyboard events in the following order: - * EV_MSC (optional, contains scancode) - * EV_KEY - * SYN_REPORT (sent before next key) - */ - - switch(type) { - case 0: // SYN_REPORT - // Clear - eventType = 0; - keyCode = KeyEvent.VK_UNDEFINED; - keyChar = 0; // Print null for unprintable char. - modifiers = 0; - break; - case 1: // EV_KEY - keyCode = LinuxEVKey2NewtVKey(code); // The device independent code. - keyChar = NewtVKey2Unicode(keyCode); // The printable character w/o key modifiers. - switch(value) { - case 0: - modifiers=0; - eventType=KeyEvent.EVENT_KEY_RELEASED; - focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar); - break; - case 1: - eventType=KeyEvent.EVENT_KEY_PRESSED; - 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, keyCode, keyChar); - - focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar); - break; - } - break; - case 4: // EV_MSC - if(code==4) { // MSC_SCAN - // scancode ignore, linux kernel specific - // keyCode = value; - } - break; - // TODO: handle joystick events - // TODO: handle mouse events - // TODO: handle headphone/hdmi connector events - } - - if(Window.DEBUG_KEY_EVENT) { - System.out.println("[time "+timeSeconds+":"+timeSecondFraction+"] type "+type+" / code "+code+" = value "+value); - } - - } else { - if(Window.DEBUG_KEY_EVENT) { - System.out.println("[time "+timeSeconds+":"+timeSecondFraction+"] type "+type+" / code "+code+" = value "+value); - } - } - } - if(null != fis) { - try { - fis.close(); - } catch (IOException e) { - } - } + while(!stop) { + int remaining=16; + while(remaining>0) { + int read = 0; + try { + read = fis.read(b, 0, remaining); + } catch (IOException e) { + stop = true; + break loop; + } + if(read<0) { + stop = true; // EOF of event device file !? + break loop; + } else { + remaining -= read; + } + } + + timeSeconds = s.getIntAt(0); + timeSecondFraction = s.getShortAt(4); + type = s.getShortAt(8); + code = s.getShortAt(10); + value = s.getIntAt(12); + + + /* + * Linux sends Keyboard events in the following order: + * EV_MSC (optional, contains scancode) + * EV_KEY + * SYN_REPORT (sent before next key) + */ + + switch(type) { + case 0: // SYN_REPORT + // Clear + eventType = 0; + keyCode = KeyEvent.VK_UNDEFINED; + keyChar = 0; // Print null for unprintable char. + if(Window.DEBUG_KEY_EVENT) { + System.out.println("[SYN_REPORT----]"); + } + break; + case 1: // EV_KEY + keyCode = LinuxEVKey2NewtVKey(code); // The device independent code. + keyChar = NewtVKey2Unicode(keyCode, modifiers); // The printable character w/ key modifiers. + if(Window.DEBUG_KEY_EVENT) { + System.out.println("[EV_KEY: [time "+timeSeconds+":"+timeSecondFraction+"] type "+type+" / code "+code+" = value "+value); + } + + switch(value) { + case 0: + eventType=KeyEvent.EVENT_KEY_RELEASED; + + switch(keyCode) { + case KeyEvent.VK_SHIFT: + modifiers &= ~InputEvent.SHIFT_MASK; + break; + case KeyEvent.VK_ALT: + modifiers &= ~InputEvent.ALT_MASK; + break; + case KeyEvent.VK_ALT_GRAPH: + modifiers &= ~InputEvent.ALT_GRAPH_MASK; + break; + case KeyEvent.VK_CONTROL: + modifiers &= ~InputEvent.CTRL_MASK; + break; + } + + if(null != focusedWindow) { + focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar); + } + if(Window.DEBUG_KEY_EVENT) { + System.out.println("[event released] keyCode: "+keyCode+" keyChar: "+keyChar+ " modifiers: "+modifiers); + } + break; + case 1: + eventType=KeyEvent.EVENT_KEY_PRESSED; + + switch(keyCode) { + case KeyEvent.VK_SHIFT: + modifiers |= InputEvent.SHIFT_MASK; + break; + case KeyEvent.VK_ALT: + modifiers |= InputEvent.ALT_MASK; + break; + case KeyEvent.VK_ALT_GRAPH: + modifiers |= InputEvent.ALT_GRAPH_MASK; + break; + case KeyEvent.VK_CONTROL: + modifiers |= InputEvent.CTRL_MASK; + break; + } + + if(null != focusedWindow) { + focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar); + } + if(Window.DEBUG_KEY_EVENT) { + System.out.println("[event pressed] keyCode: "+keyCode+" keyChar: "+keyChar+ " modifiers: "+modifiers); + } + break; + case 2: + eventType=KeyEvent.EVENT_KEY_PRESSED; + modifiers |= InputEvent.AUTOREPEAT_MASK; + + switch(keyCode) { + case KeyEvent.VK_SHIFT: + modifiers |= InputEvent.SHIFT_MASK; + break; + case KeyEvent.VK_ALT: + modifiers |= InputEvent.ALT_MASK; + break; + case KeyEvent.VK_ALT_GRAPH: + modifiers |= InputEvent.ALT_GRAPH_MASK; + break; + case KeyEvent.VK_CONTROL: + modifiers |= InputEvent.CTRL_MASK; + break; + } + + if(null != focusedWindow) { + //Send syntetic autorepeat release + focusedWindow.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyCode, keyChar); + + focusedWindow.sendKeyEvent(eventType, modifiers, keyCode, keyCode, keyChar); + } + if(Window.DEBUG_KEY_EVENT) { + System.out.println("[event released auto] keyCode: "+keyCode+" keyChar: "+keyChar+ " modifiers: "+modifiers); + System.out.println("[event pressed auto] keyCode: "+keyCode+" keyChar: "+keyChar+ " modifiers: "+modifiers); + } + modifiers &= ~InputEvent.AUTOREPEAT_MASK; + break; + } + break; + case 4: // EV_MSC + if(code==4) { // MSC_SCAN + // scancode ignore, linux kernel specific + } + break; + // TODO: handle joystick events + // TODO: handle mouse events + // TODO: handle headphone/hdmi connector events + default: // Print number. + if(Window.DEBUG_KEY_EVENT) { + System.out.println("TODO EventDevicePoller: [time "+timeSeconds+":"+timeSecondFraction+"] type "+type+" / code "+code+" = value "+value); + } + } + } + + if(null != fis) { + try { + fis.close(); + } catch (IOException e) { + } + } stop=true; - } - - private char NewtVKey2Unicode(short VK){ - if( KeyEvent.isPrintableKey(VK) ){ - return (char)VK; - } - return 0; - } - - @SuppressWarnings("unused") + } + + private char NewtVKey2Unicode(short VK, int modifiers) { + if( KeyEvent.isPrintableKey(VK, true) ) { + if((modifiers & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) { + return (char)VK; + } else { + return String.valueOf((char)VK).toLowerCase().charAt(0); + } + } + return 0; + } + + @SuppressWarnings("unused") private char LinuxEVKey2Unicode(short EVKey) { - // This is the stuff normally mapped by a system keymap - - switch(EVKey){ - case 17: // w - return 'w'; - case 31: // s - return 's'; - case 30: // a - return 'a'; - case 32: // d - return 'd'; - case 1: // ESC - return 27; - case 28: // Enter - case 96: // Keypad Enter - return '\n'; - case 57: // Space - return ' '; - case 11: // 0 - case 82: // Numpad 0 - return '0'; - case 2: // 1 - case 79: // Numpad 1 - return '1'; - case 3: // 2 - case 80: // Numpad 1 - return '2'; - case 4: // 3 - case 81: // Numpad 3 - return '3'; - case 5: // 4 - case 75: // Numpad 4 - return '4'; - case 6: // 5 - case 76: // Numpad 5 - return '5'; - case 7: // 6 - case 77: // Numpad 6 - return '6'; - case 8: // 7 - case 71: // Numpad 7 - return '7'; - case 9: // 8 - case 72: // Numpad 8 - return '8'; - case 10: // 9 - case 73: // Numpad 9 - return '9'; - - default: - } - - return 0; - } - - private short LinuxEVKey2NewtVKey(short EVKey) { - - switch(EVKey) { - case 1: // ESC - return KeyEvent.VK_ESCAPE; - case 2: // 1 - return KeyEvent.VK_1; - case 79: // Numpad 1 - return KeyEvent.VK_NUMPAD1; - case 3: // 2 - return KeyEvent.VK_2; - case 80: // Numpad 2 - return KeyEvent.VK_NUMPAD2; - case 4: // 3 - return KeyEvent.VK_3; - case 81: // Numpad 3 - return KeyEvent.VK_NUMPAD3; - case 5: // 4 - return KeyEvent.VK_4; - case 75: // Numpad 4 - return KeyEvent.VK_NUMPAD4; - case 6: // 5 - return KeyEvent.VK_5; - case 76: // Numpad 5 - return KeyEvent.VK_NUMPAD5; - case 7: // 6 - return KeyEvent.VK_6; - case 77: // Numpad 6 - return KeyEvent.VK_NUMPAD6; - case 8: // 7 - return KeyEvent.VK_7; - case 71: // Numpad 7 - return KeyEvent.VK_NUMPAD7; - case 9: // 8 - return KeyEvent.VK_8; - case 72: // Numpad 8 - return KeyEvent.VK_NUMPAD8; - case 10: // 9 - return KeyEvent.VK_9; - case 73: // Numpad 9 - return KeyEvent.VK_NUMPAD9; - case 11: // 0 - return KeyEvent.VK_0; - case 82: // Numpad 0 - return KeyEvent.VK_NUMPAD0; - case 12: - return KeyEvent.VK_MINUS; - case 13: - return KeyEvent.VK_EQUALS; - case 14: // Backspace - return KeyEvent.VK_BACK_SPACE; - - case 15: - return KeyEvent.VK_TAB; - case 16: - return KeyEvent.VK_Q; - case 17: // w - return KeyEvent.VK_W; - case 18: - return KeyEvent.VK_E; - case 19: - return KeyEvent.VK_R; - case 20: - return KeyEvent.VK_T; - case 21: - return KeyEvent.VK_Y; - case 22: - return KeyEvent.VK_U; - case 23: - return KeyEvent.VK_I; - case 24: - return KeyEvent.VK_O; - case 25: - return KeyEvent.VK_P; - case 26: // left brace - return KeyEvent.VK_LEFT_PARENTHESIS; - case 27: // right brace - return KeyEvent.VK_RIGHT_PARENTHESIS; - case 28: // Enter - case 96: // Keypad Enter - return KeyEvent.VK_ENTER; - - case 29: // left ctrl - return KeyEvent.VK_CONTROL; - case 30: // a - return KeyEvent.VK_A; - case 31: // s - return KeyEvent.VK_S; - case 32: // d - return KeyEvent.VK_D; - case 33: - return KeyEvent.VK_F; - case 34: - return KeyEvent.VK_G; - case 35: - return KeyEvent.VK_H; - case 36: - return KeyEvent.VK_J; - case 37: - return KeyEvent.VK_K; - case 38: - return KeyEvent.VK_L; - case 39: - return KeyEvent.VK_SEMICOLON; - case 40: // apostrophe - return KeyEvent.VK_DEAD_ACUTE; - case 41: // grave - return KeyEvent.VK_DEAD_GRAVE; - - case 42: // left shift - return KeyEvent.VK_SHIFT; - case 43: - return KeyEvent.VK_BACK_SLASH; - case 44: - return KeyEvent.VK_Z; - case 45: - return KeyEvent.VK_X; - case 46: - return KeyEvent.VK_C; - case 47: - return KeyEvent.VK_V; - case 48: - return KeyEvent.VK_B; - case 49: - return KeyEvent.VK_N; - case 50: - return KeyEvent.VK_M; - case 51: - return KeyEvent.VK_COMMA; - case 52: // dot - return KeyEvent.VK_PERIOD; - case 53: - return KeyEvent.VK_SLASH; - case 54: - return KeyEvent.VK_SHIFT; - case 55: // kp asterisk - return KeyEvent.VK_ASTERISK; - case 56: // left alt - return KeyEvent.VK_ALT; - case 57: // Space - return KeyEvent.VK_SPACE; - case 58: - return KeyEvent.VK_CAPS_LOCK; - - case 59: - return KeyEvent.VK_F1; - case 60: - return KeyEvent.VK_F2; - case 61: - return KeyEvent.VK_F3; - case 62: - return KeyEvent.VK_F4; - case 63: - return KeyEvent.VK_F5; - case 64: - return KeyEvent.VK_F6; - case 65: - return KeyEvent.VK_F7; - case 66: - return KeyEvent.VK_F8; - case 67: - return KeyEvent.VK_F9; - case 68: - return KeyEvent.VK_F10; - - case 69: - return KeyEvent.VK_NUM_LOCK; - case 70: - return KeyEvent.VK_SCROLL_LOCK; - - case 74: // kp minus - return KeyEvent.VK_MINUS; - case 78: // kp plus - return KeyEvent.VK_PLUS; - case 83: // kp dot - return KeyEvent.VK_PERIOD; - - // TODO: add mappings for japanese special buttons - case 85: // zenkakuhankaku - case 86: // 102nd - break; // FIXME - - case 87: - return KeyEvent.VK_F11; - case 88: - return KeyEvent.VK_F12; - - case 89: // ro - return KeyEvent.VK_ROMAN_CHARACTERS; - case 90: // Katakana - return KeyEvent.VK_KATAKANA; - case 91: - return KeyEvent.VK_HIRAGANA; - - case 92: // kenkan - break; // FIXME - case 93: // katakana hiragana - break; // FIXME - case 94: // mu henkan - break; // FIXME - case 95: // kp jp comma - break; // FIXME - - case 97: // right ctrl - return KeyEvent.VK_CONTROL; - case 98: // kp slash - return KeyEvent.VK_SLASH; - - case 99: // sysrq - break; // FIXME - - case 100: // right alt - return KeyEvent.VK_ALT; - case 101: // linefeed - break; // FIXME - case 102: // home - return KeyEvent.VK_HOME; - case 103: // KEY_UP - return KeyEvent.VK_UP; - case 104: - return KeyEvent.VK_PAGE_UP; - case 105: // KEY_LEFT - return KeyEvent.VK_LEFT; - case 106: // KEY_RIGHT - return KeyEvent.VK_RIGHT; - case 107: - return KeyEvent.VK_END; - case 108: // KEY_DOWN - return KeyEvent.VK_DOWN; - case 109: - return KeyEvent.VK_PAGE_DOWN; - case 110: - return KeyEvent.VK_INSERT; - case 111: // del - return KeyEvent.VK_DELETE; - - case 112: // macro - break; // FIXME DEAD_MACRON? - case 113: // mute - break; // FIXME - case 114: // vol up - break; // FIXME - case 115: // vol down - break; // FIXME - case 116: // power - break; // FIXME - - case 117: // kp equals - return KeyEvent.VK_EQUALS; - case 118: // kp plus minux - break; // FIXME - case 119: // pause - return KeyEvent.VK_PAUSE; - case 120: // scale AL compiz scale expose - break; // FIXME - case 121: // kp comma - return KeyEvent.VK_COMMA; - case 122: // hangeul - break; // FIXME - case 123: // hanja - break; // FIXME - case 124: // yen - break; // FIXME - - case 125: // left meta - case 126: // right meta - return KeyEvent.VK_META; - case 127: // compose - return KeyEvent.VK_COMPOSE; - - case 128: // stop - return KeyEvent.VK_STOP; - case 129: // again - return KeyEvent.VK_AGAIN; - case 130: // properties - return KeyEvent.VK_PROPS; - case 131: // undo - return KeyEvent.VK_UNDO; - case 132: // front - break; // FIXME - case 133: // copy - return KeyEvent.VK_COPY; - case 134: // open - break; // FIXME - case 135: // paste - return KeyEvent.VK_PASTE; - case 136: // find - return KeyEvent.VK_FIND; - case 137: // cut - return KeyEvent.VK_CUT; - case 138: // help - return KeyEvent.VK_HELP; - case 139: // menu - break; // FIXME - case 140: // calc - break; // FIXME - case 141: // setup - break; // FIXME - case 142: // sleep - break; // FIXME - case 143: // wakeup - break; // FIXME - case 144: // file - break; // FIXME - case 145: // send file - break; // FIXME - case 146: // delete file - break; // FIXME - case 147: // xfer - break; // FIXME - case 148: // prog1 - break; // FIXME - case 149: // prog2 - break; // FIXME - case 150: // www - break; // FIXME - case 151: // msdos - break; // FIXME - case 152: // coffee - break; // FIXME - case 153: // direction - break; // FIXME - case 154: // cycle windows - break; // FIXME - case 155: // mail - break; // FIXME - case 156: // bookmarks - break; // FIXME - case 157: // computer - break; // FIXME - case 158: // back - break; // FIXME - case 159: // forward - break; // FIXME - case 160: // close cd - break; // FIXME - case 161: // eject cd - break; // FIXME - case 162: // eject close cd - break; // FIXME - case 163: // next song - break; // FIXME - case 164: // play pause - break; // FIXME - case 165: // previous song - break; // FIXME - case 166: // stop cd - break; // FIXME - case 167: // record - break; // FIXME - case 168: // rewind - break; // FIXME - case 169: // phone - break; // FIXME - case 170: // ISO - break; // FIXME - case 171: // config - break; // FIXME - case 172: // home page - break; // FIXME - case 173: // refresh - break; // FIXME - case 174: // exit - break; // FIXME - case 175: // move - break; // FIXME - case 176: // edit - break; // FIXME - case 177: // scroll up - break; // FIXME PAGE_UP? - case 178: // scroll down - break; // FIXME PAGE_DOWN? - case 179: // kp left paren - return KeyEvent.VK_LEFT_PARENTHESIS; - case 180: // kp right paren - return KeyEvent.VK_RIGHT_PARENTHESIS; - case 181: // new - break; // FIXME - case 182: // redo - break; // FIXME - - case 183: // F13 - return KeyEvent.VK_F13; - case 184: // F14 - return KeyEvent.VK_F14; - case 185: // F15 - return KeyEvent.VK_F15; - case 186: // F16 - return KeyEvent.VK_F16; - case 187: // F17 - return KeyEvent.VK_F17; - case 188: // F18 - return KeyEvent.VK_F18; - case 189: // F19 - return KeyEvent.VK_F19; - case 190: // F20 - return KeyEvent.VK_F20; - case 191: // F21 - return KeyEvent.VK_F21; - case 192: // F22 - return KeyEvent.VK_F22; - case 193: // F23 - return KeyEvent.VK_F23; - case 194: // F24 - return KeyEvent.VK_F24; - - case 200: // play cd - break; // FIXME - case 201: // pause cd - break; // FIXME - case 202: // prog 3 - break; // FIXME - case 203: // prog 4 - break; // FIXME - case 204: // dashboard - break; // FIXME - case 205: // suspend - break; // FIXME - case 206: // close - break; // FIXME - case 207: // play - break; // FIXME - case 208: // fast forward - break; // FIXME - case 210: // print - return KeyEvent.VK_PRINTSCREEN; // FIXME ? - case 211: // HP - break; // FIXME - case 212: // camera - break; // FIXME - case 213: // sound - break; // FIXME - case 214: // question - break; // FIXME - case 215: // email - break; // FIXME - case 216: // chat - break; // FIXME - case 217: // search - break; // FIXME - case 218: // connect - break; // FIXME - case 219: // finance - break; // FIXME - case 220: // sport - break; // FIXME - case 221: // shop - break; // FIXME - case 222: // alt erase - break; // FIXME - case 223: // cancel - break; // FIXME - case 224: // brightness down - break; // FIXME - case 225: // brightness up - break; // FIXME - case 226: // media - break; // FIXME - case 227: // switch video mode - break; // FIXME - case 228: // kb dillum toggle - break; // FIXME - case 229: // kb dillum down - break; // FIXME - case 230: // kb dillum up - break; // FIXME - case 231: // send - break; // FIXME - case 232: // reply - break; // FIXME - case 233: // forward mail - break; // FIXME - case 234: // save - break; // FIXME - case 235: // documents - break; // FIXME - case 236: // battery - break; // FIXME - case 237: // bluetooth - break; // FIXME - case 238: // wlan - break; // FIXME - case 239: // UWB - break; // FIXME - case 240: // unknown - return KeyEvent.VK_UNDEFINED; // FIXME ? - case 241: // video next - break; // FIXME - case 242: // video prev - break; // FIXME - case 243: // brightness cycle - break; // FIXME - case 244: // brightness zero - break; // FIXME - case 245: // display off - break; // FIXME - case 246: // wimax - break; // FIXME - case 247: // rf kill radio off - break; // FIXME - case 248: // mic mute - break; // FIXME - - default: - } - - if(Window.DEBUG_KEY_EVENT) { - System.out.println("LinuxEVKey2NewtVKey: Unmapped EVKey "+EVKey); - } - + // This is the stuff normally mapped by a system keymap + + switch(EVKey) { + case 17: // w + return 'w'; + case 31: // s + return 's'; + case 30: // a + return 'a'; + case 32: // d + return 'd'; + case 1: // ESC + return 27; + case 28: // Enter + case 96: // Keypad Enter + return '\n'; + case 57: // Space + return ' '; + case 11: // 0 + case 82: // Numpad 0 + return '0'; + case 2: // 1 + case 79: // Numpad 1 + return '1'; + case 3: // 2 + case 80: // Numpad 1 + return '2'; + case 4: // 3 + case 81: // Numpad 3 + return '3'; + case 5: // 4 + case 75: // Numpad 4 + return '4'; + case 6: // 5 + case 76: // Numpad 5 + return '5'; + case 7: // 6 + case 77: // Numpad 6 + return '6'; + case 8: // 7 + case 71: // Numpad 7 + return '7'; + case 9: // 8 + case 72: // Numpad 8 + return '8'; + case 10: // 9 + case 73: // Numpad 9 + return '9'; + + default: + } + + return 0; + } + + private short LinuxEVKey2NewtVKey(short EVKey) { + + switch(EVKey) { + case 1: // ESC + return KeyEvent.VK_ESCAPE; + case 2: // 1 + return KeyEvent.VK_1; + case 79: // Numpad 1 + return KeyEvent.VK_NUMPAD1; + case 3: // 2 + return KeyEvent.VK_2; + case 80: // Numpad 2 + return KeyEvent.VK_NUMPAD2; + case 4: // 3 + return KeyEvent.VK_3; + case 81: // Numpad 3 + return KeyEvent.VK_NUMPAD3; + case 5: // 4 + return KeyEvent.VK_4; + case 75: // Numpad 4 + return KeyEvent.VK_NUMPAD4; + case 6: // 5 + return KeyEvent.VK_5; + case 76: // Numpad 5 + return KeyEvent.VK_NUMPAD5; + case 7: // 6 + return KeyEvent.VK_6; + case 77: // Numpad 6 + return KeyEvent.VK_NUMPAD6; + case 8: // 7 + return KeyEvent.VK_7; + case 71: // Numpad 7 + return KeyEvent.VK_NUMPAD7; + case 9: // 8 + return KeyEvent.VK_8; + case 72: // Numpad 8 + return KeyEvent.VK_NUMPAD8; + case 10: // 9 + return KeyEvent.VK_9; + case 73: // Numpad 9 + return KeyEvent.VK_NUMPAD9; + case 11: // 0 + return KeyEvent.VK_0; + case 82: // Numpad 0 + return KeyEvent.VK_NUMPAD0; + case 12: + return KeyEvent.VK_MINUS; + case 13: + return KeyEvent.VK_EQUALS; + case 14: // Backspace + return KeyEvent.VK_BACK_SPACE; + + case 15: + return KeyEvent.VK_TAB; + case 16: + return KeyEvent.VK_Q; + case 17: // w + return KeyEvent.VK_W; + case 18: + return KeyEvent.VK_E; + case 19: + return KeyEvent.VK_R; + case 20: + return KeyEvent.VK_T; + case 21: + return KeyEvent.VK_Y; + case 22: + return KeyEvent.VK_U; + case 23: + return KeyEvent.VK_I; + case 24: + return KeyEvent.VK_O; + case 25: + return KeyEvent.VK_P; + case 26: // left brace + return KeyEvent.VK_LEFT_PARENTHESIS; + case 27: // right brace + return KeyEvent.VK_RIGHT_PARENTHESIS; + case 28: // Enter + case 96: // Keypad Enter + return KeyEvent.VK_ENTER; + + case 29: // left ctrl + return KeyEvent.VK_CONTROL; + case 30: // a + return KeyEvent.VK_A; + case 31: // s + return KeyEvent.VK_S; + case 32: // d + return KeyEvent.VK_D; + case 33: + return KeyEvent.VK_F; + case 34: + return KeyEvent.VK_G; + case 35: + return KeyEvent.VK_H; + case 36: + return KeyEvent.VK_J; + case 37: + return KeyEvent.VK_K; + case 38: + return KeyEvent.VK_L; + case 39: + return KeyEvent.VK_SEMICOLON; + case 40: // apostrophe + return KeyEvent.VK_QUOTE; + case 41: // grave + return KeyEvent.VK_BACK_QUOTE; + + case 42: // left shift + return KeyEvent.VK_SHIFT; + case 43: + return KeyEvent.VK_BACK_SLASH; + case 44: + return KeyEvent.VK_Z; + case 45: + return KeyEvent.VK_X; + case 46: + return KeyEvent.VK_C; + case 47: + return KeyEvent.VK_V; + case 48: + return KeyEvent.VK_B; + case 49: + return KeyEvent.VK_N; + case 50: + return KeyEvent.VK_M; + case 51: + return KeyEvent.VK_COMMA; + case 52: // dot + return KeyEvent.VK_PERIOD; + case 53: + return KeyEvent.VK_SLASH; + case 54: + return KeyEvent.VK_SHIFT; + case 55: // kp asterisk + return KeyEvent.VK_ASTERISK; + case 56: // left alt + return KeyEvent.VK_ALT; + case 57: // Space + return KeyEvent.VK_SPACE; + case 58: + return KeyEvent.VK_CAPS_LOCK; + + case 59: + return KeyEvent.VK_F1; + case 60: + return KeyEvent.VK_F2; + case 61: + return KeyEvent.VK_F3; + case 62: + return KeyEvent.VK_F4; + case 63: + return KeyEvent.VK_F5; + case 64: + return KeyEvent.VK_F6; + case 65: + return KeyEvent.VK_F7; + case 66: + return KeyEvent.VK_F8; + case 67: + return KeyEvent.VK_F9; + case 68: + return KeyEvent.VK_F10; + + case 69: + return KeyEvent.VK_NUM_LOCK; + case 70: + return KeyEvent.VK_SCROLL_LOCK; + + case 74: // kp minus + return KeyEvent.VK_MINUS; + case 78: // kp plus + return KeyEvent.VK_PLUS; + case 83: // kp dot + return KeyEvent.VK_PERIOD; + + // TODO: add mappings for japanese special buttons + case 85: // zenkakuhankaku + case 86: // 102nd + break; // FIXME + + case 87: + return KeyEvent.VK_F11; + case 88: + return KeyEvent.VK_F12; + + case 89: // ro + return KeyEvent.VK_ROMAN_CHARACTERS; + case 90: // Katakana + return KeyEvent.VK_KATAKANA; + case 91: + return KeyEvent.VK_HIRAGANA; + + case 92: // kenkan + break; // FIXME + case 93: // katakana hiragana + break; // FIXME + case 94: // mu henkan + break; // FIXME + case 95: // kp jp comma + break; // FIXME + + case 97: // right ctrl + return KeyEvent.VK_CONTROL; + case 98: // kp slash + return KeyEvent.VK_SLASH; + + case 99: // sysrq + break; // FIXME + + case 100: // right alt + return KeyEvent.VK_ALT; + case 101: // linefeed + break; // FIXME + case 102: // home + return KeyEvent.VK_HOME; + case 103: // KEY_UP + return KeyEvent.VK_UP; + case 104: + return KeyEvent.VK_PAGE_UP; + case 105: // KEY_LEFT + return KeyEvent.VK_LEFT; + case 106: // KEY_RIGHT + return KeyEvent.VK_RIGHT; + case 107: + return KeyEvent.VK_END; + case 108: // KEY_DOWN + return KeyEvent.VK_DOWN; + case 109: + return KeyEvent.VK_PAGE_DOWN; + case 110: + return KeyEvent.VK_INSERT; + case 111: // del + return KeyEvent.VK_DELETE; + + case 112: // macro + break; // FIXME DEAD_MACRON? + case 113: // mute + break; // FIXME + case 114: // vol up + break; // FIXME + case 115: // vol down + break; // FIXME + case 116: // power + break; // FIXME + + case 117: // kp equals + return KeyEvent.VK_EQUALS; + case 118: // kp plus minux + break; // FIXME + case 119: // pause + return KeyEvent.VK_PAUSE; + case 120: // scale AL compiz scale expose + break; // FIXME + case 121: // kp comma + return KeyEvent.VK_COMMA; + case 122: // hangeul + break; // FIXME + case 123: // hanja + break; // FIXME + case 124: // yen + break; // FIXME + + case 125: // left meta + case 126: // right meta + return KeyEvent.VK_META; + case 127: // compose + return KeyEvent.VK_COMPOSE; + + case 128: // stop + return KeyEvent.VK_STOP; + case 129: // again + return KeyEvent.VK_AGAIN; + case 130: // properties + return KeyEvent.VK_PROPS; + case 131: // undo + return KeyEvent.VK_UNDO; + case 132: // front + break; // FIXME + case 133: // copy + return KeyEvent.VK_COPY; + case 134: // open + break; // FIXME + case 135: // paste + return KeyEvent.VK_PASTE; + case 136: // find + return KeyEvent.VK_FIND; + case 137: // cut + return KeyEvent.VK_CUT; + case 138: // help + return KeyEvent.VK_HELP; + case 139: // menu + break; // FIXME + case 140: // calc + break; // FIXME + case 141: // setup + break; // FIXME + case 142: // sleep + break; // FIXME + case 143: // wakeup + break; // FIXME + case 144: // file + break; // FIXME + case 145: // send file + break; // FIXME + case 146: // delete file + break; // FIXME + case 147: // xfer + break; // FIXME + case 148: // prog1 + break; // FIXME + case 149: // prog2 + break; // FIXME + case 150: // www + break; // FIXME + case 151: // msdos + break; // FIXME + case 152: // coffee + break; // FIXME + case 153: // direction + break; // FIXME + case 154: // cycle windows + break; // FIXME + case 155: // mail + break; // FIXME + case 156: // bookmarks + break; // FIXME + case 157: // computer + break; // FIXME + case 158: // back + break; // FIXME + case 159: // forward + break; // FIXME + case 160: // close cd + break; // FIXME + case 161: // eject cd + break; // FIXME + case 162: // eject close cd + break; // FIXME + case 163: // next song + break; // FIXME + case 164: // play pause + break; // FIXME + case 165: // previous song + break; // FIXME + case 166: // stop cd + break; // FIXME + case 167: // record + break; // FIXME + case 168: // rewind + break; // FIXME + case 169: // phone + break; // FIXME + case 170: // ISO + break; // FIXME + case 171: // config + break; // FIXME + case 172: // home page + break; // FIXME + case 173: // refresh + break; // FIXME + case 174: // exit + break; // FIXME + case 175: // move + break; // FIXME + case 176: // edit + break; // FIXME + case 177: // scroll up + break; // FIXME PAGE_UP? + case 178: // scroll down + break; // FIXME PAGE_DOWN? + case 179: // kp left paren + return KeyEvent.VK_LEFT_PARENTHESIS; + case 180: // kp right paren + return KeyEvent.VK_RIGHT_PARENTHESIS; + case 181: // new + break; // FIXME + case 182: // redo + break; // FIXME + + case 183: // F13 + return KeyEvent.VK_F13; + case 184: // F14 + return KeyEvent.VK_F14; + case 185: // F15 + return KeyEvent.VK_F15; + case 186: // F16 + return KeyEvent.VK_F16; + case 187: // F17 + return KeyEvent.VK_F17; + case 188: // F18 + return KeyEvent.VK_F18; + case 189: // F19 + return KeyEvent.VK_F19; + case 190: // F20 + return KeyEvent.VK_F20; + case 191: // F21 + return KeyEvent.VK_F21; + case 192: // F22 + return KeyEvent.VK_F22; + case 193: // F23 + return KeyEvent.VK_F23; + case 194: // F24 + return KeyEvent.VK_F24; + + case 200: // play cd + break; // FIXME + case 201: // pause cd + break; // FIXME + case 202: // prog 3 + break; // FIXME + case 203: // prog 4 + break; // FIXME + case 204: // dashboard + break; // FIXME + case 205: // suspend + break; // FIXME + case 206: // close + break; // FIXME + case 207: // play + break; // FIXME + case 208: // fast forward + break; // FIXME + case 210: // print + return KeyEvent.VK_PRINTSCREEN; // FIXME ? + case 211: // HP + break; // FIXME + case 212: // camera + break; // FIXME + case 213: // sound + break; // FIXME + case 214: // question + break; // FIXME + case 215: // email + break; // FIXME + case 216: // chat + break; // FIXME + case 217: // search + break; // FIXME + case 218: // connect + break; // FIXME + case 219: // finance + break; // FIXME + case 220: // sport + break; // FIXME + case 221: // shop + break; // FIXME + case 222: // alt erase + break; // FIXME + case 223: // cancel + break; // FIXME + case 224: // brightness down + break; // FIXME + case 225: // brightness up + break; // FIXME + case 226: // media + break; // FIXME + case 227: // switch video mode + break; // FIXME + case 228: // kb dillum toggle + break; // FIXME + case 229: // kb dillum down + break; // FIXME + case 230: // kb dillum up + break; // FIXME + case 231: // send + break; // FIXME + case 232: // reply + break; // FIXME + case 233: // forward mail + break; // FIXME + case 234: // save + break; // FIXME + case 235: // documents + break; // FIXME + case 236: // battery + break; // FIXME + case 237: // bluetooth + break; // FIXME + case 238: // wlan + break; // FIXME + case 239: // UWB + break; // FIXME + case 240: // unknown + return KeyEvent.VK_UNDEFINED; + case 241: // video next + break; // FIXME + case 242: // video prev + break; // FIXME + case 243: // brightness cycle + break; // FIXME + case 244: // brightness zero + break; // FIXME + case 245: // display off + break; // FIXME + case 246: // wimax + break; // FIXME + case 247: // rf kill radio off + break; // FIXME + case 248: // mic mute + break; // FIXME + + default: + } + + if(Window.DEBUG_KEY_EVENT) { + System.out.println("TODO LinuxEVKey2NewtVKey: Unmapped EVKey "+EVKey); + } + return KeyEvent.VK_UNDEFINED; - } - } + } + } } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java index c07576901..baa94facd 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java @@ -317,7 +317,7 @@ public class MacKeyUtil { case kVK_Option: return KeyEvent.VK_ALT; case kVK_Control: return KeyEvent.VK_CONTROL; case kVK_RightShift: return KeyEvent.VK_SHIFT; - case kVK_RightOption: return KeyEvent.VK_ALT; + case kVK_RightOption: return KeyEvent.VK_ALT_GRAPH; case kVK_RightControl: return KeyEvent.VK_CONTROL; // case kVK_Function: return KeyEvent.VK_F; case kVK_F17: return KeyEvent.VK_F17; diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index 965138ddf..bb72350e3 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -401,14 +401,26 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } @Override - public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short _keyCode, short keySym, char 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"); + } + + protected final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short _keyCode, char keyChar, char keySymChar) { // 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 short keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar); + final short keySym; + { + short _keySym = KeyEvent.NULL_CHAR != keySymChar ? KeyEvent.utf16ToVKey(keySymChar) : KeyEvent.VK_UNDEFINED; + keySym = KeyEvent.VK_UNDEFINED != _keySym ? _keySym : keyCode; + } /* { 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); + System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+ + ", keyCode 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+ + ", keySymChar '"+keySymChar+"', 0x"+Integer.toHexString(keySymChar)+" -> 0x"+Integer.toHexString(keySym)+ + ", mods "+toHexString(modifiers)+ + ", was: pressed "+isKeyPressed(keyCode)+", isModifierKeyCode "+isModifierKeyCode); } */ // 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED @@ -416,22 +428,20 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl switch(eventType) { case KeyEvent.EVENT_KEY_RELEASED: if( isKeyCodeTracked(keyCode) ) { - keyRepeatState.put(keyCode, false); // prev == true -> AR out - keyPressedState.put(keyCode, false); + setKeyPressed(keyCode, false); } break; case KeyEvent.EVENT_KEY_PRESSED: if( isKeyCodeTracked(keyCode) ) { - if( keyPressedState.put(keyCode, true) ) { + if( setKeyPressed(keyCode, true) ) { // key was already pressed - keyRepeatState.put(keyCode, true); // prev == false -> AR in modifiers |= InputEvent.AUTOREPEAT_MASK; - super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyCode, keyChar); // RELEASED + super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar); // RELEASED } } break; } - super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyCode, keyChar); + super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keySym, keyChar); } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index e7a8d5a33..ad7e1e8f3 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -261,13 +261,17 @@ public class WindowDriver extends WindowImpl { // nop - using event driven insetsChange(..) } + private short repeatedKey = KeyEvent.VK_UNDEFINED; + 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( setKeyPressed(keyCode, true) ) { + // AR: Key was already pressed: Either [enter | within] AR mode + final boolean withinAR = repeatedKey == keyCode; + repeatedKey = keyCode; if( !isModifierKey ) { // AR: Key was already pressed: Either [enter | within] AR mode modifiers |= InputEvent.AUTOREPEAT_MASK; - if( preKeyRepeatState ) { + if( withinAR ) { // 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 } @@ -289,11 +293,12 @@ public class WindowDriver extends WindowImpl { switch(eventType) { case KeyEvent.EVENT_KEY_RELEASED: if( isKeyCodeTracked(keyCode) ) { - if( keyRepeatState.put(keyCode, false) && !isModifierKey ) { + if( repeatedKey == keyCode && !isModifierKey ) { // AR out - send out missing PRESSED super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keySym, keyChar); } - keyPressedState.put(keyCode, false); + setKeyPressed(keyCode, false); + repeatedKey = KeyEvent.VK_UNDEFINED; } super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar); break; diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index f3a548a08..4fe025ec4 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -91,9 +91,10 @@ public class DisplayDriver extends DisplayImpl { @Override protected void closeNativeImpl() { - DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom); + DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now javaObjectAtom = 0; windowDeleteAtom = 0; + // kbdHandle = 0; aDevice.close(); // closes X11 display } @@ -103,7 +104,7 @@ public class DisplayDriver extends DisplayImpl { try { final long handle = aDevice.getHandle(); if(0 != handle) { - DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom); + DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now } } finally { if(null != aDevice) { // could be pulled by destroy event @@ -114,6 +115,7 @@ public class DisplayDriver extends DisplayImpl { protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } + // protected long getKbdHandle() { return kbdHandle; } // XKB disabled for now /** Returns <code>null</code> if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } @@ -126,18 +128,22 @@ public class DisplayDriver extends DisplayImpl { private native void CompleteDisplay0(long handle); - private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) { + private void displayCompleted(long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */) { this.javaObjectAtom=javaObjectAtom; this.windowDeleteAtom=windowDeleteAtom; + // this.kbdHandle = kbdHandle; // XKB disabled for now } - private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom); + private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */); // XKB disabled for now - private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom); + private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now /** X11 Window delete atom marker used on EDT */ private long windowDeleteAtom; /** X11 Window java object property used on EDT */ private long javaObjectAtom; + + /** X11 Keyboard handle used on EDT */ + // private long kbdHandle; // XKB disabled for now } diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 8d33d4d73..666d0cb5b 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -116,7 +116,7 @@ public class WindowDriver extends WindowImpl { edtDevice.lock(); try { CloseWindow0(edtDevice.getHandle(), windowHandleClose, - display.getJavaObjectAtom(), display.getWindowDeleteAtom()); + display.getJavaObjectAtom(), display.getWindowDeleteAtom() /* , display.getKbdHandle() */); // XKB disabled for now } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); @@ -271,13 +271,13 @@ 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) { + protected final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar0, String keyString) { // 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()); + final char keyChar = ( null != keyString ) ? keyString.charAt(0) : keyChar0; + // System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar0+">/<"+keyChar+">, keyString "+keyString+", mods "+toHexString(modifiers)+ + // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isAutoRepeat+", [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis()); if( !isAutoRepeat || !isModifierKey ) { // ! ( isModifierKey && isAutoRepeat ) switch(eventType) { @@ -296,6 +296,10 @@ public class WindowDriver extends WindowImpl { } @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"); + } + @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"); } @@ -315,7 +319,7 @@ public class WindowDriver extends WindowImpl { private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, int visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height, boolean autoPosition, int flags); - private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); + private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle*/ ); // XKB disabled for now private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, long windowDeleteAtom, int x, int y, int width, int height, int flags); private native void requestFocus0(long display, long windowHandle, boolean force); diff --git a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java index 1ebb714fa..5e240636d 100644 --- a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java +++ b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java @@ -68,6 +68,141 @@ public class SWTNewtEventFactory { return newtMods; } + public static short swtKeyCode2NewtKeyCode(final int swtKeyCode) { + final short defNEWTKeyCode = (short)swtKeyCode; + switch (swtKeyCode) { + case SWT.HOME : return com.jogamp.newt.event.KeyEvent.VK_HOME; + case SWT.END : return com.jogamp.newt.event.KeyEvent.VK_END; + case SWT.PRINT_SCREEN : return com.jogamp.newt.event.KeyEvent.VK_PRINTSCREEN; + case SWT.BS : return com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE; + case SWT.TAB : return com.jogamp.newt.event.KeyEvent.VK_TAB; + case SWT.LF : return com.jogamp.newt.event.KeyEvent.VK_ENTER; + case SWT.PAGE_DOWN : return com.jogamp.newt.event.KeyEvent.VK_PAGE_DOWN; + case SWT.PAGE_UP : return com.jogamp.newt.event.KeyEvent.VK_PAGE_UP; + case SWT.CONTROL : return com.jogamp.newt.event.KeyEvent.VK_CONTROL; + case SWT.CAPS_LOCK : return com.jogamp.newt.event.KeyEvent.VK_CAPS_LOCK; + case SWT.PAUSE : return com.jogamp.newt.event.KeyEvent.VK_PAUSE; + case SWT.SCROLL_LOCK : return com.jogamp.newt.event.KeyEvent.VK_SCROLL_LOCK; + case SWT.CANCEL : return com.jogamp.newt.event.KeyEvent.VK_CANCEL; + case SWT.INSERT : return com.jogamp.newt.event.KeyEvent.VK_INSERT; + case SWT.ESC : return com.jogamp.newt.event.KeyEvent.VK_ESCAPE; + case SWT.SPACE : return com.jogamp.newt.event.KeyEvent.VK_SPACE; + case SWT.F1 : return com.jogamp.newt.event.KeyEvent.VK_F1; + case SWT.F2 : return com.jogamp.newt.event.KeyEvent.VK_F2; + case SWT.F3 : return com.jogamp.newt.event.KeyEvent.VK_F3; + case SWT.F4 : return com.jogamp.newt.event.KeyEvent.VK_F4; + case SWT.F5 : return com.jogamp.newt.event.KeyEvent.VK_F5; + case SWT.F6 : return com.jogamp.newt.event.KeyEvent.VK_F6; + case SWT.F7 : return com.jogamp.newt.event.KeyEvent.VK_F7; + case SWT.F8 : return com.jogamp.newt.event.KeyEvent.VK_F8; + case SWT.F9 : return com.jogamp.newt.event.KeyEvent.VK_F9; + case SWT.F10 : return com.jogamp.newt.event.KeyEvent.VK_F10; + case SWT.F11 : return com.jogamp.newt.event.KeyEvent.VK_F11; + case SWT.F12 : return com.jogamp.newt.event.KeyEvent.VK_F12; + case SWT.F13 : return com.jogamp.newt.event.KeyEvent.VK_F13; + case SWT.F14 : return com.jogamp.newt.event.KeyEvent.VK_F14; + case SWT.F15 : return com.jogamp.newt.event.KeyEvent.VK_F15; + case SWT.F16 : return com.jogamp.newt.event.KeyEvent.VK_F16; + case SWT.F17 : return com.jogamp.newt.event.KeyEvent.VK_F17; + case SWT.F18 : return com.jogamp.newt.event.KeyEvent.VK_F18; + case SWT.F19 : return com.jogamp.newt.event.KeyEvent.VK_F19; + case SWT.F20 : return com.jogamp.newt.event.KeyEvent.VK_F20; + case SWT.DEL : return com.jogamp.newt.event.KeyEvent.VK_DELETE; + case SWT.KEYPAD_0 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD0; + case SWT.KEYPAD_1 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD1; + case SWT.KEYPAD_2 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD2; + case SWT.KEYPAD_3 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD3; + case SWT.KEYPAD_4 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD4; + case SWT.KEYPAD_5 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD5; + case SWT.KEYPAD_6 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD6; + case SWT.KEYPAD_7 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD7; + case SWT.KEYPAD_8 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD8; + case SWT.KEYPAD_9 : return com.jogamp.newt.event.KeyEvent.VK_NUMPAD9; + case SWT.KEYPAD_DECIMAL: return com.jogamp.newt.event.KeyEvent.VK_DECIMAL; + case SWT.KEYPAD_ADD : return com.jogamp.newt.event.KeyEvent.VK_ADD; + case SWT.KEYPAD_SUBTRACT: return com.jogamp.newt.event.KeyEvent.VK_SUBTRACT; + case SWT.KEYPAD_MULTIPLY: return com.jogamp.newt.event.KeyEvent.VK_MULTIPLY; + case SWT.KEYPAD_DIVIDE : return com.jogamp.newt.event.KeyEvent.VK_DIVIDE; + case SWT.NUM_LOCK : return com.jogamp.newt.event.KeyEvent.VK_NUM_LOCK; + case SWT.ARROW_LEFT : return com.jogamp.newt.event.KeyEvent.VK_LEFT; + case SWT.ARROW_UP : return com.jogamp.newt.event.KeyEvent.VK_UP; + case SWT.ARROW_RIGHT : return com.jogamp.newt.event.KeyEvent.VK_RIGHT; + case SWT.ARROW_DOWN : return com.jogamp.newt.event.KeyEvent.VK_DOWN; + case SWT.HELP : return com.jogamp.newt.event.KeyEvent.VK_HELP; + } + return defNEWTKeyCode; + } + + public static int newtKeyCode2SWTKeyCode(final short newtKeyCode) { + final int defSWTKeyCode = 0xFFFF & (int)newtKeyCode; + switch (newtKeyCode) { + case com.jogamp.newt.event.KeyEvent.VK_HOME : return SWT.HOME; + case com.jogamp.newt.event.KeyEvent.VK_END : return SWT.END; + case com.jogamp.newt.event.KeyEvent.VK_PRINTSCREEN : return SWT.PRINT_SCREEN; + case com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE : return SWT.BS; + case com.jogamp.newt.event.KeyEvent.VK_TAB : return SWT.TAB; + case com.jogamp.newt.event.KeyEvent.VK_ENTER : return SWT.LF; + case com.jogamp.newt.event.KeyEvent.VK_PAGE_DOWN : return SWT.PAGE_DOWN; + case com.jogamp.newt.event.KeyEvent.VK_PAGE_UP : return SWT.PAGE_UP; + case com.jogamp.newt.event.KeyEvent.VK_CONTROL : return SWT.CONTROL; + case com.jogamp.newt.event.KeyEvent.VK_CAPS_LOCK : return SWT.CAPS_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_PAUSE : return SWT.PAUSE; + case com.jogamp.newt.event.KeyEvent.VK_SCROLL_LOCK : return SWT.SCROLL_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_CANCEL : return SWT.CANCEL; + case com.jogamp.newt.event.KeyEvent.VK_INSERT : return SWT.INSERT; + case com.jogamp.newt.event.KeyEvent.VK_ESCAPE : return SWT.ESC; + case com.jogamp.newt.event.KeyEvent.VK_SPACE : return SWT.SPACE; + case com.jogamp.newt.event.KeyEvent.VK_F1 : return SWT.F1; + case com.jogamp.newt.event.KeyEvent.VK_F2 : return SWT.F2; + case com.jogamp.newt.event.KeyEvent.VK_F3 : return SWT.F3; + case com.jogamp.newt.event.KeyEvent.VK_F4 : return SWT.F4; + case com.jogamp.newt.event.KeyEvent.VK_F5 : return SWT.F5; + case com.jogamp.newt.event.KeyEvent.VK_F6 : return SWT.F6; + case com.jogamp.newt.event.KeyEvent.VK_F7 : return SWT.F7; + case com.jogamp.newt.event.KeyEvent.VK_F8 : return SWT.F8; + case com.jogamp.newt.event.KeyEvent.VK_F9 : return SWT.F9; + case com.jogamp.newt.event.KeyEvent.VK_F10 : return SWT.F10; + case com.jogamp.newt.event.KeyEvent.VK_F11 : return SWT.F11; + case com.jogamp.newt.event.KeyEvent.VK_F12 : return SWT.F12; + case com.jogamp.newt.event.KeyEvent.VK_F13 : return SWT.F13; + case com.jogamp.newt.event.KeyEvent.VK_F14 : return SWT.F14; + case com.jogamp.newt.event.KeyEvent.VK_F15 : return SWT.F15; + case com.jogamp.newt.event.KeyEvent.VK_F16 : return SWT.F16; + case com.jogamp.newt.event.KeyEvent.VK_F17 : return SWT.F17; + case com.jogamp.newt.event.KeyEvent.VK_F18 : return SWT.F18; + case com.jogamp.newt.event.KeyEvent.VK_F19 : return SWT.F19; + case com.jogamp.newt.event.KeyEvent.VK_F20 : return SWT.F20; + case com.jogamp.newt.event.KeyEvent.VK_DELETE : return SWT.DEL; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD0 : return SWT.KEYPAD_0; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD1 : return SWT.KEYPAD_1; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD2 : return SWT.KEYPAD_2; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD3 : return SWT.KEYPAD_3; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD4 : return SWT.KEYPAD_4; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD5 : return SWT.KEYPAD_5; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD6 : return SWT.KEYPAD_6; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD7 : return SWT.KEYPAD_7; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD8 : return SWT.KEYPAD_8; + case com.jogamp.newt.event.KeyEvent.VK_NUMPAD9 : return SWT.KEYPAD_9; + case com.jogamp.newt.event.KeyEvent.VK_DECIMAL : return SWT.KEYPAD_DECIMAL; + case com.jogamp.newt.event.KeyEvent.VK_ADD : return SWT.KEYPAD_ADD; + case com.jogamp.newt.event.KeyEvent.VK_SUBTRACT : return SWT.KEYPAD_SUBTRACT; + case com.jogamp.newt.event.KeyEvent.VK_MULTIPLY : return SWT.KEYPAD_MULTIPLY; + case com.jogamp.newt.event.KeyEvent.VK_DIVIDE : return SWT.KEYPAD_DIVIDE; + case com.jogamp.newt.event.KeyEvent.VK_NUM_LOCK : return SWT.NUM_LOCK; + case com.jogamp.newt.event.KeyEvent.VK_KP_LEFT : + case com.jogamp.newt.event.KeyEvent.VK_LEFT : return SWT.ARROW_LEFT; + case com.jogamp.newt.event.KeyEvent.VK_KP_UP : + case com.jogamp.newt.event.KeyEvent.VK_UP : return SWT.ARROW_UP; + case com.jogamp.newt.event.KeyEvent.VK_KP_RIGHT : + case com.jogamp.newt.event.KeyEvent.VK_RIGHT : return SWT.ARROW_RIGHT; + case com.jogamp.newt.event.KeyEvent.VK_KP_DOWN : + case com.jogamp.newt.event.KeyEvent.VK_DOWN : return SWT.ARROW_DOWN; + case com.jogamp.newt.event.KeyEvent.VK_HELP : return SWT.HELP; + } + return defSWTKeyCode; + } + + public static final com.jogamp.newt.event.InputEvent createInputEvent(org.eclipse.swt.widgets.Event event, Object source) { com.jogamp.newt.event.InputEvent res = createMouseEvent(event, source); if(null == res) { @@ -126,10 +261,11 @@ public class SWTNewtEventFactory { } final short type = eventTypeSWT2NEWT(event.type); if( (short)0 != type ) { - return new com.jogamp.newt.event.KeyEvent( + final short newtKeyCode = swtKeyCode2NewtKeyCode( event.keyCode ); + return com.jogamp.newt.event.KeyEvent.create( type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time), swtModifiers2Newt(event.stateMask, false), - (short)event.keyCode, (short)event.keyCode, event.character); + newtKeyCode, newtKeyCode, event.character); } return null; // no mapping .. } diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h index 0f7b1606b..7a63b19ce 100644 --- a/src/newt/native/KeyEvent.h +++ b/src/newt/native/KeyEvent.h @@ -33,195 +33,206 @@ #define EVENT_KEY_RELEASED 301 #define EVENT_KEY_TYPED 302 -#define J_CHAR_UNDEFINED 0xFFFF; -#define J_VK_ENTER '\n' -#define J_VK_BACK_SPACE '\b' -#define J_VK_TAB '\t' -#define J_VK_CANCEL 0x03 -#define J_VK_CLEAR 0x0C -#define J_VK_SHIFT 0x10 -#define J_VK_CONTROL 0x11 -#define J_VK_ALT 0x12 -#define J_VK_PAUSE 0x13 -#define J_VK_CAPS_LOCK 0x14 -#define J_VK_ESCAPE 0x1B -#define J_VK_SPACE 0x20 -#define J_VK_PAGE_UP 0x21 -#define J_VK_PAGE_DOWN 0x22 -#define J_VK_END 0x23 -#define J_VK_HOME 0x24 -#define J_VK_LEFT 0x25 -#define J_VK_UP 0x26 -#define J_VK_RIGHT 0x27 -#define J_VK_DOWN 0x28 -#define J_VK_COMMA 0x2C -#define J_VK_MINUS 0x2D -#define J_VK_PERIOD 0x2E -#define J_VK_SLASH 0x2F -#define J_VK_0 0x30 -#define J_VK_1 0x31 -#define J_VK_2 0x32 -#define J_VK_3 0x33 -#define J_VK_4 0x34 -#define J_VK_5 0x35 -#define J_VK_6 0x36 -#define J_VK_7 0x37 -#define J_VK_8 0x38 -#define J_VK_9 0x39 -#define J_VK_SEMICOLON 0x3B -#define J_VK_EQUALS 0x3D -#define J_VK_A 0x41 -#define J_VK_B 0x42 -#define J_VK_C 0x43 -#define J_VK_D 0x44 -#define J_VK_E 0x45 -#define J_VK_F 0x46 -#define J_VK_G 0x47 -#define J_VK_H 0x48 -#define J_VK_I 0x49 -#define J_VK_J 0x4A -#define J_VK_K 0x4B -#define J_VK_L 0x4C -#define J_VK_M 0x4D -#define J_VK_N 0x4E -#define J_VK_O 0x4F -#define J_VK_P 0x50 -#define J_VK_Q 0x51 -#define J_VK_R 0x52 -#define J_VK_S 0x53 -#define J_VK_T 0x54 -#define J_VK_U 0x55 -#define J_VK_V 0x56 -#define J_VK_W 0x57 -#define J_VK_X 0x58 -#define J_VK_Y 0x59 -#define J_VK_Z 0x5A -#define J_VK_OPEN_BRACKET 0x5B -#define J_VK_BACK_SLASH 0x5C -#define J_VK_CLOSE_BRACKET 0x5D -#define J_VK_NUMPAD0 0x60 -#define J_VK_NUMPAD1 0x61 -#define J_VK_NUMPAD2 0x62 -#define J_VK_NUMPAD3 0x63 -#define J_VK_NUMPAD4 0x64 -#define J_VK_NUMPAD5 0x65 -#define J_VK_NUMPAD6 0x66 -#define J_VK_NUMPAD7 0x67 -#define J_VK_NUMPAD8 0x68 -#define J_VK_NUMPAD9 0x69 -#define J_VK_MULTIPLY 0x6A -#define J_VK_ADD 0x6B -#define J_VK_SEPARATOR 0x6C -#define J_VK_SUBTRACT 0x6D -#define J_VK_DECIMAL 0x6E -#define J_VK_DIVIDE 0x6F -#define J_VK_DELETE 0x7F /* ASCII DEL */ -#define J_VK_NUM_LOCK 0x90 -#define J_VK_SCROLL_LOCK 0x91 -#define J_VK_F1 0x70 -#define J_VK_F2 0x71 -#define J_VK_F3 0x72 -#define J_VK_F4 0x73 -#define J_VK_F5 0x74 -#define J_VK_F6 0x75 -#define J_VK_F7 0x76 -#define J_VK_F8 0x77 -#define J_VK_F9 0x78 -#define J_VK_F10 0x79 -#define J_VK_F11 0x7A -#define J_VK_F12 0x7B -#define J_VK_F13 0xF000 -#define J_VK_F14 0xF001 -#define J_VK_F15 0xF002 -#define J_VK_F16 0xF003 -#define J_VK_F17 0xF004 -#define J_VK_F18 0xF005 -#define J_VK_F19 0xF006 -#define J_VK_F20 0xF007 -#define J_VK_F21 0xF008 -#define J_VK_F22 0xF009 -#define J_VK_F23 0xF00A -#define J_VK_F24 0xF00B -#define J_VK_PRINTSCREEN 0x9A -#define J_VK_INSERT 0x9B -#define J_VK_HELP 0x9C -#define J_VK_META 0x9D -#define J_VK_BACK_QUOTE 0xC0 -#define J_VK_QUOTE 0xDE -#define J_VK_KP_UP 0xE0 -#define J_VK_KP_DOWN 0xE1 -#define J_VK_KP_LEFT 0xE2 -#define J_VK_KP_RIGHT 0xE3 -#define J_VK_DEAD_GRAVE 0x80 -#define J_VK_DEAD_ACUTE 0x81 -#define J_VK_DEAD_CIRCUMFLEX 0x82 -#define J_VK_DEAD_TILDE 0x83 -#define J_VK_DEAD_MACRON 0x84 -#define J_VK_DEAD_BREVE 0x85 -#define J_VK_DEAD_ABOVEDOT 0x86 -#define J_VK_DEAD_DIAERESIS 0x87 -#define J_VK_DEAD_ABOVERING 0x88 -#define J_VK_DEAD_DOUBLEACUTE 0x89 -#define J_VK_DEAD_CARON 0x8a -#define J_VK_DEAD_CEDILLA 0x8b -#define J_VK_DEAD_OGONEK 0x8c -#define J_VK_DEAD_IOTA 0x8d -#define J_VK_DEAD_VOICED_SOUND 0x8e -#define J_VK_DEAD_SEMIVOICED_SOUND 0x8f -#define J_VK_AMPERSAND 0x96 -#define J_VK_ASTERISK 0x97 -#define J_VK_QUOTEDBL 0x98 -#define J_VK_LESS 0x99 -#define J_VK_GREATER 0xa0 -#define J_VK_BRACELEFT 0xa1 -#define J_VK_BRACERIGHT 0xa2 -#define J_VK_AT 0x0200 -#define J_VK_COLON 0x0201 -#define J_VK_CIRCUMFLEX 0x0202 -#define J_VK_DOLLAR 0x0203 -#define J_VK_EURO_SIGN 0x0204 -#define J_VK_EXCLAMATION_MARK 0x0205 -#define J_VK_INVERTED_EXCLAMATION_MARK 0x0206 -#define J_VK_LEFT_PARENTHESIS 0x0207 -#define J_VK_NUMBER_SIGN 0x0208 -#define J_VK_PLUS 0x0209 -#define J_VK_RIGHT_PARENTHESIS 0x020A -#define J_VK_UNDERSCORE 0x020B -#define J_VK_WINDOWS 0x020C -#define J_VK_CONTEXT_MENU 0x020D -#define J_VK_FINAL 0x0018 -#define J_VK_CONVERT 0x001C -#define J_VK_NONCONVERT 0x001D -#define J_VK_ACCEPT 0x001E -#define J_VK_MODECHANGE 0x001F -#define J_VK_KANA 0x0015 -#define J_VK_KANJI 0x0019 -#define J_VK_ALPHANUMERIC 0x00F0 -#define J_VK_KATAKANA 0x00F1 -#define J_VK_HIRAGANA 0x00F2 -#define J_VK_FULL_WIDTH 0x00F3 -#define J_VK_HALF_WIDTH 0x00F4 -#define J_VK_ROMAN_CHARACTERS 0x00F5 -#define J_VK_ALL_CANDIDATES 0x0100 -#define J_VK_PREVIOUS_CANDIDATE 0x0101 -#define J_VK_CODE_INPUT 0x0102 -#define J_VK_JAPANESE_KATAKANA 0x0103 -#define J_VK_JAPANESE_HIRAGANA 0x0104 -#define J_VK_JAPANESE_ROMAN 0x0105 -#define J_VK_KANA_LOCK 0x0106 -#define J_VK_INPUT_METHOD_ON_OFF 0x0107 -#define J_VK_CUT 0xFFD1 -#define J_VK_COPY 0xFFCD -#define J_VK_PASTE 0xFFCF -#define J_VK_UNDO 0xFFCB -#define J_VK_AGAIN 0xFFC9 -#define J_VK_FIND 0xFFD0 -#define J_VK_PROPS 0xFFCA -#define J_VK_STOP 0xFFC8 -#define J_VK_COMPOSE 0xFF20 -#define J_VK_ALT_GRAPH 0xFF7E -#define J_VK_BEGIN 0xFF58 -#define J_VK_UNDEFINED 0x0 +#define J_VK_UNDEFINED ( 0x0U ) +#define J_VK_HOME ( 0x02U ) +#define J_VK_END ( 0x03U ) +#define J_VK_FINAL ( 0x04U ) +#define J_VK_PRINTSCREEN ( 0x05U ) +#define J_VK_BACK_SPACE ( 0x08U ) +#define J_VK_TAB ( 0x09U ) +#define J_VK_ENTER ( 0x0AU ) +#define J_VK_PAGE_DOWN ( 0x0BU ) +#define J_VK_CLEAR ( 0x0CU ) +#define J_VK_SHIFT ( 0x0FU ) +#define J_VK_PAGE_UP ( 0x10U ) +#define J_VK_CONTROL ( 0x11U ) +#define J_VK_ALT ( 0x12U ) +#define J_VK_ALT_GRAPH ( 0x13U ) +#define J_VK_CAPS_LOCK ( 0x14U ) +#define J_VK_PAUSE ( 0x16U ) +#define J_VK_SCROLL_LOCK ( 0x17U ) +#define J_VK_CANCEL ( 0x18U ) +#define J_VK_INSERT ( 0x1AU ) +#define J_VK_ESCAPE ( 0x1BU ) +#define J_VK_CONVERT ( 0x1CU ) +#define J_VK_NONCONVERT ( 0x1DU ) +#define J_VK_ACCEPT ( 0x1EU ) +#define J_VK_MODECHANGE ( 0x1FU ) + +// +// Unicode: Printable [0x20 - 0x7E] +// + +#define J_VK_SPACE ( 0x20U ) +#define J_VK_EXCLAMATION_MARK ( 0x21U ) +#define J_VK_QUOTEDBL ( 0x22U ) +#define J_VK_NUMBER_SIGN ( 0x23U ) +#define J_VK_DOLLAR ( 0x24U ) +#define J_VK_PERCENT ( 0x25U ) +#define J_VK_AMPERSAND ( 0x26U ) +#define J_VK_QUOTE ( 0x27U ) +#define J_VK_LEFT_PARENTHESIS ( 0x28U ) +#define J_VK_RIGHT_PARENTHESIS ( 0x29U ) +#define J_VK_ASTERISK ( 0x2AU ) +#define J_VK_PLUS ( 0x2BU ) +#define J_VK_COMMA ( 0x2CU ) +#define J_VK_MINUS ( 0x2DU ) +#define J_VK_PERIOD ( 0x2EU ) +#define J_VK_SLASH ( 0x2FU ) +#define J_VK_0 ( 0x30U ) +#define J_VK_1 ( 0x31U ) +#define J_VK_2 ( 0x32U ) +#define J_VK_3 ( 0x33U ) +#define J_VK_4 ( 0x34U ) +#define J_VK_5 ( 0x35U ) +#define J_VK_6 ( 0x36U ) +#define J_VK_7 ( 0x37U ) +#define J_VK_8 ( 0x38U ) +#define J_VK_9 ( 0x39U ) +#define J_VK_COLON ( 0x3AU ) +#define J_VK_SEMICOLON ( 0x3BU ) +#define J_VK_LESS ( 0x3CU ) +#define J_VK_EQUALS ( 0x3DU ) +#define J_VK_GREATER ( 0x3EU ) +#define J_VK_QUESTIONMARK ( 0x3FU ) +#define J_VK_AT ( 0x40U ) +#define J_VK_A ( 0x41U ) +#define J_VK_B ( 0x42U ) +#define J_VK_C ( 0x43U ) +#define J_VK_D ( 0x44U ) +#define J_VK_E ( 0x45U ) +#define J_VK_F ( 0x46U ) +#define J_VK_G ( 0x47U ) +#define J_VK_H ( 0x48U ) +#define J_VK_I ( 0x49U ) +#define J_VK_J ( 0x4AU ) +#define J_VK_K ( 0x4BU ) +#define J_VK_L ( 0x4CU ) +#define J_VK_M ( 0x4DU ) +#define J_VK_N ( 0x4EU ) +#define J_VK_O ( 0x4FU ) +#define J_VK_P ( 0x50U ) +#define J_VK_Q ( 0x51U ) +#define J_VK_R ( 0x52U ) +#define J_VK_S ( 0x53U ) +#define J_VK_T ( 0x54U ) +#define J_VK_U ( 0x55U ) +#define J_VK_V ( 0x56U ) +#define J_VK_W ( 0x57U ) +#define J_VK_X ( 0x58U ) +#define J_VK_Y ( 0x59U ) +#define J_VK_Z ( 0x5AU ) +#define J_VK_OPEN_BRACKET ( 0x5BU ) +#define J_VK_BACK_SLASH ( 0x5CU ) +#define J_VK_CLOSE_BRACKET ( 0x5DU ) +#define J_VK_CIRCUMFLEX ( 0x5EU ) +#define J_VK_UNDERSCORE ( 0x5FU ) +#define J_VK_BACK_QUOTE ( 0x60U ) +#define J_VK_F1 ( 0x60U+ 1U ) +#define J_VK_F2 ( 0x60U+ 2U ) +#define J_VK_F3 ( 0x60U+ 3U ) +#define J_VK_F4 ( 0x60U+ 4U ) +#define J_VK_F5 ( 0x60U+ 5U ) +#define J_VK_F6 ( 0x60U+ 6U ) +#define J_VK_F7 ( 0x60U+ 7U ) +#define J_VK_F8 ( 0x60U+ 8U ) +#define J_VK_F9 ( 0x60U+ 9U ) +#define J_VK_F10 ( 0x60U+10U ) +#define J_VK_F11 ( 0x60U+11U ) +#define J_VK_F12 ( 0x60U+12U ) +#define J_VK_F13 ( 0x60U+13U ) +#define J_VK_F14 ( 0x60U+14U ) +#define J_VK_F15 ( 0x60U+15U ) +#define J_VK_F16 ( 0x60U+16U ) +#define J_VK_F17 ( 0x60U+17U ) +#define J_VK_F18 ( 0x60U+18U ) +#define J_VK_F19 ( 0x60U+19U ) +#define J_VK_F20 ( 0x60U+20U ) +#define J_VK_F21 ( 0x60U+21U ) +#define J_VK_F22 ( 0x60U+22U ) +#define J_VK_F23 ( 0x60U+23U ) +#define J_VK_F24 ( 0x60U+24U ) +#define J_VK_LEFT_BRACE ( 0x7BU ) +#define J_VK_PIPE ( 0x7CU ) +#define J_VK_RIGHT_BRACE ( 0x7DU ) +#define J_VK_TILDE ( 0x7EU ) + +// +// Unicode: Non printable controls: [0x7F - 0x9F] +// + +#define J_VK_DELETE ( 0x7FU ) +#define J_VK_NUMPAD0 ( 0x80U ) +#define J_VK_NUMPAD1 ( 0x81U ) +#define J_VK_NUMPAD2 ( 0x82U ) +#define J_VK_NUMPAD3 ( 0x83U ) +#define J_VK_NUMPAD4 ( 0x84U ) +#define J_VK_NUMPAD5 ( 0x85U ) +#define J_VK_NUMPAD6 ( 0x86U ) +#define J_VK_NUMPAD7 ( 0x87U ) +#define J_VK_NUMPAD8 ( 0x88U ) +#define J_VK_NUMPAD9 ( 0x89U ) +#define J_VK_DECIMAL ( 0x8AU ) +#define J_VK_SEPARATOR ( 0x8BU ) +#define J_VK_ADD ( 0x8CU ) +#define J_VK_SUBTRACT ( 0x8DU ) +#define J_VK_MULTIPLY ( 0x8EU ) +#define J_VK_DIVIDE ( 0x8FU ) +#define J_VK_NUM_LOCK ( 0x90U ) +#define J_VK_KP_LEFT ( 0x91U ) +#define J_VK_KP_UP ( 0x92U ) +#define J_VK_KP_RIGHT ( 0x93U ) +#define J_VK_KP_DOWN ( 0x94U ) +#define J_VK_LEFT ( 0x95U ) +#define J_VK_UP ( 0x96U ) +#define J_VK_RIGHT ( 0x97U ) +#define J_VK_DOWN ( 0x98U ) +#define J_VK_CONTEXT_MENU ( 0x99U ) +#define J_VK_WINDOWS ( 0x9AU ) +#define J_VK_META ( 0x9BU ) +#define J_VK_HELP ( 0x9CU ) +#define J_VK_COMPOSE ( 0x9DU ) +#define J_VK_BEGIN ( 0x9EU ) +#define J_VK_STOP ( 0x9FU ) + + +// +// Unicode: Printable [0x00A0 - 0xDFFF] +// + +#define J_VK_INVERTED_EXCLAMATION_MARK ( 0xA1U ) +#define J_VK_EURO_SIGN ( 0x20ACU ) + +// +// Unicode: Private 0xE000 - 0xF8FF (Marked Non-Printable) +// + +/* for Sun keyboards */ +#define J_VK_CUT ( 0xF879U ) +#define J_VK_COPY ( 0xF87AU ) +#define J_VK_PASTE ( 0xF87BU ) +#define J_VK_UNDO ( 0xF87CU ) +#define J_VK_AGAIN ( 0xF87DU ) +#define J_VK_FIND ( 0xF87EU ) +#define J_VK_PROPS ( 0xF87FU ) + +/* for input method support on Asian Keyboards */ +#define J_VK_INPUT_METHOD_ON_OFF ( 0xF890U ) +#define J_VK_CODE_INPUT ( 0xF891U ) +#define J_VK_ROMAN_CHARACTERS ( 0xF892U ) +#define J_VK_ALL_CANDIDATES ( 0xF893U ) +#define J_VK_PREVIOUS_CANDIDATE ( 0xF894U ) +#define J_VK_ALPHANUMERIC ( 0xF895U ) +#define J_VK_KATAKANA ( 0xF896U ) +#define J_VK_HIRAGANA ( 0xF897U ) +#define J_VK_FULL_WIDTH ( 0xF898U ) +#define J_VK_HALF_WIDTH ( 0xF89AU ) +#define J_VK_JAPANESE_KATAKANA ( 0xF89BU ) +#define J_VK_JAPANESE_HIRAGANA ( 0xF89CU ) +#define J_VK_JAPANESE_ROMAN ( 0xF89DU ) +#define J_VK_KANA_LOCK ( 0xF89FU ) + +#define J_VK_KEYBOARD_INVISIBLE ( 0xF8FFU ) #endif diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c index 7f070e7d3..c294b6e0b 100644 --- a/src/newt/native/NewtCommon.c +++ b/src/newt/native/NewtCommon.c @@ -72,7 +72,7 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) return strChars; } -JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached) { +JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) { JNIEnv* curEnv = NULL; JNIEnv* newEnv = NULL; int envRes; @@ -81,7 +81,12 @@ JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDe envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ; if( JNI_EDETACHED == envRes ) { // detached thread - attach to JVM - if( JNI_OK != ( envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL) ) ) { + if( asDaemon ) { + envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL); + } else { + envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL); + } + if( JNI_OK != envRes ) { fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes); return NULL; } diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h index 9a4e5ac70..9cc9e93a6 100644 --- a/src/newt/native/NewtCommon.h +++ b/src/newt/native/NewtCommon.h @@ -76,6 +76,6 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); (*jvmHandle)->DetachCurrentThread(jvmHandle); } */ -JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached); +JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached); #endif diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index d7b357349..005e82d72 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -36,6 +36,9 @@ #import "KeyEvent.h" #import "MouseEvent.h" +#include <CoreFoundation/CoreFoundation.h> +#include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */ + #include <math.h> static jfloat GetDelta(NSEvent *event, jint javaMods[]) { @@ -82,9 +85,7 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) { } static jmethodID enqueueMouseEventID = NULL; -static jmethodID sendMouseEventID = NULL; static jmethodID enqueueKeyEventID = NULL; -static jmethodID sendKeyEventID = NULL; static jmethodID requestFocusID = NULL; static jmethodID insetsChangedID = NULL; @@ -95,13 +96,11 @@ static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowRepaintID = NULL; -// Can't use USE_SENDIO_DIRECT, ie w/o enqueueing to EDT, +// Need to enqueue all events to EDT, // since we may operate on AWT-AppKit (Main Thread) // and direct issuing 'requestFocus()' would deadlock: // AWT-AppKit // AWT-EventQueue-0 -// -// #define USE_SENDIO_DIRECT 1 @implementation NewtView @@ -286,7 +285,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("drawRect: null JNIEnv\n"); return; @@ -298,9 +297,9 @@ static jmethodID windowRepaintID = NULL; dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) viewDidHide @@ -310,7 +309,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidHide: null JNIEnv\n"); return; @@ -318,9 +317,9 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ [super viewDidHide]; } @@ -332,7 +331,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidUnhide: null JNIEnv\n"); return; @@ -340,9 +339,9 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ [super viewDidUnhide]; } @@ -354,14 +353,71 @@ static jmethodID windowRepaintID = NULL; @end +static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) { + UInt32 keysDown = 0; + UniChar chars[4]; + UniCharCount realLength; + + UCKeyTranslate(keyboardLayout, keyCode, + kUCKeyActionDisplay, 0, + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, + &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars); + + return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1); +} + +static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) { + CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData); + const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); + + CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL); + if ( NULL != codeToCharDict ) { + intptr_t i; + for (i = 0; i < 128; ++i) { + CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout); + if( NULL != string ) { + CFIndex stringLen = CFStringGetLength (string); + if ( 0 < stringLen ) { + UniChar character = CFStringGetCharacterAtIndex(string, 0); + DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character); + CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character); + } + CFRelease(string); + } + } + } + return codeToCharDict; +} + +static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL; + +static void CKCH_CreateDictionaries() { + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard); + CFRelease(currentKeyboard); +} + +static UniChar CKCH_CharForKeyCode(jshort keyCode) { + UniChar rChar = 0; + + if ( NULL != CKCH_USCodeToNNChar ) { + intptr_t code = (intptr_t) keyCode; + intptr_t character = 0; + + if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) { + rChar = (UniChar) character; + DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar); + } + } + return rChar; +} + @implementation NewtMacWindow + (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz { 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"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)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"); @@ -370,9 +426,10 @@ static jmethodID windowRepaintID = NULL; windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z"); windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V"); requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V"); - if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID && + if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID && positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID) { + CKCH_CreateDictionaries(); return YES; } return NO; @@ -675,7 +732,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("sendKeyEvent: null JNIEnv\n"); return; @@ -689,36 +746,27 @@ static jint mods2JavaMods(NSUInteger mods) // printable chars for (i = 0; i < len; i++) { // Note: the key code in the NSEvent does not map to anything we can use - jchar keyChar = (jchar) [chars characterAtIndex: i]; + UniChar keyChar = (UniChar) [chars characterAtIndex: i]; + UniChar keySymChar = CKCH_CharForKeyCode(keyCode); - DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode); + DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, (int)keySymChar); - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID, - evType, javaMods, keyCode, keyCode, keyChar); - #else (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, - evType, javaMods, keyCode, keyCode, keyChar); - #endif + evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar); } } else { // non-printable chars - jchar keyChar = (jchar) -1; + jchar keyChar = (jchar) 0; DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode); - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID, - evType, javaMods, keyCode, keyCode, keyChar); - #else (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, - evType, javaMods, keyCode, keyCode, keyChar); - #endif + evType, javaMods, keyCode, keyChar, keyChar); } - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType @@ -735,7 +783,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("sendMouseEvent: null JNIEnv\n"); return; @@ -780,21 +828,14 @@ static jint mods2JavaMods(NSUInteger mods) NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]]; - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, javaWindowObject, sendMouseEventID, - evType, javaMods[0], - (jint) location.x, (jint) location.y, - javaButtonNum, scrollDeltaY); - #else (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE, evType, javaMods[0], (jint) location.x, (jint) location.y, javaButtonNum, scrollDeltaY); - #endif - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) focusChanged: (BOOL) gained @@ -812,7 +853,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("focusChanged: null JNIEnv\n"); return; @@ -820,9 +861,9 @@ static jint mods2JavaMods(NSUInteger mods) (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (BOOL) becomeFirstResponder @@ -1010,7 +1051,7 @@ static jint mods2JavaMods(NSUInteger mods) javaWindowObject = [view getJavaWindowObject]; if (javaWindowObject != NULL) { jvmHandle = [view getJVMHandle]; - env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); } } @@ -1025,9 +1066,9 @@ static jint mods2JavaMods(NSUInteger mods) (jint) contentRect.size.width, (jint) contentRect.size.height, JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } } @@ -1045,7 +1086,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("windowDidMove: null JNIEnv\n"); return; @@ -1055,9 +1096,9 @@ static jint mods2JavaMods(NSUInteger mods) p0 = [self getLocationOnScreen: p0]; (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (BOOL)windowShouldClose: (id) sender @@ -1092,7 +1133,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("windowWillClose: null JNIEnv\n"); return NO; @@ -1105,9 +1146,9 @@ static jint mods2JavaMods(NSUInteger mods) [view setDestroyNotifySent: false]; } - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed); } else { DBG_PRINT( "*************** windowWillClose (skip)\n"); @@ -1117,3 +1158,4 @@ static jint mods2JavaMods(NSUInteger mods) } @end + diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index ae09490f8..eecc2e075 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -162,7 +162,7 @@ static KeyMapEntry keyMapTable[] = { {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_ALT_GRAPH, VK_RMENU, 0}, {J_VK_NUM_LOCK, VK_NUMLOCK, 0}, // Miscellaneous Windows keys @@ -432,7 +432,7 @@ static void ParseWmVKeyAndScanCode(USHORT winVKey, BYTE winScanCode, BYTE flags, #endif } -static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) { +static jint GetModifiers(USHORT jkey) { jint modifiers = 0; // have to do &0xFFFF to avoid runtime assert caused by compiling with // /RTCcsu @@ -442,9 +442,12 @@ static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) { if ( HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0 || J_VK_SHIFT == jkey ) { modifiers |= EVENT_SHIFT_MASK; } - if ( altKeyFlagged || HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) { + if ( HIBYTE((GetKeyState(VK_LMENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) { modifiers |= EVENT_ALT_MASK; } + if ( HIBYTE((GetKeyState(VK_RMENU) & 0xFFFF)) != 0 || (USHORT)J_VK_ALT_GRAPH == jkey ) { + modifiers |= EVENT_ALT_GRAPH_MASK; + } if ( HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0 ) { modifiers |= EVENT_BUTTON1_MASK; } @@ -458,11 +461,12 @@ static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) { return modifiers; } +/** static BOOL IsAltKeyDown(BYTE flags, BOOL system) { // The Alt modifier is reported in the 29th bit of the lParam, // i.e., it is the 5th bit of `flags' (which is HIBYTE(HIWORD(lParam))). return system && ( flags & (1<<5) ) != 0; -} +} */ static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) { UINT modifiers = 0; @@ -473,7 +477,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char); - modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX ); + modifiers = GetModifiers( javaVKeyUS ); (*env)->CallVoidMethod(env, window, sendKeyEventID, (jshort) EVENT_KEY_PRESSED, @@ -491,7 +495,7 @@ static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE s ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char); - modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX ); + modifiers = GetModifiers( javaVKeyUS ); (*env)->CallVoidMethod(env, window, sendKeyEventID, (jshort) EVENT_KEY_RELEASED, @@ -860,7 +864,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE); (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 1, (jfloat) 0.0f); useDefWindowProc = 1; @@ -869,7 +873,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP case WM_LBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 1, (jfloat) 0.0f); useDefWindowProc = 1; @@ -880,7 +884,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE); (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 2, (jfloat) 0.0f); useDefWindowProc = 1; @@ -889,7 +893,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP case WM_MBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 2, (jfloat) 0.0f); useDefWindowProc = 1; @@ -900,7 +904,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE); (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 3, (jfloat) 0.0f); useDefWindowProc = 1; @@ -909,17 +913,17 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP case WM_RBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 3, (jfloat) 0.0f); useDefWindowProc = 1; break; case WM_MOUSEMOVE: - DBG_PRINT("*** WindowsWindow: WM_MOUSEMOVE %d/%d\n", (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam)); + // DBG_PRINT("*** WindowsWindow: WM_MOUSEMOVE %d/%d\n", (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam)); (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED, - GetModifiers( FALSE, 0 ), + GetModifiers( 0 ), (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam), (jshort) 0, (jfloat) 0.0f); useDefWindowProc = 1; @@ -937,7 +941,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP case WM_HSCROLL: { // Only delivered if windows has WS_HSCROLL, hence dead code! int sb = LOWORD(wParam); - int modifiers = GetModifiers( FALSE, 0 ) | EVENT_SHIFT_MASK; + int modifiers = GetModifiers( 0 ) | EVENT_SHIFT_MASK; float rotation; switch(sb) { case SB_LINELEFT: @@ -967,7 +971,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP // need to convert the coordinates to component-relative int x = GET_X_LPARAM(lParam); int y = GET_Y_LPARAM(lParam); - int modifiers = GetModifiers( FALSE, 0 ); + int modifiers = GetModifiers( 0 ); float rotationOrTilt = (float)(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTAf; int vKeys = GET_KEYSTATE_WPARAM(wParam); POINT eventPt; diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 9b11ff0dd..56b7251d2 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -28,6 +28,8 @@ #include "X11Common.h" +// #include <X11/XKBlib.h> // XKB disabled for now + jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; jmethodID visibleChangedID = NULL; @@ -52,9 +54,11 @@ static jmethodID requestFocusID = NULL; * Keycode */ +// #define DEBUG_KEYS 1 + #define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b)) -static jint X11KeySym2NewtVKey(KeySym keySym) { +static short X11KeySym2NewtVKey(KeySym keySym) { if( IS_WITHIN( keySym, XK_a, XK_z ) ) { return ( keySym - XK_a ) + J_VK_A ; } @@ -89,8 +93,14 @@ static jint X11KeySym2NewtVKey(KeySym keySym) { case XK_Control_R: return J_VK_CONTROL; case XK_Alt_L: - case XK_Alt_R: return J_VK_ALT; + case XK_Alt_R: + return J_VK_ALT_GRAPH; + case XK_Super_L: + case XK_Super_R: + return J_VK_WINDOWS; + case XK_Menu: + return J_VK_CONTEXT_MENU; case XK_Pause: return J_VK_PAUSE; case XK_Caps_Lock: @@ -158,7 +168,11 @@ static jint X11KeySym2NewtVKey(KeySym keySym) { return keySym; } -static jint X11InputState2NewtModifiers(unsigned int xstate, int javaVKey) { +#define ShiftCtrlModMask ( ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask ) + +static jboolean altGraphDown = JNI_FALSE; + +static jint X11InputState2NewtModifiers(unsigned int xstate, jshort javaVKey, jboolean keyDown) { jint modifiers = 0; if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == javaVKey ) { modifiers |= EVENT_CTRL_MASK; @@ -166,8 +180,15 @@ static jint X11InputState2NewtModifiers(unsigned int xstate, int javaVKey) { if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == javaVKey ) { modifiers |= EVENT_SHIFT_MASK; } - if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == javaVKey ) { + if ( J_VK_ALT == javaVKey ) { + altGraphDown = JNI_FALSE; modifiers |= EVENT_ALT_MASK; + } else if ( (short)J_VK_ALT_GRAPH == javaVKey ) { + altGraphDown = keyDown; + modifiers |= EVENT_ALT_GRAPH_MASK; + } else if ( (Mod1Mask & xstate) != 0 ) { + // XK_Alt_L or XK_Alt_R + modifiers |= altGraphDown ? EVENT_ALT_GRAPH_MASK : EVENT_ALT_MASK; } if ( (Button1Mask & xstate) != 0 ) { modifiers |= EVENT_BUTTON1_MASK; @@ -211,6 +232,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 } } + // displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJ)V"); // Variant using XKB displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V"); getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;"); dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V"); @@ -223,7 +245,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z"); windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V"); - sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSC)V"); + sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V"); requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V"); if (displayCompletedID == NULL || @@ -258,6 +280,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay Display * dpy = (Display *)(intptr_t)display; jlong javaObjectAtom; jlong windowDeleteAtom; + // jlong kbdHandle; // XKB disabled for now if(dpy==NULL) { NewtCommon_FatalError(env, "invalid display connection.."); @@ -276,10 +299,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay } // XSetCloseDownMode(dpy, RetainTemporary); // Just a try .. + // kbdHandle = (jlong) (intptr_t) XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); // XKB disabled for now DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy); - (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom); + (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom /*, kbdHandle*/); // XKB disabled for now } /* @@ -288,11 +312,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay * Signature: (JJJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 - (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) { Display * dpy = (Display *)(intptr_t)display; Atom wm_javaobject_atom = (Atom)javaObjectAtom; Atom wm_delete_atom = (Atom)windowDeleteAtom; + // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now if(dpy==NULL) { NewtCommon_FatalError(env, "invalid display connection.."); @@ -302,6 +327,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 (void) wm_javaobject_atom; (void) wm_delete_atom; + // XkbFreeKeyboard(kbdDesc, XkbAllNamesMask, True); // XKB disabled for now + XSync(dpy, True); // discard all pending events DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy); } @@ -309,13 +336,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 /* * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DispatchMessages - * Signature: (JIJJ)V + * Signature: (JJJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 - (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) { Display * dpy = (Display *) (intptr_t) display; Atom wm_delete_atom = (Atom)windowDeleteAtom; + // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now int num_events = 100; int autoRepeatModifiers = 0; @@ -323,6 +351,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage return; } + /** XKB disabled for now + if( NULL == kbdDesc) { + NewtCommon_throwNewRuntimeException(env, "NULL kbd handle, bail out!"); + return; + } */ + // Periodically take a break while( num_events > 0 ) { jobject jwindow = NULL; @@ -332,7 +366,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage jshort javaVKeyUS = 0; jshort javaVKeyNN = 0; jint modifiers = 0; - char keyChar = 0; + uint16_t keyChar = 0; + jstring keyString = NULL; char text[255]; // XEventsQueued(dpy, X): @@ -391,27 +426,59 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage // fall through intended case KeyPress: { KeySym shiftedKeySym; // layout depending keySym w/ SHIFT + KeySym unShiftedKeySym; // layout depending keySym w/o SHIFT + unsigned int xkey_state = evt.xkey.state; 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]; + // Layout depending keySym w/o SHIFT, + // using fixed group 0 (US default layout) + // + // unsigned int mods_rtrn = 0; + // Bool res = XkbTranslateKeyCode (kbdDesc, keyCode, 0, &mods_rtrn, &keySym); // XKB disabled for now + // if( !res ) { + keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */); + // } + + text[0] = 0; text[1] = 0; text[2] = 0; + int charCount = XLookupString(&evt.xkey, text, 2, &shiftedKeySym, NULL); + if( 1 == charCount ) { + keyChar = 0x00FF & (uint16_t) (text[0]); + } else if( 2 == charCount ) { + // Example: UTF-16: 00DF, UTF-8: c3 9f, LATIN SMALL LETTER SHARP S + keyChar = ( 0x00FF & (uint16_t)(text[0]) ) << 8 | ( 0x00FF & (uint16_t)(text[1]) ); // UTF-16BE + keyString = (*env)->NewStringUTF(env, text); } - javaVKeyNN = X11KeySym2NewtVKey(keySym); - javaVKeyUS = javaVKeyNN; // FIXME! - modifiers |= X11InputState2NewtModifiers(evt.xkey.state, javaVKeyNN) | autoRepeatModifiers; + if( 0 == keyChar ) { + // Use keyCode's keySym for dead-key (aka modifiers, etc) + unShiftedKeySym = keySym; + } else if( 0 == ( evt.xkey.state & ShiftCtrlModMask ) ) { + // Use non modded keySym + unShiftedKeySym = shiftedKeySym; + } else { + evt.xkey.state = evt.xkey.state & ~ShiftCtrlModMask; // clear shift, ctrl and Mod* + XLookupString(&evt.xkey, text, 0, &unShiftedKeySym, NULL); + // unShiftedKeySym = XLookupKeysym(&evt.xkey, 0 /* index ? */); + } - 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); + javaVKeyNN = X11KeySym2NewtVKey(unShiftedKeySym); + javaVKeyUS = X11KeySym2NewtVKey(keySym); + modifiers |= X11InputState2NewtModifiers(xkey_state, javaVKeyNN, evt.type == KeyPress) | autoRepeatModifiers; + + #ifdef DEBUG_KEYS + fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X, (0x%X, shifted: 0x%X), keyChar '%c' 0x%X %d, javaVKey[US 0x%X, NN 0x%X], xstate 0x%X %u, jmods 0x%X\n", + (int)keyCode, (int)keySym, (int) unShiftedKeySym, (int)shiftedKeySym, keyChar, keyChar, charCount, + (int)javaVKeyUS, (int)javaVKeyNN, + (int)xkey_state, (int)xkey_state, (int)modifiers); + #endif } break; case ButtonPress: case ButtonRelease: case MotionNotify: - modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0); + modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0, JNI_FALSE); break; default: @@ -447,13 +514,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage modifiers, (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); break; + case MappingNotify: + DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type); + XRefreshKeyboardMapping(&evt.xmapping); + break; case KeyPress: (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED, - modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar); + modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString); break; case KeyRelease: (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED, - modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar); + modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString); break; case DestroyNotify: DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 202ad6fff..9e96169f5 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -671,7 +671,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) // XKB disabled for now { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -698,7 +698,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 XUnmapWindow(dpy, w); // Drain all events related to this window .. - Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); + Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now XDestroyWindow(dpy, w); XSync(dpy, True); // discard all events now, no more handler diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java index ea02e930c..ea02e930c 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java index 160dc0ffe..160dc0ffe 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java index adeb700d7..adeb700d7 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java index 0b70cf151..2df1d3cb6 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java @@ -57,9 +57,6 @@ import com.jogamp.opengl.test.junit.util.UITestCase; /** * Tests using an AWT {@link GLCanvas} {@link GLAutoDrawable auto drawable} for on- and offscreen cases. - * <p> - * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}. - * </p> */ public class TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT extends UITestCase { static final int widthStep = 800/4; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java index 208367102..208367102 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java index 5bbd6737c..5bbd6737c 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java index 7f2713354..7f2713354 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java index e17c9e88b..e17c9e88b 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java new file mode 100644 index 000000000..ae5a0b3ba --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java @@ -0,0 +1,124 @@ +package com.jogamp.opengl.test.junit.jogl.demos.gl2; + +import java.net.URLConnection; + +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.opengl.util.gl2.GLUT; +import com.jogamp.opengl.util.texture.Texture; +import com.jogamp.opengl.util.texture.TextureIO; + +/** + * Adapted from + * http://www.java-tips.org/other-api-tips/jogl/how-to-draw-a-texture-mapped-teapot-with-automatically-generated-texture-coordi.html + */ +public class Teapot implements GLEventListener { + + private GLUT glut; + + /* glTexGen stuff: */ + private float sgenparams[] = { 1.0f, 1.0f, 1.0f, 0.0f }; + + private Texture tex = null; + + @Override + public void init(GLAutoDrawable drawable) { + GL2 gl = drawable.getGL().getGL2(); + glut = new GLUT(); + + gl.glClearColor(0.5f, 0.5f, 0.5f, 0.0f); + + try { + URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", this.getClass().getClassLoader()); + tex = TextureIO.newTexture(gl, TextureIO.newTextureData(gl.getGLProfile(), urlConn.getInputStream(), false, TextureIO.PNG)); + } catch (Exception e) { + e.printStackTrace(); + } + tex.bind(gl); + + // uncomment this and comment the above to see a working texture + // makeStripeImage(); + // gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + // gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, + // GL2.GL_MODULATE); + // gl.glTexParameterf(GL2.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, + // GL.GL_REPEAT); + // gl.glTexParameterf(GL2.GL_TEXTURE_1D, GL.GL_TEXTURE_MAG_FILTER, + // GL.GL_LINEAR); + // gl.glTexParameterf(GL2.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, + // GL.GL_LINEAR); + // gl.glTexImage1D(GL2.GL_TEXTURE_1D, 0, 3, stripeImageWidth, 0, + // GL.GL_RGB, GL.GL_UNSIGNED_BYTE, stripeImageBuf); + + gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); + + // gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + // gl.glTexGenfv(GL2.GL_S, GL2.GL_OBJECT_PLANE, sgenparams, 0); + + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glDepthFunc(GL.GL_LESS); + // gl.glEnable(GL2.GL_TEXTURE_GEN_S); + // gl.glEnable(GL2.GL_TEXTURE_1D); + gl.glEnable(GL2.GL_TEXTURE_2D); + gl.glEnable(GL2.GL_CULL_FACE); + gl.glEnable(GL2.GL_LIGHTING); + gl.glEnable(GL2.GL_LIGHT0); + gl.glEnable(GL2.GL_AUTO_NORMAL); + gl.glEnable(GL2.GL_NORMALIZE); + gl.glFrontFace(GL.GL_CW); + gl.glCullFace(GL.GL_BACK); + gl.glMaterialf(GL.GL_FRONT, GL2.GL_SHININESS, 64.0f); + } + + float angleZ = 0.0f; + float rotDir = 1.0f; + public float rotIncr = 0.4f; + + @Override + public void display(GLAutoDrawable gLDrawable) { + final GL2 gl = gLDrawable.getGL().getGL2(); + + tex.bind(gl); + gl.glEnable(GL2.GL_TEXTURE_2D); + + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + gl.glPushMatrix(); + gl.glRotatef(angleZ, 0.0f, 1.0f, 0.0f); + gl.glRotatef(45.0f, 0.0f, 0.0f, 1.0f); + glut.glutSolidTeapot(2.0f); + gl.glPopMatrix(); + gl.glFlush(); + if( angleZ >= 180.0f ) { + rotDir = -1.0f; + } else if (angleZ <= 0.0f ) { + rotDir = +1.0f; + } + angleZ += rotIncr * rotDir; + } + + @Override + public void reshape(GLAutoDrawable gLDrawable, int x, int y, int w, int h) { + GL2 gl = gLDrawable.getGL().getGL2(); + + gl.glViewport(0, 0, w, h); + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glLoadIdentity(); + if (w <= h) { + gl.glOrtho(-3.5, 3.5, -3.5 * (float) h / (float) w, + 3.5 * (float) h / (float) w, -3.5, 3.5); + } else { + gl.glOrtho(-3.5 * (float) w / (float) h, + 3.5 * (float) w / (float) h, -3.5, 3.5, -3.5, 3.5); + } + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glLoadIdentity(); + } + + @Override + public void dispose(GLAutoDrawable gLDrawable) { + } +}
\ No newline at end of file diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestTeapotNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestTeapotNEWT.java new file mode 100644 index 000000000..ddde837ab --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestTeapotNEWT.java @@ -0,0 +1,159 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.demos.gl2.newt; + +import com.jogamp.newt.opengl.GLWindow; +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.gl2.Teapot; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.Test; + +public class TestTeapotNEWT extends UITestCase { + static GLProfile glp; + static int width, height; + + @BeforeClass + public static void initClass() { + if(GLProfile.isAvailable(GLProfile.GL2)) { + glp = GLProfile.get(GLProfile.GL2); + Assert.assertNotNull(glp); + width = 640; + height = 480; + } else { + setTestSupported(false); + } + } + + @AfterClass + public static void releaseClass() { + } + + protected void runTestGL(GLCapabilities caps, boolean withAnimator) throws InterruptedException { + final GLWindow glWindow = GLWindow.create(caps); + + glWindow.setTitle("Teapot NEWT Test"); + Teapot demo = new Teapot(); + if( !withAnimator ) { + demo.rotIncr *= 10f; + } + glWindow.addGLEventListener(demo); + final SnapshotGLEventListener snap = new SnapshotGLEventListener(); + glWindow.addGLEventListener(snap); + + final Animator animator = withAnimator ? new Animator(glWindow) : null; + final QuitAdapter quitAdapter = new QuitAdapter(); + + //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter)); + //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter)); + glWindow.addKeyListener(quitAdapter); + glWindow.addWindowListener(quitAdapter); + + glWindow.setSize(width, height); + glWindow.setVisible(true); + if( withAnimator ) { + animator.setUpdateFPSFrames(60, System.err); + animator.start(); + } + + final long t0 = System.currentTimeMillis(); + long t1 = t0; + int snaps=3; + while(!quitAdapter.shouldQuit() && t1-t0<duration) { + Thread.sleep(100); + t1 = System.currentTimeMillis(); + if( snaps-- > 0 ) { + snap.setMakeSnapshot(); + } + if( !withAnimator ) { + glWindow.display(); + } + } + + if( withAnimator ) { + animator.stop(); + } + glWindow.destroy(); + } + + @Test + public void test01_DefCaps_Anim() throws InterruptedException { + final GLCapabilities caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true)); + runTestGL(caps, true); + } + + @Test + public void test02_DefCaps_NoAnim() throws InterruptedException { + final GLCapabilities caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true)); + runTestGL(caps, false); + } + + @Test + public void test12_FBOCaps_NoAnim() throws InterruptedException { + final GLCapabilities caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true)); + caps.setHardwareAccelerated(true); + caps.setDoubleBuffered(true); + caps.setAlphaBits(8); + caps.setDepthBits(8); + caps.setNumSamples(0); + caps.setSampleBuffers(false); + caps.setStencilBits(0); + caps.setRedBits(8); + caps.setBlueBits(8); + caps.setGreenBits(8); + + // caps.setPBuffer(true); + caps.setFBO(true); + + runTestGL(caps, false); + } + + static long duration = 500; // ms + + public static void main(String args[]) { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + org.junit.runner.JUnitCore.main(TestTeapotNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java index 34b30f04e..34b30f04e 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java index 717d5e4b8..717d5e4b8 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java index 7106ed7ce..d1b276105 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java @@ -226,8 +226,8 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase { { try { System.err.println("[K-"+_n+"]"); - AWTRobotUtil.keyPress(_n, _robot, true, KeyEvent.VK_0, 10); - AWTRobotUtil.keyPress(_n, _robot, false, KeyEvent.VK_0, 0); + AWTRobotUtil.newtKeyPress(_n, _robot, true, KeyEvent.VK_0, 10); + AWTRobotUtil.newtKeyPress(_n, _robot, false, KeyEvent.VK_0, 0); Thread.sleep( 40L ) ; _n++; if(!_display.isDisposed()) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/grayscale_texture.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/grayscale_texture.png Binary files differindex dac0f13de..dac0f13de 100755..100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/grayscale_texture.png +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/grayscale_texture.png 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 08a181e10..b075af977 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 @@ -160,81 +160,90 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase { } @SuppressWarnings("deprecation") - static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask, int keyCode, char keyCharOnly, char keyCharMod) { + static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, short modifierKey, int modifierMask, short keyCode, + char keyCharOnly, char keyCharMod) { keyAdapter.reset(); - AWTRobotUtil.keyPress(0, robot, true, keyCode, 10); // press keyCode - AWTRobotUtil.keyPress(0, robot, false, keyCode, 100); // release+typed keyCode + AWTRobotUtil.newtKeyPress(0, robot, true, keyCode, 10); // press keyCode + AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 100); // release+typed keyCode robot.waitForIdle(); - for(int j=0; j < 40 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected + for(int j=0; j < 100 && 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, keyCode, 10); // press keyCode - AWTRobotUtil.keyPress(0, robot, false, keyCode, 10); // release+typed keyCode - AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100); // release MOD + AWTRobotUtil.newtKeyPress(0, robot, true, modifierKey, 10); // press MOD + AWTRobotUtil.newtKeyPress(0, robot, true, keyCode, 10); // press keyCode + AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 10); // release+typed keyCode + AWTRobotUtil.newtKeyPress(0, robot, false, modifierKey, 100); // release MOD robot.waitForIdle(); - for(int j=0; j < 40 && keyAdapter.getQueueSize() < 3+5; j++) { // wait until events are collected + for(int j=0; j < 100 && keyAdapter.getQueueSize() < 3+5; j++) { // wait until events are collected robot.delay(100); } - NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - 3 /* press-SI */, 3 /* release-SI */, 2 /* typed-SI */, + final int modTypedCount = KeyEvent.NULL_CHAR != keyCharMod ? 2 : -1 ; // ignore due to mods 'isPrintable' impact. + NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, + 3 /* press-SI */, 3 /* release-SI */, modTypedCount /* typed-SI */, 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ ); - final List<EventObject> queue = keyAdapter.getQueued(); + final List<EventObject> queue = keyAdapter.getQueued(); int i=0; 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, (char)0); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey, KeyEvent.NULL_CHAR); 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); + KeyEvent e = (KeyEvent) queue.get(i++); + if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) { // optional, due to mods 'isPrintable' impact. + NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_TYPED, modifierMask, keyCode, keyCharMod); + e = (KeyEvent) queue.get(i++); + } + NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey, KeyEvent.NULL_CHAR); } @SuppressWarnings("deprecation") static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) { - final int m1k = KeyEvent.VK_ALT; - final int m1m = InputEvent.ALT_MASK; - final int m2k = KeyEvent.VK_CONTROL; - final int m2m = InputEvent.CTRL_MASK; - final int m3k = KeyEvent.VK_SHIFT; - final int m3m = InputEvent.SHIFT_MASK; + final short m1k = KeyEvent.VK_ALT; + final int m1m = InputEvent.ALT_MASK; + final short m2k = KeyEvent.VK_CONTROL; + final int m2m = InputEvent.CTRL_MASK; + final short m3k = KeyEvent.VK_SHIFT; + final int m3m = InputEvent.SHIFT_MASK; keyAdapter.reset(); - AWTRobotUtil.keyPress(0, robot, true, m1k, 10); // press MOD1 - AWTRobotUtil.keyPress(0, robot, true, m2k, 10); // press MOD2 - AWTRobotUtil.keyPress(0, robot, true, m3k, 10); // press MOD3 - AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P + AWTRobotUtil.newtKeyPress(0, robot, true, m1k, 10); // press MOD1 + AWTRobotUtil.newtKeyPress(0, robot, true, m2k, 10); // press MOD2 + AWTRobotUtil.newtKeyPress(0, robot, true, m3k, 10); // press MOD3 + AWTRobotUtil.newtKeyPress(0, robot, true, KeyEvent.VK_1, 10); // press P - AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P - 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 + AWTRobotUtil.newtKeyPress(0, robot, false, KeyEvent.VK_1, 100); // release+typed P + AWTRobotUtil.newtKeyPress(0, robot, false, m3k, 10); // release MOD + AWTRobotUtil.newtKeyPress(0, robot, false, m2k, 10); // release MOD + AWTRobotUtil.newtKeyPress(0, robot, false, m1k, 10); // release MOD robot.waitForIdle(); - for(int j=0; j < 40 && keyAdapter.getQueueSize() < 4+4+1; j++) { // wait until events are collected + for(int j=0; j < 100 && keyAdapter.getQueueSize() < 4+4+1; j++) { // wait until events are collected robot.delay(100); } NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - 4 /* press-SI */, 4 /* release-SI */, 1 /* typed-SI */, - 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ ); + 4 /* press-SI */, 4 /* release-SI */, -1 /* typed-SI - ignored, since unknow whether printable w/ all mods */, + 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, (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, (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_PRESSED, m1m, m1k, KeyEvent.NULL_CHAR); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m, m2k, KeyEvent.NULL_CHAR); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, m3k, KeyEvent.NULL_CHAR); - 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); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); + KeyEvent e = (KeyEvent) queue.get(i++); + if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) { // optional, due to mods 'isPrintable' impact. + NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); + e = (KeyEvent) queue.get(i++); + } + NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k, KeyEvent.NULL_CHAR); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k, KeyEvent.NULL_CHAR); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k, KeyEvent.NULL_CHAR); } void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException { @@ -265,8 +274,8 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase { 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); + testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK, KeyEvent.VK_1, '1', KeyEvent.NULL_CHAR); + testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK, KeyEvent.VK_1, '1', KeyEvent.NULL_CHAR); 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 277924477..fb42141ea 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 @@ -155,32 +155,35 @@ public class TestNewtKeyCodesAWT extends UITestCase { testNewtCanvasAWT_Impl(false); } + /** Almost all keyCodes reachable w/o modifiers [shift, alt, ..] on US keyboard! */ static CodeSeg[] codeSegments = new CodeSeg[] { - new CodeSeg(0x008, 0x008, "bs"), - // new CodeSeg(0x009, 0x009, "tab"), // TAB functions as focus traversal key - new CodeSeg(0x00a, 0x00a, "cr"), - new CodeSeg(0x010, 0x012, "shift, ctrl, alt"), - new CodeSeg(0x01B, 0x01B, "esc"), - new CodeSeg(0x020, 0x024, "space, up, down, end, home"), - new CodeSeg(0x025, 0x028, "cursor"), - new CodeSeg(0x02C, 0x02F, ", - . /"), - new CodeSeg(0x030, 0x039, "0 - 9"), - new CodeSeg(0x03B, 0x03B, ";"), - new CodeSeg(0x03D, 0x03D, "="), - new CodeSeg(0x041, 0x05A, "a - z"), - new CodeSeg(0x05B, 0x05D, "[ \\ ]"), - // new CodeSeg(0x060, 0x06B, "numpad1"), // can be mapped to normal keycodes - // new CodeSeg(0x06D, 0x06F, "numpad2"), // can be mapped to normal keycodes - new CodeSeg(0x07F, 0x07F, "del"), - // new CodeSeg(0x090, 0x091, "num lock, scroll lock"), - // new CodeSeg(0x070, 0x07B, "F1 - F12"), - // new CodeSeg(0x09A, 0x09D, "prt ins hlp meta"), - new CodeSeg(0x0C0, 0x0C0, "back quote"), - new CodeSeg(0x0DE, 0x0DE, "quote"), - // new CodeSeg(0x0E0, 0x0E3, "cursor kp"), - // new CodeSeg(0x080, 0x08F, "dead-1"), - // new CodeSeg(0x096, 0x0A2, "& ^ \" < > { }"), - // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; .. + // new CodeSeg(KeyEvent.VK_HOME, KeyEvent.VK_PRINTSCREEN, "home, end, final, prnt"), + new CodeSeg(KeyEvent.VK_BACK_SPACE, KeyEvent.VK_BACK_SPACE, "bs"), + // new CodeSeg(KeyEvent.VK_TAB, KeyEvent.VK_TAB, "tab"), // TAB functions as focus traversal key + new CodeSeg(KeyEvent.VK_ENTER, KeyEvent.VK_ENTER, "cr"), + new CodeSeg(KeyEvent.VK_PAGE_DOWN, KeyEvent.VK_PAGE_DOWN, "pg_down"), + new CodeSeg(KeyEvent.VK_SHIFT, KeyEvent.VK_ALT, "shift, pg_up, ctrl, alt"), + // new CodeSeg(KeyEvent.VK_ALT_GRAPH, KeyEvent.VK_ALT_GRAPH, "alt_gr"), // AWT Robot produces 0xff7e on X11 + // new CodeSeg(KeyEvent.VK_SCROLL_LOCK, KeyEvent.VK_SCROLL_LOCK, "scroll lock"), + new CodeSeg(KeyEvent.VK_ESCAPE, KeyEvent.VK_ESCAPE, "esc"), + new CodeSeg(KeyEvent.VK_SPACE, KeyEvent.VK_SPACE, "space"), + new CodeSeg(KeyEvent.VK_QUOTE, KeyEvent.VK_QUOTE, "quote"), + new CodeSeg(KeyEvent.VK_COMMA, KeyEvent.VK_SLASH, ", - . /"), + new CodeSeg(KeyEvent.VK_0, KeyEvent.VK_9, "0 - 9"), + new CodeSeg(KeyEvent.VK_SEMICOLON, KeyEvent.VK_SEMICOLON, ";"), + new CodeSeg(KeyEvent.VK_EQUALS, KeyEvent.VK_EQUALS, "="), + new CodeSeg(KeyEvent.VK_A, KeyEvent.VK_Z, "a - z"), + new CodeSeg(KeyEvent.VK_OPEN_BRACKET, KeyEvent.VK_CLOSE_BRACKET, "[ \\ ]"), + new CodeSeg(KeyEvent.VK_BACK_QUOTE, KeyEvent.VK_BACK_QUOTE, "`"), + new CodeSeg(KeyEvent.VK_F1, KeyEvent.VK_F8, "f1..f8"), + // new CodeSeg(KeyEvent.VK_F1, KeyEvent.VK_F12, "f1..f12"), // f9-f12 may cause some odd desktop functions! + new CodeSeg(KeyEvent.VK_DELETE, KeyEvent.VK_DELETE, "del"), + // new CodeSeg(KeyEvent.VK_NUMPAD0, KeyEvent.VK_NUMPAD9, "numpad0-9"), // can be mapped to normal keycodes + // new CodeSeg(KeyEvent.VK_DECIMAL, KeyEvent.VK_DIVIDE, "numpad ops"), // can be mapped to normal keycodes + // new CodeSeg(KeyEvent.VK_NUM_LOCK, KeyEvent.VK_NUM_LOCK, "num lock"), + // new CodeSeg(KeyEvent.VK_KP_LEFT, KeyEvent.VK_KP_DOWN, "numpad cursor arrows"), + new CodeSeg(KeyEvent.VK_LEFT, KeyEvent.VK_DOWN, "cursor arrows"), + // new CodeSeg(KeyEvent.VK_WINDOWS, KeyEvent.VK_HELP, "windows, meta, hlp"), }; static void testKeyCodes(Robot robot, NEWTKeyAdapter keyAdapter) { @@ -191,23 +194,23 @@ public class TestNewtKeyCodesAWT extends UITestCase { final CodeSeg codeSeg = codeSegments[i]; // System.err.println("*** Segment "+codeSeg.description); int eventCount = 0; - for(short c=codeSeg.min; c<=codeSeg.max; c++) { + for(short c=codeSeg.min; c<=codeSeg.max; c++) { // System.err.println("*** KeyCode 0x"+Integer.toHexString(c)); try { - AWTRobotUtil.keyPress(0, robot, true, c, 10); + AWTRobotUtil.newtKeyPress(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); + AWTRobotUtil.newtKeyPress(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) ) { + if( KeyEvent.isPrintableKey(c, false) ) { eventCount++; } robot.waitForIdle(); 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 4195711d6..e128123ed 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -29,6 +29,7 @@ package com.jogamp.opengl.test.junit.util; import jogamp.newt.WindowImplAccess; +import jogamp.newt.awt.event.AWTNewtEventFactory; import java.lang.reflect.InvocationTargetException; import java.awt.AWTException; @@ -449,6 +450,19 @@ public class AWTRobotUtil { return (int) ( System.currentTimeMillis() - t0 ) ; } + /** No validation is performed .. */ + public static int newtKeyPress(int i, Robot robot, boolean press, short newtKeyCode, int msDelay) { + final int keyCode = AWTNewtEventFactory.newtKeyCode2AWTKeyCode(newtKeyCode); + final long t0 = System.currentTimeMillis(); + if(press) { + awtRobotKeyPress(robot, keyCode, msDelay); + } else { + awtRobotKeyRelease(robot, keyCode, msDelay); + } + + return (int) ( System.currentTimeMillis() - t0 ) ; + } + /** * @param keyCode TODO * @param counter shall return the number of keys typed (press + release) 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 d007d2424..1def57edf 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java @@ -104,7 +104,7 @@ public class NEWTKeyUtil { missCodes.add(new CodeEvent(c, codeSeg.description, e)); misses++; } - if( KeyEvent.isPrintableKey(c) ) { + if( KeyEvent.isPrintableKey(c, false) ) { evtIdx += 3; // w/ TYPED } else { evtIdx += 2; @@ -118,17 +118,17 @@ public class NEWTKeyUtil { return res; } - public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode, char keyChar) { + public static void validateKeyEvent(KeyEvent e, short eventType, int modifiers, short 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 <= modifiers) { + Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifiers)+", has "+e, modifiers == e.getModifiers()); } - if(0 < keyCode) { + if(KeyEvent.VK_UNDEFINED != keyCode) { Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode()); } - if(0 < keyChar) { + if(KeyEvent.NULL_CHAR != keyChar) { Assert.assertTrue("KeyEvent char mismatch, expected 0x"+Integer.toHexString(keyChar)+", has "+e, keyChar == e.getKeyChar()); } } @@ -168,17 +168,17 @@ public class NEWTKeyUtil { * @param keyAdapter * @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 expTypedCountSI number of single key types events, set to -1 to ignore * @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 + * @param expTypedCountAR number of auto-repeat key types events, set to -1 to ignore */ 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 expPressReleaseCountSI = expPressedCountSI + expReleasedCountSI; + final int expPressReleaseCountAR = expPressedCountAR + expReleasedCountAR; + final int expPressReleaseCountALL = expPressReleaseCountSI + expPressReleaseCountAR; final int keyPressedALL = keyAdapter.getKeyPressedCount(false); final int keyPressedAR = keyAdapter.getKeyPressedCount(true); @@ -191,35 +191,39 @@ public class NEWTKeyUtil { 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; + final int pressReleaseCountALL = keyPressedALL + keyReleasedALL; + final int pressReleaseCountSI = keyPressedSI + keyReleasedSI; + final int pressReleaseCountAR = keyPressedAR + keyReleasedAR; - 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("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI +", Typed "+expTypedCountSI); + System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR +", Typed "+expTypedCountAR); - 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); + System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Typed "+keyTypedSI +", Events "+pressReleaseCountSI); + System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Typed "+keyTypedAR +", Events "+pressReleaseCountAR); + System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Typed "+keyTypedALL+", Events "+pressReleaseCountALL); - Assert.assertEquals("Internal Error: totalSI != totalALL - totalAR", totalCountSI, totalCountALL - totalCountAR); + Assert.assertEquals("Internal Error: pressReleaseSI != pressReleaseALL - pressReleaseAR", pressReleaseCountSI, pressReleaseCountALL - pressReleaseCountAR); Assert.assertEquals("Invalid: Has AR Typed events", 0, keyTypedAR); - Assert.assertEquals("Invalid: Exp AR Typed events", 0, expTypedCountAR); + if( 0 <= expTypedCountAR ) { + 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); + if( 0 <= expTypedCountSI ) { + 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); + Assert.assertEquals("Key pressRelease count failure (SI)", expPressReleaseCountSI, pressReleaseCountSI); + Assert.assertEquals("Key pressRelease count failure (AR)", expPressReleaseCountAR, pressReleaseCountAR); final List<EventObject> keyEvents = keyAdapter.getQueued(); - 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()); + Assert.assertEquals("Key pressRelease count failure (ALL) w/ list sum ", expPressReleaseCountALL, pressReleaseCountALL); + Assert.assertEquals("Key total count failure (ALL) w/ list size ", pressReleaseCountALL + keyTypedALL, keyEvents.size()); } } |