src/macosx/native/sun/awt/AWTEvent.m
Print this page
@@ -24,10 +24,11 @@
*/
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
#import <sys/time.h>
+#include <Carbon/Carbon.h>
#import "LWCToolkit.h"
#import "ThreadUtilities.h"
#import "java_awt_event_InputEvent.h"
@@ -369,30 +370,71 @@
// otherwise return character unchanged
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;
}
}
// If we got here, we keep looking for a normal key.
}
@@ -613,24 +655,26 @@
jboolean copy = JNI_FALSE;
jint *data = (*env)->GetIntArrayElements(env, inData, ©);
// 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);
JNF_COCOA_EXIT(env);