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.
This commit is contained in:
Sorin Sbarnea 2009-04-24 09:14:03 +00:00
parent 8175f9aac7
commit e69caf4d8b
12 changed files with 135 additions and 284 deletions

View File

@ -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"

View File

@ -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,
getOwnershipFlavor(),
kScrapFlavorMaskNone,
UInt8 claimString[] = {'s', 'y', 'n', 'e'};
CFDataRef claimData = CFDataCreate(kCFAllocatorDefault, claimString, 4);
err = PasteboardPutItemFlavor(
m_pboard,
0,
0);
getOwnershipFlavor(),
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");
}

View File

@ -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

View File

@ -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;

View File

@ -29,10 +29,10 @@ COSXClipboardTextConverter::~COSXClipboardTextConverter()
// do nothing
}
ScrapFlavorType
CFStringRef
COSXClipboardTextConverter::getOSXFormat() const
{
return kScrapFlavorTypeText;
return CFSTR("public.plain-text");
}
CString

View File

@ -24,7 +24,7 @@ public:
virtual ~COSXClipboardTextConverter();
// IOSXClipboardAnyTextConverter overrides
virtual ScrapFlavorType
virtual CFStringRef
getOSXFormat() const;
protected:

View File

@ -29,10 +29,10 @@ COSXClipboardUTF16Converter::~COSXClipboardUTF16Converter()
// do nothing
}
ScrapFlavorType
CFStringRef
COSXClipboardUTF16Converter::getOSXFormat() const
{
return kScrapFlavorTypeUnicode;
return CFSTR("public.utf16-plain-text");
}
CString

View File

@ -24,7 +24,7 @@ public:
virtual ~COSXClipboardUTF16Converter();
// IOSXClipboardAnyTextConverter overrides
virtual ScrapFlavorType
virtual CFStringRef
getOSXFormat() const;
protected:

View File

@ -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<UInt16>((modifiers & 0xff00u) | (vkCode & 0x00ffu));
// translate key
UInt32 result = KeyTranslate(resource, keycode, &m_deadKeyState);
// get the characters
UInt8 c1 = static_cast<UInt8>((result >> 16) & 0xffu);
UInt8 c2 = static_cast<UInt8>( 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);
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<char>(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<const KCHRResource*>(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<const CKCHRDeadKeys*>(
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<const CKCHRDeadKeyRecord*>(
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<const UInt8*>(m_resource);
const UCKeyOutput c = reinterpret_cast<const UCKeyOutput*>(base +
m_cti->keyToCharTableOffsets[table])[button];
const UCKeyOutput* cPtr = reinterpret_cast<const UCKeyOutput*>(base +
m_cti->keyToCharTableOffsets[table]);
const UCKeyOutput c = cPtr[button];
KeySequence keys;
switch (c & kUCKeyOutputTestForIndexMask) {

View File

@ -90,7 +90,7 @@ protected:
private:
class CKeyResource;
typedef std::vector<KeyboardLayoutRef> GroupList;
typedef std::vector<TISInputSourceRef> 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<KeyboardLayoutRef, SInt32> GroupMap;
typedef std::map<TISInputSourceRef, SInt32> GroupMap;
typedef std::map<UInt32, KeyID> CVirtualKeyMap;
CVirtualKeyMap m_virtualKeyMap;

View File

@ -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<COSXScreen>(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

View File

@ -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