summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-10-26 16:43:13 +0200
committerSven Gothel <[email protected]>2012-10-26 16:43:13 +0200
commitb008de41549e38aebdfcb7b094046235a8dde72f (patch)
tree4e51584207f22bd7203d1cc64bdab25e7a171eae /src/newt
parent4f05d5add18048c2fbd1837c0563446c11177e8c (diff)
Fix Bug 601 - Auto-Repeat Behavior: Adding unit tests for typed key order w/ and w/o auto repeat. Incl. fix for Windows.
Auto-Repeat tests recognizes whether auto-repeat could be triggered by AWT Robot. The latter is not possible on Windows, hence manual testing was required on this platform. Impact: X11, Windows and OSX produce proper key sequence incl. auto-repeat modifier mask.
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java11
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java82
-rw-r--r--src/newt/native/X11Display.c2
4 files changed, 61 insertions, 40 deletions
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 7daaeada6..b6f4264f5 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -48,6 +48,17 @@ package com.jogamp.newt.event;
* Besides regular modifiers like {@link InputEvent#SHIFT_MASK} etc.,
* the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected.
* </p>
+ * <p>
+ * Auto-Repeat shall behave as follow:
+ * <pre>
+ D = pressed, U = released, T = typed
+ 0 = normal, 1 = auto-repeat
+
+ D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ * </pre>
+ * The idea is if you mask out auto-repeat in your event listener
+ * you just get one long pressed key D/U/T triple.
+ * </p>
*/
@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index fd5b69ccc..9d8d92ff6 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -161,11 +161,7 @@ public class NEWTEvent extends java.util.EventObject {
return sb.append("NEWTEvent[sys:").append(isSystemEvent()).append(", source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
}
- public static String toHexString(int hex) {
+ static String toHexString(int hex) {
return "0x" + Integer.toHexString(hex);
}
-
- public static String toHexString(long hex) {
- return "0x" + Long.toHexString(hex);
- }
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 71437c461..c211bac61 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -279,61 +279,73 @@ public class WindowDriver extends WindowImpl {
return keyCode;
}
private int lastPressedKeyCode = 0;
+ private char lastTypedKeyChar = 0;
private int pressedKeyBalance = 0;
private int autoRepeat = 0;
- @Override
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ if( send ) {
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ } else {
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+ }
+ }
+
+ private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", mods "+toHexString(modifiers));
+
// Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
keyCode = validateKeyCode(eventType, modifiers, keyCode, keyChar);
+
+ // Reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED
+ // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED.
switch(eventType) {
case KeyEvent.EVENT_KEY_RELEASED:
- // reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED
+ if( 0 != autoRepeat ) {
+ // AR out - send out missing PRESSED
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | autoRepeat, keyCode, lastTypedKeyChar);
+ }
+ autoRepeat = 0;
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ if( 0 != lastTypedKeyChar ) {
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, lastTypedKeyChar);
+ lastTypedKeyChar = 0;
+ }
break;
case KeyEvent.EVENT_KEY_PRESSED:
- if(pressedKeyBalance > 1) {
- // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED.
- // Since reordering already injects RELEASE, we only need to set the AUTOREPEAT_MASK.
+ if( pressedKeyBalance > 1 ) {
pressedKeyBalance--;
- autoRepeat |= InputEvent.AUTOREPEAT_MASK;
+ if ( 0 == autoRepeat ) {
+ // AR in - skip already send PRESSED
+ autoRepeat = InputEvent.AUTOREPEAT_MASK;
+ } else {
+ emitKeyEvent(send, wait, eventType, modifiers | autoRepeat, keyCode, (char)-1);
+ }
} else {
- autoRepeat &= ~InputEvent.AUTOREPEAT_MASK;
+ autoRepeat = 0;
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, (char)-1);
}
- super.sendKeyEvent(eventType, modifiers | autoRepeat, keyCode, (char)-1);
break;
case KeyEvent.EVENT_KEY_TYPED:
- modifiers |= autoRepeat;
- super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1);
- super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ if( 0 == autoRepeat ) {
+ lastTypedKeyChar = keyChar;
+ } else {
+ modifiers |= autoRepeat;
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1);
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ }
break;
}
}
@Override
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
+ }
+
+ @Override
public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
- keyCode = validateKeyCode(eventType, modifiers, keyCode, keyChar);
- switch(eventType) {
- case KeyEvent.EVENT_KEY_RELEASED:
- // reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED
- break;
- case KeyEvent.EVENT_KEY_PRESSED:
- if(pressedKeyBalance > 1) {
- // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED.
- // Since reordering already injects RELEASE, we only need to set the AUTOREPEAT_MASK.
- pressedKeyBalance--;
- autoRepeat |= InputEvent.AUTOREPEAT_MASK;
- } else {
- autoRepeat &= ~InputEvent.AUTOREPEAT_MASK;
- }
- super.enqueueKeyEvent(wait, eventType, modifiers | autoRepeat, keyCode, (char)-1);
- break;
- case KeyEvent.EVENT_KEY_TYPED:
- modifiers |= autoRepeat;
- super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1);
- super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
- break;
- }
+ handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
}
//----------------------------------------------------------------------
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index d8202fcde..9f29acc0c 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -381,6 +381,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
} else {
autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
}
+ } else {
+ autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
}
// fall through intended
case KeyPress: