merge 1.4 r887:888 into trunk
This commit is contained in:
parent
76c47c2346
commit
cc520f08d8
|
@ -15,7 +15,10 @@
|
|||
|
||||
# TODO: split this file up, it's too long!
|
||||
|
||||
import sys, os, ConfigParser, subprocess, shutil, re, ftputil
|
||||
import sys, os, ConfigParser, shutil, re, ftputil
|
||||
|
||||
if sys.version_info >= (2, 4):
|
||||
import subprocess
|
||||
|
||||
class InternalCommands:
|
||||
|
||||
|
@ -42,7 +45,11 @@ class InternalCommands:
|
|||
config_filename = '%s.cfg' % this_cmd
|
||||
qtpro_filename = 'qsynergy.pro'
|
||||
doxygen_filename = 'doxygen.cfg'
|
||||
macPackageName = 'MacOSX-Universal'
|
||||
|
||||
macZipFiles = [
|
||||
'synergyc', 'synergys',
|
||||
'../../doc/synergy.conf.example',
|
||||
'../../doc/MacReadme.txt']
|
||||
|
||||
cmake_url = 'http://www.cmake.org/cmake/resources/software.html'
|
||||
|
||||
|
@ -59,40 +66,21 @@ class InternalCommands:
|
|||
enable_make_gui = False
|
||||
|
||||
win32_generators = {
|
||||
'1' : 'Visual Studio 10',
|
||||
'2' : 'Visual Studio 10 Win64',
|
||||
'3' : 'Visual Studio 9 2008',
|
||||
'4' : 'Visual Studio 9 2008 Win64',
|
||||
'5' : 'Visual Studio 8 2005',
|
||||
'6' : 'Visual Studio 8 2005 Win64',
|
||||
# '10' : 'CodeBlocks - MinGW Makefiles',
|
||||
# '11' : 'CodeBlocks - Unix Makefiles',
|
||||
# '12': 'Eclipse CDT4 - MinGW Makefiles',
|
||||
# '13': 'Eclipse CDT4 - NMake Makefiles',
|
||||
# '14': 'Eclipse CDT4 - Unix Makefiles',
|
||||
# '15': 'MinGW Makefiles',
|
||||
# '16': 'NMake Makefiles',
|
||||
# '17': 'Unix Makefiles',
|
||||
# '18': 'Borland Makefiles',
|
||||
# '19': 'MSYS Makefiles',
|
||||
# '20': 'Watcom WMake',
|
||||
1 : 'Visual Studio 10',
|
||||
2 : 'Visual Studio 10 Win64',
|
||||
3 : 'Visual Studio 9 2008',
|
||||
4 : 'Visual Studio 9 2008 Win64',
|
||||
5 : 'Visual Studio 8 2005',
|
||||
6 : 'Visual Studio 8 2005 Win64',
|
||||
}
|
||||
|
||||
unix_generators = {
|
||||
'1' : 'Unix Makefiles',
|
||||
# '2' : 'CodeBlocks - Unix Makefiles',
|
||||
# '3' : 'Eclipse CDT4 - Unix Makefiles',
|
||||
# '4' : 'KDevelop3',
|
||||
# '5' : 'KDevelop3 - Unix Makefiles',
|
||||
1 : 'Unix Makefiles',
|
||||
}
|
||||
|
||||
darwin_generators = {
|
||||
'1' : 'Xcode',
|
||||
'2' : 'Unix Makefiles',
|
||||
# '3' : 'CodeBlocks - Unix Makefiles',
|
||||
# '4' : 'Eclipse CDT4 - Unix Makefiles',
|
||||
# '5' : 'KDevelop3',
|
||||
# '6' : 'KDevelop3 - Unix Makefiles',
|
||||
1 : 'Unix Makefiles',
|
||||
2 : 'Xcode',
|
||||
}
|
||||
|
||||
def getBinDir(self, target=''):
|
||||
|
@ -264,7 +252,7 @@ class InternalCommands:
|
|||
# TODO
|
||||
pass
|
||||
|
||||
def build(self, targets=[]):
|
||||
def build(self, targets=[], skipConfig=False):
|
||||
|
||||
# if no mode specified, default to debug
|
||||
if len(targets) == 0:
|
||||
|
@ -277,7 +265,7 @@ class InternalCommands:
|
|||
if generator.startswith('Visual Studio'):
|
||||
|
||||
# only need to configure once for vs
|
||||
if not self.has_conf_run():
|
||||
if not self.has_conf_run() and not skipConfig:
|
||||
self.configure_internal()
|
||||
|
||||
for target in targets:
|
||||
|
@ -297,7 +285,7 @@ class InternalCommands:
|
|||
|
||||
for target in targets:
|
||||
|
||||
if not self.has_conf_run(target):
|
||||
if not self.has_conf_run(target) and not skipConfig:
|
||||
self.configure_internal(target)
|
||||
|
||||
self.try_chdir(self.getBinDir(target))
|
||||
|
@ -449,6 +437,9 @@ class InternalCommands:
|
|||
if type != 'win':
|
||||
self.configure_internal(unixTarget, '-DCONF_CPACK:BOOL=TRUE')
|
||||
|
||||
# make sure we have a release build to package
|
||||
self.build(['release'], skipConfig=True)
|
||||
|
||||
if type == None:
|
||||
self.dist_usage()
|
||||
return
|
||||
|
@ -479,27 +470,7 @@ class InternalCommands:
|
|||
|
||||
elif type == 'mac':
|
||||
if sys.platform == 'darwin':
|
||||
# nb: disabling package maker, as it doesn't
|
||||
# work too well (screws with permissions).
|
||||
#self.dist_run('cpack -G PackageMaker', unixTarget)
|
||||
|
||||
# nb: temporary fix (just distribute a zip)
|
||||
bin = self.getBinDir(unixTarget)
|
||||
version = self.getVersionFromCmake()
|
||||
zipFile = (self.project + '-' +
|
||||
version + '-' +
|
||||
self.macPackageName + '.zip')
|
||||
|
||||
zipCmd = ('zip ' + zipFile + ' ' +
|
||||
'synergyc synergys');
|
||||
|
||||
print 'Creating package: ' + zipCmd
|
||||
self.try_chdir(self.getBinDir(unixTarget))
|
||||
err = os.system(zipCmd)
|
||||
self.restore_chdir()
|
||||
if err != 0:
|
||||
raise Exception(
|
||||
'Zip failed, code: ' + err)
|
||||
self.distMac(unixTarget)
|
||||
else:
|
||||
package_unsupported = True
|
||||
|
||||
|
@ -512,6 +483,34 @@ class InternalCommands:
|
|||
% (type, sys.platform))
|
||||
|
||||
|
||||
def distMac(self, unixTarget):
|
||||
# nb: disabling package maker, as it doesn't
|
||||
# work too well (screws with permissions and causes boot to fail).
|
||||
#self.dist_run('cpack -G PackageMaker', unixTarget)
|
||||
|
||||
version = self.getVersionFromCmake()
|
||||
zipFile = (self.project + '-' + version + '-' +
|
||||
self.getMacPackageName() + '.zip')
|
||||
|
||||
# nb: temporary fix (just distribute a zip)
|
||||
bin = self.getBinDir(unixTarget)
|
||||
self.try_chdir(bin)
|
||||
|
||||
try:
|
||||
for f in self.macZipFiles:
|
||||
if not os.path.exists(f):
|
||||
raise Exception('File does not exist: ' + f)
|
||||
|
||||
zipCmd = ('zip ' + zipFile + ' ' + ' '.join(self.macZipFiles));
|
||||
|
||||
print 'Creating package: ' + zipCmd
|
||||
err = os.system(zipCmd)
|
||||
if err != 0:
|
||||
raise Exception('Zip failed, code: ' + err)
|
||||
|
||||
finally:
|
||||
self.restore_chdir()
|
||||
|
||||
def distNsis(self, vcRedistDir, qtDir):
|
||||
|
||||
if vcRedistDir == '':
|
||||
|
@ -746,8 +745,7 @@ class InternalCommands:
|
|||
|
||||
def get_generator_from_config(self):
|
||||
if self.generator_id:
|
||||
generators = self.get_generators()
|
||||
return generators[self.generator_id]
|
||||
return self.getGenerator()
|
||||
else:
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.read(self.config_filepath())
|
||||
|
@ -796,28 +794,20 @@ class InternalCommands:
|
|||
raise Exception('Unsupported platform: ' + sys.platform)
|
||||
|
||||
def get_generator_from_prompt(self):
|
||||
|
||||
return self.getGenerator()
|
||||
|
||||
def getGenerator(self):
|
||||
generators = self.get_generators()
|
||||
if len(generators.keys()) == 1:
|
||||
return generators[generators.keys()[0]]
|
||||
|
||||
# if user has specified a generator as an argument
|
||||
if self.generator_id:
|
||||
return generators[self.generator_id]
|
||||
|
||||
# if we can accept user input
|
||||
elif not self.no_prompts:
|
||||
generator_options = ''
|
||||
generators_sorted = sorted(generators.iteritems(), key=lambda t: int(t[0]))
|
||||
|
||||
for id, generator in generators_sorted:
|
||||
generator_options += '\n ' + id + ': ' + generator
|
||||
|
||||
print ('\nChoose a CMake generator:%s'
|
||||
) % generator_options
|
||||
|
||||
return self.setup_generator_prompt(generators)
|
||||
|
||||
return generators[int(self.generator_id)]
|
||||
else:
|
||||
raise Exception('No generator specified, and cannot prompt user.')
|
||||
raise Exception(
|
||||
'Generator not specified, use -g arg ' +
|
||||
'(use `hm genlist` for a list of generators).')
|
||||
|
||||
def setup_generator_prompt(self, generators):
|
||||
|
||||
|
@ -936,6 +926,27 @@ class InternalCommands:
|
|||
if err != 0:
|
||||
raise Exception('Reformat failed with error code: ' + str(err))
|
||||
|
||||
def printGeneratorList(self):
|
||||
generators = self.get_generators()
|
||||
keys = generators.keys()
|
||||
keys.sort()
|
||||
for k in keys:
|
||||
print str(k) + ': ' + generators[k]
|
||||
|
||||
def getMacPackageName(self):
|
||||
import commands
|
||||
versions = commands.getoutput('/usr/bin/sw_vers')
|
||||
result = re.search('ProductVersion:\t(\d+)\.(\d+)', versions)
|
||||
|
||||
if not result:
|
||||
print versions
|
||||
raise Exception(
|
||||
'Could not find Mac OS X version in sw_vers output.')
|
||||
|
||||
# version is major and minor with no dots (e.g. 106)
|
||||
return ('MacOSX' + str(result.group(1)) +
|
||||
str(result.group(2)) + '-Universal');
|
||||
|
||||
# the command handler should be called only from hm.py (i.e. directly
|
||||
# from the command prompt). the purpose of this class is so that we
|
||||
# don't need to do argument handling all over the place in the internal
|
||||
|
@ -1051,3 +1062,6 @@ class CommandHandler:
|
|||
|
||||
def open(self):
|
||||
self.ic.open()
|
||||
|
||||
def genlist(self):
|
||||
self.ic.printGeneratorList()
|
|
@ -0,0 +1,18 @@
|
|||
Mac OS X Readme
|
||||
===============
|
||||
|
||||
To install on Mac OS X with the .zip distribution (first seen in 1.3.6) you must follow these steps:
|
||||
|
||||
1. Extract the zip file to any location (usually double click will do this)
|
||||
2. Open Terminal, and cd to the extracted directory (e.g. /Users/my-name/Downloads/extracted-dir/)
|
||||
3. Change to super user (use the su command)
|
||||
4. Copy the binaries to /usr/bin using: cp synergy* /usr/bin
|
||||
|
||||
How to enable the root user in Mac OS X:
|
||||
http://support.apple.com/kb/ht1528
|
||||
|
||||
Once the binaries have been copied to /usr/bin, you should follow the configuration guide:
|
||||
http://synergy2.sourceforge.net/configuration.html
|
||||
|
||||
If you have any problems, see the [[Support]] page:
|
||||
http://synergy-foss.org/support
|
17
hm.py
17
hm.py
|
@ -30,9 +30,13 @@
|
|||
# This will create an in-source UNIX Makefile.
|
||||
|
||||
import sys, os
|
||||
from build import commands
|
||||
from build import toolchain
|
||||
from getopt import gnu_getopt
|
||||
|
||||
# minimum required version
|
||||
requiredMajor = 2
|
||||
requiredMinor = 3
|
||||
|
||||
# options used by all commands
|
||||
global_options = 'g:v'
|
||||
global_options_long = ['no-prompts', 'generator=', 'verbose', 'make-gui']
|
||||
|
@ -59,6 +63,7 @@ cmd_opt_dict = {
|
|||
'revision' : ['', []],
|
||||
'reformat' : ['', []],
|
||||
'open' : ['', []],
|
||||
'genlist' : ['', []]
|
||||
}
|
||||
|
||||
# aliases to valid commands
|
||||
|
@ -171,7 +176,7 @@ def run_cmd(cmd, argv = []):
|
|||
|
||||
# pass args and optarg data to command handler, which figures out
|
||||
# how to handle the arguments
|
||||
handler = commands.CommandHandler(argv, opts, args, verbose)
|
||||
handler = toolchain.CommandHandler(argv, opts, args, verbose)
|
||||
|
||||
# use reflection to get the function pointer
|
||||
cmd_func = getattr(handler, cmd)
|
||||
|
@ -181,15 +186,17 @@ def run_cmd(cmd, argv = []):
|
|||
if not verbose:
|
||||
# print friendly error for users
|
||||
sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n')
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
else:
|
||||
# if user wants to be verbose let python do it's thing
|
||||
raise
|
||||
|
||||
def main(argv):
|
||||
|
||||
if sys.version_info < (2, 4):
|
||||
print 'Python version must be at least: 2.4'
|
||||
if sys.version_info < (requiredMajor, requiredMinor):
|
||||
print ('Python version must be at least ' +
|
||||
str(requiredMajor) + '.' + str(requiredMinor) + ', but is ' +
|
||||
str(sys.version_info[0]) + '.' + str(sys.version_info[1]))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
|
|
|
@ -232,7 +232,12 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
|||
|
||||
// get keyboard info
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
#else
|
||||
KeyboardLayoutRef currentKeyboardLayout;
|
||||
OSStatus status = KLGetCurrentKeyboardLayout(¤tKeyboardLayout);
|
||||
#endif
|
||||
if (currentKeyboardLayout == NULL) {
|
||||
return kKeyNone;
|
||||
}
|
||||
|
@ -265,22 +270,49 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
|||
return 0;
|
||||
}
|
||||
|
||||
const bool layoutValid = false;
|
||||
const UCKeyboardLayout* layout;
|
||||
|
||||
// translate via uchr resource
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
|
||||
kTISPropertyUnicodeKeyLayoutData);
|
||||
const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
||||
if (layout != NULL) {
|
||||
layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
||||
layoutValid = (layout != null);
|
||||
#else
|
||||
const void* resource;
|
||||
int err = KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLuchrData, &resource);
|
||||
layoutValid == (err == noErr);
|
||||
layout = (const UCKeyboardLayout*)resource;
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
|
||||
// choose action
|
||||
UInt16 action;
|
||||
switch (eventKind) {
|
||||
case kEventRawKeyDown:
|
||||
action = kUCKeyActionDown;
|
||||
break;
|
||||
|
||||
case kEventRawKeyRepeat:
|
||||
action = kUCKeyActionAutoKey;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// translate key
|
||||
UniCharCount count;
|
||||
UniChar chars[2];
|
||||
//LOG((CLOG_DEBUG "modifiers: %08x", modifiers & 0xffu));
|
||||
LOG((CLOG_DEBUG2 "modifiers: %08x", modifiers & 0xffu));
|
||||
OSStatus status = UCKeyTranslate(layout,
|
||||
vkCode & 0xffu, action,
|
||||
(modifiers >> 8) & 0xffu,
|
||||
LMGetKbdType(), 0, &m_deadKeyState,
|
||||
sizeof(chars) / sizeof(chars[0]), &count, chars);
|
||||
|
||||
|
||||
// get the characters
|
||||
if (status == 0) {
|
||||
if (count != 0 || m_deadKeyState == 0) {
|
||||
|
@ -314,11 +346,21 @@ COSXKeyState::pollActiveModifiers() const
|
|||
SInt32
|
||||
COSXKeyState::pollActiveGroup() const
|
||||
{
|
||||
TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
GroupMap::const_iterator i = m_groupMap.find(inputSource);
|
||||
if (i != m_groupMap.end()) {
|
||||
return i->second;
|
||||
}
|
||||
bool layoutValid = true;
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef keyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
#else
|
||||
KeyboardLayoutRef keyboardLayout;
|
||||
OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout);
|
||||
layoutValid = (status == noErr);
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
GroupMap::const_iterator i = m_groupMap.find(keyboardLayout);
|
||||
if (i != m_groupMap.end()) {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -354,10 +396,23 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
|
|||
// add special keys
|
||||
getKeyMapForSpecialKeys(keyMap, g);
|
||||
|
||||
CFDataRef resource_ref;
|
||||
if ((resource_ref = (CFDataRef)TISGetInputSourceProperty(m_groups[g],
|
||||
kTISPropertyUnicodeKeyLayoutData)) != NULL) {
|
||||
const void* resource = CFDataGetBytePtr(resource_ref);
|
||||
const void* resource;
|
||||
bool layoutValid = false;
|
||||
|
||||
// add regular keys
|
||||
// try uchr resource first
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CFDataRef resourceRef = (CFDataRef)TISGetInputSourceProperty(
|
||||
m_groups[g], kTISPropertyUnicodeKeyLayoutData);
|
||||
layoutValid = resourceRef != NULL;
|
||||
if (layoutValid)
|
||||
resource = CFDataGetBytePtr(resourceRef);
|
||||
#else
|
||||
layoutValid = KLGetKeyboardLayoutProperty(
|
||||
m_groups[g], kKLuchrData, &resource);
|
||||
#endif
|
||||
|
||||
if (layoutValid) {
|
||||
CUCHRKeyResource uchr(resource, keyboardType);
|
||||
if (uchr.isValid()) {
|
||||
LOG((CLOG_DEBUG1 "using uchr resource for group %d", g));
|
||||
|
@ -366,6 +421,21 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
|
|||
}
|
||||
}
|
||||
|
||||
// NB: not sure why support for KCHR was
|
||||
// remvoed in 10.5 version?
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG((CLOG_DEBUG1 "no keyboard resource for group %d", g));
|
||||
}
|
||||
}
|
||||
|
@ -663,23 +733,41 @@ COSXKeyState::handleModifierKey(void* target,
|
|||
bool
|
||||
COSXKeyState::getGroups(GroupList& groups) const
|
||||
{
|
||||
CFIndex n;
|
||||
bool gotLayouts = false;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// get number of layouts
|
||||
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) {
|
||||
CFStringRef keys[] = { kTISPropertyInputSourceCategory };
|
||||
CFStringRef values[] = { kTISCategoryKeyboardInputSource };
|
||||
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, NULL, NULL);
|
||||
CFArrayRef kbds = TISCreateInputSourceList(dict, false);
|
||||
n = CFArrayGetCount(kbds);
|
||||
gotLayouts = (n != 0);
|
||||
#else
|
||||
OSStatus status = KLGetKeyboardLayoutCount(&n);
|
||||
gotLayouts = (status == noErr);
|
||||
#endif
|
||||
|
||||
if (!gotLayouts) {
|
||||
LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get each layout
|
||||
groups.clear();
|
||||
TISInputSourceRef inputKeyboardLayout;
|
||||
for (CFIndex i = 0; i < n; ++i) {
|
||||
inputKeyboardLayout = (TISInputSourceRef) CFArrayGetValueAtIndex(kbds, i);
|
||||
groups.push_back(inputKeyboardLayout);
|
||||
bool addToGroups = true;
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISInputSourceRef keyboardLayout =
|
||||
(TISInputSourceRef)CFArrayGetValueAtIndex(kbds, i);
|
||||
#else
|
||||
KeyboardLayoutRef keyboardLayout;
|
||||
status = KLGetKeyboardLayoutAtIndex(i, &keyboardLayout);
|
||||
addToGroups == (status == noErr);
|
||||
#endif
|
||||
if (addToGroups)
|
||||
groups.push_back(keyboardLayout);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -687,7 +775,11 @@ COSXKeyState::getGroups(GroupList& groups) const
|
|||
void
|
||||
COSXKeyState::setGroup(SInt32 group)
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
TISSetInputMethodKeyboardLayoutOverride(m_groups[group]);
|
||||
#else
|
||||
KLSetCurrentKeyboardLayout(m_groups[group]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -832,16 +924,18 @@ COSXKeyState::CKeyResource::getKeyID(UInt8 c)
|
|||
str[0] = static_cast<char>(c);
|
||||
str[1] = 0;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// get current keyboard script
|
||||
|
||||
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||||
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||||
|
||||
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||||
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||||
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)CFArrayGetValueAtIndex(langs, 0));
|
||||
#else
|
||||
CFStringEncoding encoding = GetScriptManagerVariable(smKeyScript);
|
||||
#endif
|
||||
// convert to unicode
|
||||
CFStringRef cfString =
|
||||
CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
|
||||
str, CFStringConvertIANACharSetNameToEncoding((CFStringRef) CFArrayGetValueAtIndex(langs, 0)),
|
||||
kCFAllocatorNull);
|
||||
CFStringCreateWithCStringNoCopy(
|
||||
kCFAllocatorDefault, str, encoding, kCFAllocatorNull);
|
||||
|
||||
// sometimes CFStringCreate...() returns NULL (e.g. Apple Korean
|
||||
// encoding with char value 214). if it did then make no key,
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
#include "stdset.h"
|
||||
#include "stdvector.h"
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
typedef TISInputSourceRef KeyLayout;
|
||||
#else
|
||||
typedef KeyboardLayoutRef KeyLayout;
|
||||
#endif
|
||||
|
||||
//! OS X key state
|
||||
/*!
|
||||
A key state for OS X.
|
||||
|
@ -99,7 +105,7 @@ protected:
|
|||
|
||||
private:
|
||||
class CKeyResource;
|
||||
typedef std::vector<TISInputSourceRef> GroupList;
|
||||
typedef std::vector<KeyLayout> GroupList;
|
||||
|
||||
// Add hard coded special keys to a CKeyMap.
|
||||
void getKeyMapForSpecialKeys(
|
||||
|
@ -197,7 +203,7 @@ private:
|
|||
KeyButtonOffset = 1
|
||||
};
|
||||
|
||||
typedef std::map<TISInputSourceRef, SInt32> GroupMap;
|
||||
typedef std::map<KeyLayout, SInt32> GroupMap;
|
||||
typedef std::map<UInt32, KeyID> CVirtualKeyMap;
|
||||
|
||||
CVirtualKeyMap m_virtualKeyMap;
|
||||
|
|
|
@ -97,9 +97,17 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
|||
LOG((CLOG_ERR "Synergy server requires accessibility API enabled. Please check the option for \"Enable access for assistive devices\" in the Universal Access System Preferences panel. Unintentional key-replication will occur until this is fixed."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// install display manager notification handler
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
m_displayManagerNotificationUPP =
|
||||
NewDMExtendedNotificationUPP(displayManagerCallback);
|
||||
OSStatus err = GetCurrentProcess(&m_PSN);
|
||||
err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP,
|
||||
this, 0, &m_PSN);
|
||||
#endif
|
||||
|
||||
// install fast user switching event handler
|
||||
EventTypeSpec switchEventTypes[2];
|
||||
|
@ -132,7 +140,24 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
|||
if (m_switchEventHandlerRef != 0) {
|
||||
RemoveEventHandler(m_switchEventHandlerRef);
|
||||
}
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
if (m_displayManagerNotificationUPP != NULL) {
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete m_keyState;
|
||||
delete m_screensaver;
|
||||
|
@ -178,7 +203,22 @@ COSXScreen::~COSXScreen()
|
|||
|
||||
RemoveEventHandler(m_switchEventHandlerRef);
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
||||
#else
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete m_keyState;
|
||||
delete m_screensaver;
|
||||
|
@ -526,17 +566,22 @@ void
|
|||
COSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const
|
||||
{
|
||||
if (xDelta != 0 || yDelta != 0) {
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// create a scroll event, post it and release it. not sure if kCGScrollEventUnitLine
|
||||
// is the right choice here over kCGScrollEventUnitPixel
|
||||
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(NULL,
|
||||
kCGScrollEventUnitLine,
|
||||
2,
|
||||
mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(
|
||||
NULL, kCGScrollEventUnitLine, 2,
|
||||
mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
|
||||
CGEventPost(kCGHIDEventTap, scrollEvent);
|
||||
|
||||
CFRelease(scrollEvent);
|
||||
#else
|
||||
|
||||
CGPostScrollWheelEvent(
|
||||
2, mapScrollWheelFromSynergy(yDelta),
|
||||
-mapScrollWheelFromSynergy(xDelta));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,6 +1033,42 @@ COSXScreen::handleClipboardCheck(const CEvent&, void*)
|
|||
checkClipboards();
|
||||
}
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
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;
|
||||
}
|
||||
#else
|
||||
void
|
||||
COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData)
|
||||
{
|
||||
|
@ -1007,6 +1088,7 @@ COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDispla
|
|||
screen->updateScreenShape(displayID, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
COSXScreen::onKey(CGEventRef event)
|
||||
|
@ -1275,7 +1357,12 @@ COSXScreen::getKeyState() const
|
|||
void
|
||||
COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags)
|
||||
{
|
||||
|
||||
updateScreenShape();
|
||||
}
|
||||
|
||||
void
|
||||
COSXScreen::updateScreenShape()
|
||||
{
|
||||
// get info for each display
|
||||
CGDisplayCount displayCount = 0;
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ protected:
|
|||
virtual IKeyState* getKeyState() const;
|
||||
|
||||
private:
|
||||
void updateScreenShape();
|
||||
void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
|
||||
void postMouseEvent(CGPoint&) const;
|
||||
|
||||
|
@ -114,10 +115,14 @@ private:
|
|||
// of the button pressed using the mac button mapping.
|
||||
bool onMouseButton(bool pressed, UInt16 macButton);
|
||||
bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const;
|
||||
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
bool onDisplayChange();
|
||||
#endif
|
||||
void constructMouseButtonEventMap();
|
||||
|
||||
bool onKey(CGEventRef event);
|
||||
|
||||
bool onHotKey(EventRef event) const;
|
||||
|
||||
// Added here to allow the carbon cursor hack to be called.
|
||||
|
@ -148,10 +153,14 @@ private:
|
|||
// clipboard check timer handler
|
||||
void handleClipboardCheck(const CEvent&, void*);
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5)
|
||||
// Resolution switch callback
|
||||
static void displayReconfigurationCallback(CGDirectDisplayID,
|
||||
CGDisplayChangeSummaryFlags, void*);
|
||||
|
||||
#else
|
||||
static pascal void displayManagerCallback(void* inUserData,
|
||||
SInt16 inMessage, void* inNotifyData);
|
||||
#endif
|
||||
// fast user switch callback
|
||||
static pascal OSStatus
|
||||
userSwitchCallback(EventHandlerCallRef nextHandler,
|
||||
|
@ -279,6 +288,12 @@ private:
|
|||
// does not have focus.
|
||||
WindowRef m_userInputWindow;
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||
// display manager stuff (to get screen resolution switches).
|
||||
DMExtendedNotificationUPP m_displayManagerNotificationUPP;
|
||||
ProcessSerialNumber m_PSN;
|
||||
#endif
|
||||
|
||||
// fast user switching
|
||||
EventHandlerRef m_switchEventHandlerRef;
|
||||
|
||||
|
|
Loading…
Reference in New Issue