aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2018-04-20 22:31:09 +0200
committerkoekeishiya <aasvi93@hotmail.com>2018-04-20 22:31:09 +0200
commit9117aa1c79e3f352ee7eb122df64f1b6bd9e53d8 (patch)
treedf4299b441d9bce4bf6d085c055c05902607cd63 /src
parente5f6d5df6db8128fc0b93643711d16adac6404d3 (diff)
parentc1a8031fe255baddbea041ed2bfc32787afe2108 (diff)
downloadskhd-9117aa1c79e3f352ee7eb122df64f1b6bd9e53d8.tar.gz
skhd-9117aa1c79e3f352ee7eb122df64f1b6bd9e53d8.zip
merge master
Diffstat (limited to 'src')
-rw-r--r--src/hashtable.h4
-rw-r--r--src/locale.c147
-rw-r--r--src/locale.h1
-rw-r--r--src/skhd.c11
4 files changed, 111 insertions, 52 deletions
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;
diff --git a/src/locale.c b/src/locale.c
index 974c3ae..464c3ba 100644
--- a/src/locale.c
+++ b/src/locale.c
@@ -1,45 +1,84 @@
#include "locale.h"
+#include "hashtable.h"
#include <Carbon/Carbon.h>
#include <IOKit/hidsystem/ev_keymap.h>
#define internal static
#define local_persist static
-internal CFStringRef
-cfstring_from_keycode(CGKeyCode keycode)
+internal struct table keymap_table;
+
+internal char *
+copy_cf_string_to_c(CFStringRef string)
{
- TISInputSourceRef keyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
- CFDataRef uchr = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
- CFRelease(keyboard);
+ CFStringEncoding encoding = kCFStringEncodingUTF8;
+ CFIndex length = CFStringGetLength(string);
+ CFIndex bytes = CFStringGetMaximumSizeForEncoding(length, encoding);
+ char *result = malloc(bytes + 1);
- 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);
- }
+ // 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;
+}
- if (string_length > 0 && status == noErr) {
- return CFStringCreateWithCharacters(NULL, unicode_string, string_length);
+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(UCKeyboardLayout *keyboard_layout, CGKeyCode keycode)
+{
+ 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;
@@ -47,26 +86,38 @@ cfstring_from_keycode(CGKeyCode keycode)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
-uint32_t keycode_from_char(char key)
+bool initialize_keycode_map()
{
- 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);
- }
- }
+ 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(keyboard_layout, 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);
}
- UniChar uni_char = key;
- CFStringRef char_str = CFStringCreateWithCharacters(kCFAllocatorDefault, &uni_char, 1);
- CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **)&keycode);
- CFRelease(char_str);
+ return true;
+}
+#pragma clang diagnostic pop
+uint32_t keycode_from_char(char key)
+{
+ char lookup_key[] = { key, '\0' };
+ uint32_t keycode = (uint32_t) table_find(&keymap_table, &lookup_key);
return keycode;
}
-#pragma clang diagnostic pop
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 <stdint.h>
+bool initialize_keycode_map();
uint32_t keycode_from_char(char key);
#endif
diff --git a/src/skhd.c b/src/skhd.c
index 16475f9..2e0d6b1 100644
--- a/src/skhd.c
+++ b/src/skhd.c
@@ -41,9 +41,10 @@ extern bool CGSIsSecureEventInputSet();
internal unsigned major_version = 0;
internal unsigned minor_version = 0;
-internal unsigned patch_version = 10;
-internal struct mode *current_mode;
+internal unsigned patch_version = 14;
+internal struct table hotkey_map;
internal struct table mode_map;
+internal struct mode *current_mode;
internal char *config_file;
internal void
@@ -184,7 +185,11 @@ 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 (!initialize_keycode_map()) {
+ error("skhd: could not initialize keycode map! abort..\n");
}
if (!config_file) {