From 2cb18d41124b8eed3886a0b5f5dfcb36df5b11c8 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 24 Mar 2018 21:46:07 +0100 Subject: fixes #28, retarded bug --- src/locale.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/locale.c b/src/locale.c index 974c3ae..71afeb6 100644 --- a/src/locale.c +++ b/src/locale.c @@ -49,14 +49,16 @@ cfstring_from_keycode(CGKeyCode keycode) #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" uint32_t keycode_from_char(char key) { - uint32_t keycode = 0; + 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); + CFDictionaryAddValue(keycode_map, key_string, (const void *) index); CFRelease(key_string); } } @@ -64,9 +66,9 @@ uint32_t keycode_from_char(char key) UniChar uni_char = key; CFStringRef char_str = CFStringCreateWithCharacters(kCFAllocatorDefault, &uni_char, 1); - CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **)&keycode); + CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **) &keycode); CFRelease(char_str); - return keycode; + return result; } #pragma clang diagnostic pop -- cgit v1.2.3 From 37e9bd02f28b375e5db3548d18298ace72c9559d Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 24 Mar 2018 21:47:38 +0100 Subject: bump version 0.0.11 --- src/skhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/skhd.c b/src/skhd.c index 3e2b072..f81c4ba 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -41,7 +41,7 @@ extern bool CGSIsSecureEventInputSet(); internal unsigned major_version = 0; internal unsigned minor_version = 0; -internal unsigned patch_version = 10; +internal unsigned patch_version = 11; internal struct table hotkey_map; internal char *config_file; -- cgit v1.2.3 From b8a02428123516a43c11bf7a4c4e4cd88fca4020 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 00:39:43 +0100 Subject: get rid of broken Apple code to actually fix #28 --- src/locale.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 19 deletions(-) (limited to 'src') 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 #include #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 -- cgit v1.2.3 From 21080bdeaea0ce074204d9d2d3bc4781ef266714 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 00:42:40 +0100 Subject: bump version 0.0.12 --- src/skhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/skhd.c b/src/skhd.c index f81c4ba..6c08d45 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -41,7 +41,7 @@ extern bool CGSIsSecureEventInputSet(); internal unsigned major_version = 0; internal unsigned minor_version = 0; -internal unsigned patch_version = 11; +internal unsigned patch_version = 12; internal struct table hotkey_map; internal char *config_file; -- cgit v1.2.3 From 3adf3f3f8e78995081032f757aa8d23778dfc3d2 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 00:53:44 +0100 Subject: fix whitespace --- src/locale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/locale.c b/src/locale.c index 728463b..afe7ec1 100644 --- a/src/locale.c +++ b/src/locale.c @@ -30,10 +30,10 @@ internal int hash_keymap(const char *a) { unsigned long hash = 0, high; - while(*a) { + while (*a) { hash = (hash << 4) + *a++; high = hash & 0xF0000000; - if(high) { + if (high) { hash ^= (high >> 24); } hash &= ~high; -- cgit v1.2.3 From 0ff2b146f70c47f44d41f9b6be0f63b3cb315ea8 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 01:19:54 +0100 Subject: cleanup changes for #28 --- src/locale.c | 83 ++++++++++++++++++++++++++++-------------------------------- src/locale.h | 1 + src/skhd.c | 9 ++++--- 3 files changed, 45 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/locale.c b/src/locale.c index afe7ec1..464c3ba 100644 --- a/src/locale.c +++ b/src/locale.c @@ -52,40 +52,33 @@ same_keymap(const char *a, const char *b) } internal CFStringRef -cfstring_from_keycode(CGKeyCode keycode) +cfstring_from_keycode(UCKeyboardLayout *keyboard_layout, 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); - } + 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); - } + if (string_length > 0 && status == noErr) { + return CFStringCreateWithCharacters(NULL, unicode_string, string_length); } return NULL; @@ -93,16 +86,22 @@ cfstring_from_keycode(CGKeyCode keycode) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" -internal void -initialize_keycode_map() +bool initialize_keycode_map() { + TISInputSourceRef keyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); + CFDataRef uchr = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(keyboard); + + UCKeyboardLayout *keyboard_layout = (UCKeyboardLayout *) CFDataGetBytePtr(uchr); + if (!keyboard_layout) return false; + 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); + CFStringRef key_string = cfstring_from_keycode(keyboard_layout, index); if (!key_string) continue; char *c_key_string = copy_cf_string_to_c(key_string); @@ -111,20 +110,14 @@ initialize_keycode_map() table_add(&keymap_table, c_key_string, (void *)index); } + + return true; } #pragma clang diagnostic pop uint32_t keycode_from_char(char key) { - uint32_t keycode = 0; - char lookup_key[2]; - - if (!keymap_table.count) { - initialize_keycode_map(); - } - - snprintf(lookup_key, 2, "%c", key); - keycode = (uint32_t) table_find(&keymap_table, &lookup_key); - + char lookup_key[] = { key, '\0' }; + uint32_t keycode = (uint32_t) table_find(&keymap_table, &lookup_key); return keycode; } diff --git a/src/locale.h b/src/locale.h index 7e30d1c..653bcfd 100644 --- a/src/locale.h +++ b/src/locale.h @@ -3,6 +3,7 @@ #include +bool initialize_keycode_map(); uint32_t keycode_from_char(char key); #endif diff --git a/src/skhd.c b/src/skhd.c index 6c08d45..e74715e 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -179,19 +179,23 @@ int main(int argc, char **argv) } if (!check_privileges()) { - error("skhd: must be run with accessibility access.\n"); + error("skhd: must be run with accessibility access! abort..\n"); } if (!config_file) { set_config_path(); } + printf("skhd: using config '%s'\n", config_file); + + if (!initialize_keycode_map()) { + error("skhd: could not initialize keycode map! abort..\n"); + } table_init(&hotkey_map, 131, (table_hash_func) hash_hotkey, (table_compare_func) same_hotkey); - printf("skhd: using config '%s'\n", config_file); parse_config_helper(config_file); signal(SIGCHLD, SIG_IGN); @@ -204,6 +208,5 @@ int main(int argc, char **argv) hotloader_begin(&hotloader, config_handler); CFRunLoopRun(); - return EXIT_SUCCESS; } -- cgit v1.2.3 From a6df9c3fac486b2ba9274737666ac2ca6c90dcd9 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 01:20:16 +0100 Subject: bump version 0.0.13 --- src/skhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/skhd.c b/src/skhd.c index e74715e..6205c45 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -41,7 +41,7 @@ extern bool CGSIsSecureEventInputSet(); internal unsigned major_version = 0; internal unsigned minor_version = 0; -internal unsigned patch_version = 12; +internal unsigned patch_version = 13; internal struct table hotkey_map; internal char *config_file; -- cgit v1.2.3 From 9096762ad24397ede2e91eebe10e34b89ce19172 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 25 Mar 2018 01:34:24 +0100 Subject: change order of initialization --- src/skhd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/skhd.c b/src/skhd.c index 6205c45..5360c7e 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -182,20 +182,20 @@ int main(int argc, char **argv) error("skhd: must be run with accessibility access! abort..\n"); } - if (!config_file) { - set_config_path(); - } - printf("skhd: using config '%s'\n", config_file); - if (!initialize_keycode_map()) { error("skhd: could not initialize keycode map! abort..\n"); } + if (!config_file) { + set_config_path(); + } + table_init(&hotkey_map, 131, (table_hash_func) hash_hotkey, (table_compare_func) same_hotkey); + printf("skhd: using config '%s'\n", config_file); parse_config_helper(config_file); signal(SIGCHLD, SIG_IGN); -- cgit v1.2.3 From da52cf6c58c61f45f604552a9057fc1eed324c89 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Fri, 30 Mar 2018 14:27:52 +0200 Subject: #30 don't ovewrite existing keys in hashtable --- src/hashtable.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hashtable.h b/src/hashtable.h index 48ffaad..42d0166 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -89,7 +89,9 @@ void table_add(struct table *table, void *key, void *value) { struct bucket **bucket = table_get_bucket(table, key); if (*bucket) { - (*bucket)->value = value; + if (!(*bucket)->value) { + (*bucket)->value = value; + } } else { *bucket = table_new_bucket(key, value); ++table->count; -- cgit v1.2.3 From c1a8031fe255baddbea041ed2bfc32787afe2108 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Fri, 30 Mar 2018 14:34:28 +0200 Subject: bump version v.0.0.14 --- src/skhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/skhd.c b/src/skhd.c index 5360c7e..3bdb5f3 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -41,7 +41,7 @@ extern bool CGSIsSecureEventInputSet(); internal unsigned major_version = 0; internal unsigned minor_version = 0; -internal unsigned patch_version = 13; +internal unsigned patch_version = 14; internal struct table hotkey_map; internal char *config_file; -- cgit v1.2.3