diff --git a/src/lib/platform/OSXKeyState.cpp b/src/lib/platform/OSXKeyState.cpp
index 9f3d923f..03d5d54e 100644
--- a/src/lib/platform/OSXKeyState.cpp
+++ b/src/lib/platform/OSXKeyState.cpp
@@ -18,6 +18,7 @@
#include "platform/OSXKeyState.h"
#include "platform/OSXUchrKeyResource.h"
+#include "platform/OSXMediaKeySimulator.h"
#include "arch/Arch.h"
#include "base/Log.h"
@@ -316,6 +317,12 @@ OSXKeyState::fakeCtrlAltDel()
return false;
}
+bool
+COSXKeyState::fakeMediaKey(KeyID id)
+{
+ return fakeNativeMediaKey(id);;
+}
+
CGEventFlags
OSXKeyState::getModifierStateAsOSXFlags()
{
diff --git a/src/lib/platform/OSXKeyState.h b/src/lib/platform/OSXKeyState.h
index 29cd5d6c..2aaffc47 100644
--- a/src/lib/platform/OSXKeyState.h
+++ b/src/lib/platform/OSXKeyState.h
@@ -92,6 +92,7 @@ public:
// IKeyState overrides
virtual bool fakeCtrlAltDel();
+ virtual bool fakeMediaKey(KeyID id);
virtual KeyModifierMask
pollActiveModifiers() const;
virtual SInt32 pollActiveGroup() const;
diff --git a/src/lib/platform/OSXMediaKeySimulator.h b/src/lib/platform/OSXMediaKeySimulator.h
new file mode 100644
index 00000000..277778df
--- /dev/null
+++ b/src/lib/platform/OSXMediaKeySimulator.h
@@ -0,0 +1,30 @@
+/*
+ * synergy -- 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#import
+
+#include "synergy/key_types.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+bool fakeNativeMediaKey(KeyID id);
+#if defined(__cplusplus)
+}
+#endif
diff --git a/src/lib/platform/OSXMediaKeySimulator.m b/src/lib/platform/OSXMediaKeySimulator.m
new file mode 100644
index 00000000..b7d243f6
--- /dev/null
+++ b/src/lib/platform/OSXMediaKeySimulator.m
@@ -0,0 +1,84 @@
+/*
+ * synergy -- 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/OSXMediaKeySimulator.h"
+
+#import
+
+int convertKeyIDToNXKeyType(KeyID id)
+{
+ // hidsystem/ev_keymap.h
+ // NX_KEYTYPE_SOUND_UP 0
+ // NX_KEYTYPE_SOUND_DOWN 1
+ // 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;
+ break;
+ case kKeyAudioDown:
+ type = 1;
+ break;
+ case kKeyAudioMute:
+ type = 7;
+ break;
+ case kKeyEject:
+ type = 14;
+ break;
+ case kKeyAudioPlay:
+ type = 16;
+ break;
+ case kKeyAudioNext:
+ type = 17;
+ break;
+ case kKeyAudioPrev:
+ type = 18;
+ break;
+ default:
+ break;
+ }
+
+ return type;
+}
+
+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(0, downEvent);
+ CGEventPost(0, upEvent);
+
+ return true;
+}
diff --git a/src/lib/synergy/IKeyState.h b/src/lib/synergy/IKeyState.h
index 0e6484c1..da0062c4 100644
--- a/src/lib/synergy/IKeyState.h
+++ b/src/lib/synergy/IKeyState.h
@@ -122,7 +122,14 @@ public:
complete and false if normal key processing should continue.
*/
virtual bool fakeCtrlAltDel() = 0;
-
+
+ //! Fake a media key
+ /*!
+ Synthesizes a media key down and up. Only Mac would implement this by
+ use cocoa appkit framework.
+ */
+ virtual bool fakeMediaKey(KeyID id) = 0;
+
//@}
//! @name accessors
//@{
diff --git a/src/lib/synergy/IPlatformScreen.cpp b/src/lib/synergy/IPlatformScreen.cpp
new file mode 100644
index 00000000..7c2b679f
--- /dev/null
+++ b/src/lib/synergy/IPlatformScreen.cpp
@@ -0,0 +1,24 @@
+/*
+ * synergy -- 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "synergy/IPlatformScreen.h"
+
+bool
+IPlatformScreen::fakeMediaKey(KeyID id)
+{
+ return false;
+}
diff --git a/src/lib/synergy/IPlatformScreen.h b/src/lib/synergy/IPlatformScreen.h
index 98b7668c..cd00b23c 100644
--- a/src/lib/synergy/IPlatformScreen.h
+++ b/src/lib/synergy/IPlatformScreen.h
@@ -180,6 +180,7 @@ public:
virtual bool fakeKeyUp(KeyButton button) = 0;
virtual void fakeAllKeysUp() = 0;
virtual bool fakeCtrlAltDel() = 0;
+ virtual bool fakeMediaKey(KeyID id);
virtual bool isKeyDown(KeyButton) const = 0;
virtual KeyModifierMask
getActiveModifiers() const = 0;
diff --git a/src/lib/synergy/KeyState.cpp b/src/lib/synergy/KeyState.cpp
index 79b775f3..6adeb243 100644
--- a/src/lib/synergy/KeyState.cpp
+++ b/src/lib/synergy/KeyState.cpp
@@ -571,8 +571,18 @@ KeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton serverID)
m_keyMap.mapKey(keys, id, pollActiveGroup(), m_activeModifiers,
getActiveModifiersRValue(), mask, false);
if (keyItem == NULL) {
+ // a media key won't be mapped on mac, so we need to fake it in a
+ // special way
+ if (id == kKeyAudioDown || id == kKeyAudioUp || id == kKeyAudioMute ||
+ id == kKeyAudioPrev || id == kKeyAudioNext ||
+ id == kKeyAudioPlay) {
+ LOG((CLOG_DEBUG "emulating media key"));
+ fakeMediaKey(id);
+ }
+
return;
}
+
KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask);
updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers);
if (localID != 0) {
diff --git a/src/lib/synergy/KeyState.h b/src/lib/synergy/KeyState.h
index af9bcd6a..3d148353 100644
--- a/src/lib/synergy/KeyState.h
+++ b/src/lib/synergy/KeyState.h
@@ -73,6 +73,8 @@ public:
virtual bool fakeKeyUp(KeyButton button);
virtual void fakeAllKeysUp();
virtual bool fakeCtrlAltDel() = 0;
+ virtual bool fakeMediaKey(KeyID id) = 0;
+
virtual bool isKeyDown(KeyButton) const;
virtual KeyModifierMask
getActiveModifiers() const;
diff --git a/src/lib/synergy/key_types.h b/src/lib/synergy/key_types.h
index e789e140..71d19591 100644
--- a/src/lib/synergy/key_types.h
+++ b/src/lib/synergy/key_types.h
@@ -18,7 +18,7 @@
#pragma once
-#include "base/EventTypes.h"
+#include "common/basic_types.h"
//! Key ID
/*!
@@ -284,12 +284,10 @@ static const KeyID kKeyAppUser2 = 0xE0B7;
//@}
struct KeyNameMapEntry {
-public:
const char* m_name;
KeyID m_id;
};
struct KeyModifierNameMapEntry {
-public:
const char* m_name;
KeyModifierMask m_mask;
};
@@ -300,11 +298,11 @@ A table of key names to the corresponding KeyID. Only the keys listed
above plus non-alphanumeric ASCII characters are in the table. The end
of the table is the first pair with a NULL m_name.
*/
-extern const KeyNameMapEntry kKeyNameMap[];
+extern const struct KeyNameMapEntry kKeyNameMap[];
//! Modifier key name to KeyModifierMask table
/*!
A table of modifier key names to the corresponding KeyModifierMask.
The end of the table is the first pair with a NULL m_name.
*/
-extern const KeyModifierNameMapEntry kModifierNameMap[];
+extern const struct KeyModifierNameMapEntry kModifierNameMap[];
diff --git a/src/test/unittests/synergy/KeyStateTests.h b/src/test/unittests/synergy/KeyStateTests.h
index 236bf3dc..8a9846c0 100644
--- a/src/test/unittests/synergy/KeyStateTests.h
+++ b/src/test/unittests/synergy/KeyStateTests.h
@@ -45,6 +45,7 @@ public:
MOCK_METHOD0(fakeCtrlAltDel, bool());
MOCK_METHOD1(getKeyMap, void(synergy::KeyMap&));
MOCK_METHOD1(fakeKey, void(const Keystroke&));
+ MOCK_METHOD2(fakeMediaKey, bool(KeyID, bool));
MOCK_CONST_METHOD1(pollPressedKeys, void(KeyButtonSet&));
};