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;
3415 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;
3416
3417 // Windows treats AltGr as Ctrl+Alt
3418 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) {
3419 altIsDown = TRUE;
3420 ctrlIsDown = TRUE;
3421 }
3422
3423 if (shiftIsDown) {
3424 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;
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 void AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, UINT *character, 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* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3406 void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3407 if (value != NULL) {
3408 *character = static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
3409 *isDeadKey = static_cast<UINT>(reinterpret_cast<BOOL>(deadKeyFlag));
3410 return;
3411 }
3412 }
3413
3414 // If the windows key is a return, wkey will equal 13 ('\r')
3415 // In this case, we want to return 10 ('\n')
3416 // Since ToAscii would convert VK_RETURN to '\r', we need
3417 // to have a special case here.
3418 if (wkey == VK_RETURN){
3419 *character= '\n';
3420 return;
3421 }
3422
3423 // high order bit in keyboardState indicates whether the key is down
3424 static const BYTE KEY_STATE_DOWN = 0x80;
3425 BYTE keyboardState[AwtToolkit::KB_STATE_SIZE];
3426 AwtToolkit::GetKeyboardState(keyboardState);
3427
3428 // apply modifiers to keyboard state if necessary
3429 if (modifiers) {
3430 BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
3431 BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK;
3432 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;
3433
3434 // Windows treats AltGr as Ctrl+Alt
3435 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) {
3436 altIsDown = TRUE;
3437 ctrlIsDown = TRUE;
3438 }
3439
3440 if (shiftIsDown) {
3441 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;
3490 == !shiftIsDown))
3491 {
3492 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
3493 }
3494 break;
3495 }
3496 }
3497 }
3498 } // ctrlIsDown && altIsDown
3499 } // ctrlIsDown
3500 } // modifiers
3501
3502 // instead of creating our own conversion tables, I'll let Win32
3503 // convert the character for me.
3504 WORD mbChar;
3505 UINT scancode = ::MapVirtualKey(wkey, 0);
3506 int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
3507 &mbChar, 0, GetKeyboardLayout());
3508
3509 UINT translation;
3510 BOOL deadKeyFlag = (converted == 2);
3511
3512 // Dead Key
3513 if (converted < 0) {
3514 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3515 } else
3516 // No translation available -- try known conversions or else punt.
3517 if (converted == 0) {
3518 if (wkey == VK_DELETE) {
3519 translation = '\177';
3520 } else
3521 if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
3522 translation = '0' + wkey - VK_NUMPAD0;
3523 } else {
3524 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3525 }
3526 } else
3527 // the caller expects a Unicode character.
3528 if (converted > 0) {
3529 WCHAR unicodeChar[2];
3530 VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED,
3531 (LPCSTR)&mbChar, 1, unicodeChar, 1));
3532
3533 translation = unicodeChar[0];
3534 }
3535 if (ops == SAVE) {
3536 transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3537 reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
3538 deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3539 reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
3540 }
3541
3542 *character = translation;
3543 *isDeadKey = deadKeyFlag;
3544 return;
3545 }
3546
3547 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
3548 UINT flags, BOOL system)
3549 {
3550 // VK_PROCESSKEY is a special value which means
3551 // "Current IME wants to consume this KeyEvent"
3552 // Real key code is saved by IMM32.DLL and can be retrieved by
3553 // calling ImmGetVirtualKey();
3554 if (wkey == VK_PROCESSKEY) {
3555 return mrDoDefault;
3556 }
3557 MSG msg;
3558 InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),
3559 wkey, MAKELPARAM(repCnt, flags));
3560
3561 UINT modifiers = GetJavaModifiers();
3562 jint keyLocation = GetKeyLocation(wkey, flags);
3563 BOOL isDeadKey = FALSE;
3564 UINT character;
3565 WindowsKeyToJavaChar(wkey, modifiers, SAVE, &character, &isDeadKey);
3566 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
3567 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3568
3569
3570 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
3571 TimeHelper::windowsToUTC(msg.time), jkey, character,
3572 modifiers, keyLocation, (jlong)wkey, &msg);
3573
3574 // bugid 4724007: Windows does not create a WM_CHAR for the Del key
3575 // for some reason, so we need to create the KEY_TYPED event on the
3576 // WM_KEYDOWN. Use null msg so the character doesn't get sent back
3577 // to the native window for processing (this event is synthesized
3578 // for Java - we don't want Windows trying to process it).
3579 if (jkey == java_awt_event_KeyEvent_VK_DELETE) {
3580 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
3581 TimeHelper::windowsToUTC(msg.time),
3582 java_awt_event_KeyEvent_VK_UNDEFINED,
3583 character, modifiers,
3584 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
3585 }
3586
3587 return mrConsume;
3588 }
3589
3590 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
3591 UINT flags, BOOL system)
3592 {
3593
3594 // VK_PROCESSKEY is a special value which means
3595 // "Current IME wants to consume this KeyEvent"
3596 // Real key code is saved by IMM32.DLL and can be retrieved by
3597 // calling ImmGetVirtualKey();
3598 if (wkey == VK_PROCESSKEY) {
3599 return mrDoDefault;
3600 }
3601 MSG msg;
3602 InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),
3603 wkey, MAKELPARAM(repCnt, flags));
3604
3605 UINT modifiers = GetJavaModifiers();
3606 jint keyLocation = GetKeyLocation(wkey, flags);
3607 BOOL isDeadKey = FALSE;
3608 UINT character;
3609 WindowsKeyToJavaChar(wkey, modifiers, LOAD, &character, &isDeadKey);
3610 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
3611 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
3612
3613 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
3614 TimeHelper::windowsToUTC(msg.time), jkey, character,
3615 modifiers, keyLocation, (jlong)wkey, &msg);
3616 return mrConsume;
3617 }
3618
3619 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)
3620 {
3621 // Normally we would be able to use charset and TranslateCharSetInfo
3622 // to get a code page that should be associated with this keyboard
3623 // layout change. However, there seems to be an NT 4.0 bug associated
3624 // with the WM_INPUTLANGCHANGE message, which makes the charset parameter
3625 // unreliable, especially on Asian systems. Our workaround uses the
3626 // keyboard layout handle instead.
3627 m_hkl = hKeyboardLayout;
3628 m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
3629 m_CodePage = LangToCodePage(m_idLang);
3630 BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM
5638 event (if any) accodingly. */
5639 switch (id) {
5640 case java_awt_event_KeyEvent_KEY_PRESSED:
5641 {
5642 UINT winKey = (UINT)msg.wParam;
5643 bCharChanged = FALSE;
5644
5645 if (winKey == VK_PROCESSKEY) {
5646 // Leave it up to IME
5647 break;
5648 }
5649
5650 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) {
5651 UINT newWinKey, ignored;
5652 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey);
5653 if (newWinKey != 0) {
5654 winKey = newWinKey;
5655 }
5656 }
5657
5658 BOOL isDeadKey = FALSE;
5659 UINT character;
5660 p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, &character, &isDeadKey);
5661 modifiedChar = character;
5662 bCharChanged = (keyChar != modifiedChar);
5663 }
5664 break;
5665
5666 case java_awt_event_KeyEvent_KEY_RELEASED:
5667 {
5668 keyDownConsumed = FALSE;
5669 bCharChanged = FALSE;
5670 }
5671 break;
5672
5673 case java_awt_event_KeyEvent_KEY_TYPED:
5674 {
5675 if (bCharChanged)
5676 {
5677 unicodeChar = modifiedChar;
5678 }
5679 else
5680 {
5681 unicodeChar = keyChar;
|