diff options
author | Sven Gothel <[email protected]> | 2012-09-16 21:13:51 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-09-16 21:13:51 +0200 |
commit | 646714d3dab87396b9a3119bf90ca26e0b1c97ce (patch) | |
tree | 678209f657c5f3bfa29e54c171565488a15f9951 /src/newt/classes/jogamp | |
parent | f2bd50ff25009de477a203460abe8a5597acdbc5 (diff) |
Fix Bug 601: Harmonize order of key events incl. auto-repeat and adding AUTOREPEAT_MASK modifier bit. Refine InputEvent toString(..) and list modifiers by name.
As now described in NEWT's KeyEvent:
+/**
+ * Key events are delivered in the following order:
+ * <ol>
+ * <li>{@link #EVENT_KEY_PRESSED}</li>
+ * <li>{@link #EVENT_KEY_RELEASED}</li>
+ * <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * In case the native platform does not
+ * deliver keyboard events in the above order or skip events,
+ * the NEWT driver will reorder and inject synthetic events if required.
+ * <p>
+ * Besides regular modifiers like {@link InputEvent##SHIFT_MASK} etc.,
+ * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected.
+ * </p>
+ */
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java | 20 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java | 36 |
2 files changed, 52 insertions, 4 deletions
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index d0c0b8b20..4eeafb244 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -49,6 +49,7 @@ import jogamp.newt.WindowImpl; import jogamp.newt.driver.DriverClearFocus; import jogamp.newt.driver.DriverUpdatePosition; +import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition { @@ -313,6 +314,14 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); if(valid) { + if(pressedKeyBalance > 1) { + // Auto-Repeat: OSX delivers only PRESSED + // inject auto-repeat RELEASE and TYPED keys _before_ + pressedKeyBalance--; + modifiers |= InputEvent.AUTOREPEAT_MASK; + super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); // RELEASED + super.sendKeyEvent(KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED + } // only deliver keyChar on key Typed events, harmonizing platform behavior keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar); @@ -327,6 +336,14 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); if(valid) { + if(pressedKeyBalance > 1) { + // Auto-Repeat: OSX delivers only PRESSED + // inject auto-repeat RELEASE and TYPED keys _before_ + pressedKeyBalance--; + modifiers |= InputEvent.AUTOREPEAT_MASK; + super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); // RELEASED + super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED + } // only deliver keyChar on key Typed events, harmonizing platform behavior keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar); @@ -335,14 +352,17 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl private int keyDownModifiers = 0; private int keyDownCode = 0; + private int pressedKeyBalance = 0; private boolean validateKeyEvent(int eventType, int modifiers, int keyCode) { switch(eventType) { case KeyEvent.EVENT_KEY_PRESSED: + pressedKeyBalance++; keyDownModifiers = modifiers; keyDownCode = keyCode; return true; case KeyEvent.EVENT_KEY_RELEASED: + pressedKeyBalance--; return keyDownModifiers == modifiers && keyDownCode == keyCode; case KeyEvent.EVENT_KEY_TYPED: final boolean matchKeyDown = keyDownModifiers == modifiers && keyDownCode == keyCode; diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index 5dbdeb458..18cc88472 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -46,6 +46,7 @@ import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; +import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; @@ -258,9 +259,14 @@ public class WindowDriver extends WindowImpl { // nop - using event driven insetsChange(..) } - private final int validateKeyCode(int eventType, int keyCode) { + private final int validateKeyCode(int eventType, int modifiers, int keyCode, char keyChar) { switch(eventType) { + case KeyEvent.EVENT_KEY_RELEASED: + pressedKeyBalance--; + lastPressedKeyCode = keyCode; + break; case KeyEvent.EVENT_KEY_PRESSED: + pressedKeyBalance++; lastPressedKeyCode = keyCode; break; case KeyEvent.EVENT_KEY_TYPED: @@ -273,18 +279,40 @@ public class WindowDriver extends WindowImpl { return keyCode; } private int lastPressedKeyCode = 0; + private int pressedKeyBalance = 0; + private int autoRepeat = 0; @Override public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform - keyCode = validateKeyCode(eventType, keyCode); - super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + 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.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); + break; + } } @Override public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform - keyCode = validateKeyCode(eventType, keyCode); + keyCode = validateKeyCode(eventType, modifiers, keyCode, keyChar); super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar); } |