SYNERGY-1397 MacOS function keys (#7135)
* SYNERGY-1397 MacOS function keys * SYNERGY-1397 Update ChangeLog and version number * SYNERGY-1397 Remove extra comment * SYNERGY-1397 Remove assertions * SYNERGY-1397 Change log level to warning
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
#include "base/Log.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||
|
||||
// Note that some virtual keys codes appear more than once. The
|
||||
// first instance of a virtual key code maps to the KeyID that we
|
||||
@ -129,6 +130,65 @@ static const KeyEntry s_controlKeys[] = {
|
||||
{ kKeyBrightnessDown, s_brightnessDown }
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
io_connect_t
|
||||
getService(io_iterator_t iter) {
|
||||
io_connect_t service = 0;
|
||||
auto nextIterator = IOIteratorNext(iter);
|
||||
|
||||
if (nextIterator) {
|
||||
IOServiceOpen(nextIterator, mach_task_self(), kIOHIDParamConnectType, &service);
|
||||
IOObjectRelease(nextIterator);
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
io_connect_t
|
||||
getEventDriver()
|
||||
{
|
||||
static io_connect_t sEventDrvrRef = 0;
|
||||
|
||||
if (!sEventDrvrRef) {
|
||||
// Get master device port
|
||||
mach_port_t masterPort = 0;
|
||||
if (!IOMasterPort(bootstrap_port, &masterPort)) {
|
||||
io_iterator_t iter = 0;
|
||||
auto dict = IOServiceMatching(kIOHIDSystemClass);
|
||||
|
||||
if (!IOServiceGetMatchingServices(masterPort, dict, &iter)) {
|
||||
sEventDrvrRef = getService(iter);
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_WARN, "IOService not found"));
|
||||
}
|
||||
|
||||
IOObjectRelease(iter);
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_WARN, "Couldn't obtain IO master port"));
|
||||
}
|
||||
}
|
||||
|
||||
return sEventDrvrRef;
|
||||
}
|
||||
|
||||
bool
|
||||
isModifier(UInt8 virtualKey) {
|
||||
static std::set<UInt8> modifiers {
|
||||
s_shiftVK,
|
||||
s_superVK,
|
||||
s_altVK,
|
||||
s_controlVK,
|
||||
s_capsLockVK
|
||||
};
|
||||
|
||||
return (modifiers.find(virtualKey) != modifiers.end());
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
//
|
||||
// OSXKeyState
|
||||
@ -336,26 +396,26 @@ OSXKeyState::fakeCtrlAltDel()
|
||||
bool
|
||||
OSXKeyState::fakeMediaKey(KeyID id)
|
||||
{
|
||||
return fakeNativeMediaKey(id);;
|
||||
return fakeNativeMediaKey(id);
|
||||
}
|
||||
|
||||
CGEventFlags
|
||||
OSXKeyState::getModifierStateAsOSXFlags()
|
||||
OSXKeyState::getModifierStateAsOSXFlags() const
|
||||
{
|
||||
CGEventFlags modifiers = 0;
|
||||
|
||||
|
||||
if (m_shiftPressed) {
|
||||
modifiers |= kCGEventFlagMaskShift;
|
||||
}
|
||||
|
||||
|
||||
if (m_controlPressed) {
|
||||
modifiers |= kCGEventFlagMaskControl;
|
||||
}
|
||||
|
||||
|
||||
if (m_altPressed) {
|
||||
modifiers |= kCGEventFlagMaskAlternate;
|
||||
}
|
||||
|
||||
|
||||
if (m_superPressed) {
|
||||
modifiers |= kCGEventFlagMaskCommand;
|
||||
}
|
||||
@ -363,7 +423,7 @@ OSXKeyState::getModifierStateAsOSXFlags()
|
||||
if (m_capsPressed) {
|
||||
modifiers |= kCGEventFlagMaskAlphaShift;
|
||||
}
|
||||
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
@ -476,30 +536,6 @@ OSXKeyState::getKeyMap(synergy::KeyMap& keyMap)
|
||||
}
|
||||
}
|
||||
|
||||
CGEventFlags
|
||||
OSXKeyState::getDeviceIndependedFlags() const
|
||||
{
|
||||
CGEventFlags modifiers = 0;
|
||||
|
||||
if (m_shiftPressed) {
|
||||
modifiers |= kCGEventFlagMaskShift;
|
||||
}
|
||||
|
||||
if (m_controlPressed) {
|
||||
modifiers |= kCGEventFlagMaskControl;
|
||||
}
|
||||
|
||||
if (m_altPressed) {
|
||||
modifiers |= kCGEventFlagMaskAlternate;
|
||||
}
|
||||
|
||||
if (m_superPressed) {
|
||||
modifiers |= kCGEventFlagMaskCommand;
|
||||
}
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
CGEventFlags
|
||||
OSXKeyState::getDeviceDependedFlags() const
|
||||
{
|
||||
@ -530,12 +566,9 @@ OSXKeyState::getKeyboardEventFlags() const
|
||||
{
|
||||
// set the event flags for special keys
|
||||
// http://tinyurl.com/pxl742y
|
||||
CGEventFlags modifiers = getDeviceIndependedFlags();
|
||||
CGEventFlags modifiers = getModifierStateAsOSXFlags();
|
||||
|
||||
if (m_capsPressed) {
|
||||
modifiers |= kCGEventFlagMaskAlphaShift;
|
||||
}
|
||||
else {
|
||||
if (!m_capsPressed) {
|
||||
modifiers |= getDeviceDependedFlags();
|
||||
}
|
||||
|
||||
@ -567,7 +600,30 @@ OSXKeyState::setKeyboardModifiers(CGKeyCode virtualKey, bool keyDown)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kern_return_t
|
||||
OSXKeyState::postHIDVirtualKey(UInt8 virtualKey, bool postDown)
|
||||
{
|
||||
NXEventData event;
|
||||
bzero(&event, sizeof(NXEventData));
|
||||
auto driver = getEventDriver();
|
||||
kern_return_t result = KERN_FAILURE;
|
||||
|
||||
if (driver) {
|
||||
if (isModifier(virtualKey)) {
|
||||
result = IOHIDPostEvent(driver, NX_FLAGSCHANGED, {0,0}, &event, kNXEventDataVersion, getKeyboardEventFlags(), true);
|
||||
}
|
||||
else {
|
||||
event.key.keyCode = virtualKey;
|
||||
const auto eventType = postDown ? NX_KEYDOWN : NX_KEYUP;
|
||||
result = IOHIDPostEvent(driver, eventType, {0,0}, &event, kNXEventDataVersion, 0, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
OSXKeyState::postKeyboardKey(CGKeyCode virtualKey, bool keyDown)
|
||||
{
|
||||
CGEventRef event = CGEventCreateKeyboardEvent(nullptr, virtualKey, keyDown);
|
||||
@ -596,7 +652,11 @@ OSXKeyState::fakeKey(const Keystroke& keystroke)
|
||||
button, virtualKey, keyDown ? "down" : "up", client));
|
||||
|
||||
setKeyboardModifiers(virtualKey, keyDown);
|
||||
postKeyboardKey(virtualKey, keyDown);
|
||||
if (postHIDVirtualKey(virtualKey, keyDown) != KERN_SUCCESS) {
|
||||
LOG((CLOG_WARN, "Fail to post HID event"));
|
||||
postKeyboardKey(virtualKey, keyDown);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user