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
|
#include <Carbon/Carbon.h>
#include "synthesize.h"
#include "locale.h"
#include "parse.h"
#include "hotkey.h"
#define internal static
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
internal inline void
create_and_post_keyevent(uint16_t key, bool pressed)
{
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)key, pressed);
}
internal inline void
synthesize_modifiers(struct hotkey *hotkey, bool pressed)
{
if (has_flags(hotkey, Hotkey_Flag_Alt)) {
create_and_post_keyevent(Modifier_Keycode_Alt, pressed);
}
if (has_flags(hotkey, Hotkey_Flag_Shift)) {
create_and_post_keyevent(Modifier_Keycode_Shift, pressed);
}
if (has_flags(hotkey, Hotkey_Flag_Cmd)) {
create_and_post_keyevent(Modifier_Keycode_Cmd, pressed);
}
if (has_flags(hotkey, Hotkey_Flag_Control)) {
create_and_post_keyevent(Modifier_Keycode_Ctrl, pressed);
}
if (has_flags(hotkey, Hotkey_Flag_Fn)) {
create_and_post_keyevent(Modifier_Keycode_Fn, pressed);
}
}
void synthesize_key(char *key_string)
{
if (!initialize_keycode_map()) return;
struct parser parser;
parser_init_text(&parser, key_string);
close(1);
close(2);
struct hotkey *hotkey = parse_keypress(&parser);
if (!hotkey) return;
CGSetLocalEventsSuppressionInterval(0.0f);
CGEnableEventStateCombining(false);
synthesize_modifiers(hotkey, true);
create_and_post_keyevent(hotkey->key, true);
create_and_post_keyevent(hotkey->key, false);
synthesize_modifiers(hotkey, false);
}
void synthesize_text(char *text)
{
CFStringRef text_ref = CFStringCreateWithCString(NULL, text, kCFStringEncodingUTF8);
CFIndex text_length = CFStringGetLength(text_ref);
CGEventRef de = CGEventCreateKeyboardEvent(NULL, 0, true);
CGEventRef ue = CGEventCreateKeyboardEvent(NULL, 0, false);
CGEventSetFlags(de, 0);
CGEventSetFlags(ue, 0);
UniChar c;
for (CFIndex i = 0; i < text_length; ++i)
{
c = CFStringGetCharacterAtIndex(text_ref, i);
CGEventKeyboardSetUnicodeString(de, 1, &c);
CGEventPost(kCGAnnotatedSessionEventTap, de);
usleep(1000);
CGEventKeyboardSetUnicodeString(ue, 1, &c);
CGEventPost(kCGAnnotatedSessionEventTap, ue);
}
CFRelease(ue);
CFRelease(de);
CFRelease(text_ref);
}
#pragma clang diagnostic pop
|