194 lines
3.8 KiB
C++
194 lines
3.8 KiB
C++
|
/*
|
||
|
* synergy -- mouse and keyboard sharing utility
|
||
|
* Copyright (C) 2016 Symless Ltd.
|
||
|
*
|
||
|
* 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 LICENSE 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.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "platform/IKeyResource.h"
|
||
|
|
||
|
#include <Carbon/Carbon.h>
|
||
|
|
||
|
//
|
||
|
// OSXKeyState::KeyResource
|
||
|
//
|
||
|
|
||
|
KeyID
|
||
|
IKeyResource::getKeyID(UInt8 c)
|
||
|
{
|
||
|
if (c == 0) {
|
||
|
return kKeyNone;
|
||
|
}
|
||
|
else if (c >= 32 && c < 127) {
|
||
|
// ASCII
|
||
|
return static_cast<KeyID>(c);
|
||
|
}
|
||
|
else {
|
||
|
// handle special keys
|
||
|
switch (c) {
|
||
|
case 0x01:
|
||
|
return kKeyHome;
|
||
|
|
||
|
case 0x02:
|
||
|
return kKeyKP_Enter;
|
||
|
|
||
|
case 0x03:
|
||
|
return kKeyKP_Enter;
|
||
|
|
||
|
case 0x04:
|
||
|
return kKeyEnd;
|
||
|
|
||
|
case 0x05:
|
||
|
return kKeyHelp;
|
||
|
|
||
|
case 0x08:
|
||
|
return kKeyBackSpace;
|
||
|
|
||
|
case 0x09:
|
||
|
return kKeyTab;
|
||
|
|
||
|
case 0x0b:
|
||
|
return kKeyPageUp;
|
||
|
|
||
|
case 0x0c:
|
||
|
return kKeyPageDown;
|
||
|
|
||
|
case 0x0d:
|
||
|
return kKeyReturn;
|
||
|
|
||
|
case 0x10:
|
||
|
// OS X maps all the function keys (F1, etc) to this one key.
|
||
|
// we can't determine the right key here so we have to do it
|
||
|
// some other way.
|
||
|
return kKeyNone;
|
||
|
|
||
|
case 0x1b:
|
||
|
return kKeyEscape;
|
||
|
|
||
|
case 0x1c:
|
||
|
return kKeyLeft;
|
||
|
|
||
|
case 0x1d:
|
||
|
return kKeyRight;
|
||
|
|
||
|
case 0x1e:
|
||
|
return kKeyUp;
|
||
|
|
||
|
case 0x1f:
|
||
|
return kKeyDown;
|
||
|
|
||
|
case 0x7f:
|
||
|
return kKeyDelete;
|
||
|
|
||
|
case 0x06:
|
||
|
case 0x07:
|
||
|
case 0x0a:
|
||
|
case 0x0e:
|
||
|
case 0x0f:
|
||
|
case 0x11:
|
||
|
case 0x12:
|
||
|
case 0x13:
|
||
|
case 0x14:
|
||
|
case 0x15:
|
||
|
case 0x16:
|
||
|
case 0x17:
|
||
|
case 0x18:
|
||
|
case 0x19:
|
||
|
case 0x1a:
|
||
|
// discard other control characters
|
||
|
return kKeyNone;
|
||
|
|
||
|
default:
|
||
|
// not special or unknown
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// create string with character
|
||
|
char str[2];
|
||
|
str[0] = static_cast<char>(c);
|
||
|
str[1] = 0;
|
||
|
|
||
|
// get current keyboard script
|
||
|
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||
|
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||
|
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding(
|
||
|
(CFStringRef)CFArrayGetValueAtIndex(langs, 0));
|
||
|
// convert to unicode
|
||
|
CFStringRef cfString =
|
||
|
CFStringCreateWithCStringNoCopy(
|
||
|
kCFAllocatorDefault, str, encoding, kCFAllocatorNull);
|
||
|
|
||
|
// sometimes CFStringCreate...() returns NULL (e.g. Apple Korean
|
||
|
// encoding with char value 214). if it did then make no key,
|
||
|
// otherwise CFStringCreateMutableCopy() will crash.
|
||
|
if (cfString == NULL) {
|
||
|
return kKeyNone;
|
||
|
}
|
||
|
|
||
|
// convert to precomposed
|
||
|
CFMutableStringRef mcfString =
|
||
|
CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfString);
|
||
|
CFRelease(cfString);
|
||
|
CFStringNormalize(mcfString, kCFStringNormalizationFormC);
|
||
|
|
||
|
// check result
|
||
|
int unicodeLength = CFStringGetLength(mcfString);
|
||
|
if (unicodeLength == 0) {
|
||
|
CFRelease(mcfString);
|
||
|
return kKeyNone;
|
||
|
}
|
||
|
if (unicodeLength > 1) {
|
||
|
// FIXME -- more than one character, we should handle this
|
||
|
CFRelease(mcfString);
|
||
|
return kKeyNone;
|
||
|
}
|
||
|
|
||
|
// get unicode character
|
||
|
UniChar uc = CFStringGetCharacterAtIndex(mcfString, 0);
|
||
|
CFRelease(mcfString);
|
||
|
|
||
|
// convert to KeyID
|
||
|
return static_cast<KeyID>(uc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KeyID
|
||
|
IKeyResource::unicharToKeyID(UniChar c)
|
||
|
{
|
||
|
switch (c) {
|
||
|
case 3:
|
||
|
return kKeyKP_Enter;
|
||
|
|
||
|
case 8:
|
||
|
return kKeyBackSpace;
|
||
|
|
||
|
case 9:
|
||
|
return kKeyTab;
|
||
|
|
||
|
case 13:
|
||
|
return kKeyReturn;
|
||
|
|
||
|
case 27:
|
||
|
return kKeyEscape;
|
||
|
|
||
|
case 127:
|
||
|
return kKeyDelete;
|
||
|
|
||
|
default:
|
||
|
if (c < 32) {
|
||
|
return kKeyNone;
|
||
|
}
|
||
|
return static_cast<KeyID>(c);
|
||
|
}
|
||
|
}
|