mirror of
https://github.com/debauchee/barrier.git
synced 2026-11-03 22:14:26 +08:00
merge 1.4 r887:888 into trunk
This commit is contained in:
@@ -232,7 +232,12 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
||||
|
||||
// get keyboard info
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
#else
|
||||
KeyboardLayoutRef currentKeyboardLayout;
|
||||
OSStatus status = KLGetCurrentKeyboardLayout(¤tKeyboardLayout);
|
||||
#endif
|
||||
if (currentKeyboardLayout == NULL) {
|
||||
return kKeyNone;
|
||||
}
|
||||
@@ -265,22 +270,49 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool layoutValid = false;
|
||||
const UCKeyboardLayout* layout;
|
||||
|
||||
// translate via uchr resource
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
|
||||
kTISPropertyUnicodeKeyLayoutData);
|
||||
const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
||||
if (layout != NULL) {
|
||||
layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
||||
layoutValid = (layout != null);
|
||||
#else
|
||||
const void* resource;
|
||||
int err = KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLuchrData, &resource);
|
||||
layoutValid == (err == noErr);
|
||||
layout = (const UCKeyboardLayout*)resource;
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
|
||||
// choose action
|
||||
UInt16 action;
|
||||
switch (eventKind) {
|
||||
case kEventRawKeyDown:
|
||||
action = kUCKeyActionDown;
|
||||
break;
|
||||
|
||||
case kEventRawKeyRepeat:
|
||||
action = kUCKeyActionAutoKey;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// translate key
|
||||
UniCharCount count;
|
||||
UniChar chars[2];
|
||||
//LOG((CLOG_DEBUG "modifiers: %08x", modifiers & 0xffu));
|
||||
LOG((CLOG_DEBUG2 "modifiers: %08x", modifiers & 0xffu));
|
||||
OSStatus status = UCKeyTranslate(layout,
|
||||
vkCode & 0xffu, action,
|
||||
(modifiers >> 8) & 0xffu,
|
||||
LMGetKbdType(), 0, &m_deadKeyState,
|
||||
sizeof(chars) / sizeof(chars[0]), &count, chars);
|
||||
|
||||
|
||||
// get the characters
|
||||
if (status == 0) {
|
||||
if (count != 0 || m_deadKeyState == 0) {
|
||||
@@ -314,11 +346,21 @@ COSXKeyState::pollActiveModifiers() const
|
||||
SInt32
|
||||
COSXKeyState::pollActiveGroup() const
|
||||
{
|
||||
TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
GroupMap::const_iterator i = m_groupMap.find(inputSource);
|
||||
if (i != m_groupMap.end()) {
|
||||
return i->second;
|
||||
}
|
||||
bool layoutValid = true;
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef keyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
#else
|
||||
KeyboardLayoutRef keyboardLayout;
|
||||
OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout);
|
||||
layoutValid = (status == noErr);
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
GroupMap::const_iterator i = m_groupMap.find(keyboardLayout);
|
||||
if (i != m_groupMap.end()) {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -354,10 +396,23 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
|
||||
// add special keys
|
||||
getKeyMapForSpecialKeys(keyMap, g);
|
||||
|
||||
CFDataRef resource_ref;
|
||||
if ((resource_ref = (CFDataRef)TISGetInputSourceProperty(m_groups[g],
|
||||
kTISPropertyUnicodeKeyLayoutData)) != NULL) {
|
||||
const void* resource = CFDataGetBytePtr(resource_ref);
|
||||
const void* resource;
|
||||
bool layoutValid = false;
|
||||
|
||||
// add regular keys
|
||||
// try uchr resource first
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CFDataRef resourceRef = (CFDataRef)TISGetInputSourceProperty(
|
||||
m_groups[g], kTISPropertyUnicodeKeyLayoutData);
|
||||
layoutValid = resourceRef != NULL;
|
||||
if (layoutValid)
|
||||
resource = CFDataGetBytePtr(resourceRef);
|
||||
#else
|
||||
layoutValid = KLGetKeyboardLayoutProperty(
|
||||
m_groups[g], kKLuchrData, &resource);
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
CUCHRKeyResource uchr(resource, keyboardType);
|
||||
if (uchr.isValid()) {
|
||||
LOG((CLOG_DEBUG1 "using uchr resource for group %d", g));
|
||||
@@ -366,6 +421,21 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
|
||||
}
|
||||
}
|
||||
|
||||
// NB: not sure why support for KCHR was
|
||||
// remvoed in 10.5 version?
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// try KCHR resource
|
||||
if (KLGetKeyboardLayoutProperty(m_groups[g],
|
||||
kKLKCHRData, &resource) == noErr) {
|
||||
CKCHRKeyResource kchr(resource);
|
||||
if (kchr.isValid()) {
|
||||
LOG((CLOG_DEBUG1 "using KCHR resource for group %d", g));
|
||||
getKeyMap(keyMap, g, kchr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG((CLOG_DEBUG1 "no keyboard resource for group %d", g));
|
||||
}
|
||||
}
|
||||
@@ -663,23 +733,41 @@ COSXKeyState::handleModifierKey(void* target,
|
||||
bool
|
||||
COSXKeyState::getGroups(GroupList& groups) const
|
||||
{
|
||||
CFIndex n;
|
||||
bool gotLayouts = false;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// get number of layouts
|
||||
CFStringRef keys[] = { kTISPropertyInputSourceCategory };
|
||||
CFStringRef values[] = { kTISCategoryKeyboardInputSource };
|
||||
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, NULL, NULL);
|
||||
CFArrayRef kbds = TISCreateInputSourceList(dict, false);
|
||||
CFIndex n = CFArrayGetCount(kbds);
|
||||
if (n == 0) {
|
||||
CFStringRef keys[] = { kTISPropertyInputSourceCategory };
|
||||
CFStringRef values[] = { kTISCategoryKeyboardInputSource };
|
||||
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, NULL, NULL);
|
||||
CFArrayRef kbds = TISCreateInputSourceList(dict, false);
|
||||
n = CFArrayGetCount(kbds);
|
||||
gotLayouts = (n != 0);
|
||||
#else
|
||||
OSStatus status = KLGetKeyboardLayoutCount(&n);
|
||||
gotLayouts = (status == noErr);
|
||||
#endif
|
||||
|
||||
if (!gotLayouts) {
|
||||
LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get each layout
|
||||
groups.clear();
|
||||
TISInputSourceRef inputKeyboardLayout;
|
||||
for (CFIndex i = 0; i < n; ++i) {
|
||||
inputKeyboardLayout = (TISInputSourceRef) CFArrayGetValueAtIndex(kbds, i);
|
||||
groups.push_back(inputKeyboardLayout);
|
||||
bool addToGroups = true;
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef keyboardLayout =
|
||||
(TISInputSourceRef)CFArrayGetValueAtIndex(kbds, i);
|
||||
#else
|
||||
KeyboardLayoutRef keyboardLayout;
|
||||
status = KLGetKeyboardLayoutAtIndex(i, &keyboardLayout);
|
||||
addToGroups == (status == noErr);
|
||||
#endif
|
||||
if (addToGroups)
|
||||
groups.push_back(keyboardLayout);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -687,7 +775,11 @@ COSXKeyState::getGroups(GroupList& groups) const
|
||||
void
|
||||
COSXKeyState::setGroup(SInt32 group)
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISSetInputMethodKeyboardLayoutOverride(m_groups[group]);
|
||||
#else
|
||||
KLSetCurrentKeyboardLayout(m_groups[group]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -832,16 +924,18 @@ COSXKeyState::CKeyResource::getKeyID(UInt8 c)
|
||||
str[0] = static_cast<char>(c);
|
||||
str[1] = 0;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// get current keyboard script
|
||||
|
||||
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||||
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||||
|
||||
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||||
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||||
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)CFArrayGetValueAtIndex(langs, 0));
|
||||
#else
|
||||
CFStringEncoding encoding = GetScriptManagerVariable(smKeyScript);
|
||||
#endif
|
||||
// convert to unicode
|
||||
CFStringRef cfString =
|
||||
CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
|
||||
str, CFStringConvertIANACharSetNameToEncoding((CFStringRef) CFArrayGetValueAtIndex(langs, 0)),
|
||||
kCFAllocatorNull);
|
||||
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,
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
#include "stdset.h"
|
||||
#include "stdvector.h"
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
typedef TISInputSourceRef KeyLayout;
|
||||
#else
|
||||
typedef KeyboardLayoutRef KeyLayout;
|
||||
#endif
|
||||
|
||||
//! OS X key state
|
||||
/*!
|
||||
A key state for OS X.
|
||||
@@ -99,7 +105,7 @@ protected:
|
||||
|
||||
private:
|
||||
class CKeyResource;
|
||||
typedef std::vector<TISInputSourceRef> GroupList;
|
||||
typedef std::vector<KeyLayout> GroupList;
|
||||
|
||||
// Add hard coded special keys to a CKeyMap.
|
||||
void getKeyMapForSpecialKeys(
|
||||
@@ -197,7 +203,7 @@ private:
|
||||
KeyButtonOffset = 1
|
||||
};
|
||||
|
||||
typedef std::map<TISInputSourceRef, SInt32> GroupMap;
|
||||
typedef std::map<KeyLayout, SInt32> GroupMap;
|
||||
typedef std::map<UInt32, KeyID> CVirtualKeyMap;
|
||||
|
||||
CVirtualKeyMap m_virtualKeyMap;
|
||||
|
||||
@@ -97,9 +97,17 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
||||
LOG((CLOG_ERR "Synergy server requires accessibility API enabled. Please check the option for \"Enable access for assistive devices\" in the Universal Access System Preferences panel. Unintentional key-replication will occur until this is fixed."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// install display manager notification handler
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
m_displayManagerNotificationUPP =
|
||||
NewDMExtendedNotificationUPP(displayManagerCallback);
|
||||
OSStatus err = GetCurrentProcess(&m_PSN);
|
||||
err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP,
|
||||
this, 0, &m_PSN);
|
||||
#endif
|
||||
|
||||
// install fast user switching event handler
|
||||
EventTypeSpec switchEventTypes[2];
|
||||
@@ -132,7 +140,24 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
||||
if (m_switchEventHandlerRef != 0) {
|
||||
RemoveEventHandler(m_switchEventHandlerRef);
|
||||
}
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
if (m_displayManagerNotificationUPP != NULL) {
|
||||
DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP,
|
||||
NULL, &m_PSN, 0);
|
||||
}
|
||||
|
||||
if (m_hiddenWindow) {
|
||||
ReleaseWindow(m_hiddenWindow);
|
||||
m_hiddenWindow = NULL;
|
||||
}
|
||||
|
||||
if (m_userInputWindow) {
|
||||
ReleaseWindow(m_userInputWindow);
|
||||
m_userInputWindow = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete m_keyState;
|
||||
delete m_screensaver;
|
||||
@@ -178,7 +203,22 @@ COSXScreen::~COSXScreen()
|
||||
|
||||
RemoveEventHandler(m_switchEventHandlerRef);
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP,
|
||||
NULL, &m_PSN, 0);
|
||||
|
||||
if (m_hiddenWindow) {
|
||||
ReleaseWindow(m_hiddenWindow);
|
||||
m_hiddenWindow = NULL;
|
||||
}
|
||||
|
||||
if (m_userInputWindow) {
|
||||
ReleaseWindow(m_userInputWindow);
|
||||
m_userInputWindow = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete m_keyState;
|
||||
delete m_screensaver;
|
||||
@@ -526,17 +566,22 @@ void
|
||||
COSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const
|
||||
{
|
||||
if (xDelta != 0 || yDelta != 0) {
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// create a scroll event, post it and release it. not sure if kCGScrollEventUnitLine
|
||||
// is the right choice here over kCGScrollEventUnitPixel
|
||||
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(NULL,
|
||||
kCGScrollEventUnitLine,
|
||||
2,
|
||||
mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(
|
||||
NULL, kCGScrollEventUnitLine, 2,
|
||||
mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
|
||||
CGEventPost(kCGHIDEventTap, scrollEvent);
|
||||
|
||||
CFRelease(scrollEvent);
|
||||
#else
|
||||
|
||||
CGPostScrollWheelEvent(
|
||||
2, mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,6 +1033,42 @@ COSXScreen::handleClipboardCheck(const CEvent&, void*)
|
||||
checkClipboards();
|
||||
}
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
pascal void
|
||||
COSXScreen::displayManagerCallback(void* inUserData, SInt16 inMessage, void*)
|
||||
{
|
||||
COSXScreen* screen = (COSXScreen*)inUserData;
|
||||
|
||||
if (inMessage == kDMNotifyEvent) {
|
||||
screen->onDisplayChange();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
COSXScreen::onDisplayChange()
|
||||
{
|
||||
// screen resolution may have changed. save old shape.
|
||||
SInt32 xOld = m_x, yOld = m_y, wOld = m_w, hOld = m_h;
|
||||
|
||||
// update shape
|
||||
updateScreenShape();
|
||||
|
||||
// do nothing if resolution hasn't changed
|
||||
if (xOld != m_x || yOld != m_y || wOld != m_w || hOld != m_h) {
|
||||
if (m_isPrimary) {
|
||||
// warp mouse to center if off screen
|
||||
if (!m_isOnScreen) {
|
||||
warpCursor(m_xCenter, m_yCenter);
|
||||
}
|
||||
}
|
||||
|
||||
// send new screen info
|
||||
sendEvent(getShapeChangedEvent());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
void
|
||||
COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData)
|
||||
{
|
||||
@@ -1007,6 +1088,7 @@ COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDispla
|
||||
screen->updateScreenShape(displayID, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
COSXScreen::onKey(CGEventRef event)
|
||||
@@ -1275,7 +1357,12 @@ COSXScreen::getKeyState() const
|
||||
void
|
||||
COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags)
|
||||
{
|
||||
|
||||
updateScreenShape();
|
||||
}
|
||||
|
||||
void
|
||||
COSXScreen::updateScreenShape()
|
||||
{
|
||||
// get info for each display
|
||||
CGDisplayCount displayCount = 0;
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ protected:
|
||||
virtual IKeyState* getKeyState() const;
|
||||
|
||||
private:
|
||||
void updateScreenShape();
|
||||
void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
|
||||
void postMouseEvent(CGPoint&) const;
|
||||
|
||||
@@ -114,10 +115,14 @@ private:
|
||||
// of the button pressed using the mac button mapping.
|
||||
bool onMouseButton(bool pressed, UInt16 macButton);
|
||||
bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const;
|
||||
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
bool onDisplayChange();
|
||||
#endif
|
||||
void constructMouseButtonEventMap();
|
||||
|
||||
bool onKey(CGEventRef event);
|
||||
|
||||
bool onHotKey(EventRef event) const;
|
||||
|
||||
// Added here to allow the carbon cursor hack to be called.
|
||||
@@ -148,10 +153,14 @@ private:
|
||||
// clipboard check timer handler
|
||||
void handleClipboardCheck(const CEvent&, void*);
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// Resolution switch callback
|
||||
static void displayReconfigurationCallback(CGDirectDisplayID,
|
||||
CGDisplayChangeSummaryFlags, void*);
|
||||
|
||||
#else
|
||||
static pascal void displayManagerCallback(void* inUserData,
|
||||
SInt16 inMessage, void* inNotifyData);
|
||||
#endif
|
||||
// fast user switch callback
|
||||
static pascal OSStatus
|
||||
userSwitchCallback(EventHandlerCallRef nextHandler,
|
||||
@@ -279,6 +288,12 @@ private:
|
||||
// does not have focus.
|
||||
WindowRef m_userInputWindow;
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
// display manager stuff (to get screen resolution switches).
|
||||
DMExtendedNotificationUPP m_displayManagerNotificationUPP;
|
||||
ProcessSerialNumber m_PSN;
|
||||
#endif
|
||||
|
||||
// fast user switching
|
||||
EventHandlerRef m_switchEventHandlerRef;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user