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

Print this page




3127         for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
3128             if (dynamicKeyMapTable[j].javaKey == javaKey) {
3129                 *windowsKey = dynamicKeyMapTable[j].windowsKey;
3130                 *modifiers = 0;
3131                 found = true;
3132                 if (*windowsKey == originalWindowsKey) {
3133                     return;   /* if ideal case found return, else keep looking */
3134                 }
3135             }
3136         }
3137         if (found) {
3138             return;
3139         }
3140     }
3141 
3142     *windowsKey = 0;
3143     *modifiers = 0;
3144     return;
3145 }
3146 
3147 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)

3148 {
3149     // Handle the few cases where we need to take the modifier into
3150     // consideration for the Java VK code or where we have to take the keyboard
3151     // layout into consideration so that function keys can get
3152     // recognized in a platform-independent way.
3153     switch (windowsKey) {
3154         case VK_CONVERT:
3155             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
3156                 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES;
3157             }
3158             if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) {
3159                 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE;
3160             }
3161             break;
3162         case VK_DBE_ALPHANUMERIC:
3163             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
3164                 return java_awt_event_KeyEvent_VK_CODE_INPUT;
3165             }
3166             break;
3167         case VK_KANA:
3168             if (isKanaLockAvailable()) {
3169                 return java_awt_event_KeyEvent_VK_KANA_LOCK;
3170             }
3171             break;
3172     };
3173 









3174     // for the general case, use a bi-directional table
3175     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
3176         if (keyMapTable[i].windowsKey == windowsKey) {
3177             return keyMapTable[i].javaKey;
3178         }
3179     }
3180 
3181     for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
3182         if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
3183             if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {
3184                 return dynamicKeyMapTable[j].javaKey;
3185             }else{
3186                 break;
3187             }
3188         }
3189     }
3190 
3191     return java_awt_event_KeyEvent_VK_UNDEFINED;
3192 }
3193 


3367         }
3368         kbdState[i] = 0; // "key unpressed"
3369     }
3370 }
3371 void
3372 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)
3373 {
3374     if( wkey && wkey < 256 ) {
3375         if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
3376             // At the creation time,
3377             // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"
3378             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
3379         }
3380         if(dynPrimaryKeymap[wkey].jkey ==  java_awt_event_KeyEvent_VK_UNDEFINED) {
3381             // E.g. it is non-unicode key
3382             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
3383         }
3384     }
3385 }
3386 
3387 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
3388 {
3389     static Hashtable transTable("VKEY translations");


3390 
3391     // Try to translate using last saved translation
3392     if (ops == LOAD) {

3393        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3394        if (value != NULL) {

3395            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
3396        }
3397     }
3398 
3399     // If the windows key is a return, wkey will equal 13 ('\r')
3400     // In this case, we want to return 10 ('\n')
3401     // Since ToAscii would convert VK_RETURN to '\r', we need
3402     // to have a special case here.
3403     if (wkey == VK_RETURN)
3404         return '\n';
3405 
3406     // high order bit in keyboardState indicates whether the key is down
3407     static const BYTE KEY_STATE_DOWN = 0x80;
3408     BYTE    keyboardState[AwtToolkit::KB_STATE_SIZE];
3409     AwtToolkit::GetKeyboardState(keyboardState);
3410 
3411     // apply modifiers to keyboard state if necessary
3412     if (modifiers) {
3413         BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
3414         BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK;


3467                     for (ch = _T('\033'); ch < _T('\040'); ch++) {
3468                         vk = ::VkKeyScan(ch);
3469                         if (wkey == LOBYTE(vk)) {
3470                             UINT shiftState = HIBYTE(vk);
3471                             if ((shiftState & _VKS_CTRL_MASK) ||
3472                                 (!(shiftState & _VKS_SHIFT_MASK)
3473                                 == !shiftIsDown))
3474                             {
3475                                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
3476                             }
3477                             break;
3478                         }
3479                     }
3480                 }
3481             } // ctrlIsDown && altIsDown
3482         } // ctrlIsDown
3483     } // modifiers
3484 
3485     // instead of creating our own conversion tables, I'll let Win32
3486     // convert the character for me.
3487     WORD mbChar;
3488     UINT scancode = ::MapVirtualKey(wkey, 0);
3489     int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
3490                                 &mbChar, 0, GetKeyboardLayout());
3491 
3492     UINT translation;

3493 
3494     // Dead Key
3495     if (converted < 0) {
3496         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3497     } else
3498     // No translation available -- try known conversions or else punt.
3499     if (converted == 0) {
3500         if (wkey == VK_DELETE) {
3501             translation = '\177';
3502         } else
3503         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
3504             translation = '0' + wkey - VK_NUMPAD0;
3505         } else {
3506             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3507         }
3508     } else
3509     // the caller expects a Unicode character.
3510     if (converted > 0) {
3511         WCHAR unicodeChar[2];
3512         VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED,
3513         (LPCSTR)&mbChar, 1, unicodeChar, 1));
3514 
3515         translation = unicodeChar[0];
3516     }
3517     if (ops == SAVE) {
3518         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3519                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));


3520     }


3521     return translation;
3522 }
3523 
3524 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
3525                                    UINT flags, BOOL system)
3526 {
3527     // VK_PROCESSKEY is a special value which means
3528     //          "Current IME wants to consume this KeyEvent"
3529     // Real key code is saved by IMM32.DLL and can be retrieved by
3530     // calling ImmGetVirtualKey();
3531     if (wkey == VK_PROCESSKEY) {
3532         return mrDoDefault;
3533     }
3534     MSG msg;
3535     InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),
3536                              wkey, MAKELPARAM(repCnt, flags));
3537 
3538     UINT modifiers = GetJavaModifiers();
3539     jint keyLocation = GetKeyLocation(wkey, flags);
3540     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
3541     UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);

3542     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3543 
3544 
3545     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
3546                              TimeHelper::windowsToUTC(msg.time), jkey, character,
3547                              modifiers, keyLocation, (jlong)wkey, &msg);
3548 
3549     // bugid 4724007: Windows does not create a WM_CHAR for the Del key
3550     // for some reason, so we need to create the KEY_TYPED event on the
3551     // WM_KEYDOWN.  Use null msg so the character doesn't get sent back
3552     // to the native window for processing (this event is synthesized
3553     // for Java - we don't want Windows trying to process it).
3554     if (jkey == java_awt_event_KeyEvent_VK_DELETE) {
3555         SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
3556                                  TimeHelper::windowsToUTC(msg.time),
3557                                  java_awt_event_KeyEvent_VK_UNDEFINED,
3558                                  character, modifiers,
3559                                  java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
3560     }
3561 
3562     return mrConsume;
3563 }
3564 
3565 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
3566                                  UINT flags, BOOL system)
3567 {
3568 
3569     // VK_PROCESSKEY is a special value which means
3570     //          "Current IME wants to consume this KeyEvent"
3571     // Real key code is saved by IMM32.DLL and can be retrieved by
3572     // calling ImmGetVirtualKey();
3573     if (wkey == VK_PROCESSKEY) {
3574         return mrDoDefault;
3575     }
3576     MSG msg;
3577     InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),
3578                              wkey, MAKELPARAM(repCnt, flags));
3579 
3580     UINT modifiers = GetJavaModifiers();
3581     jint keyLocation = GetKeyLocation(wkey, flags);
3582     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
3583     UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);

3584     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3585 
3586     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
3587                              TimeHelper::windowsToUTC(msg.time), jkey, character,
3588                              modifiers, keyLocation, (jlong)wkey, &msg);
3589     return mrConsume;
3590 }
3591 
3592 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)
3593 {
3594     // Normally we would be able to use charset and TranslateCharSetInfo
3595     // to get a code page that should be associated with this keyboard
3596     // layout change. However, there seems to be an NT 4.0 bug associated
3597     // with the WM_INPUTLANGCHANGE message, which makes the charset parameter
3598     // unreliable, especially on Asian systems. Our workaround uses the
3599     // keyboard layout handle instead.
3600     m_hkl = hKeyboardLayout;
3601     m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
3602     m_CodePage = LangToCodePage(m_idLang);
3603     BuildDynamicKeyMapTable();  // compute new mappings for VK_OEM


5611                    event (if any) accodingly.  */
5612                 switch (id) {
5613                 case java_awt_event_KeyEvent_KEY_PRESSED:
5614                 {
5615                     UINT winKey = (UINT)msg.wParam;
5616                     bCharChanged = FALSE;
5617 
5618                     if (winKey == VK_PROCESSKEY) {
5619                         // Leave it up to IME
5620                         break;
5621                     }
5622 
5623                     if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) {
5624                         UINT newWinKey, ignored;
5625                         p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey);
5626                         if (newWinKey != 0) {
5627                             winKey = newWinKey;
5628                         }
5629                     }
5630 
5631                     modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE);

5632                     bCharChanged = (keyChar != modifiedChar);
5633                 }
5634                 break;
5635 
5636                 case java_awt_event_KeyEvent_KEY_RELEASED:
5637                 {
5638                     keyDownConsumed = FALSE;
5639                     bCharChanged = FALSE;
5640                 }
5641                 break;
5642 
5643                 case java_awt_event_KeyEvent_KEY_TYPED:
5644                 {
5645                     if (bCharChanged)
5646                     {
5647                         unicodeChar = modifiedChar;
5648                     }
5649                     else
5650                     {
5651                         unicodeChar = keyChar;




3127         for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
3128             if (dynamicKeyMapTable[j].javaKey == javaKey) {
3129                 *windowsKey = dynamicKeyMapTable[j].windowsKey;
3130                 *modifiers = 0;
3131                 found = true;
3132                 if (*windowsKey == originalWindowsKey) {
3133                     return;   /* if ideal case found return, else keep looking */
3134                 }
3135             }
3136         }
3137         if (found) {
3138             return;
3139         }
3140     }
3141 
3142     *windowsKey = 0;
3143     *modifiers = 0;
3144     return;
3145 }
3146 
3147 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)
3148 
3149 {
3150     // Handle the few cases where we need to take the modifier into
3151     // consideration for the Java VK code or where we have to take the keyboard
3152     // layout into consideration so that function keys can get
3153     // recognized in a platform-independent way.
3154     switch (windowsKey) {
3155         case VK_CONVERT:
3156             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
3157                 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES;
3158             }
3159             if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) {
3160                 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE;
3161             }
3162             break;
3163         case VK_DBE_ALPHANUMERIC:
3164             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
3165                 return java_awt_event_KeyEvent_VK_CODE_INPUT;
3166             }
3167             break;
3168         case VK_KANA:
3169             if (isKanaLockAvailable()) {
3170                 return java_awt_event_KeyEvent_VK_KANA_LOCK;
3171             }
3172             break;
3173     };
3174 
3175     // check dead key
3176     if(isDeadKey){
3177       for (int i = 0; charToDeadVKTable[i].c != 0; i++) {
3178         if (charToDeadVKTable[i].c == character) {
3179             return charToDeadVKTable[i].javaKey;
3180         }
3181       }
3182     }
3183 
3184     // for the general case, use a bi-directional table
3185     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
3186         if (keyMapTable[i].windowsKey == windowsKey) {
3187             return keyMapTable[i].javaKey;
3188         }
3189     }
3190 
3191     for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
3192         if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
3193             if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {
3194                 return dynamicKeyMapTable[j].javaKey;
3195             }else{
3196                 break;
3197             }
3198         }
3199     }
3200 
3201     return java_awt_event_KeyEvent_VK_UNDEFINED;
3202 }
3203 


3377         }
3378         kbdState[i] = 0; // "key unpressed"
3379     }
3380 }
3381 void
3382 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)
3383 {
3384     if( wkey && wkey < 256 ) {
3385         if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
3386             // At the creation time,
3387             // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"
3388             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
3389         }
3390         if(dynPrimaryKeymap[wkey].jkey ==  java_awt_event_KeyEvent_VK_UNDEFINED) {
3391             // E.g. it is non-unicode key
3392             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
3393         }
3394     }
3395 }
3396 
3397 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)
3398 {
3399     static Hashtable transTable("VKEY translations");
3400     static Hashtable deadKeyFlagTable("Dead Key Flags");
3401     isDeadKey = FALSE;
3402 
3403     // Try to translate using last saved translation
3404     if (ops == LOAD) {
3405        void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3406        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3407        if (value != NULL) {
3408            isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
3409            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
3410        }
3411     }
3412 
3413     // If the windows key is a return, wkey will equal 13 ('\r')
3414     // In this case, we want to return 10 ('\n')
3415     // Since ToAscii would convert VK_RETURN to '\r', we need
3416     // to have a special case here.
3417     if (wkey == VK_RETURN)
3418         return '\n';
3419 
3420     // high order bit in keyboardState indicates whether the key is down
3421     static const BYTE KEY_STATE_DOWN = 0x80;
3422     BYTE    keyboardState[AwtToolkit::KB_STATE_SIZE];
3423     AwtToolkit::GetKeyboardState(keyboardState);
3424 
3425     // apply modifiers to keyboard state if necessary
3426     if (modifiers) {
3427         BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
3428         BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK;


3481                     for (ch = _T('\033'); ch < _T('\040'); ch++) {
3482                         vk = ::VkKeyScan(ch);
3483                         if (wkey == LOBYTE(vk)) {
3484                             UINT shiftState = HIBYTE(vk);
3485                             if ((shiftState & _VKS_CTRL_MASK) ||
3486                                 (!(shiftState & _VKS_SHIFT_MASK)
3487                                 == !shiftIsDown))
3488                             {
3489                                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
3490                             }
3491                             break;
3492                         }
3493                     }
3494                 }
3495             } // ctrlIsDown && altIsDown
3496         } // ctrlIsDown
3497     } // modifiers
3498 
3499     // instead of creating our own conversion tables, I'll let Win32
3500     // convert the character for me.
3501     WORD wChar[2];
3502     UINT scancode = ::MapVirtualKey(wkey, 0);
3503     int converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
3504                                   wChar, 2, 0, GetKeyboardLayout()); 
3505 
3506     UINT translation;
3507     BOOL deadKeyFlag = (converted == 2);
3508 
3509     // Dead Key
3510     if (converted < 0) {
3511         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3512     } else
3513     // No translation available -- try known conversions or else punt.
3514     if (converted == 0) {
3515         if (wkey == VK_DELETE) {
3516             translation = '\177';
3517         } else
3518         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
3519             translation = '0' + wkey - VK_NUMPAD0;
3520         } else {
3521             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3522         }
3523     } else
3524     // the caller expects a Unicode character.
3525     if (converted > 0) {
3526         translation = wChar[0];




3527     }
3528     if (ops == SAVE) {
3529         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3530                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
3531         deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3532                        reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
3533     }
3534 
3535     isDeadKey = deadKeyFlag;
3536     return translation;
3537 }
3538 
3539 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
3540                                    UINT flags, BOOL system)
3541 {
3542     // VK_PROCESSKEY is a special value which means
3543     //          "Current IME wants to consume this KeyEvent"
3544     // Real key code is saved by IMM32.DLL and can be retrieved by
3545     // calling ImmGetVirtualKey();
3546     if (wkey == VK_PROCESSKEY) {
3547         return mrDoDefault;
3548     }
3549     MSG msg;
3550     InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),
3551                              wkey, MAKELPARAM(repCnt, flags));
3552 
3553     UINT modifiers = GetJavaModifiers();
3554     jint keyLocation = GetKeyLocation(wkey, flags);
3555     BOOL isDeadKey = FALSE;
3556     UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);
3557     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
3558     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3559 
3560 
3561     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
3562                              TimeHelper::windowsToUTC(msg.time), jkey, character,
3563                              modifiers, keyLocation, (jlong)wkey, &msg);
3564 
3565     // bugid 4724007: Windows does not create a WM_CHAR for the Del key
3566     // for some reason, so we need to create the KEY_TYPED event on the
3567     // WM_KEYDOWN.  Use null msg so the character doesn't get sent back
3568     // to the native window for processing (this event is synthesized
3569     // for Java - we don't want Windows trying to process it).
3570     if (jkey == java_awt_event_KeyEvent_VK_DELETE) {
3571         SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
3572                                  TimeHelper::windowsToUTC(msg.time),
3573                                  java_awt_event_KeyEvent_VK_UNDEFINED,
3574                                  character, modifiers,
3575                                  java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
3576     }
3577 
3578     return mrConsume;
3579 }
3580 
3581 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
3582                                  UINT flags, BOOL system)
3583 {
3584 
3585     // VK_PROCESSKEY is a special value which means
3586     //          "Current IME wants to consume this KeyEvent"
3587     // Real key code is saved by IMM32.DLL and can be retrieved by
3588     // calling ImmGetVirtualKey();
3589     if (wkey == VK_PROCESSKEY) {
3590         return mrDoDefault;
3591     }
3592     MSG msg;
3593     InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),
3594                              wkey, MAKELPARAM(repCnt, flags));
3595 
3596     UINT modifiers = GetJavaModifiers();
3597     jint keyLocation = GetKeyLocation(wkey, flags);
3598     BOOL isDeadKey = FALSE;
3599     UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);
3600     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
3601     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3602 
3603     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
3604                              TimeHelper::windowsToUTC(msg.time), jkey, character,
3605                              modifiers, keyLocation, (jlong)wkey, &msg);
3606     return mrConsume;
3607 }
3608 
3609 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)
3610 {
3611     // Normally we would be able to use charset and TranslateCharSetInfo
3612     // to get a code page that should be associated with this keyboard
3613     // layout change. However, there seems to be an NT 4.0 bug associated
3614     // with the WM_INPUTLANGCHANGE message, which makes the charset parameter
3615     // unreliable, especially on Asian systems. Our workaround uses the
3616     // keyboard layout handle instead.
3617     m_hkl = hKeyboardLayout;
3618     m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
3619     m_CodePage = LangToCodePage(m_idLang);
3620     BuildDynamicKeyMapTable();  // compute new mappings for VK_OEM


5628                    event (if any) accodingly.  */
5629                 switch (id) {
5630                 case java_awt_event_KeyEvent_KEY_PRESSED:
5631                 {
5632                     UINT winKey = (UINT)msg.wParam;
5633                     bCharChanged = FALSE;
5634 
5635                     if (winKey == VK_PROCESSKEY) {
5636                         // Leave it up to IME
5637                         break;
5638                     }
5639 
5640                     if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) {
5641                         UINT newWinKey, ignored;
5642                         p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey);
5643                         if (newWinKey != 0) {
5644                             winKey = newWinKey;
5645                         }
5646                     }
5647 
5648                     BOOL isDeadKey = FALSE;
5649                     modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);
5650                     bCharChanged = (keyChar != modifiedChar);
5651                 }
5652                 break;
5653 
5654                 case java_awt_event_KeyEvent_KEY_RELEASED:
5655                 {
5656                     keyDownConsumed = FALSE;
5657                     bCharChanged = FALSE;
5658                 }
5659                 break;
5660 
5661                 case java_awt_event_KeyEvent_KEY_TYPED:
5662                 {
5663                     if (bCharChanged)
5664                     {
5665                         unicodeChar = modifiedChar;
5666                     }
5667                     else
5668                     {
5669                         unicodeChar = keyChar;