--- old/src/macosx/native/sun/awt/AWTEvent.m 2012-09-06 15:44:38.000000000 +0400 +++ new/src/macosx/native/sun/awt/AWTEvent.m 2012-09-06 15:44:38.000000000 +0400 @@ -26,6 +26,7 @@ #import #import #import +#include #import "LWCToolkit.h" #import "ThreadUtilities.h" @@ -371,26 +372,67 @@ return nsChar; } +static unichar NsGetDeadKeyChar(unsigned short keyCode) +{ + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); + // Carbon modifiers should be used instead of NSEvent modifiers + UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF; + + if (keyboardLayout) { + UInt32 deadKeyState = 0; + UniCharCount maxStringLength = 255; + UniCharCount actualStringLength = 0; + UniChar unicodeString[maxStringLength]; + + // get the deadKeyState + OSStatus status = UCKeyTranslate(keyboardLayout, + keyCode, kUCKeyActionDown, modifierKeyState, + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, + &deadKeyState, + maxStringLength, + &actualStringLength, unicodeString); + + if (status == noErr && deadKeyState != 0) { + // Press SPACE to get the dead key char + status = UCKeyTranslate(keyboardLayout, + kVK_Space, kUCKeyActionDown, 0, + LMGetKbdType(), 0, + &deadKeyState, + maxStringLength, + &actualStringLength, unicodeString); + + if (status == noErr && actualStringLength > 0) { + return unicodeString[0]; + } + } + } + return 0; +} + /* * This is the function that uses the table above to take incoming * NSEvent keyCodes and translate to the Java virtual key code. */ static void -NsCharToJavaVirtualKeyCode(unichar ch, unichar deadChar, +NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar, NSUInteger flags, unsigned short key, - jint *keyCode, jint *keyLocation, BOOL *postsTyped) + jint *keyCode, jint *keyLocation, BOOL *postsTyped, unichar *deadChar) { static size_t size = sizeof(keyTable) / sizeof(struct _key); NSInteger offset; - if (deadChar) { + if (isDeadChar) { + unichar testDeadChar = NsGetDeadKeyChar(key); const struct CharToVKEntry *map; for (map = charToDeadVKTable; map->c != 0; ++map) { - if (deadChar == map->c) { + if (testDeadChar == map->c) { *keyCode = map->javaKey; *postsTyped = NO; // TODO: use UNKNOWN here? *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN; + *deadChar = testDeadChar; return; } } @@ -615,20 +657,22 @@ // in = [testChar, testDeadChar, modifierFlags, keyCode] jchar testChar = (jchar)data[0]; - jchar testDeadChar = (jchar)data[1]; + BOOL isDeadChar = (data[1] != 0); jint modifierFlags = data[2]; jshort keyCode = (jshort)data[3]; jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED; jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN; + jchar testDeadChar = 0; - NsCharToJavaVirtualKeyCode((unichar)testChar, (unichar)testDeadChar, + NsCharToJavaVirtualKeyCode((unichar)testChar, isDeadChar, (NSUInteger)modifierFlags, (unsigned short)keyCode, - &jkeyCode, &jkeyLocation, &postsTyped); + &jkeyCode, &jkeyLocation, &postsTyped, &testDeadChar); // out = [jkeyCode, jkeyLocation]; (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode); (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation); + (*env)->SetIntArrayRegion(env, outData, 2, 1, (jint *)&testDeadChar); (*env)->ReleaseIntArrayElements(env, inData, data, 0);