changeset 6019:3f3be4c811d1

RT-32300: KeyCodes do not reflect the keys that are actually pressed on German keyboard Summary: Map OEM keys to correct key codes Reviewed-by: snorthov
author Anthony Petrov <anthony.petrov@oracle.com>
date Mon, 23 Dec 2013 19:54:26 +0400
parents e79d7e912439
children fb2575b13c01
files modules/graphics/src/main/java/com/sun/glass/events/KeyEvent.java modules/graphics/src/main/native-glass/win/ViewContainer.cpp
diffstat 2 files changed, 109 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/glass/events/KeyEvent.java	Mon Dec 23 10:15:31 2013 -0500
+++ b/modules/graphics/src/main/java/com/sun/glass/events/KeyEvent.java	Mon Dec 23 19:54:26 2013 +0400
@@ -218,6 +218,23 @@
     public final static int VK_F23                = 0xF00A;
     public final static int VK_F24                = 0xF00B;
 
+    public final static int VK_DEAD_GRAVE               = 0x80;
+    public final static int VK_DEAD_ACUTE               = 0x81;
+    public final static int VK_DEAD_CIRCUMFLEX          = 0x82;
+    public final static int VK_DEAD_TILDE               = 0x83;
+    public final static int VK_DEAD_MACRON              = 0x84;
+    public final static int VK_DEAD_BREVE               = 0x85;
+    public final static int VK_DEAD_ABOVEDOT            = 0x86;
+    public final static int VK_DEAD_DIAERESIS           = 0x87;
+    public final static int VK_DEAD_ABOVERING           = 0x88;
+    public final static int VK_DEAD_DOUBLEACUTE         = 0x89;
+    public final static int VK_DEAD_CARON               = 0x8a;
+    public final static int VK_DEAD_CEDILLA             = 0x8b;
+    public final static int VK_DEAD_OGONEK              = 0x8c;
+    public final static int VK_DEAD_IOTA                = 0x8d;
+    public final static int VK_DEAD_VOICED_SOUND        = 0x8e;
+    public final static int VK_DEAD_SEMIVOICED_SOUND    = 0x8f;
+
     /***************************************************************************
      *                                                                         *
      * Static Methods                                                          *
--- a/modules/graphics/src/main/native-glass/win/ViewContainer.cpp	Mon Dec 23 10:15:31 2013 -0500
+++ b/modules/graphics/src/main/native-glass/win/ViewContainer.cpp	Mon Dec 23 19:54:26 2013 +0400
@@ -293,10 +293,101 @@
     }
 
     WORD mbChar;
-    UINT scancode = ::MapVirtualKey(wKey, 0);
+    UINT scancode = ::MapVirtualKeyEx(wKey, 0, m_kbLayout);
     int converted = ::ToAsciiEx(wKey, scancode, kbState,
                                 &mbChar, 0, m_kbLayout);
 
+    // Depress modifiers to map a Unicode char to a key code
+    kbState[VK_CONTROL] &= ~0x80;
+    kbState[VK_SHIFT]   &= ~0x80;
+    kbState[VK_MENU]    &= ~0x80;
+    wchar_t wChar[4] = {0};
+    int unicodeConverted = ::ToUnicodeEx(wKey, scancode, kbState,
+                                wChar, 4, 0, m_kbLayout);
+    
+    // Some virtual codes require special handling
+    switch (wKey) {
+        case 0x00BA:// VK_OEM_1
+        case 0x00BB:// VK_OEM_PLUS
+        case 0x00BC:// VK_OEM_COMMA
+        case 0x00BD:// VK_OEM_MINUS
+        case 0x00BE:// VK_OEM_PERIOD
+        case 0x00BF:// VK_OEM_2
+        case 0x00C0:// VK_OEM_3
+        case 0x00DB:// VK_OEM_4
+        case 0x00DC:// VK_OEM_5
+        case 0x00DD:// VK_OEM_6
+        case 0x00DE:// VK_OEM_7
+        case 0x00DF:// VK_OEM_8
+        case 0x00E2:// VK_OEM_102
+            if (unicodeConverted < 0) {
+                // Dead key
+                switch (wChar[0]) {
+                    case L'`':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_GRAVE; break;
+                    case L'\'':  jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_ACUTE; break;
+                    case 0x00B4: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_ACUTE; break;
+                    case L'^':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_CIRCUMFLEX; break;
+                    case L'~':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_TILDE; break;
+                    case 0x02DC: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_TILDE; break;
+                    case 0x00AF: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_MACRON; break;
+                    case 0x02D8: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_BREVE; break;
+                    case 0x02D9: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_ABOVEDOT; break;
+                    case L'"':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_DIAERESIS; break;
+                    case 0x00A8: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_DIAERESIS; break;
+                    case 0x02DA: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_ABOVERING; break;
+                    case 0x02DD: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_DOUBLEACUTE; break;
+                    case 0x02C7: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_CARON; break;            // aka hacek
+                    case L',':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_CEDILLA; break;
+                    case 0x00B8: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_CEDILLA; break;
+                    case 0x02DB: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_OGONEK; break;
+                    case 0x037A: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_IOTA; break;             // ASCII ???
+                    case 0x309B: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_VOICED_SOUND; break;
+                    case 0x309C: jKeyCode = com_sun_glass_events_KeyEvent_VK_DEAD_SEMIVOICED_SOUND; break;
+
+                    default:     jKeyCode = com_sun_glass_events_KeyEvent_VK_UNDEFINED; break;
+                };
+            } else if (unicodeConverted == 1) {
+                switch (wChar[0]) {
+                    case L'!':   jKeyCode = com_sun_glass_events_KeyEvent_VK_EXCLAMATION; break;
+                    case L'"':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DOUBLE_QUOTE; break;
+                    case L'#':   jKeyCode = com_sun_glass_events_KeyEvent_VK_NUMBER_SIGN; break;
+                    case L'$':   jKeyCode = com_sun_glass_events_KeyEvent_VK_DOLLAR; break;
+                    case L'&':   jKeyCode = com_sun_glass_events_KeyEvent_VK_AMPERSAND; break;
+                    case L'\'':  jKeyCode = com_sun_glass_events_KeyEvent_VK_QUOTE; break;
+                    case L'(':   jKeyCode = com_sun_glass_events_KeyEvent_VK_LEFT_PARENTHESIS; break;
+                    case L')':   jKeyCode = com_sun_glass_events_KeyEvent_VK_RIGHT_PARENTHESIS; break;
+                    case L'*':   jKeyCode = com_sun_glass_events_KeyEvent_VK_ASTERISK; break;
+                    case L'+':   jKeyCode = com_sun_glass_events_KeyEvent_VK_PLUS; break;
+                    case L',':   jKeyCode = com_sun_glass_events_KeyEvent_VK_COMMA; break;
+                    case L'-':   jKeyCode = com_sun_glass_events_KeyEvent_VK_MINUS; break;
+                    case L'.':   jKeyCode = com_sun_glass_events_KeyEvent_VK_PERIOD; break;
+                    case L'/':   jKeyCode = com_sun_glass_events_KeyEvent_VK_SLASH; break;
+                    case L':':   jKeyCode = com_sun_glass_events_KeyEvent_VK_COLON; break;
+                    case L';':   jKeyCode = com_sun_glass_events_KeyEvent_VK_SEMICOLON; break;
+                    case L'<':   jKeyCode = com_sun_glass_events_KeyEvent_VK_LESS; break;
+                    case L'=':   jKeyCode = com_sun_glass_events_KeyEvent_VK_EQUALS; break;
+                    case L'>':   jKeyCode = com_sun_glass_events_KeyEvent_VK_GREATER; break;
+                    case L'@':   jKeyCode = com_sun_glass_events_KeyEvent_VK_AT; break;
+                    case L'[':   jKeyCode = com_sun_glass_events_KeyEvent_VK_OPEN_BRACKET; break;
+                    case L'\\':  jKeyCode = com_sun_glass_events_KeyEvent_VK_BACK_SLASH; break;
+                    case L']':   jKeyCode = com_sun_glass_events_KeyEvent_VK_CLOSE_BRACKET; break;
+                    case L'^':   jKeyCode = com_sun_glass_events_KeyEvent_VK_CIRCUMFLEX; break;
+                    case L'_':   jKeyCode = com_sun_glass_events_KeyEvent_VK_UNDERSCORE; break;
+                    case L'`':   jKeyCode = com_sun_glass_events_KeyEvent_VK_BACK_QUOTE; break;
+                    case L'{':   jKeyCode = com_sun_glass_events_KeyEvent_VK_BRACELEFT; break;
+                    case L'}':   jKeyCode = com_sun_glass_events_KeyEvent_VK_BRACERIGHT; break;
+                    case 0x00A1: jKeyCode = com_sun_glass_events_KeyEvent_VK_INV_EXCLAMATION; break;
+                    case 0x20A0: jKeyCode = com_sun_glass_events_KeyEvent_VK_EURO_SIGN; break;
+
+                    default:     jKeyCode = com_sun_glass_events_KeyEvent_VK_UNDEFINED; break;
+                }
+            } else if (unicodeConverted == 0 || unicodeConverted > 1) {
+                jKeyCode = com_sun_glass_events_KeyEvent_VK_UNDEFINED;
+            }
+            break;
+    };
+
+
     int keyCharCount = 0;
     jchar keyChars[4];
     const bool isAutoRepeat = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN)