diff options
author | Damien Plisson <damien.plisson@yahoo.fr> | 2010-03-15 23:38:04 +0300 |
---|---|---|
committer | Damien Plisson <damien.plisson@yahoo.fr> | 2010-03-15 23:38:04 +0300 |
commit | c12cfa37753e440aa585c2044dc433a46e494e59 (patch) | |
tree | 299da364312ccc42cf9c3abdc57a14d4c10ad70a | |
parent | 8fdb4d45063f01be975cf3c6351607115a0b8d4e (diff) |
Fix [#20419] OSX Cocoa physical punctuation keys retrieval fix
Cocoa charactersIgnoringModifiers API still takes the Shift key into account. Fix is to use Apple new 10.5 Carbon(!) API that is 64bit compatible to take into account the international keyboard layout when retrieving the physical key pressed/released.
Needed to use an even older API for 10.4 builds.
-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; |