diff options
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 5289920cccb..bcbc59a34a9 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -29,6 +29,9 @@ #import <Cocoa/Cocoa.h> +/*For the currently not ported to Cocoa keyboard layout functions (64bit & 10.6 compatible)*/ +#include <Carbon/Carbon.h> + #include <sys/time.h> #include <sys/types.h> #include <sys/sysctl.h> @@ -53,9 +56,8 @@ #include "AssertMacros.h" #pragma mark KeyMap, mouse converters - - -/* Keycodes from Carbon include file */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +/* Keycodes not defined in Tiger */ /* * Summary: * Virtual keycodes @@ -203,7 +205,7 @@ enum { kVK_JIS_Eisu = 0x66, kVK_JIS_Kana = 0x68 }; - +#endif static GHOST_TButtonMask convertButton(int button) { @@ -230,7 +232,7 @@ static GHOST_TButtonMask convertButton(int button) * @param recvChar the character ignoring modifiers (except for shift) * @return Ghost key code */ -static GHOST_TKey convertKey(int rawCode, unichar recvChar) +static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction) { //printf("\nrecvchar %c 0x%x",recvChar,recvChar); @@ -350,26 +352,68 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar) return GHOST_kKeyUnknown; default: - /*Then detect on character value for "remappable" keys in int'l keyboards*/ + /* alphanumerical or punctuation key that is remappable in int'l keyboards */ if ((recvChar >= 'A') && (recvChar <= 'Z')) { return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA); } else if ((recvChar >= 'a') && (recvChar <= 'z')) { return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA); - } else - switch (recvChar) { - case '-': return GHOST_kKeyMinus; - case '=': return GHOST_kKeyEqual; - case ',': return GHOST_kKeyComma; - case '.': return GHOST_kKeyPeriod; - case '/': return GHOST_kKeySlash; - case ';': return GHOST_kKeySemicolon; - case '\'': return GHOST_kKeyQuote; - case '\\': return GHOST_kKeyBackslash; - case '[': return GHOST_kKeyLeftBracket; - case ']': return GHOST_kKeyRightBracket; - case '`': return GHOST_kKeyAccentGrave; - default: - return GHOST_kKeyUnknown; + } else { +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + KeyboardLayoutRef keyLayout; + UCKeyboardLayout *uchrData; + + KLGetCurrentKeyboardLayout(&keyLayout); + KLGetKeyboardLayoutProperty(keyLayout, kKLuchrData, (const void **) + &uchrData); + /*get actual character value of the "remappable" keys in int'l keyboards, + if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger), + then fallback on using the received charactersIgnoringModifiers */ + if (uchrData) + { + UInt32 deadKeyState=0; + UniCharCount actualStrLength=0; + + UCKeyTranslate(uchrData, rawCode, keyAction, 0, + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar); + + } +#else + /* Leopard and Snow Leopard 64bit compatible API*/ + CFDataRef uchrHandle; /*the keyboard layout*/ + TISInputSourceRef kbdTISHandle; + + kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource(); + uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,kTISPropertyUnicodeKeyLayoutData); + CFRelease(kbdTISHandle); + + /*get actual character value of the "remappable" keys in int'l keyboards, + if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger), + then fallback on using the received charactersIgnoringModifiers */ + if (uchrHandle) + { + UInt32 deadKeyState=0; + UniCharCount actualStrLength=0; + + UCKeyTranslate((UCKeyboardLayout*)CFDataGetBytePtr(uchrHandle), rawCode, keyAction, 0, + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar); + + } +#endif + switch (recvChar) { + case '-': return GHOST_kKeyMinus; + case '=': return GHOST_kKeyEqual; + case ',': return GHOST_kKeyComma; + case '.': return GHOST_kKeyPeriod; + case '/': return GHOST_kKeySlash; + case ';': return GHOST_kKeySemicolon; + case '\'': return GHOST_kKeyQuote; + case '\\': return GHOST_kKeyBackslash; + case '[': return GHOST_kKeyLeftBracket; + case ']': return GHOST_kKeyRightBracket; + case '`': return GHOST_kKeyAccentGrave; + default: + return GHOST_kKeyUnknown; + } } } return GHOST_kKeyUnknown; @@ -1573,9 +1617,11 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) charsIgnoringModifiers = [event charactersIgnoringModifiers]; if ([charsIgnoringModifiers length]>0) keyCode = convertKey([event keyCode], - [charsIgnoringModifiers characterAtIndex:0]); + [charsIgnoringModifiers characterAtIndex:0], + [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp); else - keyCode = convertKey([event keyCode],0); + keyCode = convertKey([event keyCode],0, + [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp); characters = [event characters]; @@ -1595,9 +1641,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) if ([event type] == NSKeyDown) { pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii) ); - //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii); + //printf("\nKey down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii); } else { pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyUp, window, keyCode, ascii) ); + //printf("\nKey up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii); } break; |