aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2019-03-15 19:21:10 +0100
committerkoekeishiya <aasvi93@hotmail.com>2019-03-15 19:21:10 +0100
commit3aac6931638a8d5da8563e179d71218354e908a6 (patch)
tree4726ae32eabd205e995685529df92fc72a2381a2
parent757c3af5cf6cabb7c72bfd23ca2f1ab2324bee8d (diff)
downloadskhd-3aac6931638a8d5da8563e179d71218354e908a6.tar.gz
skhd-3aac6931638a8d5da8563e179d71218354e908a6.zip
#70 fix memory leak, and code cleanup
-rw-r--r--src/locale.c113
1 files changed, 64 insertions, 49 deletions
diff --git a/src/locale.c b/src/locale.c
index f7aebe3..64f8b04 100644
--- a/src/locale.c
+++ b/src/locale.c
@@ -1,24 +1,25 @@
#include "locale.h"
#include "hashtable.h"
+#include "sbuffer.h"
#include <Carbon/Carbon.h>
#include <IOKit/hidsystem/ev_keymap.h>
+#define array_count(a) (sizeof((a)) / sizeof(*(a)))
+
#define internal static
#define global static
global struct table keymap_table;
+global char **keymap_keys;
internal char *
copy_cfstring(CFStringRef string)
{
- CFStringEncoding encoding = kCFStringEncodingUTF8;
- CFIndex length = CFStringGetLength(string);
- CFIndex bytes = CFStringGetMaximumSizeForEncoding(length, encoding);
- char *result = malloc(bytes + 1);
+ CFIndex num_bytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8);
+ char *result = malloc(num_bytes + 1);
// NOTE(koekeishiya): Boolean: typedef -> unsigned char; false = 0, true != 0
- Boolean success = CFStringGetCString(string, result, bytes + 1, encoding);
- if (!success) {
+ if (!CFStringGetCString(string, result, num_bytes + 1, kCFStringEncodingUTF8)) {
free(result);
result = NULL;
}
@@ -51,50 +52,45 @@ same_keymap(const char *a, const char *b)
return *a == '\0' && *b == '\0';
}
-internal CFStringRef
-cfstring_from_keycode(UCKeyboardLayout *keyboard_layout, CGKeyCode keycode)
+internal void
+free_keycode_map(void)
{
- 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);
+ for (int i = 0; i < buf_len(keymap_keys); ++i) {
+ free(keymap_keys[i]);
}
- return NULL;
+ buf_free(keymap_keys);
+ keymap_keys = NULL;
}
-uint32_t keycode_from_char(char key)
+internal uint32_t layout_dependent_keycodes[] =
{
- char lookup_key[] = { key, '\0' };
- uint32_t keycode = (uint32_t) table_find(&keymap_table, &lookup_key);
- return keycode;
-}
+ kVK_ANSI_A, kVK_ANSI_B, kVK_ANSI_C,
+ kVK_ANSI_D, kVK_ANSI_E, kVK_ANSI_F,
+ kVK_ANSI_G, kVK_ANSI_H, kVK_ANSI_I,
+ kVK_ANSI_J, kVK_ANSI_K, kVK_ANSI_L,
+ kVK_ANSI_M, kVK_ANSI_N, kVK_ANSI_O,
+ kVK_ANSI_P, kVK_ANSI_Q, kVK_ANSI_R,
+ kVK_ANSI_S, kVK_ANSI_T, kVK_ANSI_U,
+ kVK_ANSI_V, kVK_ANSI_W, kVK_ANSI_X,
+ kVK_ANSI_Y, kVK_ANSI_Z, kVK_ANSI_0,
+ kVK_ANSI_1, kVK_ANSI_2, kVK_ANSI_3,
+ kVK_ANSI_4, kVK_ANSI_5, kVK_ANSI_6,
+ kVK_ANSI_7, kVK_ANSI_8, kVK_ANSI_9,
+ kVK_ANSI_Grave, kVK_ANSI_Equal, kVK_ANSI_Minus,
+ kVK_ANSI_RightBracket, kVK_ANSI_LeftBracket, kVK_ANSI_Quote,
+ kVK_ANSI_Semicolon, kVK_ANSI_Backslash, kVK_ANSI_Comma,
+ kVK_ANSI_Slash, kVK_ANSI_Period, kVK_ISO_Section
+};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
bool initialize_keycode_map(void)
{
+ UniChar chars[255];
+ UniCharCount len;
+ UInt32 state;
+
TISInputSourceRef keyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
CFDataRef uchr = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
CFRelease(keyboard);
@@ -102,23 +98,42 @@ bool initialize_keycode_map(void)
UCKeyboardLayout *keyboard_layout = (UCKeyboardLayout *) CFDataGetBytePtr(uchr);
if (!keyboard_layout) return false;
+ free_keycode_map();
table_free(&keymap_table);
table_init(&keymap_table,
- 131,
+ 61,
(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_cfstring(key_string);
- CFRelease(key_string);
- if (!c_key_string) continue;
-
- table_add(&keymap_table, c_key_string, (void *)index);
+ for (int i = 0; i < array_count(layout_dependent_keycodes); ++i) {
+ if (UCKeyTranslate(keyboard_layout,
+ layout_dependent_keycodes[i],
+ kUCKeyActionDown,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysMask,
+ &state,
+ array_count(chars),
+ &len,
+ chars) == noErr && len > 0) {
+ CFStringRef key_cfstring = CFStringCreateWithCharacters(NULL, chars, len);
+ char *key_cstring = copy_cfstring(key_cfstring);
+ CFRelease(key_cfstring);
+
+ if (key_cstring) {
+ table_add(&keymap_table, key_cstring, (void *)layout_dependent_keycodes[i]);
+ buf_push(keymap_keys, key_cstring);
+ }
+ }
}
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;
+}