diff --git a/lib/common/MacOSXPrecomp.h b/lib/common/MacOSXPrecomp.h new file mode 100644 index 00000000..64e7c90a --- /dev/null +++ b/lib/common/MacOSXPrecomp.h @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'deleteme' target in the 'deleteme' project. +// + +#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_2 + + +#include diff --git a/lib/common/common.h b/lib/common/common.h index c2c910e8..1e406693 100644 --- a/lib/common/common.h +++ b/lib/common/common.h @@ -27,7 +27,7 @@ # endif // we may not have run configure on OS X -# if defined(__APPLE__) +# if defined(__APPLE__) # define SYSAPI_UNIX 1 # define WINAPI_CARBON 1 @@ -45,11 +45,9 @@ # define HAVE_MEMORY_H 1 # define HAVE_NANOSLEEP 1 # define HAVE_OSTREAM 1 -# define HAVE_POLL 1 # define HAVE_POSIX_SIGWAIT 1 # define HAVE_PTHREAD 1 # define HAVE_PTHREAD_SIGNAL 1 -# define HAVE_SOCKLEN_T 1 # define HAVE_SSTREAM 1 # define HAVE_STDINT_H 1 # define HAVE_STDLIB_H 1 @@ -74,7 +72,7 @@ # define STDC_HEADERS 1 # define TIME_WITH_SYS_TIME 1 # define X_DISPLAY_MISSING 1 -# endif +# endif #endif // VC++ specific diff --git a/lib/platform/COSXClipboardTextConverter.cpp b/lib/platform/COSXClipboardTextConverter.cpp index 0b92dee1..bcbc228e 100644 --- a/lib/platform/COSXClipboardTextConverter.cpp +++ b/lib/platform/COSXClipboardTextConverter.cpp @@ -35,14 +35,54 @@ COSXClipboardTextConverter::getOSXFormat() const return kScrapFlavorTypeText; } +CString +COSXClipboardTextConverter::convertString( + const CString& data, + CFStringEncoding fromEncoding, + CFStringEncoding toEncoding) +{ + CFStringRef stringRef = + CFStringCreateWithCString(kCFAllocatorDefault, + data.c_str(), fromEncoding); + + if (stringRef == NULL) { + return CString(); + } + + CFIndex buffSize; + CFRange entireString = CFRangeMake(0, CFStringGetLength(stringRef)); + + CFStringGetBytes(stringRef, entireString, toEncoding, + 0, false, NULL, 0, &buffSize); + + char* buffer = new char[buffSize]; + + if (buffer == NULL) { + CFRelease(stringRef); + return CString(); + } + + CFStringGetBytes(stringRef, entireString, toEncoding, + 0, false, (UInt8*)buffer, buffSize, NULL); + + CString result(buffer, buffSize); + + delete[] buffer; + CFRelease(stringRef); + + return result; +} + CString COSXClipboardTextConverter::doFromIClipboard(const CString& data) const { - return CUnicode::UTF8ToText(data); + return convertString(data, kCFStringEncodingUTF8, + CFStringGetSystemEncoding()); } CString COSXClipboardTextConverter::doToIClipboard(const CString& data) const { - return CUnicode::textToUTF8(data); + return convertString(data, CFStringGetSystemEncoding(), + kCFStringEncodingUTF8); } diff --git a/lib/platform/COSXClipboardTextConverter.h b/lib/platform/COSXClipboardTextConverter.h index dc2649d5..2a75f4f0 100644 --- a/lib/platform/COSXClipboardTextConverter.h +++ b/lib/platform/COSXClipboardTextConverter.h @@ -32,6 +32,10 @@ protected: virtual CString doFromIClipboard(const CString&) const; virtual CString doToIClipboard(const CString&) const; + // generic encoding converter + static CString convertString(const CString& data, + CFStringEncoding fromEncoding, + CFStringEncoding toEncoding); }; #endif diff --git a/lib/platform/COSXEventQueueBuffer.cpp b/lib/platform/COSXEventQueueBuffer.cpp index 22dadc9d..76dcd35c 100644 --- a/lib/platform/COSXEventQueueBuffer.cpp +++ b/lib/platform/COSXEventQueueBuffer.cpp @@ -68,7 +68,7 @@ COSXEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID) default: event = CEvent(CEvent::kSystem, IEventQueue::getSystemTarget(), &m_event); - return kNone; + return kSystem; } } } diff --git a/lib/platform/COSXKeyState.cpp b/lib/platform/COSXKeyState.cpp index ec454ace..ed9d295f 100644 --- a/lib/platform/COSXKeyState.cpp +++ b/lib/platform/COSXKeyState.cpp @@ -190,18 +190,308 @@ static const CKeyEntry s_keys[] = { { 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() { - // FIXME + // do nothing } COSXKeyState::~COSXKeyState() { - // FIXME + // 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 @@ -229,15 +519,17 @@ COSXKeyState::doUpdateKeys() // 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)); + 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) +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(button), press); + CGPostKeyboardEvent(0, static_cast(button) - 1, press); } KeyButton @@ -292,3 +584,47 @@ COSXKeyState::adjustModifiers(Keystrokes& /*keys*/, // 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(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(c) & 0xffu; + } + } + + KeyModifierMask activeMask = getActiveModifiers(); + if (id != kKeyNone && c != 0) { + // FIXME + } + + // map modifier key + if (maskOut != NULL) { + activeMask &= ~KeyModifierModeSwitch; + *maskOut = activeMask; + } + + return id; + +} diff --git a/lib/platform/COSXKeyState.h b/lib/platform/COSXKeyState.h index ef563e14..94e98f07 100644 --- a/lib/platform/COSXKeyState.h +++ b/lib/platform/COSXKeyState.h @@ -28,10 +28,21 @@ public: COSXKeyState(); virtual ~COSXKeyState(); + //! Map key event to a key + /*! + Converts a key event into a KeyID and the shadow modifier state + to a modifier mask. + */ + KeyID mapKeyFromEvent(EventRef event, + KeyModifierMask* maskOut) const; + // IKeyState overrides virtual bool fakeCtrlAltDel(); virtual const char* getKeyName(KeyButton) const; - + virtual void sendKeyEvent(void* target, + bool press, bool isAutoRepeat, + KeyID key, KeyModifierMask mask, + SInt32 count, KeyButton button); protected: // IKeyState overrides virtual void doUpdateKeys(); @@ -50,6 +61,8 @@ private: typedef std::map CKeyMap; CKeyMap m_keyMap; + + static const KeyID s_virtualKey[]; }; #endif diff --git a/lib/platform/COSXScreen.cpp b/lib/platform/COSXScreen.cpp index 80fb0677..2cd002a1 100644 --- a/lib/platform/COSXScreen.cpp +++ b/lib/platform/COSXScreen.cpp @@ -35,16 +35,72 @@ COSXScreen::COSXScreen(bool isPrimary) : m_sequenceNumber(0), m_screensaver(NULL), m_screensaverNotify(false), - m_ownClipboard(false) + m_ownClipboard(false), + m_hiddenWindow(NULL), + m_userInputWindow(NULL), + m_displayManagerNotificationUPP(NULL) { try { m_displayID = CGMainDisplayID(); updateScreenShape(); m_screensaver = new COSXScreenSaver(); m_keyState = new COSXKeyState(); - LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h)); + + if (m_isPrimary) { + // 1x1 window (to minimze the back buffer allocated for this + // window. + Rect bounds = { 100, 100, 101, 101 }; + + // m_hiddenWindow is a window meant to let us get mouse moves + // when the focus is on this computer. If you get your event + // from the application event target you'll get every mouse + // moves. On the other hand the Window event target will only + // get events when the mouse moves over the window. + + // The ignoreClicks attributes makes it impossible for the + // user to click on our invisible window. + CreateNewWindow(kUtilityWindowClass, + kWindowNoShadowAttribute | + kWindowIgnoreClicksAttribute | + kWindowNoActivatesAttribute, + &bounds, &m_hiddenWindow); + + // Make it invisible + SetWindowAlpha(m_hiddenWindow, 0); + ShowWindow(m_hiddenWindow); + + // m_userInputWindow is a window meant to let us get mouse moves + // when the focus is on this computer. + Rect inputBounds = { 100, 100, 200, 200 }; + CreateNewWindow(kUtilityWindowClass, + kWindowNoShadowAttribute | + kWindowOpaqueForEventsAttribute | + kWindowStandardHandlerAttribute, + &inputBounds, &m_userInputWindow); + + SetWindowAlpha(m_userInputWindow, 0); + } + + m_displayManagerNotificationUPP = + NewDMExtendedNotificationUPP(displayManagerCallback); + + OSStatus err = GetCurrentProcess(&m_PSN); + + err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP, + this, 0, &m_PSN); } catch (...) { + 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; + } delete m_keyState; delete m_screensaver; throw; @@ -64,6 +120,20 @@ COSXScreen::~COSXScreen() disable(); EVENTQUEUE->adoptBuffer(NULL); EVENTQUEUE->removeHandler(CEvent::kSystem, IEventQueue::getSystemTarget()); + + if (m_hiddenWindow) { + ReleaseWindow(m_hiddenWindow); + m_hiddenWindow = NULL; + } + + if (m_userInputWindow) { + ReleaseWindow(m_userInputWindow); + m_userInputWindow = NULL; + } + + DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, + NULL, &m_PSN, 0); + delete m_keyState; delete m_screensaver; } @@ -159,6 +229,7 @@ COSXScreen::postMouseEvent(const CGPoint & pos) const // 2 - Right // 3 - Middle // Whatever the USB device defined. + // // It is a bit weird that the behaviour of buttons over 3 are dependent // on currently plugged in USB devices. CGPostMouseEvent(pos, true, sizeof(m_buttons) / sizeof(m_buttons[0]), @@ -233,12 +304,12 @@ void COSXScreen::fakeMouseWheel(SInt32 delta) const { CFPropertyListRef pref = ::CFPreferencesCopyValue( - CFSTR("com.apple.scrollwheel.scaling"), - kCFPreferencesAnyApplication, + CFSTR("com.apple.scrollwheel.scaling") , + kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); - int32_t wheelIncr = 10; + int32_t wheelIncr = 1; if (pref != NULL) { CFTypeID id = CFGetTypeID(pref); @@ -248,6 +319,9 @@ COSXScreen::fakeMouseWheel(SInt32 delta) const double scaling; if (CFNumberGetValue(value, kCFNumberDoubleType, &scaling)) { wheelIncr = (int32_t)(8 * scaling); + if (wheelIncr == 0) { + wheelIncr = 1; + } } } CFRelease(pref); @@ -311,7 +385,13 @@ void COSXScreen::enter() { if (m_isPrimary) { - // FIXME -- stop capturing input, watch jump zones + // stop capturing input, watch jump zones + HideWindow( m_userInputWindow ); + ShowWindow( m_hiddenWindow ); + + SetMouseCoalescingEnabled(true, NULL); + + CGSetLocalEventsSuppressionInterval(HUGE_VAL); } else { // show cursor @@ -340,10 +420,21 @@ COSXScreen::leave() updateKeys(); // warp to center + // FIXME -- this should be the center of the main monitor warpCursor(m_xCenter, m_yCenter); // capture events - // FIXME + HideWindow(m_hiddenWindow); + ShowWindow(m_userInputWindow); + RepositionWindow(m_userInputWindow, + m_userInputWindow, kWindowCenterOnMainScreen); + SetUserFocusWindow(m_userInputWindow); + + // The OS will coalesce some events if they are similar enough in a + // short period of time this is bad for us since we need every event + // to send it over to other machines. So disable it. + SetMouseCoalescingEnabled(false, NULL); + CGSetLocalEventsSuppressionInterval(0.0001); } else { // hide cursor @@ -457,13 +548,13 @@ COSXScreen::isPrimary() const } void -COSXScreen::sendEvent(CEvent::Type type, void* data) +COSXScreen::sendEvent(CEvent::Type type, void* data) const { EVENTQUEUE->addEvent(CEvent(type, getEventTarget(), data)); } void -COSXScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id) +COSXScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id) const { CClipboardInfo* info = (CClipboardInfo*)malloc(sizeof(CClipboardInfo)); info->m_id = id; @@ -471,50 +562,284 @@ COSXScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id) sendEvent(type, info); } - void COSXScreen::handleSystemEvent(const CEvent& event, void*) { -/* - EventRef * carbonEvent = reinterpret_cast(event.getData()); + EventRef* carbonEvent = reinterpret_cast(event.getData()); assert(carbonEvent != NULL); - UInt32 eventClass = GetEventClass( *carbonEvent ); + UInt32 eventClass = GetEventClass(*carbonEvent); - switch( eventClass ) - { - case kEventClassMouse: + switch (eventClass) { + case kEventClassMouse: + switch (GetEventKind(*carbonEvent)) { + case kEventMouseDown: { - UInt32 eventKind = GetEventKind( *carbonEvent ); - switch( eventKind ) - { - case kEventMouseMoved: - { - HIPoint point; - GetEventParameter( *carbonEvent, - kEventParamMouseDelta, - typeHIPoint, - NULL, - sizeof(point), - NULL, - &point); - - } break; - } - }break; - - case kEventClassKeyboard: - { - + UInt16 myButton; + GetEventParameter(*carbonEvent, + kEventParamMouseButton, + typeMouseButton, + NULL, + sizeof(myButton), + NULL, + &myButton); + onMouseButton(true, myButton); + break; } - default: + case kEventMouseUp: { - - } break; - + UInt16 myButton; + GetEventParameter(*carbonEvent, + kEventParamMouseButton, + typeMouseButton, + NULL, + sizeof(myButton), + NULL, + &myButton); + onMouseButton(false, myButton); + break; + } + + case kEventMouseDragged: + case kEventMouseMoved: + { + HIPoint point; + GetEventParameter(*carbonEvent, + kEventParamMouseLocation, + typeHIPoint, + NULL, + sizeof(point), + NULL, + &point); + onMouseMove((SInt32)point.x, (SInt32)point.y); + break; + } + + case kEventMouseWheelMoved: + { + EventMouseWheelAxis axis; + SInt32 delta; + GetEventParameter(*carbonEvent, + kEventParamMouseWheelAxis, + typeMouseWheelAxis, + NULL, + sizeof(axis), + NULL, + &axis); + if (axis == kEventMouseWheelAxisY) { + GetEventParameter(*carbonEvent, + kEventParamMouseWheelDelta, + typeLongInteger, + NULL, + sizeof(delta), + NULL, + &delta); + onMouseWheel(120 * (SInt32)delta); + } + break; + } + } + break; + + case kEventClassKeyboard: + switch (GetEventKind(*carbonEvent)) { + case kEventRawKeyUp: + case kEventRawKeyDown: + case kEventRawKeyRepeat: + case kEventRawKeyModifiersChanged: +// case kEventHotKeyPressed: +// case kEventHotKeyReleased: + onKey(*carbonEvent); + break; + } + break; + + case kEventClassWindow: + SendEventToWindow(*carbonEvent, m_userInputWindow); + switch (GetEventKind(*carbonEvent)) { + case kEventWindowActivated: + LOG((CLOG_DEBUG1 "window activated")); + break; + + case kEventWindowDeactivated: + LOG((CLOG_DEBUG1 "window deactivated")); + break; + + case kEventWindowFocusAcquired: + LOG((CLOG_DEBUG1 "focus acquired")); + break; + + case kEventWindowFocusRelinquish: + LOG((CLOG_DEBUG1 "focus released")); + break; + } + break; + + default: + break; } -*/ +} + +bool +COSXScreen::onMouseMove(SInt32 mx, SInt32 my) +{ + LOG((CLOG_DEBUG2 "mouse move %+d,%+d", mx, my)); + + SInt32 x = mx - m_xCursor; + SInt32 y = my - m_yCursor; + + if ((x == 0 && y == 0) || (mx == m_xCenter && mx == m_yCenter)) { + return true; + } + + // save position to compute delta of next motion + m_xCursor = mx; + m_yCursor = my; + + if (m_isOnScreen) { + // motion on primary screen + sendEvent(getMotionOnPrimaryEvent(), + CMotionInfo::alloc(m_xCursor, m_yCursor)); + } + else { + // motion on secondary screen. warp mouse back to + // center. + warpCursor(m_xCenter, m_yCenter); + + // examine the motion. if it's about the distance + // from the center of the screen to an edge then + // it's probably a bogus motion that we want to + // ignore (see warpCursorNoFlush() for a further + // description). + static SInt32 bogusZoneSize = 10; + if (-x + bogusZoneSize > m_xCenter - m_x || + x + bogusZoneSize > m_x + m_w - m_xCenter || + -y + bogusZoneSize > m_yCenter - m_y || + y + bogusZoneSize > m_y + m_h - m_yCenter) { + LOG((CLOG_DEBUG "dropped bogus motion %+d,%+d", x, y)); + } + else { + // send motion + sendEvent(getMotionOnSecondaryEvent(), CMotionInfo::alloc(x, y)); + } + } + + return true; +} + +bool +COSXScreen::onMouseButton(bool pressed, UInt16 macButton) const +{ + // Buttons 2 and 3 are inverted on the mac + ButtonID button = mapMacButtonToSynergy(macButton); + + if (pressed) { + LOG((CLOG_DEBUG1 "event: button press button=%d", button)); + if (button != kButtonNone) { + sendEvent(getButtonDownEvent(), CButtonInfo::alloc(button)); + } + } + else { + LOG((CLOG_DEBUG1 "event: button release button=%d", button)); + if (button != kButtonNone) { + sendEvent(getButtonUpEvent(), CButtonInfo::alloc(button)); + } + } + + return true; +} + +bool +COSXScreen::onMouseWheel(SInt32 delta) const +{ + LOG((CLOG_DEBUG1 "event: button wheel delta=%d", delta)); + sendEvent(getWheelEvent(), CWheelInfo::alloc(delta)); + return true; +} + +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; +} + + +bool +COSXScreen::onKey(EventRef event) const +{ + UInt32 eventKind = GetEventKind(event); + + KeyButton button; + GetEventParameter(event, kEventParamKeyCode, typeUInt32, + NULL, sizeof(button), NULL, &button); + + bool down = (eventKind == kEventRawKeyDown); + bool up = (eventKind == kEventRawKeyUp); + bool isRepeat = (eventKind == kEventRawKeyRepeat); + + LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button)); + + if (down) { + m_keyState->setKeyDown(button, true); + } + else if (up) { + m_keyState->setKeyDown(button, false); + } + + KeyModifierMask mask; + KeyID key = m_keyState->mapKeyFromEvent(event, &mask); + + m_keyState->sendKeyEvent(getEventTarget(), down, isRepeat, + key, mask, 0, button); + + return true; +} + +ButtonID +COSXScreen::mapMacButtonToSynergy(UInt16 macButton) const +{ + switch (macButton) { + case 1: + return kButtonLeft; + + case 2: + return kButtonRight; + + case 3: + return kButtonMiddle; + } + + return kButtonNone; } void @@ -574,7 +899,7 @@ COSXScreen::updateScreenShape() m_xCenter = m_x + (m_w >> 1); m_yCenter = m_y + (m_h >> 1); - LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d on %u %s", m_x, m_y, m_w, m_h, displayCount, (displayCount == 1) ? "display" : "displays")); - free(displays); + + LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d on %u %s", m_x, m_y, m_w, m_h, displayCount, (displayCount == 1) ? "display" : "displays")); } diff --git a/lib/platform/COSXScreen.h b/lib/platform/COSXScreen.h index 12aca416..dc61af3e 100644 --- a/lib/platform/COSXScreen.h +++ b/lib/platform/COSXScreen.h @@ -28,11 +28,6 @@ public: COSXScreen(bool isPrimary); virtual ~COSXScreen(); - //! @name manipulators - //@{ - - //@} - // IScreen overrides virtual void* getEventTarget() const; virtual bool getClipboard(ClipboardID id, IClipboard*) const; @@ -79,8 +74,28 @@ private: void postMouseEvent(const CGPoint &) const; // convenience function to send events - void sendEvent(CEvent::Type type, void* = NULL); - void sendClipboardEvent(CEvent::Type type, ClipboardID id); + void sendEvent(CEvent::Type type, void* = NULL) const; + void sendClipboardEvent(CEvent::Type type, ClipboardID id) const; + + // message handlers + bool onMouseMove(SInt32 x, SInt32 y); + // mouse button handler. pressed is true if this is a mousedown + // event, false if it is a mouseup event. macButton is the index + // of the button pressed using the mac button mapping. + bool onMouseButton(bool pressed, UInt16 macButton) const; + bool onMouseWheel(SInt32 delta) const; + + bool onDisplayChange(); + + bool onKey(EventRef event) const; + + // map mac mouse button to synergy buttons + ButtonID mapMacButtonToSynergy(UInt16) const; + + /// Resolution switch callback + static pascal void displayManagerCallback(void* inUserData, + SInt16 inMessage, void* inNotifyData); + private: // true if screen is being used as a primary screen, false otherwise @@ -115,6 +130,17 @@ private: // clipboard stuff bool m_ownClipboard; + + // window object that gets user input events when the server + // has focus. + WindowRef m_hiddenWindow; + // window object that gets user input events when the server + // does not have focus. + WindowRef m_userInputWindow; + + // display manager stuff (to get screen resolution switches). + DMExtendedNotificationUPP m_displayManagerNotificationUPP; + ProcessSerialNumber m_PSN; }; #endif diff --git a/synergy.xcode/project.pbxproj b/synergy.xcode/project.pbxproj index 37e1c34e..0e9f1125 100644 --- a/synergy.xcode/project.pbxproj +++ b/synergy.xcode/project.pbxproj @@ -71,6 +71,8 @@ //084 08FB7793FE84155DC02AAC07 = { buildSettings = { + MACOSX_DEPLOYMENT_TARGET = 10.2; + SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk; }; buildStyles = ( 014CEA460018CE2711CA2923, @@ -186,6 +188,7 @@ files = ( 4C537F15064E293000D3815C, 4C537F17064E293000D3815C, + 4C7D7CDA066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -214,6 +217,7 @@ GCC_WARN_UNKNOWN_PRAGMAS = NO; HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io ./lib/net ./lib/synergy ./lib/platform ./lib/client"; INSTALL_PATH = /usr/local/bin; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -455,6 +459,7 @@ 4C537F51064E2A0F00D3815C, 4C537F53064E2A0F00D3815C, 4C537F55064E2A0F00D3815C, + 4C7D7CE4066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -489,6 +494,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io ./lib/net ./lib/synergy ./lib/platform"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -874,6 +880,7 @@ 4C5E868A0648C2ED003C637B = { buildActionMask = 2147483647; files = ( + 4C7D7CDD066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -900,6 +907,7 @@ GCC_WARN_UNKNOWN_PRAGMAS = NO; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -1328,6 +1336,7 @@ }; 4C5E86CA0648C6FB003C637B = { children = ( + 4C7D7CD9066319560097CA11, 4C5E86CB0648C725003C637B, ); isa = PBXGroup; @@ -3246,11 +3255,93 @@ settings = { }; }; + 4C7D7CD9066319560097CA11 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = common.h; + path = lib/common/common.h; + refType = 4; + sourceTree = ""; + }; + 4C7D7CDA066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CDB066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CDC066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CDD066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CDE066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CDF066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE0066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE1066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE2066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE3066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE4066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; + 4C7D7CE5066319560097CA11 = { + fileRef = 4C7D7CD9066319560097CA11; + isa = PBXBuildFile; + settings = { + }; + }; 4CB43775063E406A00969041 = { buildActionMask = 2147483647; files = ( 4C5E87BE0648C969003C637B, 4C5E87C00648C969003C637B, + 4C7D7CE5066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3279,6 +3370,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io ./lib/net ./lib/synergy ./lib/platform"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3365,6 +3457,7 @@ 4C5E86BF0648C412003C637B, 4C5E86C30648C653003C637B, 4C5E86C70648C6B7003C637B, + 4C7D7CDC066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3405,6 +3498,7 @@ HEADER_SEARCH_PATHS = ./lib/common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3452,6 +3546,7 @@ 4C5E87090648C7B9003C637B, 4C5E870A0648C7B9003C637B, 4C5E870C0648C7B9003C637B, + 4C7D7CDE066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3489,6 +3584,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3580,6 +3676,7 @@ 4C5E871F0648C809003C637B, 4C5E87210648C809003C637B, 4C5E87220648C809003C637B, + 4C7D7CDF066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3610,6 +3707,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3658,6 +3756,7 @@ 4C5E87310648C83C003C637B, 4C5E87320648C83C003C637B, 4C5E87340648C83C003C637B, + 4C7D7CE0066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3687,6 +3786,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3725,6 +3825,7 @@ 4C5E875B0648C870003C637B, 4C5E875C0648C870003C637B, 4C5E875E0648C870003C637B, + 4C7D7CE1066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3759,6 +3860,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3876,6 +3978,7 @@ 4C5E879C0648C8BD003C637B, 4C5E879E0648C8BD003C637B, 4C5E87A00648C8BD003C637B, + 4C7D7CE2066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -3914,6 +4017,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io ./lib/net"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -3972,6 +4076,7 @@ 4CD034960650B6F100525ED1, 4CD034980650B6F100525ED1, 4CD0349A0650B6F100525ED1, + 4C7D7CE3066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -4006,6 +4111,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io /lib/synergy"; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; @@ -4034,6 +4140,7 @@ files = ( 4C5E87C70648C9D2003C637B, 4C5E87C90648C9D2003C637B, + 4C7D7CDB066319560097CA11, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -4064,6 +4171,7 @@ HEADER_SEARCH_PATHS = "./lib/common ./lib/arch ./lib/base ./lib/mt ./lib/io ./lib/net ./lib/synergy ./lib/platform ./lib/client"; INSTALL_PATH = /usr/local/bin; LIBRARY_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.2; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = "";