Fixed handling of auto-repeat, ctrl + character key, and button

to KeyCode translation.
This commit is contained in:
crs 2004-08-04 22:48:08 +00:00
parent 8c93cfdb24
commit b72d882f41
4 changed files with 66 additions and 24 deletions

View File

@ -18,7 +18,7 @@
struct CKeyEntry { struct CKeyEntry {
public: public:
KeyID m_keyID; KeyID m_keyID;
KeyButton m_button; UInt32 m_keyCode;
}; };
static const CKeyEntry s_keys[] = { static const CKeyEntry s_keys[] = {
/* ASCII */ /* ASCII */
@ -466,6 +466,19 @@ COSXKeyState::~COSXKeyState()
// do nothing // do nothing
} }
KeyButton
COSXKeyState::mapKeyCodeToKeyButton(UInt32 keyCode)
{
// 'A' maps to 0 so shift every id by +1
return static_cast<KeyButton>(keyCode + 1);
}
UInt32
COSXKeyState::mapKeyButtonToKeyCode(KeyButton keyButton)
{
return static_cast<UInt32>(keyButton - 1);
}
void void
COSXKeyState::sendKeyEvent(void* target, COSXKeyState::sendKeyEvent(void* target,
bool press, bool isAutoRepeat, bool press, bool isAutoRepeat,
@ -524,10 +537,9 @@ COSXKeyState::doUpdateKeys()
// FIXME -- this probably needs to be more dynamic to support // FIXME -- this probably needs to be more dynamic to support
// non-english keyboards. also need to map modifiers needed // non-english keyboards. also need to map modifiers needed
// for each KeyID. // 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) { for (UInt32 i = 0; i < sizeof(s_keys) / sizeof(s_keys[0]); ++i) {
m_keyMap.insert(std::make_pair(s_keys[i].m_keyID, 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 // add modifiers
@ -558,8 +570,7 @@ COSXKeyState::doFakeKeyEvent(KeyButton button, bool press, bool isAutoRepeat)
{ {
LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press)); LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press));
// let system figure out character for us // let system figure out character for us
// FIXME -- subtracting one because we added one in doUpdateKeys. CGPostKeyboardEvent(0, mapKeyButtonToKeyCode(button), press);
CGPostKeyboardEvent(0, static_cast<CGKeyCode>(button) - 1, press);
} }
KeyButton KeyButton
@ -629,9 +640,20 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
KeyID id = s_virtualKey[vkCode]; KeyID id = s_virtualKey[vkCode];
// check if not in table; map character to key id // check if not in table; map character to key id
KeyModifierMask activeMask = getActiveModifiers();
if (id == kKeyNone && c != 0) { if (id == kKeyNone && c != 0) {
if ((c & 0x80u) == 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<KeyID>(c) & 0xffu; id = static_cast<KeyID>(c) & 0xffu;
} }
else { else {
@ -643,11 +665,6 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
id = static_cast<KeyID>(c) & 0xffu; id = static_cast<KeyID>(c) & 0xffu;
} }
} }
KeyModifierMask activeMask = getActiveModifiers();
if (id != kKeyNone && c != 0) {
// FIXME
}
// map modifier key // map modifier key
if (maskOut != NULL) { if (maskOut != NULL) {
@ -665,8 +682,8 @@ COSXKeyState::addKeyButton(KeyButtons& keys, KeyID id) const
if (keyIndex == m_keyMap.end()) { if (keyIndex == m_keyMap.end()) {
return; return;
} }
// XXX -- subtract one because added one in doUpdateKeys // YYY -1
keys.push_back(keyIndex->second - 1); keys.push_back(keyIndex->second);
} }
void void
@ -706,8 +723,8 @@ COSXKeyState::handleModifierKey(void* target, KeyID id, bool down)
if (keyIndex == m_keyMap.end()) { if (keyIndex == m_keyMap.end()) {
return; return;
} }
// FIXME -- subtract one because we added one in doUpdateKeys // YYY -1
KeyButton button = keyIndex->second - 1; KeyButton button = keyIndex->second;
setKeyDown(button, down); setKeyDown(button, down);
sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button); sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button);
} }

View File

@ -25,9 +25,31 @@ A key state for OS X.
*/ */
class COSXKeyState : public CKeyState { class COSXKeyState : public CKeyState {
public: 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(); COSXKeyState();
virtual ~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 //! Map key event to a key
/*! /*!
Converts a key event into a KeyID and the shadow modifier state Converts a key event into a KeyID and the shadow modifier state

View File

@ -808,15 +808,16 @@ COSXScreen::onKey(EventRef event) const
UInt32 eventKind = GetEventKind(event); UInt32 eventKind = GetEventKind(event);
// get the key // get the key
KeyButton button; UInt32 keyCode;
GetEventParameter(event, kEventParamKeyCode, typeUInt32, GetEventParameter(event, kEventParamKeyCode, typeUInt32,
NULL, sizeof(button), NULL, &button); NULL, sizeof(keyCode), NULL, &keyCode);
LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button)); 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 // sadly, OS X doesn't report the keyCode for modifier keys. keyCode
// be zero for modifier keys. since that's not good enough we'll have // will be zero for modifier keys. since that's not good enough we'll
// to figure out what the key was. // have to figure out what the key was.
if (button == 0 && eventKind == kEventRawKeyModifiersChanged) { if (keyCode == 0 && eventKind == kEventRawKeyModifiersChanged) {
// get old and new modifier state // get old and new modifier state
KeyModifierMask oldMask = getActiveModifiers(); KeyModifierMask oldMask = getActiveModifiers();
KeyModifierMask newMask = mapMacModifiersToSynergy(event); KeyModifierMask newMask = mapMacModifiersToSynergy(event);
@ -839,7 +840,7 @@ COSXScreen::onKey(EventRef event) const
KeyID key = m_keyState->mapKeyFromEvent(event, &mask); KeyID key = m_keyState->mapKeyFromEvent(event, &mask);
m_keyState->sendKeyEvent(getEventTarget(), down, isRepeat, m_keyState->sendKeyEvent(getEventTarget(), down, isRepeat,
key, mask, 0, button); key, mask, 1, button);
return true; return true;
} }

View File

@ -28,7 +28,9 @@ typedef UInt32 KeyID;
//! Key Code //! Key Code
/*! /*!
Type to hold a physical key identifier. That is, it identifies a 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; typedef UInt16 KeyButton;