diff --git a/lib/platform/COSXKeyState.cpp b/lib/platform/COSXKeyState.cpp index bbbfc2ff..bab7c1fb 100644 --- a/lib/platform/COSXKeyState.cpp +++ b/lib/platform/COSXKeyState.cpp @@ -18,7 +18,7 @@ struct CKeyEntry { public: KeyID m_keyID; - KeyButton m_button; + UInt32 m_keyCode; }; static const CKeyEntry s_keys[] = { /* ASCII */ @@ -466,6 +466,19 @@ COSXKeyState::~COSXKeyState() // do nothing } +KeyButton +COSXKeyState::mapKeyCodeToKeyButton(UInt32 keyCode) +{ + // 'A' maps to 0 so shift every id by +1 + return static_cast(keyCode + 1); +} + +UInt32 +COSXKeyState::mapKeyButtonToKeyCode(KeyButton keyButton) +{ + return static_cast(keyButton - 1); +} + void COSXKeyState::sendKeyEvent(void* target, bool press, bool isAutoRepeat, @@ -524,10 +537,9 @@ COSXKeyState::doUpdateKeys() // FIXME -- this probably needs to be more dynamic to support // non-english keyboards. also need to map modifiers needed // for each KeyID. - // FIXME -- add one so we don't use KeyButton 0 (reserved to be no key) for (UInt32 i = 0; i < sizeof(s_keys) / sizeof(s_keys[0]); ++i) { m_keyMap.insert(std::make_pair(s_keys[i].m_keyID, - s_keys[i].m_button + 1)); + mapKeyCodeToKeyButton(s_keys[i].m_keyCode))); } // add modifiers @@ -558,8 +570,7 @@ COSXKeyState::doFakeKeyEvent(KeyButton button, bool press, bool isAutoRepeat) { LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press)); // let system figure out character for us - // FIXME -- subtracting one because we added one in doUpdateKeys. - CGPostKeyboardEvent(0, static_cast(button) - 1, press); + CGPostKeyboardEvent(0, mapKeyButtonToKeyCode(button), press); } KeyButton @@ -629,9 +640,20 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const KeyID id = s_virtualKey[vkCode]; // check if not in table; map character to key id + KeyModifierMask activeMask = getActiveModifiers(); if (id == kKeyNone && c != 0) { if ((c & 0x80u) == 0) { - // ASCII + // ASCII. if it's a control code and the control key is + // pressed then map it back to the original character. + if ((activeMask & KeyModifierControl) != 0 && c >= 1 && c <= 31) { + c += 'A' - 1; + + // if shift isn't pressed then map to lowercase + if ((activeMask & KeyModifierShift) == 0) { + c += 'a' - 'A'; + } + } + id = static_cast(c) & 0xffu; } else { @@ -643,11 +665,6 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const id = static_cast(c) & 0xffu; } } - - KeyModifierMask activeMask = getActiveModifiers(); - if (id != kKeyNone && c != 0) { - // FIXME - } // map modifier key if (maskOut != NULL) { @@ -665,8 +682,8 @@ COSXKeyState::addKeyButton(KeyButtons& keys, KeyID id) const if (keyIndex == m_keyMap.end()) { return; } - // XXX -- subtract one because added one in doUpdateKeys - keys.push_back(keyIndex->second - 1); +// YYY -1 + keys.push_back(keyIndex->second); } void @@ -706,8 +723,8 @@ COSXKeyState::handleModifierKey(void* target, KeyID id, bool down) if (keyIndex == m_keyMap.end()) { return; } - // FIXME -- subtract one because we added one in doUpdateKeys - KeyButton button = keyIndex->second - 1; +// YYY -1 + KeyButton button = keyIndex->second; setKeyDown(button, down); sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button); } diff --git a/lib/platform/COSXKeyState.h b/lib/platform/COSXKeyState.h index f83ec07d..037efb16 100644 --- a/lib/platform/COSXKeyState.h +++ b/lib/platform/COSXKeyState.h @@ -25,9 +25,31 @@ A key state for OS X. */ class COSXKeyState : public CKeyState { public: + // OS X uses a physical key if 0 for the 'A' key. synergy reserves + // KeyButton 0 so we offset all OS X physical key ids by this much + // when used as a KeyButton and by minus this much to map a KeyButton + // to a physical button. + enum { + KeyButtonOffset = 1 + }; + COSXKeyState(); virtual ~COSXKeyState(); + //! Map physical key id to a KeyButton id + /*! + Maps an OS X key code to a KeyButton. This simply remaps the ids + so we don't use KeyButton 0. + */ + static KeyButton mapKeyCodeToKeyButton(UInt32 keyCode); + + //! Map KeyButton id to a physical key id + /*! + Maps a KeyButton to an OS X key code. This is the inverse of + mapKeyCodeToKeyButton. + */ + static UInt32 mapKeyButtonToKeyCode(KeyButton keyButton); + //! Map key event to a key /*! Converts a key event into a KeyID and the shadow modifier state diff --git a/lib/platform/COSXScreen.cpp b/lib/platform/COSXScreen.cpp index d9dd62f8..75016d5f 100644 --- a/lib/platform/COSXScreen.cpp +++ b/lib/platform/COSXScreen.cpp @@ -808,15 +808,16 @@ COSXScreen::onKey(EventRef event) const UInt32 eventKind = GetEventKind(event); // get the key - KeyButton button; + UInt32 keyCode; GetEventParameter(event, kEventParamKeyCode, typeUInt32, - NULL, sizeof(button), NULL, &button); - LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button)); + NULL, sizeof(keyCode), NULL, &keyCode); + LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, keyCode)); + KeyButton button = COSXKeyState::mapKeyCodeToKeyButton(keyCode); - // sadly, OS X doesn't report the button for modifier keys. button will - // be zero for modifier keys. since that's not good enough we'll have - // to figure out what the key was. - if (button == 0 && eventKind == kEventRawKeyModifiersChanged) { + // sadly, OS X doesn't report the keyCode for modifier keys. keyCode + // will be zero for modifier keys. since that's not good enough we'll + // have to figure out what the key was. + if (keyCode == 0 && eventKind == kEventRawKeyModifiersChanged) { // get old and new modifier state KeyModifierMask oldMask = getActiveModifiers(); KeyModifierMask newMask = mapMacModifiersToSynergy(event); @@ -839,7 +840,7 @@ COSXScreen::onKey(EventRef event) const KeyID key = m_keyState->mapKeyFromEvent(event, &mask); m_keyState->sendKeyEvent(getEventTarget(), down, isRepeat, - key, mask, 0, button); + key, mask, 1, button); return true; } diff --git a/lib/synergy/KeyTypes.h b/lib/synergy/KeyTypes.h index 687408be..c988779a 100644 --- a/lib/synergy/KeyTypes.h +++ b/lib/synergy/KeyTypes.h @@ -28,7 +28,9 @@ typedef UInt32 KeyID; //! Key Code /*! Type to hold a physical key identifier. That is, it identifies a -physical key on the keyboard. +physical key on the keyboard. KeyButton 0 is reserved to be an +invalid key; platforms that use 0 as a physical key identifier +will have to remap that value to some arbitrary unused id. */ typedef UInt16 KeyButton;