bool OSXKeyState::mapSynergyHotKeyToMac(KeyID key, KeyModifierMask mask, UInt32 &macVirtualKey, UInt32 &macModifierMask) const { // look up button for key KeyButton button = getButton(key, pollActiveGroup()); if (button == 0 && key != kKeyNone) { return false; } macVirtualKey = mapKeyButtonToVirtualKey(button); // calculate modifier mask macModifierMask = 0; if ((mask & KeyModifierShift) != 0) { macModifierMask |= shiftKey; } if ((mask & KeyModifierControl) != 0) { macModifierMask |= controlKey; } if ((mask & KeyModifierAlt) != 0) { macModifierMask |= cmdKey; } if ((mask & KeyModifierSuper) != 0) { macModifierMask |= optionKey; } if ((mask & KeyModifierCapsLock) != 0) { macModifierMask |= alphaLock; } if ((mask & KeyModifierNumLock) != 0) { macModifierMask |= s_osxNumLock; } return true; }
void OSXKeyState::fakeKey(const Keystroke& keystroke) { switch (keystroke.m_type) { case Keystroke::kButton: { 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)); 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; } // 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; } case Keystroke::kGroup: { SInt32 group = keystroke.m_data.m_group.m_group; if (keystroke.m_data.m_group.m_absolute) { LOG((CLOG_DEBUG1 " group %d", group)); setGroup(group); } else { LOG((CLOG_DEBUG1 " group %+d", group)); setGroup(getEffectiveGroup(pollActiveGroup(), group)); } break; } } }
void COSXKeyState::fakeKey(const Keystroke& keystroke) { CGEventRef ref; switch (keystroke.m_type) { case Keystroke::kButton: { LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); // let system figure out character for us ref = CGEventCreateKeyboardEvent(0, mapKeyButtonToVirtualKey( keystroke.m_data.m_button.m_button), keystroke.m_data.m_button.m_press); if (ref == NULL) { LOG((CLOG_CRIT "unable to create keyboard event for keystroke")); } UInt32 vk = mapKeyButtonToVirtualKey(keystroke.m_data.m_button.m_button); UInt32 modifierDown = keystroke.m_data.m_button.m_press; // check the key for specials and store the value (persistent until changed) if (vk == s_shiftVK) shiftPressed=modifierDown; if (vk == s_controlVK) controlPressed=modifierDown; if (vk == s_altVK) altPressed=modifierDown; if (vk == s_superVK) superPressed=modifierDown; if (vk == s_capsLockVK) capsPressed=modifierDown; //Set the event flags for special keys - see following link: //http://stackoverflow.com/questions/2008126/cgeventpost-possible-bug-when-simulating-keyboard-events CGEventFlags modifiers = 0; if (shiftPressed) modifiers |= kCGEventFlagMaskShift; if (controlPressed) modifiers |= kCGEventFlagMaskControl; if (altPressed) modifiers |= kCGEventFlagMaskAlternate; if (superPressed) modifiers |= kCGEventFlagMaskCommand; if (capsPressed) modifiers |= kCGEventFlagMaskAlphaShift; CGEventSetFlags(ref, modifiers); CGEventPost(kCGHIDEventTap, ref); // add a delay if client data isn't zero if (keystroke.m_data.m_button.m_client) { ARCH->sleep(0.01); } } break; case Keystroke::kGroup: if (keystroke.m_data.m_group.m_absolute) { LOG((CLOG_DEBUG1 " group %d", keystroke.m_data.m_group.m_group)); setGroup(keystroke.m_data.m_group.m_group); } else { LOG((CLOG_DEBUG1 " group %+d", keystroke.m_data.m_group.m_group)); setGroup(getEffectiveGroup(pollActiveGroup(), keystroke.m_data.m_group.m_group)); } break; } }