summaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-10-31 04:04:39 +0100
committerSven Gothel <[email protected]>2012-10-31 04:04:39 +0100
commitb62e1d027c289877686d6008ea8dd40e4e1541ec (patch)
treef0af41cb2c9bdd92c37192880439843de1b85f32 /src/newt/classes
parentdda5e1611fc41089a5f8d486435d3d2d7e9b76d6 (diff)
Fix NEWT KeyEvent: Deliver keyChar w/ pressed and released; Deliver proper modified flags and modifier-key events; Simplify Windows key handling
Preface: Modifier-keys are SHIFT, CTRL, ALT and META and they have a matching modifier-bit. - Simplify Windows key handling - Employ MapVirtualKey(..) for virtual-key to character and scancode to virtual-key mappings, allowing to drop tracking of keyCode to keyChar in java code. This also removes the platform restriction of delivering keyChar at TYPED only. - Deliver keyChar w/ pressed and released - Due to the lift restriction on the Windows platform (see above), we can deliver keyChar w/ all key events on all platforms. - Deliver proper modified flags and modifier-key events All modifier-keys deliver pressed, released and typed events with their modifier-bit set. The above is covered by unit tests, which passed on X11, Windows and OSX (manual test run).
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java111
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java40
3 files changed, 84 insertions, 78 deletions
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 8d3d9e88f..927c9aa85 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -59,6 +59,10 @@ package com.jogamp.newt.event;
* 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>
+ * <p>
+ * {@link #isModifierKey() Modifiers keys} will produce regular events (pressed, released and typed),
+ * however they will not produce Auto-Repeat events itself.
+ * </p>
*/
@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
@@ -69,12 +73,12 @@ public class KeyEvent extends InputEvent
this.keyChar=keyChar;
}
- /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */
+ /** Returns the character matching the {@link #getKeyCode() virtual key code}, if exist. */
public char getKeyChar() {
return keyChar;
}
- /** Always valid. */
+ /** Returns the virtual key code. */
public int getKeyCode() {
return keyCode;
}
@@ -100,49 +104,68 @@ public class KeyEvent extends InputEvent
}
}
- public boolean isActionKey() {
+ /** Returns true if <code>keyCode</code> represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+ public static boolean isModifierKey(int keyCode) {
+ switch (keyCode) {
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_ALT:
+ case VK_ALT_GRAPH:
+ case VK_META:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /** Returns true if {@link #getKeyCode()} represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+ public boolean isModifierKey() {
+ return isModifierKey(keyCode);
+ }
+
+ public boolean isActionKey() {
switch (keyCode) {
- case VK_HOME:
- case VK_END:
- case VK_PAGE_UP:
- case VK_PAGE_DOWN:
- case VK_UP:
- case VK_DOWN:
- case VK_LEFT:
- case VK_RIGHT:
-
- case VK_F1:
- case VK_F2:
- case VK_F3:
- case VK_F4:
- case VK_F5:
- case VK_F6:
- case VK_F7:
- case VK_F8:
- case VK_F9:
- case VK_F10:
- case VK_F11:
- case VK_F12:
- case VK_F13:
- case VK_F14:
- case VK_F15:
- case VK_F16:
- case VK_F17:
- case VK_F18:
- case VK_F19:
- case VK_F20:
- case VK_F21:
- case VK_F22:
- case VK_F23:
- case VK_F24:
- case VK_PRINTSCREEN:
- case VK_CAPS_LOCK:
- case VK_PAUSE:
- case VK_INSERT:
-
- case VK_HELP:
- case VK_WINDOWS:
- return true;
+ case VK_HOME:
+ case VK_END:
+ case VK_PAGE_UP:
+ case VK_PAGE_DOWN:
+ case VK_UP:
+ case VK_DOWN:
+ case VK_LEFT:
+ case VK_RIGHT:
+
+ case VK_F1:
+ case VK_F2:
+ case VK_F3:
+ case VK_F4:
+ case VK_F5:
+ case VK_F6:
+ case VK_F7:
+ case VK_F8:
+ case VK_F9:
+ case VK_F10:
+ case VK_F11:
+ case VK_F12:
+ case VK_F13:
+ case VK_F14:
+ case VK_F15:
+ case VK_F16:
+ case VK_F17:
+ case VK_F18:
+ case VK_F19:
+ case VK_F20:
+ case VK_F21:
+ case VK_F22:
+ case VK_F23:
+ case VK_F24:
+ case VK_PRINTSCREEN:
+ case VK_CAPS_LOCK:
+ case VK_PAUSE:
+ case VK_INSERT:
+
+ case VK_HELP:
+ case VK_WINDOWS:
+ return true;
}
return false;
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 121c3fa99..5755bdf11 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -324,9 +324,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
// Note that we send the key char for the key code on this
// platform -- we do not get any useful key codes out of the system
final int keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(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);
+
+ // 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED
// Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE and TYPED keys _before_ PRESSED
switch(eventType) {
case KeyEvent.EVENT_KEY_RELEASED:
@@ -334,7 +335,6 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
keyRepeatState.put(keyCode, false); // prev == true -> AR out
keyPressedState.put(keyCode, false);
}
- keyChar = (char)-1;
break;
case KeyEvent.EVENT_KEY_PRESSED:
if( isKeyCodeTracked(keyCode) ) {
@@ -342,11 +342,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
// key was already pressed
keyRepeatState.put(keyCode, true); // prev == false -> AR in
modifiers |= InputEvent.AUTOREPEAT_MASK;
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); // RELEASED
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar); // RELEASED
emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED
}
}
- keyChar = (char)-1;
break;
case KeyEvent.EVENT_KEY_TYPED:
break;
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 8b57a241d..c513b9e84 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -46,7 +46,6 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
-import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseAdapter;
@@ -260,11 +259,6 @@ public class WindowDriver extends WindowImpl {
// nop - using event driven insetsChange(..)
}
- /** We have to regenerate the keyCode for EVENT_KEY_TYPED on this platform. */
- private int lastPressedKeyCode = 0;
- /** We have to reorder the native key events to match NEWT's order */
- private IntIntHashMap typedKeyCode2KeyChar = new IntIntHashMap(KeyEvent.VK_CONTEXT_MENU+1);
-
private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
if( send ) {
super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
@@ -274,52 +268,42 @@ public class WindowDriver extends WindowImpl {
}
private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- // final int kc = 0 <= keyCode ? keyCode : lastPressedKeyCode;
- // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", key "+toHexString(kc)+", mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(kc)+", repeat "+isKeyInAutoRepeat(kc));
-
+ final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+ // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+
// 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:
if( isKeyCodeTracked(keyCode) ) {
- if( keyRepeatState.put(keyCode, false) ) {
+ if( keyRepeatState.put(keyCode, false) && !isModifierKeyCode ) {
// AR out - send out missing PRESSED
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, (char)-1);
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
}
keyPressedState.put(keyCode, false);
}
emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
- final char lastTypedKeyChar = (char) typedKeyCode2KeyChar.put(keyCode, 0);
- if( 0 < lastTypedKeyChar ) {
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, lastTypedKeyChar);
- }
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
break;
case KeyEvent.EVENT_KEY_PRESSED:
- lastPressedKeyCode = keyCode;
if( isKeyCodeTracked(keyCode) ) {
if( keyPressedState.put(keyCode, true) ) {
// key was already pressed
- if( keyRepeatState.put(keyCode, true) ) {
- emitKeyEvent(send, wait, eventType, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, (char)-1);
- } // else AR in - skip already send PRESSED
+ if( keyRepeatState.put(keyCode, true) && !isModifierKeyCode ) {
+ emitKeyEvent(send, wait, eventType, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+ } // else AR in - skip already send PRESSED ; or ALT
} else {
- emitKeyEvent(send, wait, eventType, modifiers, keyCode, (char)-1);
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
}
} else {
- emitKeyEvent(send, wait, eventType, modifiers, keyCode, (char)-1);
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
}
break;
case KeyEvent.EVENT_KEY_TYPED:
- if(-1==keyCode) {
- keyCode = lastPressedKeyCode;
- }
- lastPressedKeyCode = -1;
if( 1 == isKeyInAutoRepeat(keyCode) ) {
modifiers |= InputEvent.AUTOREPEAT_MASK;
- emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1);
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar);
emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
- } else {
- typedKeyCode2KeyChar.put(keyCode, keyChar);
}
break;
}