#include #define NEXT_TRACK "osascript -e 'tell application \"iTunes\"' -e 'next track' -e 'end tell'" #define BACK_TRACK "osascript -e 'tell application \"iTunes\"' -e 'back track' -e 'end tell'" // back track - go to beginning of current track, or previous track if at beginning of current. #define PREVIOUS_TRACK "osascript -e 'tell application \"iTunes\"' -e 'previous track' -e 'end tell'" // previous track - start playing previous track #define PLAYPAUSE "osascript -e 'tell application \"iTunes\"' -e 'playpause' -e 'end tell'" // playpause - toggle play/pause of current track, a.k.a. space bar #define VOLUME_UP "osascript -e 'tell application \"iTunes\"' -e 'set currentVolume to sound volume' -e 'if currentVolume is greater than 90 then' -e 'set currentVolume to 100' -e 'end if' -e 'set sound volume to (currentVolume + 10)' -e 'end tell'" #define VOLUME_DOWN "osascript -e 'tell application \"iTunes\"' -e 'set currentVolume to sound volume' -e 'if currentVolume is less than 10 then' -e 'set currentVolume to 0' -e 'end if' -e 'set sound volume to (currentVolume - 10)' -e 'end tell'" CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { CGKeyCode keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); CGEventFlags flags = CGEventGetFlags (event); if ((flags & kCGEventFlagMaskCommand) && (flags & kCGEventFlagMaskControl) && (flags & kCGEventFlagMaskAlternate)) { if (keycode == 124) system(NEXT_TRACK); else if (keycode == 123) system(PREVIOUS_TRACK); else if (keycode == 126) system(VOLUME_UP); else if (keycode == 125) system(VOLUME_DOWN); else if (keycode == 49) system(PLAYPAUSE); } return event; } int main(void) { CFMachPortRef eventTap; CGEventMask eventMask; CFRunLoopSourceRef runLoopSource; eventMask = (1 << kCGEventKeyUp); eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, eventMask, myCGEventCallback, NULL); if (!eventTap) { fprintf(stderr, "failed to create event tap\n"); exit(1); } runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); CGEventTapEnable(eventTap, true); CFRunLoopRun(); exit(0); }