diff --git a/src/lib/platform/OSXMediaKeySimulator.h b/src/lib/platform/OSXMediaKeySimulator.h index 277778df..c62a19bc 100644 --- a/src/lib/platform/OSXMediaKeySimulator.h +++ b/src/lib/platform/OSXMediaKeySimulator.h @@ -18,6 +18,7 @@ #pragma once #import +#import #include "synergy/key_types.h" @@ -25,6 +26,8 @@ extern "C" { #endif bool fakeNativeMediaKey(KeyID id); +bool isMediaKeyEvent(CGEventRef event); +bool getMediaKeyEventInfo(CGEventRef event, KeyID* keyId, bool* down, bool* isRepeat); #if defined(__cplusplus) } #endif diff --git a/src/lib/platform/OSXMediaKeySimulator.m b/src/lib/platform/OSXMediaKeySimulator.m index 646807e3..1106a2ea 100644 --- a/src/lib/platform/OSXMediaKeySimulator.m +++ b/src/lib/platform/OSXMediaKeySimulator.m @@ -13,52 +13,40 @@ */ #import "platform/OSXMediaKeySimulator.h" - #import +#import int convertKeyIDToNXKeyType(KeyID id) { - // hidsystem/ev_keymap.h - // NX_KEYTYPE_SOUND_UP 0 - // NX_KEYTYPE_SOUND_DOWN 1 - // NX_KEYTYPE_BRIGHTNESS_UP 2 - // NX_KEYTYPE_BRIGHTNESS_DOWN 3 - // NX_KEYTYPE_MUTE 7 - // NX_KEYTYPE_EJECT 14 - // NX_KEYTYPE_PLAY 16 - // NX_KEYTYPE_NEXT 17 - // NX_KEYTYPE_PREVIOUS 18 - // NX_KEYTYPE_FAST 19 - // NX_KEYTYPE_REWIND 20 - int type = -1; + switch (id) { case kKeyAudioUp: - type = 0; + type = NX_KEYTYPE_SOUND_UP; break; case kKeyAudioDown: - type = 1; + type = NX_KEYTYPE_SOUND_DOWN; break; case kKeyBrightnessUp: - type = 2; + type = NX_KEYTYPE_BRIGHTNESS_UP; break; case kKeyBrightnessDown: - type = 3; + type = NX_KEYTYPE_BRIGHTNESS_DOWN; break; case kKeyAudioMute: - type = 7; + type = NX_KEYTYPE_MUTE; break; case kKeyEject: - type = 14; + type = NX_KEYTYPE_EJECT; break; case kKeyAudioPlay: - type = 16; + type = NX_KEYTYPE_PLAY; break; case kKeyAudioNext: - type = 17; + type = NX_KEYTYPE_NEXT; break; case kKeyAudioPrev: - type = 18; + type = NX_KEYTYPE_PREVIOUS; break; default: break; @@ -67,6 +55,80 @@ int convertKeyIDToNXKeyType(KeyID id) return type; } +static KeyID +convertNXKeyTypeToKeyID(uint32_t const type) +{ + KeyID id = 0; + + switch (type) { + case NX_KEYTYPE_SOUND_UP: + id = kKeyAudioUp; + break; + case NX_KEYTYPE_SOUND_DOWN: + id = kKeyAudioDown; + break; + case NX_KEYTYPE_MUTE: + id = kKeyAudioMute; + break; + case NX_KEYTYPE_EJECT: + id = kKeyEject; + break; + case NX_KEYTYPE_PLAY: + id = kKeyAudioPlay; + break; + case NX_KEYTYPE_FAST: + case NX_KEYTYPE_NEXT: + id = kKeyAudioNext; + break; + case NX_KEYTYPE_REWIND: + case NX_KEYTYPE_PREVIOUS: + id = kKeyAudioPrev; + break; + default: + break; + } + + return id; +} + +bool +isMediaKeyEvent(CGEventRef event) { + NSEvent* nsEvent = nil; + @try { + nsEvent = [NSEvent eventWithCGEvent: event]; + if ([nsEvent subtype] != 8) { + return false; + } + uint32_t const nxKeyId = ([nsEvent data1] & 0xFFFF0000) >> 16; + if (convertNXKeyTypeToKeyID (nxKeyId)) { + return true; + } + } @catch (NSException* e) { + } + return false; +} + +bool +getMediaKeyEventInfo(CGEventRef event, KeyID* const keyId, + bool* const down, bool* const isRepeat) { + NSEvent* nsEvent = nil; + @try { + nsEvent = [NSEvent eventWithCGEvent: event]; + } @catch (NSException* e) { + return false; + } + if (keyId) { + *keyId = convertNXKeyTypeToKeyID (([nsEvent data1] & 0xFFFF0000) >> 16); + } + if (down) { + *down = !([nsEvent data1] & 0x100); + } + if (isRepeat) { + *isRepeat = [nsEvent data1] & 0x1; + } + return true; +} + bool fakeNativeMediaKey(KeyID id) { diff --git a/src/lib/platform/OSXScreen.cpp b/src/lib/platform/OSXScreen.cpp index 2a4c5c4a..da18190e 100644 --- a/src/lib/platform/OSXScreen.cpp +++ b/src/lib/platform/OSXScreen.cpp @@ -25,6 +25,7 @@ #include "platform/OSXKeyState.h" #include "platform/OSXScreenSaver.h" #include "platform/OSXDragSimulator.h" +#include "platform/OSXMediaKeySimulator.h" #include "platform/OSXPasteboardPeeker.h" #include "synergy/Clipboard.h" #include "synergy/KeyMap.h" @@ -1333,6 +1334,23 @@ OSXScreen::onKey(CGEventRef event) return true; } +void +OSXScreen::onMediaKey(CGEventRef event) +{ + KeyID keyID; + bool down; + bool isRepeat; + + if (!getMediaKeyEventInfo (event, &keyID, &down, &isRepeat)) { + LOG ((CLOG_ERR "Failed to decode media key event")); + return; + } + + LOG ((CLOG_DEBUG2 "Media key event: keyID=0x%02x, %s, repeat=%s", + keyID, (down ? "down": "up"), + (isRepeat ? "yes" : "no"))); +} + bool OSXScreen::onHotKey(EventRef event) const { @@ -1941,8 +1959,13 @@ OSXScreen::handleCGInputEvent(CGEventTapProxy proxy, case NX_NULLEVENT: break; case NX_SYSDEFINED: - LOG((CLOG_DEBUG2 "unknown system defined event")); - return event; + if (isMediaKeyEvent (event)) { + LOG((CLOG_DEBUG2 "detected media key event")); + screen->onMediaKey (event); + } else { + LOG((CLOG_DEBUG2 "ignoring unknown system defined event")); + return event; + } break; case NX_NUMPROCS: break; diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index 77a0cedc..dce5ac08 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -128,6 +128,8 @@ private: void constructMouseButtonEventMap(); bool onKey(CGEventRef event); + + void onMediaKey(CGEventRef event); bool onHotKey(EventRef event) const;