From d69056799a399058005b4950751397a31110de4a Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Mon, 7 Aug 2017 20:23:44 +0200 Subject: v0.0.1 --- src/locale.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/locale.c (limited to 'src/locale.c') diff --git a/src/locale.c b/src/locale.c new file mode 100644 index 0000000..5b262c7 --- /dev/null +++ b/src/locale.c @@ -0,0 +1,117 @@ +#include "locale.h" + +#include +#include + +#define internal static +#define local_persist static + +bool same_string(char *text, unsigned length, const char *match) +{ + const char *at = match; + unsigned index = 0; + while(*at++ == text[index++] && index < length); + return (*at == '\0' && index == length) ? true : false; +} + +internal CFStringRef +cfstring_from_keycode(CGKeyCode keycode) +{ + TISInputSourceRef keyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); + CFDataRef uchr = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(keyboard); + + UCKeyboardLayout *keyboard_layout = (UCKeyboardLayout *) CFDataGetBytePtr(uchr); + if(keyboard_layout) { + UInt32 dead_key_state = 0; + UniCharCount max_string_length = 255; + UniCharCount string_length = 0; + UniChar unicode_string[max_string_length]; + + OSStatus status = UCKeyTranslate(keyboard_layout, keycode, + kUCKeyActionDown, 0, + LMGetKbdType(), 0, + &dead_key_state, + max_string_length, + &string_length, + unicode_string); + + if(string_length == 0 && dead_key_state) { + status = UCKeyTranslate(keyboard_layout, kVK_Space, + kUCKeyActionDown, 0, + LMGetKbdType(), 0, + &dead_key_state, + max_string_length, + &string_length, + unicode_string); + } + + if(string_length > 0 && status == noErr) { + return CFStringCreateWithCharacters(NULL, unicode_string, string_length); + } + } + + return NULL; +} + +uint32_t keycode_from_char(char key) +{ + uint32_t keycode = 0; + local_persist CFMutableDictionaryRef keycode_map = NULL; + if(!keycode_map) { + keycode_map = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, &kCFCopyStringDictionaryKeyCallBacks, NULL); + for(unsigned index = 0; index < 128; ++index) { + CFStringRef key_string = cfstring_from_keycode(index); + if(key_string) { + CFDictionaryAddValue(keycode_map, key_string, (const void *)index); + CFRelease(key_string); + } + } + } + + UniChar uni_char = key; + CFStringRef char_str = CFStringCreateWithCharacters(kCFAllocatorDefault, &uni_char, 1); + CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **)&keycode); + CFRelease(char_str); + + return keycode; +} + +uint32_t keycode_from_literal(char *key, unsigned length) +{ + if(same_string(key, length, "return")) { + return kVK_Return; + } else if(same_string(key, length, "tab")) { + return kVK_Tab; + } else if(same_string(key, length, "space")) { + return kVK_Space; + } else if(same_string(key, length, "backspace")) { + return kVK_Delete; + } else if(same_string(key, length, "delete")) { + return kVK_ForwardDelete; + } else if(same_string(key, length, "escape")) { + return kVK_Escape; + } else if(same_string(key, length, "home")) { + return kVK_Home; + } else if(same_string(key, length, "end")) { + return kVK_End; + } else if(same_string(key, length, "pageup")) { + return kVK_PageUp; + } else if(same_string(key, length, "pagedown")) { + return kVK_PageDown; + } else if(same_string(key, length, "help")) { + return kVK_Help; + } else if(same_string(key, length, "left")) { + return kVK_LeftArrow; + } else if(same_string(key, length, "right")) { + return kVK_RightArrow; + } else if(same_string(key, length, "up")) { + return kVK_UpArrow; + } else if(same_string(key, length, "down")) { + return kVK_DownArrow; + } else if(same_string(key, length, "f1")) { + return kVK_F1; + } else { + return 0; + } +} -- cgit v1.2.3