This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

#5592 Post keyboard events to lower level HID client

  • Loading branch information...
XinyuHou committed Nov 22, 2016
1 parent 7c12608 commit e8145aa779feae145aaaf3b4ff5b657f71a91a83
Showing with 109 additions and 65 deletions.
  1. +103 −65 src/lib/platform/OSXKeyState.cpp
  2. +6 −0 src/lib/platform/OSXKeyState.h
@@ -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
@@ -469,6 +470,105 @@ 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));
+
+ switch (virtualKeyCode)
+ {
+ case s_shiftVK:
+ case s_superVK:
+ case s_altVK:
+ case s_controlVK:
+ case s_capsLockVK:
+ switch (virtualKeyCode)
+ {
+ case s_shiftVK:
+ modifiersDelta = NX_SHIFTMASK;
+ m_shiftPressed = postDown;
+ break;
+ case s_superVK:
+ modifiersDelta = NX_COMMANDMASK;
+ m_superPressed = postDown;
+ break;
+ case s_altVK:
+ modifiersDelta = NX_ALTERNATEMASK;
+ m_altPressed = postDown;
+ break;
+ case s_controlVK:
+ modifiersDelta = NX_CONTROLMASK;
+ m_controlPressed = postDown;
+ break;
+ case s_capsLockVK:
+ modifiersDelta = NX_ALPHASHIFTMASK;
+ m_capsPressed = postDown;
+ break;
+ }
+
+ // update the modifier bit
+ if (postDown) {
+ modifiers |= modifiersDelta;
+ }
+ else {
+ modifiers &= ~modifiersDelta;
+ }
+
+ kern_return_t kr;
+ kr = IOHIDPostEvent(getEventDriver(), NX_FLAGSCHANGED, loc,
+ &event, kNXEventDataVersion, modifiers, true);
+ assert(KERN_SUCCESS == kr);
+ 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);
+ break;
+ }
+}
+
void
OSXKeyState::fakeKey(const Keystroke& keystroke)
{
@@ -477,76 +577,14 @@ OSXKeyState::fakeKey(const Keystroke& keystroke)
KeyButton button = keystroke.m_data.m_button.m_button;
bool keyDown = keystroke.m_data.m_button.m_press;
- UInt32 client = keystroke.m_data.m_button.m_client;
- CGEventSourceRef source = 0;
CGKeyCode virtualKey = mapKeyButtonToVirtualKey(button);
LOG((CLOG_DEBUG1
- " button=0x%04x virtualKey=0x%04x keyDown=%s client=0x%04x",
- button, virtualKey, keyDown ? "down" : "up", client));
+ " button=0x%04x virtualKey=0x%04x keyDown=%s",
+ button, virtualKey, keyDown ? "down" : "up"));
- CGEventRef ref = CGEventCreateKeyboardEvent(
- source, virtualKey, keyDown);
-
- if (ref == NULL) {
- LOG((CLOG_CRIT "unable to create keyboard event for keystroke"));
- return;
- }
-
- // persist modifier state.
- if (virtualKey == s_shiftVK) {
- m_shiftPressed = keyDown;
- }
-
- if (virtualKey == s_controlVK) {
- m_controlPressed = keyDown;
- }
-
- if (virtualKey == s_altVK) {
- m_altPressed = keyDown;
- }
-
- if (virtualKey == s_superVK) {
- m_superPressed = keyDown;
- }
-
- if (virtualKey == s_capsLockVK) {
- m_capsPressed = keyDown;
- }
+ postHIDVirtualKey(virtualKey, keyDown);
- // set the event flags for special keys
- // http://tinyurl.com/pxl742y
- CGEventFlags modifiers = 0;
-
- if (m_shiftPressed) {
- modifiers |= kCGEventFlagMaskShift;
- }
-
- if (m_controlPressed) {
- modifiers |= kCGEventFlagMaskControl;
- }
-
- if (m_altPressed) {
- modifiers |= kCGEventFlagMaskAlternate;
- }
-
- if (m_superPressed) {
- modifiers |= kCGEventFlagMaskCommand;
- }
-
- if (m_capsPressed) {
- modifiers |= kCGEventFlagMaskAlphaShift;
- }
-
- CGEventSetFlags(ref, modifiers);
- CGEventPost(kCGHIDEventTap, ref);
- CFRelease(ref);
-
- // add a delay if client data isn't zero
- // FIXME -- why?
- if (client != 0) {
- ARCH->sleep(0.01);
- }
break;
}
@@ -149,6 +149,12 @@ class OSXKeyState : public KeyState {
static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton);
void init();
+
+ // Post a key event to HID manager. It posts an event to HID client, a
+ // much lower level than window manager which's the target from carbon
+ // CGEventPost
+ void postHIDVirtualKey(const UInt8 virtualKeyCode,
+ const bool postDown);
private:
// OS X uses a physical key if 0 for the 'A' key. synergy reserves

0 comments on commit e8145aa

Please sign in to comment.