barrier/lib/platform/COSXKeyState.cpp

631 lines
16 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "COSXKeyState.h"
#include "CLog.h"
struct CKeyEntry {
public:
KeyID m_keyID;
KeyButton m_button;
};
static const CKeyEntry s_keys[] = {
/* ASCII */
{ ' ', 49 },
{ '!', 18 },
{ '\"', 39 },
{ '#', 20 },
{ '$', 21 },
{ '%', 23 },
{ '&', 26 },
{ '\'', 39 },
{ '(', 25 },
{ ')', 29 },
{ '*', 28 },
{ '+', 24 },
{ ',', 43 },
{ '-', 27 },
{ '.', 47 },
{ '/', 44 },
{ '0', 29 },
{ '1', 18 },
{ '2', 19 },
{ '3', 20 },
{ '4', 21 },
{ '5', 23 },
{ '6', 22 },
{ '7', 26 },
{ '8', 28 },
{ '9', 25 },
{ ':', 41 },
{ ';', 41 },
{ '<', 43 },
{ '=', 24 },
{ '>', 47 },
{ '?', 44 },
{ '@', 19 },
{ 'A', 0 },
{ 'B', 11 },
{ 'C', 8 },
{ 'D', 2 },
{ 'E', 14 },
{ 'F', 3 },
{ 'G', 5 },
{ 'H', 4 },
{ 'I', 34 },
{ 'J', 38 },
{ 'K', 40 },
{ 'L', 37 },
{ 'M', 46 },
{ 'N', 45 },
{ 'O', 31 },
{ 'P', 35 },
{ 'Q', 12 },
{ 'R', 15 },
{ 'S', 1 },
{ 'T', 17 },
{ 'U', 32 },
{ 'V', 9 },
{ 'W', 13 },
{ 'X', 7 },
{ 'Y', 16 },
{ 'Z', 6 },
{ '[', 33 },
{ '\\', 42 },
{ ']', 30 },
{ '^', 22 },
{ '_', 27 },
{ '`', 50 },
{ 'a', 0 },
{ 'b', 11 },
{ 'c', 8 },
{ 'd', 2 },
{ 'e', 14 },
{ 'f', 3 },
{ 'g', 5 },
{ 'h', 4 },
{ 'i', 34 },
{ 'j', 38 },
{ 'k', 40 },
{ 'l', 37 },
{ 'm', 46 },
{ 'n', 45 },
{ 'o', 31 },
{ 'p', 35 },
{ 'q', 12 },
{ 'r', 15 },
{ 's', 1 },
{ 't', 17 },
{ 'u', 32 },
{ 'v', 9 },
{ 'w', 13 },
{ 'x', 7 },
{ 'y', 16 },
{ 'z', 6 },
{ '{', 33 },
{ '|', 42 },
{ '}', 30 },
{ '~', 50 },
/* TTY functions */
{ kKeyBackSpace, 51 },
{ kKeyTab, 48 },
{ kKeyLinefeed, 36 },
// { kKeyClear, 0xFFFF },
{ kKeyReturn, 36 },
{ kKeyPause, 113 },
{ kKeyScrollLock, 107 },
// { kKeySysReq, 0xFFFF }, /* no mapping on apple */
{ kKeyEscape, 53 },
{ kKeyDelete, 117 },
/* cursor control */
{ kKeyHome, 115 },
{ kKeyLeft, 123 },
{ kKeyUp, 126 },
{ kKeyRight, 124 },
{ kKeyDown, 125 },
{ kKeyPageUp, 116 },
{ kKeyPageDown, 121 },
{ kKeyEnd, 119 },
{ kKeyBegin, 115 },
/* numeric keypad */
{ kKeyKP_Space, 49 },
{ kKeyKP_0, 82 },
{ kKeyKP_1, 83 },
{ kKeyKP_2, 84 },
{ kKeyKP_3, 85 },
{ kKeyKP_4, 86 },
{ kKeyKP_5, 87 },
{ kKeyKP_6, 88 },
{ kKeyKP_7, 89 },
{ kKeyKP_8, 91 },
{ kKeyKP_9, 92 },
{ kKeyKP_Enter, 76 },
{ kKeyKP_Decimal, 65 },
{ kKeyKP_Add, 69 },
{ kKeyKP_Subtract, 78 },
{ kKeyKP_Multiply, 67 },
{ kKeyKP_Divide, 75 },
/* Function keys */
{ kKeyF1, 122 },
{ kKeyF2, 120 },
{ kKeyF3, 99 },
{ kKeyF4, 118 },
{ kKeyF5, 96 },
{ kKeyF6, 97 },
{ kKeyF7, 98 },
{ kKeyF8, 100 },
{ kKeyF9, 101 },
{ kKeyF10, 109 },
{ kKeyF11, 103 },
{ kKeyF12, 111 },
/* Modifier keys */
{ kKeyShift_L, 56 },
{ kKeyShift_R, 56 },
{ kKeyControl_L, 59 },
{ kKeyControl_R, 59 },
{ kKeyAlt_L, 55 },
{ kKeyAlt_R, 55 },
{ kKeyCapsLock, 57 },
{ kKeyNumLock, 71 },
{ kKeyMeta_L, 58 },
{ kKeyMeta_R, 58 },
{ kKeySuper_L, 58 },
{ kKeySuper_R, 58 },
{ kKeyLeftTab, 48 }
};
const KeyID COSXKeyState::s_virtualKey[] =
{
/* 0x00 */ kKeyNone, // A
/* 0x01 */ kKeyNone, // S
/* 0x02 */ kKeyNone, // D
/* 0x03 */ kKeyNone, // F
/* 0x04 */ kKeyNone, // H
/* 0x05 */ kKeyNone, // G
/* 0x06 */ kKeyNone, // Z
/* 0x07 */ kKeyNone, // X
/* 0x08 */ kKeyNone, // C
/* 0x09 */ kKeyNone, // V
/* 0x0a */ kKeyNone, // ~ on some european keyboards
/* 0x0b */ kKeyNone, // B
/* 0x0c */ kKeyNone, // Q
/* 0x0d */ kKeyNone, // W
/* 0x0e */ kKeyNone, // E
/* 0x0f */ kKeyNone, // R
/* 0x10 */ kKeyNone, // Y
/* 0x11 */ kKeyNone, // T
/* 0x12 */ kKeyNone, // 1
/* 0x13 */ kKeyNone, // 2
/* 0x14 */ kKeyNone, // 3
/* 0x15 */ kKeyNone, // 4
/* 0x16 */ kKeyNone, // 6
/* 0x17 */ kKeyNone, // 5
/* 0x18 */ kKeyNone, // =
/* 0x19 */ kKeyNone, // 9
/* 0x1a */ kKeyNone, // 7
/* 0x1b */ kKeyNone, // -
/* 0x1c */ kKeyNone, // 8
/* 0x1d */ kKeyNone, // 0
/* 0x1e */ kKeyNone, // ]
/* 0x1f */ kKeyNone, // O
/* 0x20 */ kKeyNone, // U
/* 0x21 */ kKeyNone, // [
/* 0x22 */ kKeyNone, // I
/* 0x23 */ kKeyNone, // P
/* 0x24 */ kKeyReturn, // return
/* 0x25 */ kKeyNone, // L
/* 0x26 */ kKeyNone, // J
/* 0x27 */ kKeyNone, // '
/* 0x28 */ kKeyNone, // K
/* 0x29 */ kKeyNone, // ;
/* 0x2a */ kKeyNone, /* \ */
/* 0x2b */ kKeyNone, // ,
/* 0x2c */ kKeyNone, // /
/* 0x2d */ kKeyNone, // M
/* 0x2e */ kKeyNone, // M
/* 0x2f */ kKeyNone, // .
/* 0x30 */ kKeyTab, // tab
/* 0x31 */ kKeyKP_Space, // space
/* 0x32 */ kKeyNone, // `
/* 0x33 */ kKeyBackSpace, // Backspace
/* 0x34 */ kKeyNone, // undefined
/* 0x35 */ kKeyEscape, // escape
/* 0x36 */ kKeyNone, // undefined
/* 0x37 */ kKeyAlt_L, // alt
/* 0x38 */ kKeyShift_L, // shift
/* 0x39 */ kKeyCapsLock, // capslok
/* 0x3a */ kKeyMeta_L, // meta
/* 0x3b */ kKeyControl_L, // control
/* 0x3c */ kKeyNone, // undefined
/* 0x3d */ kKeyNone, // undefined
/* 0x3e */ kKeyNone, // undefined
/* 0x3f */ kKeyNone, // undefined
/* 0x40 */ kKeyNone, // undefined
/* 0x41 */ kKeyKP_Decimal, // keypad .
/* 0x42 */ kKeyNone, // undefined
/* 0x43 */ kKeyKP_Multiply, // keypad *
/* 0x44 */ kKeyNone, // undefined
/* 0x45 */ kKeyKP_Add, // keypad +
/* 0x46 */ kKeyNone, // undefined
/* 0x47 */ kKeyNumLock, // numlock
/* 0x48 */ kKeyNone, // undefined
/* 0x49 */ kKeyNone, // undefined
/* 0x4a */ kKeyNone, // undefined
/* 0x4b */ kKeyKP_Divide, /* keypad \ */
/* 0x4c */ kKeyKP_Enter, // keypad enter
/* 0x4d */ kKeyNone, // undefined
/* 0x4e */ kKeyKP_Subtract, // keypad -
/* 0x4f */ kKeyNone, // undefined
/* 0x50 */ kKeyNone, // undefined
/* 0x51 */ kKeyNone, // undefined
/* 0x52 */ kKeyKP_0, // keypad 0
/* 0x53 */ kKeyKP_1, // keypad 1
/* 0x54 */ kKeyKP_2, // keypad 2
/* 0x55 */ kKeyKP_3, // keypad 3
/* 0x56 */ kKeyKP_4, // keypad 4
/* 0x57 */ kKeyKP_5, // keypad 5
/* 0x58 */ kKeyKP_6, // keypad 6
/* 0x59 */ kKeyKP_7, // keypad 7
/* 0x5a */ kKeyKP_8, // keypad 8
/* 0x5b */ kKeyKP_9, // keypad 9
/* 0x5c */ kKeyNone, // undefined
/* 0x5d */ kKeyNone, // undefined
/* 0x5e */ kKeyNone, // undefined
/* 0x5f */ kKeyNone, // undefined
/* 0x60 */ kKeyF5, // F5
/* 0x61 */ kKeyF6, // F6
/* 0x62 */ kKeyF7, // F7
/* 0x63 */ kKeyF3, // F3
/* 0x64 */ kKeyF8, // F8
/* 0x65 */ kKeyF9, // F9
/* 0x66 */ kKeyNone, // undefined
/* 0x67 */ kKeyF11, // F11
/* 0x68 */ kKeyNone, // undefined
/* 0x69 */ kKeyNone, // undefined
/* 0x6a */ kKeyNone, // undefined
/* 0x6b */ kKeyF10, // F10
/* 0x6c */ kKeyNone, // undefined
/* 0x6d */ kKeyF12, // F12
/* 0x6e */ kKeyNone, // undefined
/* 0x6f */ kKeyPause, // pause
/* 0x70 */ kKeyNone, // undefined
/* 0x71 */ kKeyBegin, // home
/* 0x72 */ kKeyPageUp, // PageUP
/* 0x73 */ kKeyDelete, // Delete
/* 0x74 */ kKeyF4, // F4
/* 0x75 */ kKeyEnd, // end
/* 0x76 */ kKeyF2, // F2
/* 0x77 */ kKeyNone, // undefined
/* 0x78 */ kKeyF1, // F1
/* 0x79 */ kKeyPageDown, // PageDown
/* 0x7a */ kKeyNone, // undefined
/* 0x7b */ kKeyLeft, // left
/* 0x7c */ kKeyRight, // right
/* 0x7d */ kKeyDown, // down
/* 0x7e */ kKeyUp, // up
/* 0x7f */ kKeyNone, // unassigned
/* 0x80 */ kKeyNone, // unassigned
/* 0x81 */ kKeyNone, // unassigned
/* 0x82 */ kKeyNone, // unassigned
/* 0x83 */ kKeyNone, // unassigned
/* 0x84 */ kKeyNone, // unassigned
/* 0x85 */ kKeyNone, // unassigned
/* 0x86 */ kKeyNone, // unassigned
/* 0x87 */ kKeyNone, // unassigned
/* 0x88 */ kKeyNone, // unassigned
/* 0x89 */ kKeyNone, // unassigned
/* 0x8a */ kKeyNone, // unassigned
/* 0x8b */ kKeyNone, // unassigned
/* 0x8c */ kKeyNone, // unassigned
/* 0x8d */ kKeyNone, // unassigned
/* 0x8e */ kKeyNone, // unassigned
/* 0x8f */ kKeyNone, // unassigned
/* 0x90 */ kKeyNone, // unassigned
/* 0x91 */ kKeyNone, // unassigned
/* 0x92 */ kKeyNone, // unassigned
/* 0x93 */ kKeyNone, // unassigned
/* 0x94 */ kKeyNone, // unassigned
/* 0x95 */ kKeyNone, // unassigned
/* 0x96 */ kKeyNone, // unassigned
/* 0x97 */ kKeyNone, // unassigned
/* 0x98 */ kKeyNone, // unassigned
/* 0x99 */ kKeyNone, // unassigned
/* 0x9a */ kKeyNone, // unassigned
/* 0x9b */ kKeyNone, // unassigned
/* 0x9c */ kKeyNone, // unassigned
/* 0x9d */ kKeyNone, // unassigned
/* 0x9e */ kKeyNone, // unassigned
/* 0x9f */ kKeyNone, // unassigned
/* 0xa0 */ kKeyNone, // unassigned
/* 0xa1 */ kKeyNone, // unassigned
/* 0xa2 */ kKeyNone, // unassigned
/* 0xa3 */ kKeyNone, // unassigned
/* 0xa4 */ kKeyNone, // unassigned
/* 0xa5 */ kKeyNone, // unassigned
/* 0xa6 */ kKeyNone, // unassigned
/* 0xa7 */ kKeyNone, // unassigned
/* 0xa8 */ kKeyNone, // unassigned
/* 0xa9 */ kKeyNone, // unassigned
/* 0xaa */ kKeyNone, // unassigned
/* 0xab */ kKeyNone, // unassigned
/* 0xac */ kKeyNone, // unassigned
/* 0xad */ kKeyNone, // unassigned
/* 0xae */ kKeyNone, // unassigned
/* 0xaf */ kKeyNone, // unassigned
/* 0xb0 */ kKeyNone, // unassigned
/* 0xb1 */ kKeyNone, // unassigned
/* 0xb2 */ kKeyNone, // unassigned
/* 0xb3 */ kKeyNone, // unassigned
/* 0xb4 */ kKeyNone, // unassigned
/* 0xb5 */ kKeyNone, // unassigned
/* 0xb6 */ kKeyNone, // unassigned
/* 0xb7 */ kKeyNone, // unassigned
/* 0xb8 */ kKeyNone, // unassigned
/* 0xb9 */ kKeyNone, // unassigned
/* 0xba */ kKeyNone, // unassigned
/* 0xbb */ kKeyNone, // unassigned
/* 0xbc */ kKeyNone, // unassigned
/* 0xbd */ kKeyNone, // unassigned
/* 0xbe */ kKeyNone, // unassigned
/* 0xbf */ kKeyNone, // unassigned
/* 0xc0 */ kKeyNone, // unassigned
/* 0xc1 */ kKeyNone, // unassigned
/* 0xc2 */ kKeyNone, // unassigned
/* 0xc3 */ kKeyNone, // unassigned
/* 0xc4 */ kKeyNone, // unassigned
/* 0xc5 */ kKeyNone, // unassigned
/* 0xc6 */ kKeyNone, // unassigned
/* 0xc7 */ kKeyNone, // unassigned
/* 0xc8 */ kKeyNone, // unassigned
/* 0xc9 */ kKeyNone, // unassigned
/* 0xca */ kKeyNone, // unassigned
/* 0xcb */ kKeyNone, // unassigned
/* 0xcc */ kKeyNone, // unassigned
/* 0xcd */ kKeyNone, // unassigned
/* 0xce */ kKeyNone, // unassigned
/* 0xcf */ kKeyNone, // unassigned
/* 0xd0 */ kKeyNone, // unassigned
/* 0xd1 */ kKeyNone, // unassigned
/* 0xd2 */ kKeyNone, // unassigned
/* 0xd3 */ kKeyNone, // unassigned
/* 0xd4 */ kKeyNone, // unassigned
/* 0xd5 */ kKeyNone, // unassigned
/* 0xd6 */ kKeyNone, // unassigned
/* 0xd7 */ kKeyNone, // unassigned
/* 0xd8 */ kKeyNone, // unassigned
/* 0xd9 */ kKeyNone, // unassigned
/* 0xda */ kKeyNone, // unassigned
/* 0xdb */ kKeyNone, // unassigned
/* 0xdc */ kKeyNone, // unassigned
/* 0xdd */ kKeyNone, // unassigned
/* 0xde */ kKeyNone, // unassigned
/* 0xdf */ kKeyNone, // unassigned
/* 0xe0 */ kKeyNone, // unassigned
/* 0xe1 */ kKeyNone, // unassigned
/* 0xe2 */ kKeyNone, // unassigned
/* 0xe3 */ kKeyNone, // unassigned
/* 0xe4 */ kKeyNone, // unassigned
/* 0xe5 */ kKeyNone, // unassigned
/* 0xe6 */ kKeyNone, // unassigned
/* 0xe7 */ kKeyNone, // unassigned
/* 0xe8 */ kKeyNone, // unassigned
/* 0xe9 */ kKeyNone, // unassigned
/* 0xea */ kKeyNone, // unassigned
/* 0xeb */ kKeyNone, // unassigned
/* 0xec */ kKeyNone, // unassigned
/* 0xed */ kKeyNone, // unassigned
/* 0xee */ kKeyNone, // unassigned
/* 0xef */ kKeyNone, // unassigned
/* 0xf0 */ kKeyNone, // unassigned
/* 0xf1 */ kKeyNone, // unassigned
/* 0xf2 */ kKeyNone, // unassigned
/* 0xf3 */ kKeyNone, // unassigned
/* 0xf4 */ kKeyNone, // unassigned
/* 0xf5 */ kKeyNone, // unassigned
/* 0xf6 */ kKeyNone, // unassigned
/* 0xf7 */ kKeyNone, // unassigned
/* 0xf8 */ kKeyNone, // unassigned
/* 0xf9 */ kKeyNone, // unassigned
/* 0xfa */ kKeyNone, // unassigned
/* 0xfb */ kKeyNone, // unassigned
/* 0xfc */ kKeyNone, // unassigned
/* 0xfd */ kKeyNone, // unassigned
/* 0xfe */ kKeyNone, // unassigned
/* 0xff */ kKeyNone // unassigned
};
//
// COSXKeyState
//
COSXKeyState::COSXKeyState()
{
// do nothing
}
COSXKeyState::~COSXKeyState()
{
// do nothing
}
void
COSXKeyState::sendKeyEvent(void* target,
bool press, bool isAutoRepeat,
KeyID key, KeyModifierMask mask,
SInt32 count, KeyButton button)
{
if (press || isAutoRepeat) {
// send key
if (press) {
CKeyState::sendKeyEvent(target, true, false,
key, mask, 1, button);
if (count > 0) {
--count;
}
}
if (count >= 1) {
CKeyState::sendKeyEvent(target, true, true,
key, mask, count, button);
}
}
else {
// do key up
CKeyState::sendKeyEvent(target, false, false, key, mask, 1, button);
}
}
bool
COSXKeyState::fakeCtrlAltDel()
{
// pass keys through unchanged
return false;
}
const char*
COSXKeyState::getKeyName(KeyButton) const
{
// FIXME
return "";
}
void
COSXKeyState::doUpdateKeys()
{
// FIXME -- get the current keyboard state. call setKeyDown(),
// setToggled(), and addModifier() as appropriate.
// save key mapping
// FIXME -- this probably needs to be more dynamic to support
// non-english keyboards. also need to map modifiers needed
// for each KeyID.
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));
}
}
void
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
CGPostKeyboardEvent(0, static_cast<CGKeyCode>(button) - 1, press);
}
KeyButton
COSXKeyState::mapKey(Keystrokes& keys, KeyID id,
KeyModifierMask desiredMask,
bool isAutoRepeat) const
{
// look up virtual key
CKeyMap::const_iterator keyIndex = m_keyMap.find(id);
if (keyIndex == m_keyMap.end()) {
return 0;
}
CGKeyCode keyCode = keyIndex->second;
// adjust the modifiers to match the desired modifiers
Keystrokes undo;
if (!adjustModifiers(keys, undo, desiredMask)) {
LOG((CLOG_DEBUG2 "failed to adjust modifiers"));
return 0;
}
// add the key event
Keystroke keystroke;
keystroke.m_key = keyCode;
if (!isAutoRepeat) {
keystroke.m_press = true;
keystroke.m_repeat = false;
keys.push_back(keystroke);
}
else {
keystroke.m_press = false;
keystroke.m_repeat = true;
keys.push_back(keystroke);
keystroke.m_press = true;
keys.push_back(keystroke);
}
// put undo keystrokes at end of keystrokes in reverse order
while (!undo.empty()) {
keys.push_back(undo.back());
undo.pop_back();
}
return keyCode;
}
bool
COSXKeyState::adjustModifiers(Keystrokes& /*keys*/,
Keystrokes& /*undo*/,
KeyModifierMask /*desiredMask*/) const
{
// FIXME -- should add necessary modifier events to keys and undo
return true;
}
KeyID
COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
{
char c;
GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar,
NULL, sizeof(c), NULL, &c);
UInt32 vkCode;
GetEventParameter(event, kEventParamKeyCode, typeUInt32,
NULL, sizeof(vkCode), NULL, &vkCode);
KeyID id = s_virtualKey[vkCode];
// check if not in table; map character to key id
if (id == kKeyNone && c != 0) {
if ((c & 0x80u) == 0) {
// ASCII
id = static_cast<KeyID>(c) & 0xffu;
}
else {
// character is not really ASCII. instead it's some
// character in the current ANSI code page. try to
// convert that to a Unicode character. if we fail
// then use the single byte character as is.
//FIXME
id = static_cast<KeyID>(c) & 0xffu;
}
}
KeyModifierMask activeMask = getActiveModifiers();
if (id != kKeyNone && c != 0) {
// FIXME
}
// map modifier key
if (maskOut != NULL) {
activeMask &= ~KeyModifierModeSwitch;
*maskOut = activeMask;
}
return id;
}