static IntPtr tapEventCallback(IntPtr proxy, CGEventType type, IntPtr evtHandle, IntPtr info) { using (new NSAutoreleasePool()) { var evt = new CGEvent(evtHandle); if (!SPMediaKeyTap.Shared.ShouldInterceptMediaKeyEvents) { return(evtHandle); } switch (type) { //kCGEventTapDisabledByTimeout case (CGEventType)kCGEventTapDisabledByTimeout: CGEvent.TapEnable(SPMediaKeyTap.Shared.eventPort); return(evtHandle); case (CGEventType)kCGEventTapDisabledByUser: return(evtHandle); } NSEvent nsEvent = null; try{ nsEvent = NSEvent.EventWithCGEvent(evtHandle); } catch (Exception ex) { return(evtHandle); } if (nsEvent.Subtype != SPSystemDefinedEventMediaKeys) { return(evtHandle); } long keyCode = ((nsEvent.Data1 & 0xFFFF0000) >> 16); var keyFlags = (nsEvent.Data1 & 0x0000FFFF); var keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; if (keyCode == 10 && keyFlags == 6972) { switch (nsEvent.Data2) { case 786608: // Play / Pause on OS < 10.10 Yosemite case 786637: // Play / Pause on OS >= 10.10 Yosemite Console.WriteLine(@"Play/Pause bluetooth keypress detected...sending corresponding media key event"); SPMediaKeyTap.Shared.RecievedEvent(MediaKey.Play); break; case 786611: // Next Console.WriteLine(@"Next bluetooth keypress detected...sending corresponding media key event"); SPMediaKeyTap.Shared.RecievedEvent(MediaKey.Next); break; case 786612: // Previous Console.WriteLine(@"Previous bluetooth keypress detected...sending corresponding media key event"); SPMediaKeyTap.Shared.RecievedEvent(MediaKey.Previous); break; case 786613: // Fast-forward Console.WriteLine(@"Fast-forward bluetooth keypress detected...sending corresponding media key event"); SPMediaKeyTap.Shared.RecievedEvent(MediaKey.Fast); break; case 786614: // Rewind Console.WriteLine(@"Rewind bluetooth keypress detected...sending corresponding media key event"); SPMediaKeyTap.Shared.RecievedEvent(MediaKey.Rewind); break; default: // TODO make this popup a message in the UI (with a link to submit the issue and a "don't show this message again" checkbox) LogManager.Shared.Log($"Unknown bluetooth key received: keyCode:{keyCode} keyFlags:{keyFlags} keyState:{keyState} {nsEvent.Data2}"); return(evtHandle); } } else { if (keyCode != NX_KEYTYPE_PLAY && keyCode != NX_KEYTYPE_FAST && keyCode != NX_KEYTYPE_REWIND && keyCode != NX_KEYTYPE_PREVIOUS && keyCode != NX_KEYTYPE_NEXT) { return(evtHandle); } //These always come in pairs if (lastKeyCode != keyCode) { SPMediaKeyTap.Shared.BeginInvokeOnMainThread(() => { SPMediaKeyTap.Shared.RecievedEvent((MediaKey)keyCode); }); lastKeyCode = keyCode; } else { lastKeyCode = 0; } } evt.Dispose(); return(IntPtr.Zero); } }