-
Notifications
You must be signed in to change notification settings - Fork 12
/
alterkeys.c
121 lines (107 loc) · 2.84 KB
/
alterkeys.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
// alterkeys.c
// http://osxbook.com
// modified by Chance Miller to support multikeyboard use
//
// Complile using the following command line:
// gcc -Wall -o alterkeys alterkeys.c -framework ApplicationServices
//
// You need superuser privileges to create the event tap, unless accessibility
// is enabled. To do so, select the "Enable access for assistive devices"
// checkbox in the Universal Access system preference pane.
#include <ApplicationServices/ApplicationServices.h>
//Global Variables to keey track of modifier keys pressed
bool ctr = false;
bool sft = false;
bool cmd = false;
bool opt = false;
// This callback will be invoked every time there is a keystroke.
//
CGEventRef
myCGEventCallback(CGEventTapProxy proxy, CGEventType type,
CGEventRef event, void *refcon)
{
// Paranoid sanity check.
if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp) && (type != kCGEventFlagsChanged))
return event;
// The incoming keycode.
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
//Control
if(keycode == (CGKeyCode)59||keycode == (CGKeyCode)62){
if(ctr){
ctr = false;
}
else{
ctr = true;
}
}
if(ctr){
CGEventSetFlags(event,NX_CONTROLMASK|CGEventGetFlags(event));
}
//Shift
if(keycode == (CGKeyCode)60||keycode == (CGKeyCode)56){
if(sft){
sft = false;
}
else{
sft = true;
}
}
if(sft){
CGEventSetFlags(event,NX_SHIFTMASK|CGEventGetFlags(event));
}
//Command
if(keycode == (CGKeyCode)55||keycode == (CGKeyCode)54){
if(cmd){
cmd = false;
}
else{
cmd = true;
}
}
if(cmd){
CGEventSetFlags(event,NX_COMMANDMASK|CGEventGetFlags(event));
}
//Option
if(keycode == (CGKeyCode)58||keycode == (CGKeyCode)61){
if(opt){
opt = false;
}
else{
opt = true;
}
}
if(opt){
CGEventSetFlags(event,NX_ALTERNATEMASK|CGEventGetFlags(event));
}
CGEventSetIntegerValueField(
event, kCGKeyboardEventKeycode, (int64_t)keycode);
// We must return the event for it to be useful.
return event;
}
int
main(void)
{
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;
// Create an event tap. We are interested in key presses.
eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1 << kCGEventFlagsChanged));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
eventMask, myCGEventCallback, NULL);
if (!eventTap) {
fprintf(stderr, "failed to create event tap\n");
exit(1);
}
// Create a run loop source.
runLoopSource = CFMachPortCreateRunLoopSource(
kCFAllocatorDefault, eventTap, 0);
// Add to the current run loop.
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
kCFRunLoopCommonModes);
// Enable the event tap.
CGEventTapEnable(eventTap, true);
// Set it all running.
CFRunLoopRun();
// In a real program, one would have arranged for cleaning up.
exit(0);
}