summaryrefslogtreecommitdiffstats
path: root/src/lib/platform/OSXMediaKeySupport.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/platform/OSXMediaKeySupport.mm')
-rw-r--r--src/lib/platform/OSXMediaKeySupport.mm154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/lib/platform/OSXMediaKeySupport.mm b/src/lib/platform/OSXMediaKeySupport.mm
new file mode 100644
index 0000000..a4d5767
--- /dev/null
+++ b/src/lib/platform/OSXMediaKeySupport.mm
@@ -0,0 +1,154 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2016 Symless.
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file COPYING that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#import "platform/OSXMediaKeySupport.h"
+#import <Cocoa/Cocoa.h>
+#import <IOKit/hidsystem/ev_keymap.h>
+
+int convertKeyIDToNXKeyType(KeyID id)
+{
+ int type = -1;
+
+ switch (id) {
+ case kKeyAudioUp:
+ type = NX_KEYTYPE_SOUND_UP;
+ break;
+ case kKeyAudioDown:
+ type = NX_KEYTYPE_SOUND_DOWN;
+ break;
+ case kKeyBrightnessUp:
+ type = NX_KEYTYPE_BRIGHTNESS_UP;
+ break;
+ case kKeyBrightnessDown:
+ type = NX_KEYTYPE_BRIGHTNESS_DOWN;
+ break;
+ case kKeyAudioMute:
+ type = NX_KEYTYPE_MUTE;
+ break;
+ case kKeyEject:
+ type = NX_KEYTYPE_EJECT;
+ break;
+ case kKeyAudioPlay:
+ type = NX_KEYTYPE_PLAY;
+ break;
+ case kKeyAudioNext:
+ type = NX_KEYTYPE_NEXT;
+ break;
+ case kKeyAudioPrev:
+ type = NX_KEYTYPE_PREVIOUS;
+ break;
+ default:
+ break;
+ }
+
+ 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)
+{
+
+ NSEvent* downRef = [NSEvent otherEventWithType:NSSystemDefined
+ location: NSMakePoint(0, 0) modifierFlags:0xa00
+ timestamp:0 windowNumber:0 context:0 subtype:8
+ data1:(convertKeyIDToNXKeyType(id) << 16) | ((0xa) << 8)
+ data2:-1];
+ CGEventRef downEvent = [downRef CGEvent];
+
+ NSEvent* upRef = [NSEvent otherEventWithType:NSSystemDefined
+ location: NSMakePoint(0, 0) modifierFlags:0xa00
+ timestamp:0 windowNumber:0 context:0 subtype:8
+ data1:(convertKeyIDToNXKeyType(id) << 16) | ((0xb) << 8)
+ data2:-1];
+ CGEventRef upEvent = [upRef CGEvent];
+
+ CGEventPost(kCGHIDEventTap, downEvent);
+ CGEventPost(kCGHIDEventTap, upEvent);
+
+ return true;
+}