diff options
author | koekeishiya <aasvi93@hotmail.com> | 2018-03-25 00:39:43 +0100 |
---|---|---|
committer | koekeishiya <aasvi93@hotmail.com> | 2018-03-25 00:39:43 +0100 |
commit | b8a02428123516a43c11bf7a4c4e4cd88fca4020 (patch) | |
tree | 912c3743c4c7143caa68f30ae55c6235dd29528c /src | |
parent | c91e3f4e520f794bcc8b6f952059656be660eab7 (diff) | |
download | skhd-b8a02428123516a43c11bf7a4c4e4cd88fca4020.tar.gz skhd-b8a02428123516a43c11bf7a4c4e4cd88fca4020.zip |
get rid of broken Apple code to actually fix #28
Diffstat (limited to 'src')
-rw-r--r-- | src/locale.c | 94 |
1 files changed, 75 insertions, 19 deletions
diff --git a/src/locale.c b/src/locale.c index 71afeb6..728463b 100644 --- a/src/locale.c +++ b/src/locale.c @@ -1,10 +1,56 @@ #include "locale.h" +#include "hashtable.h" #include <Carbon/Carbon.h> #include <IOKit/hidsystem/ev_keymap.h> #define internal static #define local_persist static +internal struct table keymap_table; + +internal char * +copy_cf_string_to_c(CFStringRef string) +{ + CFStringEncoding encoding = kCFStringEncodingUTF8; + CFIndex length = CFStringGetLength(string); + CFIndex bytes = CFStringGetMaximumSizeForEncoding(length, encoding); + char *result = malloc(bytes + 1); + + // NOTE(koekeishiya): Boolean: typedef -> unsigned char; false = 0, true != 0 + Boolean success = CFStringGetCString(string, result, bytes + 1, encoding); + if (!success) { + free(result); + result = NULL; + } + + return result; +} + +internal int +hash_keymap(const char *a) +{ + unsigned long hash = 0, high; + while(*a) { + hash = (hash << 4) + *a++; + high = hash & 0xF0000000; + if(high) { + hash ^= (high >> 24); + } + hash &= ~high; + } + return hash; +} + +internal bool +same_keymap(const char *a, const char *b) +{ + while (*a && *b && *a == *b) { + ++a; + ++b; + } + return *a == '\0' && *b == '\0'; +} + internal CFStringRef cfstring_from_keycode(CGKeyCode keycode) { @@ -47,28 +93,38 @@ cfstring_from_keycode(CGKeyCode keycode) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" +internal void +initialize_keycode_map() +{ + table_init(&keymap_table, + 131, + (table_hash_func) hash_keymap, + (table_compare_func) same_keymap); + + for (unsigned index = 0; index < 128; ++index) { + CFStringRef key_string = cfstring_from_keycode(index); + if (!key_string) continue; + + char *c_key_string = copy_cf_string_to_c(key_string); + CFRelease(key_string); + if (!c_key_string) continue; + + table_add(&keymap_table, c_key_string, (void *)index); + } +} +#pragma clang diagnostic pop + uint32_t keycode_from_char(char key) { - uint32_t result = 0; - uint32_t *keycode = &result; - - 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); - } - } + uint32_t keycode = 0; + char lookup_key[2]; + + if (!keymap_table.count) { + initialize_keycode_map(); } - UniChar uni_char = key; - CFStringRef char_str = CFStringCreateWithCharacters(kCFAllocatorDefault, &uni_char, 1); - CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **) &keycode); - CFRelease(char_str); + snprintf(lookup_key, 2, "%c", key); + keycode = (uint32_t) table_find(&keymap_table, &lookup_key); - return result; + return keycode; } -#pragma clang diagnostic pop |