#3305 Used Mac native way to simulate media keys

This commit is contained in:
Jerry (Xinyu Hou) 2016-06-16 15:18:31 +00:00 committed by Andrew Nelless
parent e72e86c9b2
commit d9a6c14170
11 changed files with 171 additions and 6 deletions

View File

@ -18,6 +18,7 @@
#include "platform/OSXKeyState.h" #include "platform/OSXKeyState.h"
#include "platform/OSXUchrKeyResource.h" #include "platform/OSXUchrKeyResource.h"
#include "platform/OSXMediaKeySimulator.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/Log.h" #include "base/Log.h"
@ -316,6 +317,12 @@ OSXKeyState::fakeCtrlAltDel()
return false; return false;
} }
bool
COSXKeyState::fakeMediaKey(KeyID id)
{
return fakeNativeMediaKey(id);;
}
CGEventFlags CGEventFlags
OSXKeyState::getModifierStateAsOSXFlags() OSXKeyState::getModifierStateAsOSXFlags()
{ {

View File

@ -92,6 +92,7 @@ public:
// IKeyState overrides // IKeyState overrides
virtual bool fakeCtrlAltDel(); virtual bool fakeCtrlAltDel();
virtual bool fakeMediaKey(KeyID id);
virtual KeyModifierMask virtual KeyModifierMask
pollActiveModifiers() const; pollActiveModifiers() const;
virtual SInt32 pollActiveGroup() const; virtual SInt32 pollActiveGroup() const;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#import <CoreFoundation/CoreFoundation.h>
#include "synergy/key_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
bool fakeNativeMediaKey(KeyID id);
#if defined(__cplusplus)
}
#endif

View File

@ -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 <Cocoa/Cocoa.h>
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;
}

View File

@ -123,6 +123,13 @@ public:
*/ */
virtual bool fakeCtrlAltDel() = 0; 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 //! @name accessors
//@{ //@{

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "synergy/IPlatformScreen.h"
bool
IPlatformScreen::fakeMediaKey(KeyID id)
{
return false;
}

View File

@ -180,6 +180,7 @@ public:
virtual bool fakeKeyUp(KeyButton button) = 0; virtual bool fakeKeyUp(KeyButton button) = 0;
virtual void fakeAllKeysUp() = 0; virtual void fakeAllKeysUp() = 0;
virtual bool fakeCtrlAltDel() = 0; virtual bool fakeCtrlAltDel() = 0;
virtual bool fakeMediaKey(KeyID id);
virtual bool isKeyDown(KeyButton) const = 0; virtual bool isKeyDown(KeyButton) const = 0;
virtual KeyModifierMask virtual KeyModifierMask
getActiveModifiers() const = 0; getActiveModifiers() const = 0;

View File

@ -571,8 +571,18 @@ KeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton serverID)
m_keyMap.mapKey(keys, id, pollActiveGroup(), m_activeModifiers, m_keyMap.mapKey(keys, id, pollActiveGroup(), m_activeModifiers,
getActiveModifiersRValue(), mask, false); getActiveModifiersRValue(), mask, false);
if (keyItem == NULL) { 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; return;
} }
KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask); KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask);
updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers); updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers);
if (localID != 0) { if (localID != 0) {

View File

@ -73,6 +73,8 @@ public:
virtual bool fakeKeyUp(KeyButton button); virtual bool fakeKeyUp(KeyButton button);
virtual void fakeAllKeysUp(); virtual void fakeAllKeysUp();
virtual bool fakeCtrlAltDel() = 0; virtual bool fakeCtrlAltDel() = 0;
virtual bool fakeMediaKey(KeyID id) = 0;
virtual bool isKeyDown(KeyButton) const; virtual bool isKeyDown(KeyButton) const;
virtual KeyModifierMask virtual KeyModifierMask
getActiveModifiers() const; getActiveModifiers() const;

View File

@ -18,7 +18,7 @@
#pragma once #pragma once
#include "base/EventTypes.h" #include "common/basic_types.h"
//! Key ID //! Key ID
/*! /*!
@ -284,12 +284,10 @@ static const KeyID kKeyAppUser2 = 0xE0B7;
//@} //@}
struct KeyNameMapEntry { struct KeyNameMapEntry {
public:
const char* m_name; const char* m_name;
KeyID m_id; KeyID m_id;
}; };
struct KeyModifierNameMapEntry { struct KeyModifierNameMapEntry {
public:
const char* m_name; const char* m_name;
KeyModifierMask m_mask; 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 above plus non-alphanumeric ASCII characters are in the table. The end
of the table is the first pair with a NULL m_name. 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 //! Modifier key name to KeyModifierMask table
/*! /*!
A table of modifier key names to the corresponding KeyModifierMask. A table of modifier key names to the corresponding KeyModifierMask.
The end of the table is the first pair with a NULL m_name. The end of the table is the first pair with a NULL m_name.
*/ */
extern const KeyModifierNameMapEntry kModifierNameMap[]; extern const struct KeyModifierNameMapEntry kModifierNameMap[];

View File

@ -45,6 +45,7 @@ public:
MOCK_METHOD0(fakeCtrlAltDel, bool()); MOCK_METHOD0(fakeCtrlAltDel, bool());
MOCK_METHOD1(getKeyMap, void(synergy::KeyMap&)); MOCK_METHOD1(getKeyMap, void(synergy::KeyMap&));
MOCK_METHOD1(fakeKey, void(const Keystroke&)); MOCK_METHOD1(fakeKey, void(const Keystroke&));
MOCK_METHOD2(fakeMediaKey, bool(KeyID, bool));
MOCK_CONST_METHOD1(pollPressedKeys, void(KeyButtonSet&)); MOCK_CONST_METHOD1(pollPressedKeys, void(KeyButtonSet&));
}; };