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!
|
# 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:
|
class InternalCommands:
|
||||||
|
|
||||||
|
@ -42,7 +45,11 @@ class InternalCommands:
|
||||||
config_filename = '%s.cfg' % this_cmd
|
config_filename = '%s.cfg' % this_cmd
|
||||||
qtpro_filename = 'qsynergy.pro'
|
qtpro_filename = 'qsynergy.pro'
|
||||||
doxygen_filename = 'doxygen.cfg'
|
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'
|
cmake_url = 'http://www.cmake.org/cmake/resources/software.html'
|
||||||
|
|
||||||
|
@ -59,40 +66,21 @@ class InternalCommands:
|
||||||
enable_make_gui = False
|
enable_make_gui = False
|
||||||
|
|
||||||
win32_generators = {
|
win32_generators = {
|
||||||
'1' : 'Visual Studio 10',
|
1 : 'Visual Studio 10',
|
||||||
'2' : 'Visual Studio 10 Win64',
|
2 : 'Visual Studio 10 Win64',
|
||||||
'3' : 'Visual Studio 9 2008',
|
3 : 'Visual Studio 9 2008',
|
||||||
'4' : 'Visual Studio 9 2008 Win64',
|
4 : 'Visual Studio 9 2008 Win64',
|
||||||
'5' : 'Visual Studio 8 2005',
|
5 : 'Visual Studio 8 2005',
|
||||||
'6' : 'Visual Studio 8 2005 Win64',
|
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',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unix_generators = {
|
unix_generators = {
|
||||||
'1' : 'Unix Makefiles',
|
1 : 'Unix Makefiles',
|
||||||
# '2' : 'CodeBlocks - Unix Makefiles',
|
|
||||||
# '3' : 'Eclipse CDT4 - Unix Makefiles',
|
|
||||||
# '4' : 'KDevelop3',
|
|
||||||
# '5' : 'KDevelop3 - Unix Makefiles',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
darwin_generators = {
|
darwin_generators = {
|
||||||
'1' : 'Xcode',
|
1 : 'Unix Makefiles',
|
||||||
'2' : 'Unix Makefiles',
|
2 : 'Xcode',
|
||||||
# '3' : 'CodeBlocks - Unix Makefiles',
|
|
||||||
# '4' : 'Eclipse CDT4 - Unix Makefiles',
|
|
||||||
# '5' : 'KDevelop3',
|
|
||||||
# '6' : 'KDevelop3 - Unix Makefiles',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def getBinDir(self, target=''):
|
def getBinDir(self, target=''):
|
||||||
|
@ -264,7 +252,7 @@ class InternalCommands:
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def build(self, targets=[]):
|
def build(self, targets=[], skipConfig=False):
|
||||||
|
|
||||||
# if no mode specified, default to debug
|
# if no mode specified, default to debug
|
||||||
if len(targets) == 0:
|
if len(targets) == 0:
|
||||||
|
@ -277,7 +265,7 @@ class InternalCommands:
|
||||||
if generator.startswith('Visual Studio'):
|
if generator.startswith('Visual Studio'):
|
||||||
|
|
||||||
# only need to configure once for vs
|
# 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()
|
self.configure_internal()
|
||||||
|
|
||||||
for target in targets:
|
for target in targets:
|
||||||
|
@ -297,7 +285,7 @@ class InternalCommands:
|
||||||
|
|
||||||
for target in targets:
|
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.configure_internal(target)
|
||||||
|
|
||||||
self.try_chdir(self.getBinDir(target))
|
self.try_chdir(self.getBinDir(target))
|
||||||
|
@ -449,6 +437,9 @@ class InternalCommands:
|
||||||
if type != 'win':
|
if type != 'win':
|
||||||
self.configure_internal(unixTarget, '-DCONF_CPACK:BOOL=TRUE')
|
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:
|
if type == None:
|
||||||
self.dist_usage()
|
self.dist_usage()
|
||||||
return
|
return
|
||||||
|
@ -479,27 +470,7 @@ class InternalCommands:
|
||||||
|
|
||||||
elif type == 'mac':
|
elif type == 'mac':
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
# nb: disabling package maker, as it doesn't
|
self.distMac(unixTarget)
|
||||||
# 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)
|
|
||||||
else:
|
else:
|
||||||
package_unsupported = True
|
package_unsupported = True
|
||||||
|
|
||||||
|
@ -512,6 +483,34 @@ class InternalCommands:
|
||||||
% (type, sys.platform))
|
% (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):
|
def distNsis(self, vcRedistDir, qtDir):
|
||||||
|
|
||||||
if vcRedistDir == '':
|
if vcRedistDir == '':
|
||||||
|
@ -746,8 +745,7 @@ class InternalCommands:
|
||||||
|
|
||||||
def get_generator_from_config(self):
|
def get_generator_from_config(self):
|
||||||
if self.generator_id:
|
if self.generator_id:
|
||||||
generators = self.get_generators()
|
return self.getGenerator()
|
||||||
return generators[self.generator_id]
|
|
||||||
else:
|
else:
|
||||||
config = ConfigParser.RawConfigParser()
|
config = ConfigParser.RawConfigParser()
|
||||||
config.read(self.config_filepath())
|
config.read(self.config_filepath())
|
||||||
|
@ -796,28 +794,20 @@ class InternalCommands:
|
||||||
raise Exception('Unsupported platform: ' + sys.platform)
|
raise Exception('Unsupported platform: ' + sys.platform)
|
||||||
|
|
||||||
def get_generator_from_prompt(self):
|
def get_generator_from_prompt(self):
|
||||||
|
return self.getGenerator()
|
||||||
|
|
||||||
|
def getGenerator(self):
|
||||||
generators = self.get_generators()
|
generators = self.get_generators()
|
||||||
|
if len(generators.keys()) == 1:
|
||||||
|
return generators[generators.keys()[0]]
|
||||||
|
|
||||||
# if user has specified a generator as an argument
|
# if user has specified a generator as an argument
|
||||||
if self.generator_id:
|
if self.generator_id:
|
||||||
return generators[self.generator_id]
|
return generators[int(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)
|
|
||||||
|
|
||||||
else:
|
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):
|
def setup_generator_prompt(self, generators):
|
||||||
|
|
||||||
|
@ -936,6 +926,27 @@ class InternalCommands:
|
||||||
if err != 0:
|
if err != 0:
|
||||||
raise Exception('Reformat failed with error code: ' + str(err))
|
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
|
# 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
|
# 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
|
# don't need to do argument handling all over the place in the internal
|
||||||
|
@ -1051,3 +1062,6 @@ class CommandHandler:
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
self.ic.open()
|
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.
|
# This will create an in-source UNIX Makefile.
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
from build import commands
|
from build import toolchain
|
||||||
from getopt import gnu_getopt
|
from getopt import gnu_getopt
|
||||||
|
|
||||||
|
# minimum required version
|
||||||
|
requiredMajor = 2
|
||||||
|
requiredMinor = 3
|
||||||
|
|
||||||
# options used by all commands
|
# options used by all commands
|
||||||
global_options = 'g:v'
|
global_options = 'g:v'
|
||||||
global_options_long = ['no-prompts', 'generator=', 'verbose', 'make-gui']
|
global_options_long = ['no-prompts', 'generator=', 'verbose', 'make-gui']
|
||||||
|
@ -59,6 +63,7 @@ cmd_opt_dict = {
|
||||||
'revision' : ['', []],
|
'revision' : ['', []],
|
||||||
'reformat' : ['', []],
|
'reformat' : ['', []],
|
||||||
'open' : ['', []],
|
'open' : ['', []],
|
||||||
|
'genlist' : ['', []]
|
||||||
}
|
}
|
||||||
|
|
||||||
# aliases to valid commands
|
# aliases to valid commands
|
||||||
|
@ -171,7 +176,7 @@ def run_cmd(cmd, argv = []):
|
||||||
|
|
||||||
# pass args and optarg data to command handler, which figures out
|
# pass args and optarg data to command handler, which figures out
|
||||||
# how to handle the arguments
|
# 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
|
# use reflection to get the function pointer
|
||||||
cmd_func = getattr(handler, cmd)
|
cmd_func = getattr(handler, cmd)
|
||||||
|
@ -181,15 +186,17 @@ def run_cmd(cmd, argv = []):
|
||||||
if not verbose:
|
if not verbose:
|
||||||
# print friendly error for users
|
# print friendly error for users
|
||||||
sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n')
|
sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n')
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
# if user wants to be verbose let python do it's thing
|
# if user wants to be verbose let python do it's thing
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
||||||
if sys.version_info < (2, 4):
|
if sys.version_info < (requiredMajor, requiredMinor):
|
||||||
print 'Python version must be at least: 2.4'
|
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)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -232,7 +232,12 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
||||||
|
|
||||||
// get keyboard info
|
// get keyboard info
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||||
|
#else
|
||||||
|
KeyboardLayoutRef currentKeyboardLayout;
|
||||||
|
OSStatus status = KLGetCurrentKeyboardLayout(¤tKeyboardLayout);
|
||||||
|
#endif
|
||||||
if (currentKeyboardLayout == NULL) {
|
if (currentKeyboardLayout == NULL) {
|
||||||
return kKeyNone;
|
return kKeyNone;
|
||||||
}
|
}
|
||||||
|
@ -265,22 +270,49 @@ COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool layoutValid = false;
|
||||||
|
const UCKeyboardLayout* layout;
|
||||||
|
|
||||||
// translate via uchr resource
|
// translate via uchr resource
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
|
CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
|
||||||
kTISPropertyUnicodeKeyLayoutData);
|
kTISPropertyUnicodeKeyLayoutData);
|
||||||
const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
|
||||||
if (layout != NULL) {
|
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
|
// translate key
|
||||||
UniCharCount count;
|
UniCharCount count;
|
||||||
UniChar chars[2];
|
UniChar chars[2];
|
||||||
//LOG((CLOG_DEBUG "modifiers: %08x", modifiers & 0xffu));
|
LOG((CLOG_DEBUG2 "modifiers: %08x", modifiers & 0xffu));
|
||||||
OSStatus status = UCKeyTranslate(layout,
|
OSStatus status = UCKeyTranslate(layout,
|
||||||
vkCode & 0xffu, action,
|
vkCode & 0xffu, action,
|
||||||
(modifiers >> 8) & 0xffu,
|
(modifiers >> 8) & 0xffu,
|
||||||
LMGetKbdType(), 0, &m_deadKeyState,
|
LMGetKbdType(), 0, &m_deadKeyState,
|
||||||
sizeof(chars) / sizeof(chars[0]), &count, chars);
|
sizeof(chars) / sizeof(chars[0]), &count, chars);
|
||||||
|
|
||||||
// get the characters
|
// get the characters
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
if (count != 0 || m_deadKeyState == 0) {
|
if (count != 0 || m_deadKeyState == 0) {
|
||||||
|
@ -314,11 +346,21 @@ COSXKeyState::pollActiveModifiers() const
|
||||||
SInt32
|
SInt32
|
||||||
COSXKeyState::pollActiveGroup() const
|
COSXKeyState::pollActiveGroup() const
|
||||||
{
|
{
|
||||||
TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource();
|
bool layoutValid = true;
|
||||||
GroupMap::const_iterator i = m_groupMap.find(inputSource);
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
if (i != m_groupMap.end()) {
|
TISInputSourceRef keyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||||
return i->second;
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,10 +396,23 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap)
|
||||||
// add special keys
|
// add special keys
|
||||||
getKeyMapForSpecialKeys(keyMap, g);
|
getKeyMapForSpecialKeys(keyMap, g);
|
||||||
|
|
||||||
CFDataRef resource_ref;
|
const void* resource;
|
||||||
if ((resource_ref = (CFDataRef)TISGetInputSourceProperty(m_groups[g],
|
bool layoutValid = false;
|
||||||
kTISPropertyUnicodeKeyLayoutData)) != NULL) {
|
|
||||||
const void* resource = CFDataGetBytePtr(resource_ref);
|
// 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);
|
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));
|
||||||
|
@ -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));
|
LOG((CLOG_DEBUG1 "no keyboard resource for group %d", g));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,23 +733,41 @@ COSXKeyState::handleModifierKey(void* target,
|
||||||
bool
|
bool
|
||||||
COSXKeyState::getGroups(GroupList& groups) const
|
COSXKeyState::getGroups(GroupList& groups) const
|
||||||
{
|
{
|
||||||
|
CFIndex n;
|
||||||
|
bool gotLayouts = false;
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
// get number of layouts
|
// get number of layouts
|
||||||
CFStringRef keys[] = { kTISPropertyInputSourceCategory };
|
CFStringRef keys[] = { kTISPropertyInputSourceCategory };
|
||||||
CFStringRef values[] = { kTISCategoryKeyboardInputSource };
|
CFStringRef values[] = { kTISCategoryKeyboardInputSource };
|
||||||
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, NULL, NULL);
|
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, NULL, NULL);
|
||||||
CFArrayRef kbds = TISCreateInputSourceList(dict, false);
|
CFArrayRef kbds = TISCreateInputSourceList(dict, false);
|
||||||
CFIndex n = CFArrayGetCount(kbds);
|
n = CFArrayGetCount(kbds);
|
||||||
if (n == 0) {
|
gotLayouts = (n != 0);
|
||||||
|
#else
|
||||||
|
OSStatus status = KLGetKeyboardLayoutCount(&n);
|
||||||
|
gotLayouts = (status == noErr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!gotLayouts) {
|
||||||
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) {
|
||||||
inputKeyboardLayout = (TISInputSourceRef) CFArrayGetValueAtIndex(kbds, i);
|
bool addToGroups = true;
|
||||||
groups.push_back(inputKeyboardLayout);
|
#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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -687,7 +775,11 @@ COSXKeyState::getGroups(GroupList& groups) const
|
||||||
void
|
void
|
||||||
COSXKeyState::setGroup(SInt32 group)
|
COSXKeyState::setGroup(SInt32 group)
|
||||||
{
|
{
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
TISSetInputMethodKeyboardLayoutOverride(m_groups[group]);
|
TISSetInputMethodKeyboardLayoutOverride(m_groups[group]);
|
||||||
|
#else
|
||||||
|
KLSetCurrentKeyboardLayout(m_groups[group]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -832,16 +924,18 @@ COSXKeyState::CKeyResource::getKeyID(UInt8 c)
|
||||||
str[0] = static_cast<char>(c);
|
str[0] = static_cast<char>(c);
|
||||||
str[1] = 0;
|
str[1] = 0;
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
// get current keyboard script
|
// get current keyboard script
|
||||||
|
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
||||||
TISInputSourceRef isref = TISCopyCurrentKeyboardInputSource();
|
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
||||||
CFArrayRef langs = (CFArrayRef) TISGetInputSourceProperty(isref, kTISPropertyInputSourceLanguages);
|
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)CFArrayGetValueAtIndex(langs, 0));
|
||||||
|
#else
|
||||||
|
CFStringEncoding encoding = GetScriptManagerVariable(smKeyScript);
|
||||||
|
#endif
|
||||||
// convert to unicode
|
// convert to unicode
|
||||||
CFStringRef cfString =
|
CFStringRef cfString =
|
||||||
CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
|
CFStringCreateWithCStringNoCopy(
|
||||||
str, CFStringConvertIANACharSetNameToEncoding((CFStringRef) CFArrayGetValueAtIndex(langs, 0)),
|
kCFAllocatorDefault, str, encoding, kCFAllocatorNull);
|
||||||
kCFAllocatorNull);
|
|
||||||
|
|
||||||
// sometimes CFStringCreate...() returns NULL (e.g. Apple Korean
|
// sometimes CFStringCreate...() returns NULL (e.g. Apple Korean
|
||||||
// encoding with char value 214). if it did then make no key,
|
// encoding with char value 214). if it did then make no key,
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
#include "stdset.h"
|
#include "stdset.h"
|
||||||
#include "stdvector.h"
|
#include "stdvector.h"
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
|
typedef TISInputSourceRef KeyLayout;
|
||||||
|
#else
|
||||||
|
typedef KeyboardLayoutRef KeyLayout;
|
||||||
|
#endif
|
||||||
|
|
||||||
//! OS X key state
|
//! OS X key state
|
||||||
/*!
|
/*!
|
||||||
A key state for OS X.
|
A key state for OS X.
|
||||||
|
@ -99,7 +105,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CKeyResource;
|
class CKeyResource;
|
||||||
typedef std::vector<TISInputSourceRef> GroupList;
|
typedef std::vector<KeyLayout> GroupList;
|
||||||
|
|
||||||
// Add hard coded special keys to a CKeyMap.
|
// Add hard coded special keys to a CKeyMap.
|
||||||
void getKeyMapForSpecialKeys(
|
void getKeyMapForSpecialKeys(
|
||||||
|
@ -197,7 +203,7 @@ private:
|
||||||
KeyButtonOffset = 1
|
KeyButtonOffset = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<TISInputSourceRef, SInt32> GroupMap;
|
typedef std::map<KeyLayout, SInt32> GroupMap;
|
||||||
typedef std::map<UInt32, KeyID> CVirtualKeyMap;
|
typedef std::map<UInt32, KeyID> CVirtualKeyMap;
|
||||||
|
|
||||||
CVirtualKeyMap m_virtualKeyMap;
|
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."));
|
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
|
// install display manager notification handler
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this);
|
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
|
// install fast user switching event handler
|
||||||
EventTypeSpec switchEventTypes[2];
|
EventTypeSpec switchEventTypes[2];
|
||||||
|
@ -132,7 +140,24 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
||||||
if (m_switchEventHandlerRef != 0) {
|
if (m_switchEventHandlerRef != 0) {
|
||||||
RemoveEventHandler(m_switchEventHandlerRef);
|
RemoveEventHandler(m_switchEventHandlerRef);
|
||||||
}
|
}
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
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_keyState;
|
||||||
delete m_screensaver;
|
delete m_screensaver;
|
||||||
|
@ -178,7 +203,22 @@ COSXScreen::~COSXScreen()
|
||||||
|
|
||||||
RemoveEventHandler(m_switchEventHandlerRef);
|
RemoveEventHandler(m_switchEventHandlerRef);
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this);
|
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_keyState;
|
||||||
delete m_screensaver;
|
delete m_screensaver;
|
||||||
|
@ -526,17 +566,22 @@ void
|
||||||
COSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const
|
COSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const
|
||||||
{
|
{
|
||||||
if (xDelta != 0 || yDelta != 0) {
|
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
|
// create a scroll event, post it and release it. not sure if kCGScrollEventUnitLine
|
||||||
// is the right choice here over kCGScrollEventUnitPixel
|
// is the right choice here over kCGScrollEventUnitPixel
|
||||||
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(NULL,
|
CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(
|
||||||
kCGScrollEventUnitLine,
|
NULL, kCGScrollEventUnitLine, 2,
|
||||||
2,
|
mapScrollWheelFromSynergy(yDelta),
|
||||||
mapScrollWheelFromSynergy(yDelta),
|
-mapScrollWheelFromSynergy(xDelta));
|
||||||
-mapScrollWheelFromSynergy(xDelta));
|
|
||||||
|
|
||||||
CGEventPost(kCGHIDEventTap, scrollEvent);
|
CGEventPost(kCGHIDEventTap, scrollEvent);
|
||||||
|
|
||||||
CFRelease(scrollEvent);
|
CFRelease(scrollEvent);
|
||||||
|
#else
|
||||||
|
|
||||||
|
CGPostScrollWheelEvent(
|
||||||
|
2, mapScrollWheelFromSynergy(yDelta),
|
||||||
|
-mapScrollWheelFromSynergy(xDelta));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,6 +1033,42 @@ COSXScreen::handleClipboardCheck(const CEvent&, void*)
|
||||||
checkClipboards();
|
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
|
void
|
||||||
COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData)
|
COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void* inUserData)
|
||||||
{
|
{
|
||||||
|
@ -1007,6 +1088,7 @@ COSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDispla
|
||||||
screen->updateScreenShape(displayID, flags);
|
screen->updateScreenShape(displayID, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
COSXScreen::onKey(CGEventRef event)
|
COSXScreen::onKey(CGEventRef event)
|
||||||
|
@ -1275,7 +1357,12 @@ COSXScreen::getKeyState() const
|
||||||
void
|
void
|
||||||
COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags)
|
COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags)
|
||||||
{
|
{
|
||||||
|
updateScreenShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
COSXScreen::updateScreenShape()
|
||||||
|
{
|
||||||
// get info for each display
|
// get info for each display
|
||||||
CGDisplayCount displayCount = 0;
|
CGDisplayCount displayCount = 0;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ protected:
|
||||||
virtual IKeyState* getKeyState() const;
|
virtual IKeyState* getKeyState() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateScreenShape();
|
||||||
void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
|
void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
|
||||||
void postMouseEvent(CGPoint&) const;
|
void postMouseEvent(CGPoint&) const;
|
||||||
|
|
||||||
|
@ -114,10 +115,14 @@ private:
|
||||||
// of the button pressed using the mac button mapping.
|
// of the button pressed using the mac button mapping.
|
||||||
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;
|
||||||
|
|
||||||
|
#if !defined(MAC_OS_X_VERSION_10_5)
|
||||||
|
bool onDisplayChange();
|
||||||
|
#endif
|
||||||
void constructMouseButtonEventMap();
|
void constructMouseButtonEventMap();
|
||||||
|
|
||||||
bool onKey(CGEventRef event);
|
bool onKey(CGEventRef event);
|
||||||
|
|
||||||
bool onHotKey(EventRef event) const;
|
bool onHotKey(EventRef event) const;
|
||||||
|
|
||||||
// Added here to allow the carbon cursor hack to be called.
|
// Added here to allow the carbon cursor hack to be called.
|
||||||
|
@ -148,10 +153,14 @@ private:
|
||||||
// clipboard check timer handler
|
// clipboard check timer handler
|
||||||
void handleClipboardCheck(const CEvent&, void*);
|
void handleClipboardCheck(const CEvent&, void*);
|
||||||
|
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_5)
|
||||||
// Resolution switch callback
|
// Resolution switch callback
|
||||||
static void displayReconfigurationCallback(CGDirectDisplayID,
|
static void displayReconfigurationCallback(CGDirectDisplayID,
|
||||||
CGDisplayChangeSummaryFlags, void*);
|
CGDisplayChangeSummaryFlags, void*);
|
||||||
|
#else
|
||||||
|
static pascal void displayManagerCallback(void* inUserData,
|
||||||
|
SInt16 inMessage, void* inNotifyData);
|
||||||
|
#endif
|
||||||
// fast user switch callback
|
// fast user switch callback
|
||||||
static pascal OSStatus
|
static pascal OSStatus
|
||||||
userSwitchCallback(EventHandlerCallRef nextHandler,
|
userSwitchCallback(EventHandlerCallRef nextHandler,
|
||||||
|
@ -279,6 +288,12 @@ private:
|
||||||
// does not have focus.
|
// does not have focus.
|
||||||
WindowRef m_userInputWindow;
|
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
|
// fast user switching
|
||||||
EventHandlerRef m_switchEventHandlerRef;
|
EventHandlerRef m_switchEventHandlerRef;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue