Add support for building with 64-bit architectures on OS X.

This patch brings full 64-bit compatibility to Synergy on OS X by
replacing all obsolete 32-bit only Carbon functions with modern
equivalents. All functions introduced have been available since 10.4 so
this won't affect the minimum deployment target. Specifically:

Creating an empty CGEvent and getting its location is behaviourally
identical to GetGlobalMouse, and yes, both are in flipped coordinates.
This was tested with a multi-monitor configuration as well.

TrackMouseLocationWithOptions is behaviourally identical to
GetGlobalMouse in these cases because the timeout was 0 and none of the
other out params were used, except for the MouseTrackingResult in one
call was checked against kMouseTrackingTimedOut. Since the timeout was 0
and not kEventDurationForever, that value never could have been returned
anyway.

Instead of attempting to define SIntXX and UIntXX manually, MacTypes.h
is included on OS X. These types were wrong in 64-bit mode because of
this, causing type redefinition errors.
This commit is contained in:
Jake Petroules 2014-10-15 19:00:30 -07:00
parent 70c8f98615
commit 7dd2db25ec
5 changed files with 41 additions and 33 deletions

View File

@ -165,13 +165,12 @@ if (UNIX)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
message(STATUS "DARWIN_VERSION=${DARWIN_VERSION}") message(STATUS "DARWIN_VERSION=${DARWIN_VERSION}")
if (DARWIN_VERSION LESS 9) if (DARWIN_VERSION LESS 9)
# 10.4: universal (32-bit intel and power pc) # 10.4: Universal (32-bit and 64-bit Intel and PowerPC)
set(CMAKE_OSX_ARCHITECTURES "ppc;i386" set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386:x86_64"
CACHE STRING "" FORCE) CACHE STRING "" FORCE)
else() else()
# 10.5+: 32-bit only -- missing funcs in 64-bit os libs # 10.5+: Intel only
# such as GetGlobalMouse. set(CMAKE_OSX_ARCHITECTURES "i386;x86_64"
set(CMAKE_OSX_ARCHITECTURES "i386"
CACHE STRING "" FORCE) CACHE STRING "" FORCE)
endif() endif()

View File

@ -72,6 +72,9 @@
// Added this because it doesn't compile on OS X 10.6 because they are already defined in Carbon // Added this because it doesn't compile on OS X 10.6 because they are already defined in Carbon
#if !defined(__MACTYPES__) #if !defined(__MACTYPES__)
#if defined(__APPLE__)
#include <CoreServices/CoreServices.h>
#else
typedef signed TYPE_OF_SIZE_1 SInt8; typedef signed TYPE_OF_SIZE_1 SInt8;
typedef signed TYPE_OF_SIZE_2 SInt16; typedef signed TYPE_OF_SIZE_2 SInt16;
typedef signed TYPE_OF_SIZE_4 SInt32; typedef signed TYPE_OF_SIZE_4 SInt32;
@ -79,6 +82,7 @@ typedef unsigned TYPE_OF_SIZE_1 UInt8;
typedef unsigned TYPE_OF_SIZE_2 UInt16; typedef unsigned TYPE_OF_SIZE_2 UInt16;
typedef unsigned TYPE_OF_SIZE_4 UInt32; typedef unsigned TYPE_OF_SIZE_4 UInt32;
#endif #endif
#endif
// //
// clean up // clean up
// //

View File

@ -292,13 +292,14 @@ COSXScreen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
void void
COSXScreen::getCursorPos(SInt32& x, SInt32& y) const COSXScreen::getCursorPos(SInt32& x, SInt32& y) const
{ {
Point mouse; CGEventRef event = CGEventCreate(NULL);
GetGlobalMouse(&mouse); CGPoint mouse = CGEventGetLocation(event);
x = mouse.h; x = mouse.x;
y = mouse.v; y = mouse.y;
m_cursorPosValid = true; m_cursorPosValid = true;
m_xCursor = x; m_xCursor = x;
m_yCursor = y; m_yCursor = y;
CFRelease(event);
} }
void void
@ -696,15 +697,16 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
// we can do. // we can do.
// get current position // get current position
Point oldPos; CGEventRef event = CGEventCreate(NULL);
GetGlobalMouse(&oldPos); CGPoint oldPos = CGEventGetLocation(event);
CFRelease(event);
// synthesize event // synthesize event
CGPoint pos; CGPoint pos;
m_xCursor = static_cast<SInt32>(oldPos.h); m_xCursor = static_cast<SInt32>(oldPos.x);
m_yCursor = static_cast<SInt32>(oldPos.v); m_yCursor = static_cast<SInt32>(oldPos.y);
pos.x = oldPos.h + dx; pos.x = oldPos.x + dx;
pos.y = oldPos.v + dy; pos.y = oldPos.y + dy;
postMouseEvent(pos); postMouseEvent(pos);
// we now assume we don't know the current cursor position // we now assume we don't know the current cursor position
@ -1052,7 +1054,7 @@ COSXScreen::handleSystemEvent(const CEvent& event, void*)
// get scroll amount // get scroll amount
r = GetEventParameter(*carbonEvent, r = GetEventParameter(*carbonEvent,
kSynergyMouseScrollAxisX, kSynergyMouseScrollAxisX,
typeLongInteger, typeSInt32,
NULL, NULL,
sizeof(xScroll), sizeof(xScroll),
NULL, NULL,
@ -1062,7 +1064,7 @@ COSXScreen::handleSystemEvent(const CEvent& event, void*)
} }
r = GetEventParameter(*carbonEvent, r = GetEventParameter(*carbonEvent,
kSynergyMouseScrollAxisY, kSynergyMouseScrollAxisY,
typeLongInteger, typeSInt32,
NULL, NULL,
sizeof(yScroll), sizeof(yScroll),
NULL, NULL,
@ -1090,7 +1092,10 @@ COSXScreen::handleSystemEvent(const CEvent& event, void*)
break; break;
case kEventClassWindow: case kEventClassWindow:
SendEventToWindow(*carbonEvent, m_userInputWindow); // 2nd param was formerly GetWindowEventTarget(m_userInputWindow) which is 32-bit only,
// however as m_userInputWindow is never initialized to anything we can take advantage of
// the fact that GetWindowEventTarget(NULL) == NULL
SendEventToEventTarget(*carbonEvent, NULL);
switch (GetEventKind(*carbonEvent)) { switch (GetEventKind(*carbonEvent)) {
case kEventWindowActivated: case kEventWindowActivated:
LOG((CLOG_DEBUG1 "window activated")); LOG((CLOG_DEBUG1 "window activated"));
@ -1514,15 +1519,16 @@ COSXScreen::getScrollSpeedFactor() const
void void
COSXScreen::enableDragTimer(bool enable) COSXScreen::enableDragTimer(bool enable)
{ {
UInt32 modifiers;
MouseTrackingResult res;
if (enable && m_dragTimer == NULL) { if (enable && m_dragTimer == NULL) {
m_dragTimer = m_events->newTimer(0.01, NULL); m_dragTimer = m_events->newTimer(0.01, NULL);
m_events->adoptHandler(CEvent::kTimer, m_dragTimer, m_events->adoptHandler(CEvent::kTimer, m_dragTimer,
new TMethodEventJob<COSXScreen>(this, new TMethodEventJob<COSXScreen>(this,
&COSXScreen::handleDrag)); &COSXScreen::handleDrag));
TrackMouseLocationWithOptions(NULL, 0, 0, &m_dragLastPoint, &modifiers, &res); CGEventRef event = CGEventCreate(NULL);
CGPoint mouse = CGEventGetLocation(event);
m_dragLastPoint.h = (short)mouse.x;
m_dragLastPoint.v = (short)mouse.y;
CFRelease(event);
} }
else if (!enable && m_dragTimer != NULL) { else if (!enable && m_dragTimer != NULL) {
m_events->removeHandler(CEvent::kTimer, m_dragTimer); m_events->removeHandler(CEvent::kTimer, m_dragTimer);
@ -1534,15 +1540,14 @@ COSXScreen::enableDragTimer(bool enable)
void void
COSXScreen::handleDrag(const CEvent&, void*) COSXScreen::handleDrag(const CEvent&, void*)
{ {
Point p; CGEventRef event = CGEventCreate(NULL);
UInt32 modifiers; CGPoint p = CGEventGetLocation(event);
MouseTrackingResult res; CFRelease(event);
TrackMouseLocationWithOptions(NULL, 0, 0, &p, &modifiers, &res); if ((short)p.x != m_dragLastPoint.h || (short)p.y != m_dragLastPoint.v) {
m_dragLastPoint.h = (short)p.x;
if (res != kMouseTrackingTimedOut && (p.h != m_dragLastPoint.h || p.v != m_dragLastPoint.v)) { m_dragLastPoint.v = (short)p.y;
m_dragLastPoint = p; onMouseMove((SInt32)p.x, (SInt32)p.y);
onMouseMove((SInt32)p.h, (SInt32)p.v);
} }
} }

View File

@ -142,7 +142,7 @@ COSXScreenSaver::launchTerminationCallback(
OSStatus result; OSStatus result;
ProcessSerialNumber psn; ProcessSerialNumber psn;
EventParamType actualType; EventParamType actualType;
UInt32 actualSize; ByteCount actualSize;
result = GetEventParameter(theEvent, kEventParamProcessID, result = GetEventParameter(theEvent, kEventParamProcessID,
typeProcessSerialNumber, &actualType, typeProcessSerialNumber, &actualType,

View File

@ -302,9 +302,9 @@ CDaemonApp::handleIpcMessage(const CEvent& e, void*)
LOG((CLOG_DEBUG "new command, elevate=%d command=%s", cm->elevate(), command.c_str())); LOG((CLOG_DEBUG "new command, elevate=%d command=%s", cm->elevate(), command.c_str()));
CString debugArg("--debug"); CString debugArg("--debug");
UInt32 debugArgPos = static_cast<UInt32>(command.find(debugArg)); size_t debugArgPos = command.find(debugArg);
if (debugArgPos != CString::npos) { if (debugArgPos != CString::npos) {
UInt32 from = debugArgPos + static_cast<UInt32>(debugArg.size()) + 1; UInt32 from = static_cast<UInt32>(debugArgPos) + static_cast<UInt32>(debugArg.size()) + 1;
UInt32 nextSpace = static_cast<UInt32>(command.find(" ", from)); UInt32 nextSpace = static_cast<UInt32>(command.find(" ", from));
CString logLevel(command.substr(from, nextSpace - from)); CString logLevel(command.substr(from, nextSpace - from));