Fixed handling of auto-repeat, ctrl + character key, and button
to KeyCode translation.
This commit is contained in:
parent
8c93cfdb24
commit
b72d882f41
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue