// // MPKeyMapper.m // MacPass // // Created by Michael Starke on 07.02.14. // Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. // // Uses Code from: // SRKeyCodeTransformer.h // ShortcutRecorder // // Copyright 2006-2007 Contributors. All rights reserved. // // License: BSD // // Contributors: // David Dauer // Jesper // Jamie Kirkpatrick #import "MPKeyMapper.h" #import uint16_t const kMPUnknownKeyCode = UINT16_MAX; @implementation MPKeyMapper + (NSString *)stringForKey:(CGKeyCode)keyCode { TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard,kTISPropertyUnicodeKeyLayoutData); if(!layoutData) { currentKeyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); } CFRelease(currentKeyboard); const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); UInt32 keysDown = 0; UniChar chars[4]; UniCharCount realLength; UCKeyTranslate(keyboardLayout, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars); return CFBridgingRelease(CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1)); } + (CGKeyCode)keyCodeForCharacter:(NSString *)character { static NSMutableDictionary *keyboardCodeDictionary; TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); NSString *localizedName = (__bridge NSString *)TISGetInputSourceProperty(currentKeyboard, kTISPropertyLocalizedName); CFRelease(currentKeyboard); if(keyboardCodeDictionary == nil) { /* Input source should not change that much while we are running */ keyboardCodeDictionary = [[NSMutableDictionary alloc] initWithCapacity:2]; } NSDictionary *charToCodeDict = keyboardCodeDictionary[localizedName]; if(nil == keyboardCodeDictionary[localizedName]) { /* We need 128 places for this dict */ charToCodeDict = [[NSMutableDictionary alloc] initWithCapacity:128]; /* Loop through every keycode (0 - 127) to find its current mapping. */ for(CGKeyCode keyCode = 0; keyCode < 128; ++keyCode) { NSString *string = [self stringForKey:keyCode]; if(string != nil) { ((NSMutableDictionary *)charToCodeDict)[string] = @(keyCode); } } keyboardCodeDictionary[localizedName] = [[NSDictionary alloc] initWithDictionary:charToCodeDict]; } /* Add mapping */ /* Generate table of keycodes and characters. */ NSString *singleCharacter = [[character substringToIndex:1] lowercaseString]; if(charToCodeDict[singleCharacter]) { return [charToCodeDict[singleCharacter] integerValue]; } return kMPUnknownKeyCode; } @end