aboutsummaryrefslogtreecommitdiff
path: root/src/locale.c
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2018-03-25 00:39:43 +0100
committerkoekeishiya <aasvi93@hotmail.com>2018-03-25 00:39:43 +0100
commitb8a02428123516a43c11bf7a4c4e4cd88fca4020 (patch)
tree912c3743c4c7143caa68f30ae55c6235dd29528c /src/locale.c
parentc91e3f4e520f794bcc8b6f952059656be660eab7 (diff)
downloadskhd-b8a02428123516a43c11bf7a4c4e4cd88fca4020.tar.gz
skhd-b8a02428123516a43c11bf7a4c4e4cd88fca4020.zip
get rid of broken Apple code to actually fix #28
Diffstat (limited to 'src/locale.c')
-rw-r--r--src/locale.c94
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