-
Notifications
You must be signed in to change notification settings - Fork 3
/
RepeatHook.c
136 lines (109 loc) · 4.26 KB
/
RepeatHook.c
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Compile using $cc -O3 RepeatHook.c -framework ApplicationServices
#include <stdio.h>
#include <time.h>
#include <ApplicationServices/ApplicationServices.h>
int isKeyboardEvent(CGEventType);
int isMouseCursorEvent(CGEventType);
int getEvent(CGEventType);
CGEventRef myCGEventCallback(CGEventTapProxy, CGEventType, CGEventRef, void *);
#define EVENT_UNDEFINED 0
#define EVENT_KEY_DOWN 1
#define EVENT_KEY_UP 2
#define EVENT_LEFT_MOUSE_DOWN 3
#define EVENT_LEFT_MOUSE_UP 4
#define EVENT_RIGHT_MOUSE_DOWN 5
#define EVENT_RIGHT_MOUSE_UP 6
#define EVENT_MOUSE_SCROLLED 7
#define EVENT_MOUSE_MOVED 8
int main (int argc, const char * argv[]) {
CGEventFlags oldFlags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
CGEventMask eventMask = (CGEventMaskBit(kCGEventKeyDown) |
CGEventMaskBit(kCGEventKeyUp) |
CGEventMaskBit(kCGEventLeftMouseDown) |
CGEventMaskBit(kCGEventLeftMouseUp) |
CGEventMaskBit(kCGEventRightMouseDown) |
CGEventMaskBit(kCGEventRightMouseUp) |
CGEventMaskBit(kCGEventScrollWheel) |
CGEventMaskBit(kCGEventMouseMoved) |
CGEventMaskBit(kCGEventFlagsChanged));
CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, &oldFlags);
printf("Setting up...\n");
if (!eventTap) {
fprintf(stderr, "failed to create event tap\nyou need to enable \"Enable access for assitive devices\" in Universal Access preference panel.");
exit(1);
}
printf("Setting up loop source...\n");
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
printf("Enabling event Tap...\n");
CGEventTapEnable(eventTap, true);
printf("Running loop\n");
printf("###################################\n");
fflush(stdout);
CFRunLoopRun();
return 0;
}
CGEventRef myCGEventCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
if (!isKeyboardEvent(type) &&
!isMouseCursorEvent(type) &&
(type != kCGEventScrollWheel) &&
(type != kCGEventFlagsChanged)) {
return event;
}
int eventCode = getEvent(type);
if (type == kCGEventFlagsChanged) {
CGKeyCode keyCode = (CGKeyCode) CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
CGEventFlags flag = CGEventGetFlags(event);
int code = (int) keyCode;
printf("E:%d,C:%d,M:%llu\n", eventCode, code, flag);
}
if (type == kCGEventKeyDown || type == kCGEventKeyUp) {
CGKeyCode keyCode = (CGKeyCode) CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
int code = (int) keyCode;
printf("E:%d,C:%d\n", eventCode, code);
}
if (isMouseCursorEvent(type)) {
CGPoint point = CGEventGetLocation(event);
double x = (double) point.x;
double y = (double) point.y;
printf("E:%d,X:%.0f,Y:%.0f\n", eventCode, x, y);
}
if (type == kCGEventScrollWheel) {
printf("E:%d\n", eventCode);
}
fflush(stdout);
return event;
}
int isKeyboardEvent(CGEventType type) {
return (type == kCGEventKeyDown) || (type == kCGEventKeyUp);
}
int isMouseCursorEvent(CGEventType type) {
return (type == kCGEventLeftMouseDown) ||
(type == kCGEventLeftMouseUp) ||
(type == kCGEventRightMouseDown) ||
(type == kCGEventRightMouseUp) ||
(type == kCGEventMouseMoved);
}
int getEvent(CGEventType type) {
int output = 0;
if (type == kCGEventKeyDown) {
output = EVENT_KEY_DOWN;
} else if (type == kCGEventKeyUp) {
output = EVENT_KEY_UP;
} else if (type == kCGEventLeftMouseDown) {
output = EVENT_LEFT_MOUSE_DOWN;
} else if (type == kCGEventLeftMouseUp) {
output = EVENT_LEFT_MOUSE_UP;
} else if (type == kCGEventRightMouseDown) {
output = EVENT_RIGHT_MOUSE_DOWN;
} else if (type == kCGEventRightMouseUp) {
output = EVENT_RIGHT_MOUSE_UP;
} else if (type == kCGEventMouseMoved) {
output = EVENT_MOUSE_MOVED;
} else if (type == kCGEventScrollWheel) {
output = EVENT_MOUSE_SCROLLED;
} else if (type == kCGEventFlagsChanged) {
output = EVENT_UNDEFINED;
}
return output;
}