Created
May 3, 2010 00:33
-
-
Save atr000/387590 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* keyremap.c | |
* | |
* features: | |
* 1. map lower enter to forward delete key - useful for macbooks | |
* (works only when secure event input is not activated, | |
* which happens very rarely, e.g. when password fields are focused) | |
* 2. send enter key event when right command key is released | |
* without any other key pressed while it was down | |
* | |
* by Bert Mu"nnich, January 2009 | |
* Based on http://www.osxbook.com/book/bonus/chapter2/alterkeys/ | |
* so the credits go to Amit Singh | |
* | |
* Compile it using the following cmdline: | |
* gcc -framework ApplicationServices -O3 -o keyremap keyremap.c | |
* | |
* Tested on Mac OS X 10.6.1 | |
*/ | |
#define debug(...) if (debugMsgsEnabled) printf(__VA_ARGS__) | |
#define RIGHT_CMD_DOWN 1048848 | |
#define MODIFIER_UP 256 | |
#include <ApplicationServices/ApplicationServices.h> | |
const CGKeyCode ENTER = (CGKeyCode) 76; | |
const CGKeyCode FWDDEL = (CGKeyCode) 117; | |
const CGKeyCode RIGHT_CMD = (CGKeyCode) 54; | |
static bool sendEnter = false; | |
static bool debugMsgsEnabled = false; | |
const char *progname = ""; | |
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { | |
CGKeyCode keycode = (CGKeyCode) CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); | |
CGEventFlags modifiers = CGEventGetFlags(event); | |
debug("Type: %i Modifiers: %i Keycode: %i\n", type, (int) modifiers, keycode); | |
if (keycode == RIGHT_CMD) { | |
if (modifiers == RIGHT_CMD_DOWN) { | |
sendEnter = true; | |
} else if (modifiers == MODIFIER_UP && sendEnter) { | |
debug("right cmd released with no other key pressed -> send enter key event\n"); | |
sendEnter = false; | |
// we had to get a new CGEventRef every time because creating a | |
// global one causes a bus error inside CGEventCreateKeyboardEvent | |
CGEventRef enterKey = CGEventCreateKeyboardEvent(NULL, ENTER, true); | |
CGEventSetFlags(enterKey, (CGEventFlags) 256); | |
// press the enter key... | |
CGEventSetType(enterKey, kCGEventKeyDown); | |
CGEventTapPostEvent(proxy, enterKey); | |
// ... and release it | |
CGEventSetType(enterKey, kCGEventKeyUp); | |
CGEventTapPostEvent(proxy, enterKey); | |
CFRelease(enterKey); | |
} | |
} else if (sendEnter) { | |
debug("another key pressed while right cmd down -> don't send enter key event\n"); | |
sendEnter = false; | |
} | |
if (keycode == ENTER) { | |
debug("change enter to fwd delete\n"); | |
CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, FWDDEL); | |
} | |
return event; | |
} | |
int main(int argc, char **argv) { | |
if (argc > 1) { | |
debugMsgsEnabled = true; | |
} | |
progname = argv[0]; | |
CFMachPortRef eventTap; | |
CFRunLoopSourceRef runLoopSource; | |
CGEventMask eventMask = CGEventMaskBit(kCGEventFlagsChanged) | CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp); | |
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, NULL); | |
if (!eventTap) { | |
fprintf(stderr, "Failed to create event tap!\n"); | |
exit(1); | |
} | |
runLoopSource = CFMachPortCreateRunLoopSource(NULL, eventTap, 0); | |
CFRelease(eventTap); | |
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); | |
CFRelease(runLoopSource); | |
CFRunLoopRun(); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment