From e69caf4d8b71071bae3b83fac248d88de770c6b7 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Fri, 24 Apr 2009 09:14:03 +0000 Subject: [PATCH] I integrated the synergy.10.5.patch - now it does use new API (10.5) Fixed issue #33: Modernize support for various MacOS APIs to their 10.5 equivalents. --- configure.in | 2 +- lib/platform/COSXClipboard.cpp | 93 +++++----- lib/platform/COSXClipboard.h | 6 +- lib/platform/COSXClipboardAnyTextConverter.h | 2 +- lib/platform/COSXClipboardTextConverter.cpp | 4 +- lib/platform/COSXClipboardTextConverter.h | 2 +- lib/platform/COSXClipboardUTF16Converter.cpp | 4 +- lib/platform/COSXClipboardUTF16Converter.h | 2 +- lib/platform/COSXKeyState.cpp | 177 ++++--------------- lib/platform/COSXKeyState.h | 39 +--- lib/platform/COSXScreen.cpp | 79 ++++----- lib/platform/COSXScreen.h | 9 +- 12 files changed, 135 insertions(+), 284 deletions(-) diff --git a/configure.in b/configure.in index 14367546..0c439399 100644 --- a/configure.in +++ b/configure.in @@ -254,7 +254,7 @@ dnl XXX depends on the language) to insert setting the environment dnl variable when running the compiler. we'd like to put that in CC, dnl CXX and OBJC but that breaks depcomp. let's hope this works. if test x"$acx_host_winapi" = xCARBON; then - MACOSX_DEPLOYMENT_TARGET="10.2" + MACOSX_DEPLOYMENT_TARGET="10.5" CCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CCDEPMODE" CXXDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CXXDEPMODE" OBJCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $OBJCDEPMODE" diff --git a/lib/platform/COSXClipboard.cpp b/lib/platform/COSXClipboard.cpp index 7d39eaad..3fdfb479 100644 --- a/lib/platform/COSXClipboard.cpp +++ b/lib/platform/COSXClipboard.cpp @@ -24,7 +24,7 @@ COSXClipboard::COSXClipboard() : m_time(0), - m_scrap(NULL) + m_pboard(NULL) { m_converters.push_back(new COSXClipboardUTF16Converter); m_converters.push_back(new COSXClipboardTextConverter); @@ -39,23 +39,27 @@ bool COSXClipboard::empty() { LOG((CLOG_DEBUG "empty clipboard")); - assert(m_scrap != NULL); + assert(m_pboard != NULL); - OSStatus err = ClearScrap(&m_scrap); + OSStatus err = PasteboardClear(m_pboard); if (err != noErr) { LOG((CLOG_DEBUG "failed to grab clipboard")); return false; } + // we own the clipboard - err = PutScrapFlavor( - m_scrap, + UInt8 claimString[] = {'s', 'y', 'n', 'e'}; + CFDataRef claimData = CFDataCreate(kCFAllocatorDefault, claimString, 4); + + err = PasteboardPutItemFlavor( + m_pboard, + 0, getOwnershipFlavor(), - kScrapFlavorMaskNone, - 0, - 0); + claimData, + kPasteboardFlavorNoFlags); if (err != noErr) { - LOG((CLOG_DEBUG "failed to grab clipboard")); + LOG((CLOG_DEBUG "failed to grab clipboard (%d)", err)); return false; } @@ -75,14 +79,16 @@ COSXClipboard::add(EFormat format, const CString & data) // skip converters for other formats if (converter->getFormat() == format) { CString osXData = converter->fromIClipboard(data); - ScrapFlavorType flavorType = converter->getOSXFormat(); + CFStringRef flavorType = converter->getOSXFormat(); + CFDataRef data_ref = CFDataCreate(kCFAllocatorDefault, (UInt8 *)osXData.data(), osXData.size()); - PutScrapFlavor( - m_scrap, + PasteboardPutItemFlavor( + m_pboard, + (PasteboardItemID) 1, flavorType, - kScrapFlavorMaskNone, - osXData.size(), - osXData.data()); + data_ref, + kPasteboardFlavorNoFlags); + LOG((CLOG_DEBUG "added %d bytes to clipboard format: %d", data.size(), format)); } } } @@ -92,7 +98,7 @@ COSXClipboard::open(Time time) const { LOG((CLOG_DEBUG "open clipboard")); m_time = time; - OSStatus err = GetCurrentScrap(&m_scrap); + OSStatus err = PasteboardCreate(kPasteboardClipboard, &m_pboard); return (err == noErr); } @@ -100,7 +106,7 @@ void COSXClipboard::close() const { LOG((CLOG_DEBUG "close clipboard")); - m_scrap = NULL; + m_pboard = NULL; } IClipboard::Time @@ -112,16 +118,16 @@ COSXClipboard::getTime() const bool COSXClipboard::has(EFormat format) const { - assert(m_scrap != NULL); + assert(m_pboard != NULL); for (ConverterList::const_iterator index = m_converters.begin(); index != m_converters.end(); ++index) { IOSXClipboardConverter* converter = *index; if (converter->getFormat() == format) { - ScrapFlavorFlags flags; - ScrapFlavorType type = converter->getOSXFormat(); + PasteboardFlavorFlags* flags = NULL; + CFStringRef type = converter->getOSXFormat(); - if (GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) { + if (PasteboardGetItemFlavorFlags(m_pboard, (void *)1, type, flags) == noErr) { return true; } } @@ -134,6 +140,7 @@ CString COSXClipboard::get(EFormat format) const { CString result; + CFStringRef type; // find the converter for the first clipboard format we can handle IOSXClipboardConverter* converter = NULL; @@ -141,11 +148,11 @@ COSXClipboard::get(EFormat format) const index != m_converters.end(); ++index) { converter = *index; - ScrapFlavorFlags flags; - ScrapFlavorType type = converter->getOSXFormat(); + PasteboardFlavorFlags* flags = NULL; + type = converter->getOSXFormat(); if (converter->getFormat() == format && - GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) { + PasteboardGetItemFlavorFlags(m_pboard, (void *)1, type, flags) == noErr) { break; } converter = NULL; @@ -157,27 +164,16 @@ COSXClipboard::get(EFormat format) const } // get the clipboard data. - char* buffer = NULL; + CFDataRef buffer = NULL; try { - Size flavorSize; - OSStatus err = GetScrapFlavorSize(m_scrap, - converter->getOSXFormat(), &flavorSize); + OSStatus err = PasteboardCopyItemFlavorData(m_pboard, (void *)1, + type, &buffer); + if (err != noErr) { throw err; } - buffer = new char[flavorSize]; - if (buffer == NULL) { - throw memFullErr; - } - - err = GetScrapFlavorData(m_scrap, - converter->getOSXFormat(), &flavorSize, buffer); - if (err != noErr) { - throw err; - } - - result = CString(buffer, flavorSize); + result = CString((char *) CFDataGetBytePtr(buffer), CFDataGetLength(buffer)); } catch (OSStatus err) { LOG((CLOG_DEBUG "exception thrown in COSXClipboard::get MacError (%d)", err)); @@ -186,7 +182,9 @@ COSXClipboard::get(EFormat format) const LOG((CLOG_DEBUG "unknown exception in COSXClipboard::get")); RETHROW_XTHREAD } - delete[] buffer; + + if (buffer != NULL) + CFRelease(buffer); return converter->toIClipboard(result); } @@ -204,17 +202,18 @@ COSXClipboard::clearConverters() bool COSXClipboard::isOwnedBySynergy() { - ScrapFlavorFlags flags; - ScrapRef scrap; - OSStatus err = GetCurrentScrap(&scrap); + PasteboardFlavorFlags flags; + PasteboardRef pboard; + OSStatus err = PasteboardCreate(kPasteboardClipboard, &pboard); if (err == noErr) { - err = GetScrapFlavorFlags(scrap, getOwnershipFlavor() , &flags); + err = PasteboardGetItemFlavorFlags(pboard, 0, getOwnershipFlavor() , &flags); } return (err == noErr); } -ScrapFlavorType +CFStringRef COSXClipboard::getOwnershipFlavor() { - return 'Syne'; + return CFSTR("Syne"); } + diff --git a/lib/platform/COSXClipboard.h b/lib/platform/COSXClipboard.h index 19f95ec7..a086205e 100644 --- a/lib/platform/COSXClipboard.h +++ b/lib/platform/COSXClipboard.h @@ -41,7 +41,7 @@ public: private: void clearConverters(); - static ScrapFlavorType + static CFStringRef getOwnershipFlavor(); private: @@ -49,7 +49,7 @@ private: mutable Time m_time; ConverterList m_converters; - mutable ScrapRef m_scrap; + mutable PasteboardRef m_pboard; }; //! Clipboard format converter interface @@ -69,7 +69,7 @@ public: getFormat() const = 0; //! returns the scrap flavor type that this object converts from/to - virtual ScrapFlavorType + virtual CFStringRef getOSXFormat() const = 0; //! Convert from IClipboard format diff --git a/lib/platform/COSXClipboardAnyTextConverter.h b/lib/platform/COSXClipboardAnyTextConverter.h index 5d0b79f3..fe2eb9bf 100644 --- a/lib/platform/COSXClipboardAnyTextConverter.h +++ b/lib/platform/COSXClipboardAnyTextConverter.h @@ -26,7 +26,7 @@ public: // IOSXClipboardConverter overrides virtual IClipboard::EFormat getFormat() const; - virtual ScrapFlavorType + virtual CFStringRef getOSXFormat() const = 0; virtual CString fromIClipboard(const CString &) const; virtual CString toIClipboard(const CString &) const; diff --git a/lib/platform/COSXClipboardTextConverter.cpp b/lib/platform/COSXClipboardTextConverter.cpp index bcbc228e..03c3a4f3 100644 --- a/lib/platform/COSXClipboardTextConverter.cpp +++ b/lib/platform/COSXClipboardTextConverter.cpp @@ -29,10 +29,10 @@ COSXClipboardTextConverter::~COSXClipboardTextConverter() // do nothing } -ScrapFlavorType +CFStringRef COSXClipboardTextConverter::getOSXFormat() const { - return kScrapFlavorTypeText; + return CFSTR("public.plain-text"); } CString diff --git a/lib/platform/COSXClipboardTextConverter.h b/lib/platform/COSXClipboardTextConverter.h index 2a75f4f0..d71a0923 100644 --- a/lib/platform/COSXClipboardTextConverter.h +++ b/lib/platform/COSXClipboardTextConverter.h @@ -24,7 +24,7 @@ public: virtual ~COSXClipboardTextConverter(); // IOSXClipboardAnyTextConverter overrides - virtual ScrapFlavorType + virtual CFStringRef getOSXFormat() const; protected: diff --git a/lib/platform/COSXClipboardUTF16Converter.cpp b/lib/platform/COSXClipboardUTF16Converter.cpp index 10693c83..908f91b6 100644 --- a/lib/platform/COSXClipboardUTF16Converter.cpp +++ b/lib/platform/COSXClipboardUTF16Converter.cpp @@ -29,10 +29,10 @@ COSXClipboardUTF16Converter::~COSXClipboardUTF16Converter() // do nothing } -ScrapFlavorType +CFStringRef COSXClipboardUTF16Converter::getOSXFormat() const { - return kScrapFlavorTypeUnicode; + return CFSTR("public.utf16-plain-text"); } CString diff --git a/lib/platform/COSXClipboardUTF16Converter.h b/lib/platform/COSXClipboardUTF16Converter.h index 1499a7ed..9a114b3b 100644 --- a/lib/platform/COSXClipboardUTF16Converter.h +++ b/lib/platform/COSXClipboardUTF16Converter.h @@ -24,7 +24,7 @@ public: virtual ~COSXClipboardUTF16Converter(); // IOSXClipboardAnyTextConverter overrides - virtual ScrapFlavorType + virtual CFStringRef getOSXFormat() const; protected: diff --git a/lib/platform/COSXKeyState.cpp b/lib/platform/COSXKeyState.cpp index e904d5e4..0435be40 100644 --- a/lib/platform/COSXKeyState.cpp +++ b/lib/platform/COSXKeyState.cpp @@ -118,8 +118,6 @@ static const CKeyEntry s_controlKeys[] = { COSXKeyState::COSXKeyState() : m_deadKeyState(0) { - // enable input in scripts other that roman - KeyScript(smKeyEnableKybds); // build virtual key map for (size_t i = 0; i < sizeof(s_controlKeys) / @@ -208,9 +206,9 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids, } // get keyboard info - KeyboardLayoutRef keyboardLayout; - OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout); - if (status != noErr) { + + TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); + if (currentKeyboardLayout != NULL) { return kKeyNone; } @@ -231,9 +229,9 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids, } // translate via uchr resource - const void* resource; - if (KLGetKeyboardLayoutProperty(keyboardLayout, - kKLuchrData, &resource) == noErr) { + CFDataRef resource; + if ((resource = (CFDataRef)TISGetInputSourceProperty(currentKeyboardLayout, + kTISPropertyUnicodeKeyLayoutData)) != NULL) { // choose action UInt16 action; switch (eventKind) { @@ -272,30 +270,6 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids, } } - // translate via KCHR resource - if (KLGetKeyboardLayoutProperty(keyboardLayout, - kKLKCHRData, &resource) == noErr) { - // build keycode - UInt16 keycode = - static_cast((modifiers & 0xff00u) | (vkCode & 0x00ffu)); - - // translate key - UInt32 result = KeyTranslate(resource, keycode, &m_deadKeyState); - - // get the characters - UInt8 c1 = static_cast((result >> 16) & 0xffu); - UInt8 c2 = static_cast( result & 0xffu); - if (c2 != 0) { - m_deadKeyState = 0; - if (c1 != 0) { - ids.push_back(CKeyResource::getKeyID(c1)); - } - ids.push_back(CKeyResource::getKeyID(c2)); - adjustAltGrModifier(ids, maskOut, isCommand); - return mapVirtualKeyToKeyButton(vkCode); - } - } - return 0; } @@ -315,14 +289,11 @@ COSXKeyState::pollActiveModifiers() const SInt32 COSXKeyState::pollActiveGroup() const { - KeyboardLayoutRef keyboardLayout; - OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout); - if (status == noErr) { - GroupMap::const_iterator i = m_groupMap.find(keyboardLayout); - if (i != m_groupMap.end()) { - return i->second; - } - } + TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource(); + GroupMap::const_iterator i = m_groupMap.find(inputSource); + if (i != m_groupMap.end()) { + return i->second; + } return 0; } @@ -358,12 +329,10 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap) // add special keys getKeyMapForSpecialKeys(keyMap, g); - // add regular keys - - // try uchr resource first - const void* resource; - if (KLGetKeyboardLayoutProperty(m_groups[g], - kKLuchrData, &resource) == noErr) { + CFDataRef resource_ref; + if ((resource_ref = (CFDataRef)TISGetInputSourceProperty(m_groups[g], + kTISPropertyUnicodeKeyLayoutData)) != NULL) { + const void* resource = CFDataGetBytePtr(resource_ref); CUCHRKeyResource uchr(resource, keyboardType); if (uchr.isValid()) { LOG((CLOG_DEBUG1 "using uchr resource for group %d", g)); @@ -372,17 +341,6 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap) } } - // 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; - } - } - LOG((CLOG_DEBUG1 "no keyboard resource for group %d", g)); } } @@ -651,21 +609,22 @@ bool COSXKeyState::getGroups(GroupList& groups) const { // get number of layouts - CFIndex n; - OSStatus status = KLGetKeyboardLayoutCount(&n); - if (status != noErr) { + 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) { LOG((CLOG_DEBUG1 "can't get keyboard layouts")); return false; } // get each layout groups.clear(); + TISInputSourceRef inputKeyboardLayout; for (CFIndex i = 0; i < n; ++i) { - KeyboardLayoutRef keyboardLayout; - status = KLGetKeyboardLayoutAtIndex(i, &keyboardLayout); - if (status == noErr) { - groups.push_back(keyboardLayout); - } + inputKeyboardLayout = (TISInputSourceRef) CFArrayGetValueAtIndex(kbds, i); + groups.push_back(inputKeyboardLayout); } return true; } @@ -673,7 +632,7 @@ COSXKeyState::getGroups(GroupList& groups) const void COSXKeyState::setGroup(SInt32 group) { - KLSetCurrentKeyboardLayout(m_groups[group]); + TISSetInputMethodKeyboardLayoutOverride(m_groups[group]); } void @@ -818,10 +777,15 @@ COSXKeyState::CKeyResource::getKeyID(UInt8 c) str[0] = static_cast(c); str[1] = 0; + // get current keyboard script + + TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource(); + CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages); + // convert to unicode CFStringRef cfString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, - str, GetScriptManagerVariable(smKeyScript), + str, CFStringConvertIANACharSetNameToEncoding((CFStringRef) CFArrayGetValueAtIndex(langs, 0)), kCFAllocatorNull); // sometimes CFStringCreate...() returns NULL (e.g. Apple Korean @@ -889,79 +853,6 @@ COSXKeyState::CKeyResource::unicharToKeyID(UniChar c) } -// -// COSXKeyState::CKCHRKeyResource -// - -COSXKeyState::CKCHRKeyResource::CKCHRKeyResource(const void* resource) -{ - m_resource = reinterpret_cast(resource); -} - -bool -COSXKeyState::CKCHRKeyResource::isValid() const -{ - return (m_resource != NULL); -} - -UInt32 -COSXKeyState::CKCHRKeyResource::getNumModifierCombinations() const -{ - // only 32 (not 256) because the righthanded modifier bits are ignored - return 32; -} - -UInt32 -COSXKeyState::CKCHRKeyResource::getNumTables() const -{ - return m_resource->m_numTables; -} - -UInt32 -COSXKeyState::CKCHRKeyResource::getNumButtons() const -{ - return 128; -} - -UInt32 -COSXKeyState::CKCHRKeyResource::getTableForModifier(UInt32 mask) const -{ - assert(mask < getNumModifierCombinations()); - - return m_resource->m_tableSelectionIndex[mask]; -} - -KeyID -COSXKeyState::CKCHRKeyResource::getKey(UInt32 table, UInt32 button) const -{ - assert(table < getNumTables()); - assert(button < getNumButtons()); - - UInt8 c = m_resource->m_characterTables[table][button]; - if (c == 0) { - // could be a dead key - const CKCHRDeadKeys* dkp = - reinterpret_cast( - m_resource->m_characterTables[getNumTables()]); - const CKCHRDeadKeyRecord* dkr = dkp->m_records; - for (SInt16 i = 0; i < dkp->m_numRecords; ++i) { - if (dkr->m_tableIndex == table && dkr->m_virtualKey == button) { - // get the no completion entry - c = dkr->m_completion[dkr->m_numCompletions][1]; - return CKeyMap::getDeadKey(getKeyID(c)); - } - - // next table. skip all the completions and the no match - // pair to get the next table. - dkr = reinterpret_cast( - dkr->m_completion[dkr->m_numCompletions + 1]); - } - } - - return getKeyID(c); -} - - // // COSXKeyState::CUCHRKeyResource // @@ -1078,8 +969,10 @@ COSXKeyState::CUCHRKeyResource::getKey(UInt32 table, UInt32 button) const assert(button < getNumButtons()); const UInt8* base = reinterpret_cast(m_resource); - const UCKeyOutput c = reinterpret_cast(base + - m_cti->keyToCharTableOffsets[table])[button]; + const UCKeyOutput* cPtr = reinterpret_cast(base + + m_cti->keyToCharTableOffsets[table]); + + const UCKeyOutput c = cPtr[button]; KeySequence keys; switch (c & kUCKeyOutputTestForIndexMask) { diff --git a/lib/platform/COSXKeyState.h b/lib/platform/COSXKeyState.h index baf69713..775d3f19 100644 --- a/lib/platform/COSXKeyState.h +++ b/lib/platform/COSXKeyState.h @@ -90,7 +90,7 @@ protected: private: class CKeyResource; - typedef std::vector GroupList; + typedef std::vector GroupList; // Add hard coded special keys to a CKeyMap. void getKeyMapForSpecialKeys( @@ -149,41 +149,6 @@ private: static KeyID unicharToKeyID(UniChar); }; - class CKCHRKeyResource : public CKeyResource { - public: - CKCHRKeyResource(const void*); - - // CKeyResource overrides - virtual bool isValid() const; - virtual UInt32 getNumModifierCombinations() const; - virtual UInt32 getNumTables() const; - virtual UInt32 getNumButtons() const; - virtual UInt32 getTableForModifier(UInt32 mask) const; - virtual KeyID getKey(UInt32 table, UInt32 button) const; - - private: - struct KCHRResource { - public: - SInt16 m_version; - UInt8 m_tableSelectionIndex[256]; - SInt16 m_numTables; - UInt8 m_characterTables[1][128]; - }; - struct CKCHRDeadKeyRecord { - public: - UInt8 m_tableIndex; - UInt8 m_virtualKey; - SInt16 m_numCompletions; - UInt8 m_completion[1][2]; - }; - struct CKCHRDeadKeys { - public: - SInt16 m_numRecords; - CKCHRDeadKeyRecord m_records[1]; - }; - - const KCHRResource* m_resource; - }; class CUCHRKeyResource : public CKeyResource { public: @@ -223,7 +188,7 @@ private: KeyButtonOffset = 1 }; - typedef std::map GroupMap; + typedef std::map GroupMap; typedef std::map CVirtualKeyMap; CVirtualKeyMap m_virtualKeyMap; diff --git a/lib/platform/COSXScreen.cpp b/lib/platform/COSXScreen.cpp index 82574cf4..73377911 100644 --- a/lib/platform/COSXScreen.cpp +++ b/lib/platform/COSXScreen.cpp @@ -73,7 +73,6 @@ COSXScreen::COSXScreen(bool isPrimary) : m_clipboardTimer(NULL), m_hiddenWindow(NULL), m_userInputWindow(NULL), - m_displayManagerNotificationUPP(NULL), m_switchEventHandlerRef(0), m_pmMutex(new CMutex), m_pmWatchThread(NULL), @@ -83,7 +82,7 @@ COSXScreen::COSXScreen(bool isPrimary) : { try { m_displayID = CGMainDisplayID(); - updateScreenShape(); + updateScreenShape(m_displayID, 0); m_screensaver = new COSXScreenSaver(getEventTarget()); m_keyState = new COSXKeyState(); @@ -123,11 +122,8 @@ COSXScreen::COSXScreen(bool isPrimary) : } // install display manager notification handler - m_displayManagerNotificationUPP = - NewDMExtendedNotificationUPP(displayManagerCallback); - OSStatus err = GetCurrentProcess(&m_PSN); - err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP, - this, 0, &m_PSN); + GetCurrentProcess(&m_PSN); + CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, &m_PSN); // install fast user switching event handler EventTypeSpec switchEventTypes[2]; @@ -158,18 +154,15 @@ COSXScreen::COSXScreen(bool isPrimary) : if (m_switchEventHandlerRef != 0) { RemoveEventHandler(m_switchEventHandlerRef); } - if (m_displayManagerNotificationUPP != NULL) { - DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, - NULL, &m_PSN, 0); - } + CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, &m_PSN); if (m_hiddenWindow) { - ReleaseWindow(m_hiddenWindow); + CFRelease(m_hiddenWindow); m_hiddenWindow = NULL; } if (m_userInputWindow) { - ReleaseWindow(m_userInputWindow); + CFRelease(m_userInputWindow); m_userInputWindow = NULL; } delete m_keyState; @@ -216,16 +209,14 @@ COSXScreen::~COSXScreen() RemoveEventHandler(m_switchEventHandlerRef); - DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, - NULL, &m_PSN, 0); - + CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, &m_PSN); if (m_hiddenWindow) { - ReleaseWindow(m_hiddenWindow); + CFRelease(m_hiddenWindow); m_hiddenWindow = NULL; } if (m_userInputWindow) { - ReleaseWindow(m_userInputWindow); + CFRelease(m_userInputWindow); m_userInputWindow = NULL; } @@ -614,7 +605,7 @@ COSXScreen::enter() CGSetLocalEventsSuppressionInterval(0.0); // enable global hotkeys - setGlobalHotKeysEnabled(true); + //setGlobalHotKeysEnabled(true); } else { // show cursor @@ -664,7 +655,7 @@ COSXScreen::leave() CGSetLocalEventsSuppressionInterval(0.0001); // disable global hotkeys - setGlobalHotKeysEnabled(false); + //setGlobalHotKeysEnabled(false); } else { // hide cursor @@ -1061,26 +1052,24 @@ COSXScreen::handleClipboardCheck(const CEvent&, void*) } pascal void -COSXScreen::displayManagerCallback(void* inUserData, SInt16 inMessage, void*) +COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData) { COSXScreen* screen = (COSXScreen*)inUserData; - if (inMessage == kDMNotifyEvent) { - screen->onDisplayChange(); + if (flags & ~0x1 != 0) { /* Something actually did change */ + screen->onDisplayChange(displayID, flags); } } bool -COSXScreen::onDisplayChange() +COSXScreen::onDisplayChange(const CGDirectDisplayID dispID, const CGDisplayChangeSummaryFlags flags) { - // screen resolution may have changed. save old shape. - SInt32 xOld = m_x, yOld = m_y, wOld = m_w, hOld = m_h; // update shape - updateScreenShape(); + updateScreenShape(dispID, flags); // do nothing if resolution hasn't changed - if (xOld != m_x || yOld != m_y || wOld != m_w || hOld != m_h) { + if (flags | kCGDisplaySetModeFlag != 0) { if (m_isPrimary) { // warp mouse to center if off screen if (!m_isOnScreen) { @@ -1316,12 +1305,15 @@ COSXScreen::getScrollSpeedFactor() const void COSXScreen::enableDragTimer(bool enable) { + UInt32 modifiers; + MouseTrackingResult res; + if (enable && m_dragTimer == NULL) { m_dragTimer = EVENTQUEUE->newTimer(0.01, NULL); EVENTQUEUE->adoptHandler(CEvent::kTimer, m_dragTimer, new TMethodEventJob(this, &COSXScreen::handleDrag)); - GetMouse(&m_dragLastPoint); + TrackMouseLocationWithOptions(NULL, 0, 0, &m_dragLastPoint, &modifiers, &res); } else if (!enable && m_dragTimer != NULL) { EVENTQUEUE->removeHandler(CEvent::kTimer, m_dragTimer); @@ -1334,8 +1326,12 @@ void COSXScreen::handleDrag(const CEvent&, void*) { Point p; - GetMouse(&p); - if (p.h != m_dragLastPoint.h || p.v != m_dragLastPoint.v) { + UInt32 modifiers; + MouseTrackingResult res; + + TrackMouseLocationWithOptions(NULL, 0, 0, &p, &modifiers, &res); + + if (res != kMouseTrackingTimedOut && (p.h != m_dragLastPoint.h || p.v != m_dragLastPoint.v)) { m_dragLastPoint = p; onMouseMove((SInt32)p.h, (SInt32)p.v); } @@ -1357,7 +1353,7 @@ COSXScreen::getKeyState() const } void -COSXScreen::updateScreenShape() +COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags) { // get info for each display CGDisplayCount displayCount = 0; @@ -1395,16 +1391,10 @@ COSXScreen::updateScreenShape() m_h = (SInt32)totalBounds.size.height; // get center of default screen - GDHandle mainScreen = GetMainDevice(); - if (mainScreen != NULL) { - const Rect& rect = (*mainScreen)->gdRect; - m_xCenter = (rect.left + rect.right) / 2; - m_yCenter = (rect.top + rect.bottom) / 2; - } - else { - m_xCenter = m_x + (m_w >> 1); - m_yCenter = m_y + (m_h >> 1); - } + CGDirectDisplayID main = CGMainDisplayID(); + const CGRect rect = CGDisplayBounds(main); + m_xCenter = (rect.origin.x + rect.size.width) / 2; + m_yCenter = (rect.origin.y + rect.size.height) / 2; delete[] displays; @@ -1581,6 +1571,10 @@ COSXScreen::handleConfirmSleep(const CEvent& event, void*) // older SDKs to build an app that works on newer systems and older // SDKs will not provide the symbols. // +// FIXME: This is hosed as of OS 10.5; patches to repair this are +// a good thing. +// +#if 0 #ifdef __cplusplus extern "C" { @@ -1663,6 +1657,7 @@ COSXScreen::getGlobalHotKeysEnabled() return (mode == CGSGlobalHotKeyEnable); } +#endif // // COSXScreen::CHotKeyItem diff --git a/lib/platform/COSXScreen.h b/lib/platform/COSXScreen.h index f280d802..e688eb31 100644 --- a/lib/platform/COSXScreen.h +++ b/lib/platform/COSXScreen.h @@ -86,7 +86,7 @@ protected: virtual IKeyState* getKeyState() const; private: - void updateScreenShape(); + void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags); void postMouseEvent(CGPoint&) const; // convenience function to send events @@ -101,7 +101,7 @@ private: bool onMouseButton(bool pressed, UInt16 macButton); bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const; - bool onDisplayChange(); + bool onDisplayChange(CGDirectDisplayID, CGDisplayChangeSummaryFlags); bool onKey(EventRef event); bool onHotKey(EventRef event) const; @@ -131,8 +131,8 @@ private: void handleClipboardCheck(const CEvent&, void*); // Resolution switch callback - static pascal void displayManagerCallback(void* inUserData, - SInt16 inMessage, void* inNotifyData); + static void displayReconfigurationCallback(CGDirectDisplayID, + CGDisplayChangeSummaryFlags, void*); // fast user switch callback static pascal OSStatus @@ -220,7 +220,6 @@ private: WindowRef m_userInputWindow; // display manager stuff (to get screen resolution switches). - DMExtendedNotificationUPP m_displayManagerNotificationUPP; ProcessSerialNumber m_PSN; // fast user switching