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 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. dnl CXX and OBJC but that breaks depcomp. let's hope this works.
if test x"$acx_host_winapi" = xCARBON; then 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" CCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CCDEPMODE"
CXXDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CXXDEPMODE" CXXDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CXXDEPMODE"
OBJCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $OBJCDEPMODE" OBJCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $OBJCDEPMODE"

View File

@ -24,7 +24,7 @@
COSXClipboard::COSXClipboard() : COSXClipboard::COSXClipboard() :
m_time(0), m_time(0),
m_scrap(NULL) m_pboard(NULL)
{ {
m_converters.push_back(new COSXClipboardUTF16Converter); m_converters.push_back(new COSXClipboardUTF16Converter);
m_converters.push_back(new COSXClipboardTextConverter); m_converters.push_back(new COSXClipboardTextConverter);
@ -39,23 +39,27 @@ bool
COSXClipboard::empty() COSXClipboard::empty()
{ {
LOG((CLOG_DEBUG "empty clipboard")); 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) { if (err != noErr) {
LOG((CLOG_DEBUG "failed to grab clipboard")); LOG((CLOG_DEBUG "failed to grab clipboard"));
return false; return false;
} }
// we own the clipboard // we own the clipboard
err = PutScrapFlavor( UInt8 claimString[] = {'s', 'y', 'n', 'e'};
m_scrap, CFDataRef claimData = CFDataCreate(kCFAllocatorDefault, claimString, 4);
err = PasteboardPutItemFlavor(
m_pboard,
0,
getOwnershipFlavor(), getOwnershipFlavor(),
kScrapFlavorMaskNone, claimData,
0, kPasteboardFlavorNoFlags);
0);
if (err != noErr) { if (err != noErr) {
LOG((CLOG_DEBUG "failed to grab clipboard")); LOG((CLOG_DEBUG "failed to grab clipboard (%d)", err));
return false; return false;
} }
@ -75,14 +79,16 @@ COSXClipboard::add(EFormat format, const CString & data)
// skip converters for other formats // skip converters for other formats
if (converter->getFormat() == format) { if (converter->getFormat() == format) {
CString osXData = converter->fromIClipboard(data); CString osXData = converter->fromIClipboard(data);
ScrapFlavorType flavorType = converter->getOSXFormat(); CFStringRef flavorType = converter->getOSXFormat();
CFDataRef data_ref = CFDataCreate(kCFAllocatorDefault, (UInt8 *)osXData.data(), osXData.size());
PutScrapFlavor( PasteboardPutItemFlavor(
m_scrap, m_pboard,
(PasteboardItemID) 1,
flavorType, flavorType,
kScrapFlavorMaskNone, data_ref,
osXData.size(), kPasteboardFlavorNoFlags);
osXData.data()); 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")); LOG((CLOG_DEBUG "open clipboard"));
m_time = time; m_time = time;
OSStatus err = GetCurrentScrap(&m_scrap); OSStatus err = PasteboardCreate(kPasteboardClipboard, &m_pboard);
return (err == noErr); return (err == noErr);
} }
@ -100,7 +106,7 @@ void
COSXClipboard::close() const COSXClipboard::close() const
{ {
LOG((CLOG_DEBUG "close clipboard")); LOG((CLOG_DEBUG "close clipboard"));
m_scrap = NULL; m_pboard = NULL;
} }
IClipboard::Time IClipboard::Time
@ -112,16 +118,16 @@ COSXClipboard::getTime() const
bool bool
COSXClipboard::has(EFormat format) const COSXClipboard::has(EFormat format) const
{ {
assert(m_scrap != NULL); assert(m_pboard != NULL);
for (ConverterList::const_iterator index = m_converters.begin(); for (ConverterList::const_iterator index = m_converters.begin();
index != m_converters.end(); ++index) { index != m_converters.end(); ++index) {
IOSXClipboardConverter* converter = *index; IOSXClipboardConverter* converter = *index;
if (converter->getFormat() == format) { if (converter->getFormat() == format) {
ScrapFlavorFlags flags; PasteboardFlavorFlags* flags = NULL;
ScrapFlavorType type = converter->getOSXFormat(); CFStringRef type = converter->getOSXFormat();
if (GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) { if (PasteboardGetItemFlavorFlags(m_pboard, (void *)1, type, flags) == noErr) {
return true; return true;
} }
} }
@ -134,6 +140,7 @@ CString
COSXClipboard::get(EFormat format) const COSXClipboard::get(EFormat format) const
{ {
CString result; CString result;
CFStringRef type;
// find the converter for the first clipboard format we can handle // find the converter for the first clipboard format we can handle
IOSXClipboardConverter* converter = NULL; IOSXClipboardConverter* converter = NULL;
@ -141,11 +148,11 @@ COSXClipboard::get(EFormat format) const
index != m_converters.end(); ++index) { index != m_converters.end(); ++index) {
converter = *index; converter = *index;
ScrapFlavorFlags flags; PasteboardFlavorFlags* flags = NULL;
ScrapFlavorType type = converter->getOSXFormat(); type = converter->getOSXFormat();
if (converter->getFormat() == format && if (converter->getFormat() == format &&
GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) { PasteboardGetItemFlavorFlags(m_pboard, (void *)1, type, flags) == noErr) {
break; break;
} }
converter = NULL; converter = NULL;
@ -157,27 +164,16 @@ COSXClipboard::get(EFormat format) const
} }
// get the clipboard data. // get the clipboard data.
char* buffer = NULL; CFDataRef buffer = NULL;
try { try {
Size flavorSize; OSStatus err = PasteboardCopyItemFlavorData(m_pboard, (void *)1,
OSStatus err = GetScrapFlavorSize(m_scrap, type, &buffer);
converter->getOSXFormat(), &flavorSize);
if (err != noErr) { if (err != noErr) {
throw err; throw err;
} }
buffer = new char[flavorSize]; result = CString((char *) CFDataGetBytePtr(buffer), CFDataGetLength(buffer));
if (buffer == NULL) {
throw memFullErr;
}
err = GetScrapFlavorData(m_scrap,
converter->getOSXFormat(), &flavorSize, buffer);
if (err != noErr) {
throw err;
}
result = CString(buffer, flavorSize);
} }
catch (OSStatus err) { catch (OSStatus err) {
LOG((CLOG_DEBUG "exception thrown in COSXClipboard::get MacError (%d)", 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")); LOG((CLOG_DEBUG "unknown exception in COSXClipboard::get"));
RETHROW_XTHREAD RETHROW_XTHREAD
} }
delete[] buffer;
if (buffer != NULL)
CFRelease(buffer);
return converter->toIClipboard(result); return converter->toIClipboard(result);
} }
@ -204,17 +202,18 @@ COSXClipboard::clearConverters()
bool bool
COSXClipboard::isOwnedBySynergy() COSXClipboard::isOwnedBySynergy()
{ {
ScrapFlavorFlags flags; PasteboardFlavorFlags flags;
ScrapRef scrap; PasteboardRef pboard;
OSStatus err = GetCurrentScrap(&scrap); OSStatus err = PasteboardCreate(kPasteboardClipboard, &pboard);
if (err == noErr) { if (err == noErr) {
err = GetScrapFlavorFlags(scrap, getOwnershipFlavor() , &flags); err = PasteboardGetItemFlavorFlags(pboard, 0, getOwnershipFlavor() , &flags);
} }
return (err == noErr); return (err == noErr);
} }
ScrapFlavorType CFStringRef
COSXClipboard::getOwnershipFlavor() COSXClipboard::getOwnershipFlavor()
{ {
return 'Syne'; return CFSTR("Syne");
} }

View File

@ -41,7 +41,7 @@ public:
private: private:
void clearConverters(); void clearConverters();
static ScrapFlavorType static CFStringRef
getOwnershipFlavor(); getOwnershipFlavor();
private: private:
@ -49,7 +49,7 @@ private:
mutable Time m_time; mutable Time m_time;
ConverterList m_converters; ConverterList m_converters;
mutable ScrapRef m_scrap; mutable PasteboardRef m_pboard;
}; };
//! Clipboard format converter interface //! Clipboard format converter interface
@ -69,7 +69,7 @@ public:
getFormat() const = 0; getFormat() const = 0;
//! returns the scrap flavor type that this object converts from/to //! returns the scrap flavor type that this object converts from/to
virtual ScrapFlavorType virtual CFStringRef
getOSXFormat() const = 0; getOSXFormat() const = 0;
//! Convert from IClipboard format //! Convert from IClipboard format

View File

@ -26,7 +26,7 @@ public:
// IOSXClipboardConverter overrides // IOSXClipboardConverter overrides
virtual IClipboard::EFormat virtual IClipboard::EFormat
getFormat() const; getFormat() const;
virtual ScrapFlavorType virtual CFStringRef
getOSXFormat() const = 0; getOSXFormat() const = 0;
virtual CString fromIClipboard(const CString &) const; virtual CString fromIClipboard(const CString &) const;
virtual CString toIClipboard(const CString &) const; virtual CString toIClipboard(const CString &) const;

View File

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

View File

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

View File

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

View File

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

View File

@ -118,8 +118,6 @@ static const CKeyEntry s_controlKeys[] = {
COSXKeyState::COSXKeyState() : COSXKeyState::COSXKeyState() :
m_deadKeyState(0) m_deadKeyState(0)
{ {
// enable input in scripts other that roman
KeyScript(smKeyEnableKybds);
// build virtual key map // build virtual key map
for (size_t i = 0; i < sizeof(s_controlKeys) / for (size_t i = 0; i < sizeof(s_controlKeys) /
@ -208,9 +206,9 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
} }
// get keyboard info // get keyboard info
KeyboardLayoutRef keyboardLayout;
OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout); TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
if (status != noErr) { if (currentKeyboardLayout != NULL) {
return kKeyNone; return kKeyNone;
} }
@ -231,9 +229,9 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
} }
// translate via uchr resource // translate via uchr resource
const void* resource; CFDataRef resource;
if (KLGetKeyboardLayoutProperty(keyboardLayout, if ((resource = (CFDataRef)TISGetInputSourceProperty(currentKeyboardLayout,
kKLuchrData, &resource) == noErr) { kTISPropertyUnicodeKeyLayoutData)) != NULL) {
// choose action // choose action
UInt16 action; UInt16 action;
switch (eventKind) { 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; return 0;
} }
@ -315,14 +289,11 @@ COSXKeyState::pollActiveModifiers() const
SInt32 SInt32
COSXKeyState::pollActiveGroup() const COSXKeyState::pollActiveGroup() const
{ {
KeyboardLayoutRef keyboardLayout; TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource();
OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout); GroupMap::const_iterator i = m_groupMap.find(inputSource);
if (status == noErr) { if (i != m_groupMap.end()) {
GroupMap::const_iterator i = m_groupMap.find(keyboardLayout); return i->second;
if (i != m_groupMap.end()) { }
return i->second;
}
}
return 0; return 0;
} }
@ -358,12 +329,10 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
// add special keys // add special keys
getKeyMapForSpecialKeys(keyMap, g); getKeyMapForSpecialKeys(keyMap, g);
// add regular keys CFDataRef resource_ref;
if ((resource_ref = (CFDataRef)TISGetInputSourceProperty(m_groups[g],
// try uchr resource first kTISPropertyUnicodeKeyLayoutData)) != NULL) {
const void* resource; const void* resource = CFDataGetBytePtr(resource_ref);
if (KLGetKeyboardLayoutProperty(m_groups[g],
kKLuchrData, &resource) == noErr) {
CUCHRKeyResource uchr(resource, keyboardType); CUCHRKeyResource uchr(resource, keyboardType);
if (uchr.isValid()) { if (uchr.isValid()) {
LOG((CLOG_DEBUG1 "using uchr resource for group %d", g)); 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)); LOG((CLOG_DEBUG1 "no keyboard resource for group %d", g));
} }
} }
@ -651,21 +609,22 @@ bool
COSXKeyState::getGroups(GroupList& groups) const COSXKeyState::getGroups(GroupList& groups) const
{ {
// get number of layouts // get number of layouts
CFIndex n; CFStringRef keys[] = { kTISPropertyInputSourceCategory };
OSStatus status = KLGetKeyboardLayoutCount(&n); CFStringRef values[] = { kTISCategoryKeyboardInputSource };
if (status != noErr) { 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")); LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
return false; return false;
} }
// get each layout // get each layout
groups.clear(); groups.clear();
TISInputSourceRef inputKeyboardLayout;
for (CFIndex i = 0; i < n; ++i) { for (CFIndex i = 0; i < n; ++i) {
KeyboardLayoutRef keyboardLayout; inputKeyboardLayout = (TISInputSourceRef) CFArrayGetValueAtIndex(kbds, i);
status = KLGetKeyboardLayoutAtIndex(i, &keyboardLayout); groups.push_back(inputKeyboardLayout);
if (status == noErr) {
groups.push_back(keyboardLayout);
}
} }
return true; return true;
} }
@ -673,7 +632,7 @@ COSXKeyState::getGroups(GroupList& groups) const
void void
COSXKeyState::setGroup(SInt32 group) COSXKeyState::setGroup(SInt32 group)
{ {
KLSetCurrentKeyboardLayout(m_groups[group]); TISSetInputMethodKeyboardLayoutOverride(m_groups[group]);
} }
void void
@ -818,10 +777,15 @@ COSXKeyState::CKeyResource::getKeyID(UInt8 c)
str[0] = static_cast<char>(c); str[0] = static_cast<char>(c);
str[1] = 0; str[1] = 0;
// get current keyboard script
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
// convert to unicode // convert to unicode
CFStringRef cfString = CFStringRef cfString =
CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
str, GetScriptManagerVariable(smKeyScript), str, CFStringConvertIANACharSetNameToEncoding((CFStringRef) CFArrayGetValueAtIndex(langs, 0)),
kCFAllocatorNull); kCFAllocatorNull);
// sometimes CFStringCreate...() returns NULL (e.g. Apple Korean // 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 // COSXKeyState::CUCHRKeyResource
// //
@ -1078,8 +969,10 @@ COSXKeyState::CUCHRKeyResource::getKey(UInt32 table, UInt32 button) const
assert(button < getNumButtons()); assert(button < getNumButtons());
const UInt8* base = reinterpret_cast<const UInt8*>(m_resource); const UInt8* base = reinterpret_cast<const UInt8*>(m_resource);
const UCKeyOutput c = reinterpret_cast<const UCKeyOutput*>(base + const UCKeyOutput* cPtr = reinterpret_cast<const UCKeyOutput*>(base +
m_cti->keyToCharTableOffsets[table])[button]; m_cti->keyToCharTableOffsets[table]);
const UCKeyOutput c = cPtr[button];
KeySequence keys; KeySequence keys;
switch (c & kUCKeyOutputTestForIndexMask) { switch (c & kUCKeyOutputTestForIndexMask) {

View File

@ -90,7 +90,7 @@ protected:
private: private:
class CKeyResource; class CKeyResource;
typedef std::vector<KeyboardLayoutRef> GroupList; typedef std::vector<TISInputSourceRef> GroupList;
// Add hard coded special keys to a CKeyMap. // Add hard coded special keys to a CKeyMap.
void getKeyMapForSpecialKeys( void getKeyMapForSpecialKeys(
@ -149,41 +149,6 @@ private:
static KeyID unicharToKeyID(UniChar); 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 { class CUCHRKeyResource : public CKeyResource {
public: public:
@ -223,7 +188,7 @@ private:
KeyButtonOffset = 1 KeyButtonOffset = 1
}; };
typedef std::map<KeyboardLayoutRef, SInt32> GroupMap; typedef std::map<TISInputSourceRef, SInt32> GroupMap;
typedef std::map<UInt32, KeyID> CVirtualKeyMap; typedef std::map<UInt32, KeyID> CVirtualKeyMap;
CVirtualKeyMap m_virtualKeyMap; CVirtualKeyMap m_virtualKeyMap;

View File

@ -73,7 +73,6 @@ COSXScreen::COSXScreen(bool isPrimary) :
m_clipboardTimer(NULL), m_clipboardTimer(NULL),
m_hiddenWindow(NULL), m_hiddenWindow(NULL),
m_userInputWindow(NULL), m_userInputWindow(NULL),
m_displayManagerNotificationUPP(NULL),
m_switchEventHandlerRef(0), m_switchEventHandlerRef(0),
m_pmMutex(new CMutex), m_pmMutex(new CMutex),
m_pmWatchThread(NULL), m_pmWatchThread(NULL),
@ -83,7 +82,7 @@ COSXScreen::COSXScreen(bool isPrimary) :
{ {
try { try {
m_displayID = CGMainDisplayID(); m_displayID = CGMainDisplayID();
updateScreenShape(); updateScreenShape(m_displayID, 0);
m_screensaver = new COSXScreenSaver(getEventTarget()); m_screensaver = new COSXScreenSaver(getEventTarget());
m_keyState = new COSXKeyState(); m_keyState = new COSXKeyState();
@ -123,11 +122,8 @@ COSXScreen::COSXScreen(bool isPrimary) :
} }
// install display manager notification handler // install display manager notification handler
m_displayManagerNotificationUPP = GetCurrentProcess(&m_PSN);
NewDMExtendedNotificationUPP(displayManagerCallback); CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, &m_PSN);
OSStatus err = GetCurrentProcess(&m_PSN);
err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP,
this, 0, &m_PSN);
// install fast user switching event handler // install fast user switching event handler
EventTypeSpec switchEventTypes[2]; EventTypeSpec switchEventTypes[2];
@ -158,18 +154,15 @@ COSXScreen::COSXScreen(bool isPrimary) :
if (m_switchEventHandlerRef != 0) { if (m_switchEventHandlerRef != 0) {
RemoveEventHandler(m_switchEventHandlerRef); RemoveEventHandler(m_switchEventHandlerRef);
} }
if (m_displayManagerNotificationUPP != NULL) { CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, &m_PSN);
DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP,
NULL, &m_PSN, 0);
}
if (m_hiddenWindow) { if (m_hiddenWindow) {
ReleaseWindow(m_hiddenWindow); CFRelease(m_hiddenWindow);
m_hiddenWindow = NULL; m_hiddenWindow = NULL;
} }
if (m_userInputWindow) { if (m_userInputWindow) {
ReleaseWindow(m_userInputWindow); CFRelease(m_userInputWindow);
m_userInputWindow = NULL; m_userInputWindow = NULL;
} }
delete m_keyState; delete m_keyState;
@ -216,16 +209,14 @@ COSXScreen::~COSXScreen()
RemoveEventHandler(m_switchEventHandlerRef); RemoveEventHandler(m_switchEventHandlerRef);
DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, &m_PSN);
NULL, &m_PSN, 0);
if (m_hiddenWindow) { if (m_hiddenWindow) {
ReleaseWindow(m_hiddenWindow); CFRelease(m_hiddenWindow);
m_hiddenWindow = NULL; m_hiddenWindow = NULL;
} }
if (m_userInputWindow) { if (m_userInputWindow) {
ReleaseWindow(m_userInputWindow); CFRelease(m_userInputWindow);
m_userInputWindow = NULL; m_userInputWindow = NULL;
} }
@ -614,7 +605,7 @@ COSXScreen::enter()
CGSetLocalEventsSuppressionInterval(0.0); CGSetLocalEventsSuppressionInterval(0.0);
// enable global hotkeys // enable global hotkeys
setGlobalHotKeysEnabled(true); //setGlobalHotKeysEnabled(true);
} }
else { else {
// show cursor // show cursor
@ -664,7 +655,7 @@ COSXScreen::leave()
CGSetLocalEventsSuppressionInterval(0.0001); CGSetLocalEventsSuppressionInterval(0.0001);
// disable global hotkeys // disable global hotkeys
setGlobalHotKeysEnabled(false); //setGlobalHotKeysEnabled(false);
} }
else { else {
// hide cursor // hide cursor
@ -1061,26 +1052,24 @@ COSXScreen::handleClipboardCheck(const CEvent&, void*)
} }
pascal void pascal void
COSXScreen::displayManagerCallback(void* inUserData, SInt16 inMessage, void*) COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData)
{ {
COSXScreen* screen = (COSXScreen*)inUserData; COSXScreen* screen = (COSXScreen*)inUserData;
if (inMessage == kDMNotifyEvent) { if (flags & ~0x1 != 0) { /* Something actually did change */
screen->onDisplayChange(); screen->onDisplayChange(displayID, flags);
} }
} }
bool 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 // update shape
updateScreenShape(); updateScreenShape(dispID, flags);
// do nothing if resolution hasn't changed // 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) { if (m_isPrimary) {
// warp mouse to center if off screen // warp mouse to center if off screen
if (!m_isOnScreen) { if (!m_isOnScreen) {
@ -1316,12 +1305,15 @@ 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 = EVENTQUEUE->newTimer(0.01, NULL); m_dragTimer = EVENTQUEUE->newTimer(0.01, NULL);
EVENTQUEUE->adoptHandler(CEvent::kTimer, m_dragTimer, EVENTQUEUE->adoptHandler(CEvent::kTimer, m_dragTimer,
new TMethodEventJob<COSXScreen>(this, new TMethodEventJob<COSXScreen>(this,
&COSXScreen::handleDrag)); &COSXScreen::handleDrag));
GetMouse(&m_dragLastPoint); TrackMouseLocationWithOptions(NULL, 0, 0, &m_dragLastPoint, &modifiers, &res);
} }
else if (!enable && m_dragTimer != NULL) { else if (!enable && m_dragTimer != NULL) {
EVENTQUEUE->removeHandler(CEvent::kTimer, m_dragTimer); EVENTQUEUE->removeHandler(CEvent::kTimer, m_dragTimer);
@ -1334,8 +1326,12 @@ void
COSXScreen::handleDrag(const CEvent&, void*) COSXScreen::handleDrag(const CEvent&, void*)
{ {
Point p; Point p;
GetMouse(&p); UInt32 modifiers;
if (p.h != m_dragLastPoint.h || p.v != m_dragLastPoint.v) { 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; m_dragLastPoint = p;
onMouseMove((SInt32)p.h, (SInt32)p.v); onMouseMove((SInt32)p.h, (SInt32)p.v);
} }
@ -1357,7 +1353,7 @@ COSXScreen::getKeyState() const
} }
void void
COSXScreen::updateScreenShape() COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags)
{ {
// get info for each display // get info for each display
CGDisplayCount displayCount = 0; CGDisplayCount displayCount = 0;
@ -1395,16 +1391,10 @@ COSXScreen::updateScreenShape()
m_h = (SInt32)totalBounds.size.height; m_h = (SInt32)totalBounds.size.height;
// get center of default screen // get center of default screen
GDHandle mainScreen = GetMainDevice(); CGDirectDisplayID main = CGMainDisplayID();
if (mainScreen != NULL) { const CGRect rect = CGDisplayBounds(main);
const Rect& rect = (*mainScreen)->gdRect; m_xCenter = (rect.origin.x + rect.size.width) / 2;
m_xCenter = (rect.left + rect.right) / 2; m_yCenter = (rect.origin.y + rect.size.height) / 2;
m_yCenter = (rect.top + rect.bottom) / 2;
}
else {
m_xCenter = m_x + (m_w >> 1);
m_yCenter = m_y + (m_h >> 1);
}
delete[] displays; 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 // older SDKs to build an app that works on newer systems and older
// SDKs will not provide the symbols. // 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 #ifdef __cplusplus
extern "C" { extern "C" {
@ -1663,6 +1657,7 @@ COSXScreen::getGlobalHotKeysEnabled()
return (mode == CGSGlobalHotKeyEnable); return (mode == CGSGlobalHotKeyEnable);
} }
#endif
// //
// COSXScreen::CHotKeyItem // COSXScreen::CHotKeyItem

View File

@ -86,7 +86,7 @@ protected:
virtual IKeyState* getKeyState() const; virtual IKeyState* getKeyState() const;
private: private:
void updateScreenShape(); void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
void postMouseEvent(CGPoint&) const; void postMouseEvent(CGPoint&) const;
// convenience function to send events // convenience function to send events
@ -101,7 +101,7 @@ private:
bool onMouseButton(bool pressed, UInt16 macButton); bool onMouseButton(bool pressed, UInt16 macButton);
bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const; bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const;
bool onDisplayChange(); bool onDisplayChange(CGDirectDisplayID, CGDisplayChangeSummaryFlags);
bool onKey(EventRef event); bool onKey(EventRef event);
bool onHotKey(EventRef event) const; bool onHotKey(EventRef event) const;
@ -131,8 +131,8 @@ private:
void handleClipboardCheck(const CEvent&, void*); void handleClipboardCheck(const CEvent&, void*);
// Resolution switch callback // Resolution switch callback
static pascal void displayManagerCallback(void* inUserData, static void displayReconfigurationCallback(CGDirectDisplayID,
SInt16 inMessage, void* inNotifyData); CGDisplayChangeSummaryFlags, void*);
// fast user switch callback // fast user switch callback
static pascal OSStatus static pascal OSStatus
@ -220,7 +220,6 @@ private:
WindowRef m_userInputWindow; WindowRef m_userInputWindow;
// display manager stuff (to get screen resolution switches). // display manager stuff (to get screen resolution switches).
DMExtendedNotificationUPP m_displayManagerNotificationUPP;
ProcessSerialNumber m_PSN; ProcessSerialNumber m_PSN;
// fast user switching // fast user switching