diff --git a/src/lib/platform/OSXIOHID.h b/src/lib/platform/OSXIOHID.h
new file mode 100644
index 00000000..16c18646
--- /dev/null
+++ b/src/lib/platform/OSXIOHID.h
@@ -0,0 +1,34 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ *
+ * 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 LICENSE 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
+
+#include
+
+//! IOHID event on Mac
+class OSXIOHID {
+public:
+ void postModifierKeys(UInt32 mask);
+ void postKey(const UInt8 virtualKeyCode,
+ const bool down);
+ void fakeMouseButton(UInt32 button, bool press);
+
+private:
+ void postMouseEvent(io_connect_t event, UInt32 type,
+ NXEventData* ev, IOOptionBits flags,
+ IOOptionBits options);
+};
diff --git a/src/lib/platform/OSXIOHID.mm b/src/lib/platform/OSXIOHID.mm
new file mode 100644
index 00000000..803ce724
--- /dev/null
+++ b/src/lib/platform/OSXIOHID.mm
@@ -0,0 +1,141 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ *
+ * 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 LICENSE 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 "platform/OSXIOHID.h"
+
+#include "base/Log.h"
+
+#include
+#include
+#include
+
+static io_connect_t getEventDriver(void)
+{
+ static mach_port_t sEventDrvrRef = 0;
+ mach_port_t masterPort, service, iter;
+ kern_return_t kr;
+
+ if (!sEventDrvrRef) {
+ // Get master device port
+ kr = IOMasterPort(bootstrap_port, &masterPort);
+ assert(KERN_SUCCESS == kr);
+
+ kr = IOServiceGetMatchingServices(masterPort,
+ IOServiceMatching(kIOHIDSystemClass), &iter);
+ assert(KERN_SUCCESS == kr);
+
+ service = IOIteratorNext(iter);
+ assert(service);
+
+ kr = IOServiceOpen(service, mach_task_self(),
+ kIOHIDParamConnectType, &sEventDrvrRef);
+ assert(KERN_SUCCESS == kr);
+
+ IOObjectRelease(service);
+ IOObjectRelease(iter);
+ }
+
+ return sEventDrvrRef;
+}
+
+void
+OSXIOHID::postModifierKeys(UInt32 mask)
+{
+ NXEventData event;
+ bzero(&event, sizeof(NXEventData));
+ IOGPoint loc = { 0, 0 };
+ kern_return_t kr;
+ kr = IOHIDPostEvent(getEventDriver(), NX_FLAGSCHANGED, loc,
+ &event, kNXEventDataVersion, mask, true);
+ assert(KERN_SUCCESS == kr);
+}
+
+void
+OSXIOHID::postKey(const UInt8 virtualKeyCode,
+ const bool down)
+{
+ NXEventData event;
+ bzero(&event, sizeof(NXEventData));
+ IOGPoint loc = { 0, 0 };
+ event.key.repeat = false;
+ event.key.keyCode = virtualKeyCode;
+ event.key.origCharSet = event.key.charSet = NX_ASCIISET;
+ event.key.origCharCode = event.key.charCode = 0;
+ kern_return_t kr;
+ kr = IOHIDPostEvent(getEventDriver(),
+ down ? NX_KEYDOWN : NX_KEYUP,
+ loc, &event, kNXEventDataVersion, 0, false);
+ assert(KERN_SUCCESS == kr);
+}
+
+void
+OSXIOHID::fakeMouseButton(UInt32 button, bool press)
+{
+ NXEventData event;
+ memset (&event, 0, sizeof(event));
+
+ // Mouse presses actually generate two events, one with a bitfield of buttons, one with a button number
+ event.compound.subType = NX_SUBTYPE_AUX_MOUSE_BUTTONS;
+ event.compound.misc.L[0] = (1 << button);
+ event.compound.misc.L[1] = press ? (1 << button) : 0;
+ postMouseEvent(getEventDriver(), NX_SYSDEFINED, &event, 0, 0);
+
+ memset(&event, 0, sizeof(event));
+ event.mouse.buttonNumber = button;
+ UInt32 type;
+
+ switch (button){
+ case 0:
+ type = press ? NX_LMOUSEDOWN : NX_LMOUSEUP;
+ break;
+ case 1:
+ type = press ? NX_RMOUSEDOWN : NX_RMOUSEUP;
+ break;
+ default:
+ type = press ? NX_OMOUSEDOWN : NX_OMOUSEUP;
+ }
+
+ if (press) {
+ event.mouse.pressure = 255;
+ }
+
+ postMouseEvent(getEventDriver(), type, &event, 0, 0);
+}
+
+void
+OSXIOHID::postMouseEvent(
+ io_connect_t event, UInt32 type,
+ NXEventData* ev, IOOptionBits flags,
+ IOOptionBits options)
+{
+
+ IOGPoint location = {0, 0};
+ if ((options & kIOHIDSetRelativeCursorPosition) && type != NX_MOUSEMOVED){
+ // Mouse button only accepts absolute coordinates
+ CGEventRef cge = CGEventCreate(nil);
+ CGPoint loc = CGEventGetLocation(cge);
+ CFRelease(cge);
+ location.x = floor(loc.x + ev->mouseMove.dx);
+ location.y = floor(loc.y + ev->mouseMove.dy);
+ options = (options & ~kIOHIDSetRelativeCursorPosition) | kIOHIDSetCursorPosition;
+ }
+
+ kern_return_t res = IOHIDPostEvent(event, type, location, ev, kNXEventDataVersion, flags | NX_NONCOALSESCEDMASK, options);
+ if (res != kIOReturnSuccess) {
+ LOG((CLOG_DEBUG1 "IOHIDPostEvent event failed: %x\n", res));
+ }
+}
diff --git a/src/lib/platform/OSXKeyState.cpp b/src/lib/platform/OSXKeyState.cpp
index 95492340..cf48b993 100644
--- a/src/lib/platform/OSXKeyState.cpp
+++ b/src/lib/platform/OSXKeyState.cpp
@@ -16,6 +16,7 @@
* along with this program. If not, see .
*/
+#include "platform/OSXIOHID.h"
#include "platform/OSXKeyState.h"
#include "platform/OSXUchrKeyResource.h"
#include "platform/OSXMediaKeySupport.h"
@@ -470,46 +471,13 @@ OSXKeyState::getKeyMap(synergy::KeyMap& keyMap)
}
}
-static io_connect_t getEventDriver(void)
-{
- static mach_port_t sEventDrvrRef = 0;
- mach_port_t masterPort, service, iter;
- kern_return_t kr;
-
- if (!sEventDrvrRef) {
- // Get master device port
- kr = IOMasterPort(bootstrap_port, &masterPort);
- assert(KERN_SUCCESS == kr);
-
- kr = IOServiceGetMatchingServices(masterPort,
- IOServiceMatching(kIOHIDSystemClass), &iter);
- assert(KERN_SUCCESS == kr);
-
- service = IOIteratorNext(iter);
- assert(service);
-
- kr = IOServiceOpen(service, mach_task_self(),
- kIOHIDParamConnectType, &sEventDrvrRef);
- assert(KERN_SUCCESS == kr);
-
- IOObjectRelease(service);
- IOObjectRelease(iter);
- }
-
- return sEventDrvrRef;
-}
-
void
OSXKeyState::postHIDVirtualKey(const UInt8 virtualKeyCode,
const bool postDown)
{
static UInt32 modifiers = 0;
-
- NXEventData event;
- IOGPoint loc = { 0, 0 };
UInt32 modifiersDelta = 0;
-
- bzero(&event, sizeof(NXEventData));
+ OSXIOHID hid;
switch (virtualKeyCode)
{
@@ -549,22 +517,12 @@ OSXKeyState::postHIDVirtualKey(const UInt8 virtualKeyCode,
else {
modifiers &= ~modifiersDelta;
}
-
- kern_return_t kr;
- kr = IOHIDPostEvent(getEventDriver(), NX_FLAGSCHANGED, loc,
- &event, kNXEventDataVersion, modifiers, true);
- assert(KERN_SUCCESS == kr);
+
+ hid.postModifierKeys(modifiers);
break;
default:
- event.key.repeat = false;
- event.key.keyCode = virtualKeyCode;
- event.key.origCharSet = event.key.charSet = NX_ASCIISET;
- event.key.origCharCode = event.key.charCode = 0;
- kr = IOHIDPostEvent(getEventDriver(),
- postDown ? NX_KEYDOWN : NX_KEYUP,
- loc, &event, kNXEventDataVersion, 0, false);
- assert(KERN_SUCCESS == kr);
+ hid.postKey(virtualKeyCode, postDown);
break;
}
}
diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm
index 8e619306..d96ed1ab 100644
--- a/src/lib/platform/OSXScreen.mm
+++ b/src/lib/platform/OSXScreen.mm
@@ -18,8 +18,8 @@
#include "platform/OSXScreen.h"
-#include "base/EventQueue.h"
#include "client/Client.h"
+#include "platform/OSXIOHID.h"
#include "platform/OSXClipboard.h"
#include "platform/OSXEventQueueBuffer.h"
#include "platform/OSXKeyState.h"
@@ -35,16 +35,18 @@
#include "mt/Mutex.h"
#include "mt/Thread.h"
#include "arch/XArch.h"
-#include "base/Log.h"
+#include "base/EventQueue.h"
#include "base/IEventQueue.h"
#include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
+#include "base/Log.h"
#include
#include
#include
#include
#include
+#include
// This isn't in any Apple SDK that I know of as of yet.
enum {
@@ -514,67 +516,15 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
if (index >= NumButtonIDs) {
return;
}
-
- CGPoint pos;
- if (!m_cursorPosValid) {
- SInt32 x, y;
- getCursorPos(x, y);
- }
- pos.x = m_xCursor;
- pos.y = m_yCursor;
- // variable used to detect mouse coordinate differences between
- // old & new mouse clicks. Used in double click detection.
- SInt32 xDiff = m_xCursor - m_lastSingleClickXCursor;
- SInt32 yDiff = m_yCursor - m_lastSingleClickYCursor;
- double diff = sqrt(xDiff * xDiff + yDiff * yDiff);
- // max sqrt(x^2 + y^2) difference allowed to double click
- // since we don't have double click distance in NX APIs
- // we define our own defaults.
- const double maxDiff = sqrt(2) + 0.0001;
-
- double clickTime = [NSEvent doubleClickInterval];
-
- // As long as the click is within the time window and distance window
- // increase clickState (double click, triple click, etc)
- // This will allow for higher than triple click but the quartz documenation
- // does not specify that this should be limited to triple click
- if (press) {
- if ((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff){
- m_clickState++;
- }
- else {
- m_clickState = 1;
- }
-
- m_lastClickTime = ARCH->time();
- }
-
- if (m_clickState == 1){
- m_lastSingleClickXCursor = m_xCursor;
- m_lastSingleClickYCursor = m_yCursor;
- }
-
- EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
-
LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", index, press ? "pressed" : "released"));
- MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
- CGEventType type = thisButtonMap[state];
+ OSXIOHID hid;
+ hid.fakeMouseButton(index, press);
- CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, static_cast(index));
-
- CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState);
-
- // Fix for sticky keys
- CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags();
- CGEventSetFlags(event, modifiers);
-
+ EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
m_buttonState.set(index, state);
- CGEventPost(kCGHIDEventTap, event);
-
- CFRelease(event);
-
+
if (!press && (id == kButtonLeft)) {
if (m_fakeDraggingStarted) {
m_getDropTargetThread = new Thread(new TMethodJob(
@@ -1894,21 +1844,22 @@ OSXScreen::handleCGInputEventSecondary(
CGEventRef event,
void* refcon)
{
- // this fix is really screwing with the correct show/hide behavior. it
- // should be tested better before reintroducing.
- return event;
+ CGEventMask mask = kCGEventFlagMaskCommand;
+ mask = CGEventGetFlags(event);
+ LOG ((CLOG_INFO "%x", mask));
+ auto i = CGEventGetIntegerValueField(event, kCGEventSourceUnixProcessID);
+ LOG ((CLOG_INFO "Target PID:%lld", i));
- OSXScreen* screen = (OSXScreen*)refcon;
- if (screen->m_cursorHidden && type == kCGEventMouseMoved) {
+ switch(type) {
+ case kCGEventLeftMouseDown:
+ case kCGEventRightMouseDown:
+ case kCGEventOtherMouseDown:
+ case kCGEventScrollWheel:
+ case kCGEventKeyDown:
+ case kCGEventFlagsChanged:
+ ;//LOG((CLOG_INFO "local input detected"));
+ }
- CGPoint pos = CGEventGetLocation(event);
- if (pos.x != screen->m_xCenter || pos.y != screen->m_yCenter) {
-
- LOG((CLOG_DEBUG "show cursor on secondary, type=%d pos=%d,%d",
- type, pos.x, pos.y));
- screen->showCursor();
- }
- }
return event;
}