diff --git a/src/keycode.h b/src/keycode.h index 53ebd9f8..d26c69af 100644 --- a/src/keycode.h +++ b/src/keycode.h @@ -13,7 +13,8 @@ extern "C" #include /* Really only need */ #include - +#import + enum _MMKeyCode { K_NOT_A_KEY = 9999, K_BACKSPACE = kVK_Delete, @@ -49,24 +50,24 @@ enum _MMKeyCode { K_SPACE = kVK_Space, K_PRINTSCREEN = K_NOT_A_KEY, - K_AUDIO_VOLUME_MUTE = kVK_Mute, - K_AUDIO_VOLUME_DOWN = kVK_VolumeDown, - K_AUDIO_VOLUME_UP = kVK_VolumeUp, - K_AUDIO_PLAY = K_NOT_A_KEY, + K_AUDIO_VOLUME_MUTE = NX_KEYTYPE_MUTE, + K_AUDIO_VOLUME_DOWN = NX_KEYTYPE_SOUND_DOWN, + K_AUDIO_VOLUME_UP = NX_KEYTYPE_SOUND_UP, + K_AUDIO_PLAY = NX_KEYTYPE_PLAY, K_AUDIO_STOP = K_NOT_A_KEY, - K_AUDIO_PAUSE = K_NOT_A_KEY, - K_AUDIO_PREV = K_NOT_A_KEY, - K_AUDIO_NEXT = K_NOT_A_KEY, + K_AUDIO_PAUSE = NX_KEYTYPE_PLAY, + K_AUDIO_PREV = NX_KEYTYPE_PREVIOUS, + K_AUDIO_NEXT = NX_KEYTYPE_NEXT, K_AUDIO_REWIND = K_NOT_A_KEY, K_AUDIO_FORWARD = K_NOT_A_KEY, K_AUDIO_REPEAT = K_NOT_A_KEY, K_AUDIO_RANDOM = K_NOT_A_KEY, - K_LIGHTS_MON_UP = K_NOT_A_KEY, - K_LIGHTS_MON_DOWN = K_NOT_A_KEY, - K_LIGHTS_KBD_TOGGLE = K_NOT_A_KEY, - K_LIGHTS_KBD_UP = K_NOT_A_KEY, - K_LIGHTS_KBD_DOWN = K_NOT_A_KEY + K_LIGHTS_MON_UP = NX_KEYTYPE_BRIGHTNESS_UP, + K_LIGHTS_MON_DOWN = NX_KEYTYPE_BRIGHTNESS_DOWN, + K_LIGHTS_KBD_TOGGLE = NX_KEYTYPE_ILLUMINATION_TOGGLE, + K_LIGHTS_KBD_UP = NX_KEYTYPE_ILLUMINATION_UP, + K_LIGHTS_KBD_DOWN = NX_KEYTYPE_ILLUMINATION_DOWN }; typedef CGKeyCode MMKeyCode; diff --git a/src/keypress.c b/src/keypress.c index dffd7bb4..9909a5f6 100644 --- a/src/keypress.c +++ b/src/keypress.c @@ -6,6 +6,8 @@ #if defined(IS_MACOSX) #include + #import + #import #elif defined(USE_X11) #include #include "xdisplay.h" @@ -26,6 +28,45 @@ microsleep(DEADBEEF_UNIFORM(0.0, 62.5))) #endif +#if defined(IS_MACOSX) +bool keyCodeRequiresSystemDefinedEvent(MMKeyCode code) { + return code == NX_KEYTYPE_SOUND_UP || + code == NX_KEYTYPE_SOUND_DOWN || + code == NX_KEYTYPE_MUTE || + code == NX_KEYTYPE_PLAY || + code == NX_KEYTYPE_BRIGHTNESS_UP || + code == NX_KEYTYPE_BRIGHTNESS_DOWN || + code == NX_KEYTYPE_PLAY || + code == NX_KEYTYPE_PREVIOUS || + code == NX_KEYTYPE_NEXT || + code == NX_KEYTYPE_ILLUMINATION_UP || + code == NX_KEYTYPE_ILLUMINATION_DOWN || + code == NX_KEYTYPE_ILLUMINATION_TOGGLE + ; +} +static io_connect_t _getAuxiliaryKeyDriver(void) +{ + static mach_port_t sEventDrvrRef = 0; + mach_port_t masterPort, service, iter; + kern_return_t kr; + + if (!sEventDrvrRef) + { + kr = IOMasterPort( bootstrap_port, &masterPort ); + assert(KERN_SUCCESS == kr); + kr = IOServiceGetMatchingServices(masterPort, IOServiceMatching( kIOHIDSystemClass), &iter ); + assert(KERN_SUCCESS == kr); + service = IOIteratorNext( iter ); + assert(service); + kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &sEventDrvrRef ); + assert(KERN_SUCCESS == kr); + IOObjectRelease(service); + IOObjectRelease(iter); + } + return sEventDrvrRef; +} +#endif + #if defined(IS_WINDOWS) void win32KeyEvent(int key, MMKeyFlags flags) { @@ -43,14 +84,26 @@ void win32KeyEvent(int key, MMKeyFlags flags) void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags) { #if defined(IS_MACOSX) - CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, - (CGKeyCode)code, down); - assert(keyEvent != NULL); - - CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp); - CGEventSetFlags(keyEvent, flags); - CGEventPost(kCGSessionEventTap, keyEvent); - CFRelease(keyEvent); + if (keyCodeRequiresSystemDefinedEvent(code)) { + NXEventData event; + kern_return_t kr; + IOGPoint loc = { 0, 0 }; + UInt32 evtInfo = code << 16 | (down?NX_KEYDOWN:NX_KEYUP) << 8; + bzero(&event, sizeof(NXEventData)); + event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS; + event.compound.misc.L[0] = evtInfo; + kr = IOHIDPostEvent( _getAuxiliaryKeyDriver(), NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE ); + assert( KERN_SUCCESS == kr ); + } else { + CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, + (CGKeyCode)code, down); + assert(keyEvent != NULL); + + CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp); + CGEventSetFlags(keyEvent, flags); + CGEventPost(kCGSessionEventTap, keyEvent); + CFRelease(keyEvent); + } #elif defined(IS_WINDOWS) const DWORD dwFlags = down ? 0 : KEYEVENTF_KEYUP;