src/windows/native/sun/windows/awt_Component.cpp

Print this page

        

@@ -3142,11 +3142,12 @@
     *windowsKey = 0;
     *modifiers = 0;
     return;
 }
 
-UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
+UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)
+
 {
     // Handle the few cases where we need to take the modifier into
     // consideration for the Java VK code or where we have to take the keyboard
     // layout into consideration so that function keys can get
     // recognized in a platform-independent way.

@@ -3169,10 +3170,19 @@
                 return java_awt_event_KeyEvent_VK_KANA_LOCK;
             }
             break;
     };
 
+    // check dead key
+    if(isDeadKey){
+      for (int i = 0; charToDeadVKTable[i].c != 0; i++) {
+        if (charToDeadVKTable[i].c == character) {
+            return charToDeadVKTable[i].javaKey;
+        }
+      }
+    }
+
     // for the general case, use a bi-directional table
     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
         if (keyMapTable[i].windowsKey == windowsKey) {
             return keyMapTable[i].javaKey;
         }

@@ -3382,18 +3392,22 @@
             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
         }
     }
 }
 
-UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
+UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)
 {
     static Hashtable transTable("VKEY translations");
+    static Hashtable deadKeyFlagTable("Dead Key Flags");
+    isDeadKey = FALSE;
 
     // Try to translate using last saved translation
     if (ops == LOAD) {
+       void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
        if (value != NULL) {
+           isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
        }
     }
 
     // If the windows key is a return, wkey will equal 13 ('\r')

@@ -3482,16 +3496,17 @@
         } // ctrlIsDown
     } // modifiers
 
     // instead of creating our own conversion tables, I'll let Win32
     // convert the character for me.
-    WORD mbChar;
+    WORD wChar[2];
     UINT scancode = ::MapVirtualKey(wkey, 0);
-    int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
-                                &mbChar, 0, GetKeyboardLayout());
+    int converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
+                                  wChar, 2, 0, GetKeyboardLayout()); 
 
     UINT translation;
+    BOOL deadKeyFlag = (converted == 2);
 
     // Dead Key
     if (converted < 0) {
         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
     } else

@@ -3506,20 +3521,20 @@
             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
         }
     } else
     // the caller expects a Unicode character.
     if (converted > 0) {
-        WCHAR unicodeChar[2];
-        VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED,
-        (LPCSTR)&mbChar, 1, unicodeChar, 1));
-
-        translation = unicodeChar[0];
+        translation = wChar[0];
     }
     if (ops == SAVE) {
         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
+        deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
+                       reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
     }
+
+    isDeadKey = deadKeyFlag;
     return translation;
 }
 
 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
                                    UINT flags, BOOL system)

@@ -3535,12 +3550,13 @@
     InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),
                              wkey, MAKELPARAM(repCnt, flags));
 
     UINT modifiers = GetJavaModifiers();
     jint keyLocation = GetKeyLocation(wkey, flags);
-    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
-    UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+    BOOL isDeadKey = FALSE;
+    UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);
+    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
 
 
     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
                              TimeHelper::windowsToUTC(msg.time), jkey, character,

@@ -3577,12 +3593,13 @@
     InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),
                              wkey, MAKELPARAM(repCnt, flags));
 
     UINT modifiers = GetJavaModifiers();
     jint keyLocation = GetKeyLocation(wkey, flags);
-    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
-    UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
+    BOOL isDeadKey = FALSE;
+    UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);
+    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
 
     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
                              TimeHelper::windowsToUTC(msg.time), jkey, character,
                              modifiers, keyLocation, (jlong)wkey, &msg);

@@ -5626,11 +5643,12 @@
                         if (newWinKey != 0) {
                             winKey = newWinKey;
                         }
                     }
 
-                    modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE);
+                    BOOL isDeadKey = FALSE;
+                    modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);
                     bCharChanged = (keyChar != modifiedChar);
                 }
                 break;
 
                 case java_awt_event_KeyEvent_KEY_RELEASED: