1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include "locale.h"
#include <Carbon/Carbon.h>
#include <IOKit/hidsystem/ev_keymap.h>
#define internal static
#define local_persist static
bool same_string(char *text, unsigned length, const char *match)
{
const char *at = match;
unsigned index = 0;
while(*at++ == text[index++] && index < length);
return (*at == '\0' && index == length) ? true : false;
}
internal CFStringRef
cfstring_from_keycode(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);
}
if(string_length > 0 && status == noErr) {
return CFStringCreateWithCharacters(NULL, unicode_string, string_length);
}
}
return NULL;
}
uint32_t keycode_from_char(char key)
{
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);
}
}
}
UniChar uni_char = key;
CFStringRef char_str = CFStringCreateWithCharacters(kCFAllocatorDefault, &uni_char, 1);
CFDictionaryGetValueIfPresent(keycode_map, char_str, (const void **)&keycode);
CFRelease(char_str);
return keycode;
}
uint32_t keycode_from_literal(char *key, unsigned length)
{
if(same_string(key, length, "return")) {
return kVK_Return;
} else if(same_string(key, length, "tab")) {
return kVK_Tab;
} else if(same_string(key, length, "space")) {
return kVK_Space;
} else if(same_string(key, length, "backspace")) {
return kVK_Delete;
} else if(same_string(key, length, "delete")) {
return kVK_ForwardDelete;
} else if(same_string(key, length, "escape")) {
return kVK_Escape;
} else if(same_string(key, length, "home")) {
return kVK_Home;
} else if(same_string(key, length, "end")) {
return kVK_End;
} else if(same_string(key, length, "pageup")) {
return kVK_PageUp;
} else if(same_string(key, length, "pagedown")) {
return kVK_PageDown;
} else if(same_string(key, length, "help")) {
return kVK_Help;
} else if(same_string(key, length, "left")) {
return kVK_LeftArrow;
} else if(same_string(key, length, "right")) {
return kVK_RightArrow;
} else if(same_string(key, length, "up")) {
return kVK_UpArrow;
} else if(same_string(key, length, "down")) {
return kVK_DownArrow;
} else if(same_string(key, length, "f1")) {
return kVK_F1;
} else {
return 0;
}
}
|