diff --git a/CMakeLists.txt b/CMakeLists.txt index 326036e2..818713cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,91 +1,91 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Version number for Synergy+ -SET(VERSION_MAJOR 1) -SET(VERSION_MINOR 5) -SET(VERSION_REV 0) -SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV}") - - -# The check for 2.6 may be too strict (consider lowering). -CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7) - -# CMake complains if we don't have this. -IF(COMMAND cmake_policy) - CMAKE_POLICY(SET CMP0003 NEW) -ENDIF(COMMAND cmake_policy) - -# We're escaping quotes in the Windows version number, because -# for some reason CMake won't do it at config version 2.4.7 -# It seems that this restores the newer behaviour where define -# args are not auto-escaped. -IF(COMMAND cmake_policy) - CMAKE_POLICY(SET CMP0005 NEW) -ENDIF(COMMAND cmake_policy) - -# First, declare project (important for prerequisite checks). -PROJECT(synergy-plus C CXX) - -# Set some easy to type variables. -SET(root_dir ${CMAKE_SOURCE_DIR}) -SET(cmake_dir ${root_dir}/cmake) -SET(bin_dir ${root_dir}/bin) -SET(doc_dir ${root_dir}/doc) - -# Now for the stuff to generate config.h (and setup defines). -INCLUDE(${cmake_dir}/CMakeLists_config.txt) - -# Now for all the executables and libraries. -INCLUDE(${cmake_dir}/CMakeLists_lib.txt) -INCLUDE(${cmake_dir}/CMakeLists_synergyc.txt) -INCLUDE(${cmake_dir}/CMakeLists_synergys.txt) -INCLUDE(${cmake_dir}/CMakeLists_launcher.txt) - -# Setup the CPack config. -INCLUDE(${cmake_dir}/CMakeLists_cpack.txt) - -# Setup doxygen -INCLUDE(${cmake_dir}/CMakeLists_doxygen.txt) - -IF(WIN32) - # add /analyze in order to unconver potential bugs in the source code - # Details: http://msdn.microsoft.com/en-us/library/fwkeyyhe.aspx - # add /FR to generate browse information (ncb files) usefull for using IDE - - #define _BIND_TO_CURRENT_CRT_VERSION 1 - #define _BIND_TO_CURRENT_ATL_VERSION 1 - #define _BIND_TO_CURRENT_MFC_VERSION 1 - #define _BIND_TO_CURRENT_OPENMP_VERSION 1 - # next line replaced the previous 4 ones: - #define _BIND_TO_CURRENT_VCLIBS_VERSION 1; - - # compiler: /MP - use multi cores to compile - # added _SECURE_SCL=1 for finding bugs with iterators - http://msdn.microsoft.com/en-us/library/aa985965.aspx - - # common args between all vs builds - SET(VS_ARGS "/FR /MP /D _BIND_TO_CURRENT_VCLIBS_VERSION=1 /D _SECURE_SCL=1 ${VS_ARGS_EXTRA}") - - # we may use `cmake -D VS_ARGS_EXTRA="/analyze"` for example to specify - # analyze mode (since we don't always want to use it; e.g. on non-team - # or non-x86 compiler editions where there's no support) - SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${VS_ARGS}") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${VS_ARGS}") - - # this line removes "/D NDEBUG" from release, we want them in order to find bugs even on release builds. - SET(CMAKE_CXX_FLAGS_RELEASE "/MD /O2 /Ob2") - -ENDIF(WIN32) - +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Version number for Synergy+ +SET(VERSION_MAJOR 1) +SET(VERSION_MINOR 5) +SET(VERSION_REV 0) +SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV}") + + +# The check for 2.6 may be too strict (consider lowering). +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7) + +# CMake complains if we don't have this. +IF(COMMAND cmake_policy) + CMAKE_POLICY(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +# We're escaping quotes in the Windows version number, because +# for some reason CMake won't do it at config version 2.4.7 +# It seems that this restores the newer behaviour where define +# args are not auto-escaped. +IF(COMMAND cmake_policy) + CMAKE_POLICY(SET CMP0005 NEW) +ENDIF(COMMAND cmake_policy) + +# First, declare project (important for prerequisite checks). +PROJECT(synergy-plus C CXX) + +# Set some easy to type variables. +SET(root_dir ${CMAKE_SOURCE_DIR}) +SET(cmake_dir ${root_dir}/cmake) +SET(bin_dir ${root_dir}/bin) +SET(doc_dir ${root_dir}/doc) + +# Now for the stuff to generate config.h (and setup defines). +INCLUDE(${cmake_dir}/CMakeLists_config.txt) + +# Now for all the executables and libraries. +INCLUDE(${cmake_dir}/CMakeLists_lib.txt) +INCLUDE(${cmake_dir}/CMakeLists_synergyc.txt) +INCLUDE(${cmake_dir}/CMakeLists_synergys.txt) +INCLUDE(${cmake_dir}/CMakeLists_launcher.txt) + +# Setup the CPack config. +INCLUDE(${cmake_dir}/CMakeLists_cpack.txt) + +# Setup doxygen +INCLUDE(${cmake_dir}/CMakeLists_doxygen.txt) + +IF(WIN32) + # add /analyze in order to unconver potential bugs in the source code + # Details: http://msdn.microsoft.com/en-us/library/fwkeyyhe.aspx + # add /FR to generate browse information (ncb files) usefull for using IDE + + #define _BIND_TO_CURRENT_CRT_VERSION 1 + #define _BIND_TO_CURRENT_ATL_VERSION 1 + #define _BIND_TO_CURRENT_MFC_VERSION 1 + #define _BIND_TO_CURRENT_OPENMP_VERSION 1 + # next line replaced the previous 4 ones: + #define _BIND_TO_CURRENT_VCLIBS_VERSION 1; + + # compiler: /MP - use multi cores to compile + # added _SECURE_SCL=1 for finding bugs with iterators - http://msdn.microsoft.com/en-us/library/aa985965.aspx + + # common args between all vs builds + SET(VS_ARGS "/FR /MP /D _BIND_TO_CURRENT_VCLIBS_VERSION=1 /D _SECURE_SCL=1 ${VS_ARGS_EXTRA}") + + # we may use `cmake -D VS_ARGS_EXTRA="/analyze"` for example to specify + # analyze mode (since we don't always want to use it; e.g. on non-team + # or non-x86 compiler editions where there's no support) + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${VS_ARGS}") + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${VS_ARGS}") + + # this line removes "/D NDEBUG" from release, we want them in order to find bugs even on release builds. + SET(CMAKE_CXX_FLAGS_RELEASE "/MD /O2 /Ob2") + +ENDIF(WIN32) + diff --git a/COMPILE b/COMPILE index 5cacebef..0762f55f 100644 --- a/COMPILE +++ b/COMPILE @@ -1 +1 @@ -See: http://code.google.com/p/synergy-plus/wiki/Compiling +See: http://code.google.com/p/synergy-plus/wiki/Compiling diff --git a/README b/README index efe217c1..4f301343 100644 --- a/README +++ b/README @@ -1,17 +1,17 @@ -See: http://code.google.com/p/synergy-plus/wiki/Readme - -Announcement | 2009-08-04 -========================= -We have recently switched to CMake, to replace Automake. -Plese read the Compiling wiki page for help with CMake: -http://code.google.com/p/synergy-plus/wiki/Compiling - -Linux/Mac ---------- -Instead of using the traditional GNU style `./configure; make` -commands, you will now need to use CMake. - -Windows -------- -Instead of using the VS2005 and VS2008 directories, you now need -to generate the Visual Studio project files using CMake. +See: http://code.google.com/p/synergy-plus/wiki/Readme + +Announcement | 2009-08-04 +========================= +We have recently switched to CMake, to replace Automake. +Plese read the Compiling wiki page for help with CMake: +http://code.google.com/p/synergy-plus/wiki/Compiling + +Linux/Mac +--------- +Instead of using the traditional GNU style `./configure; make` +commands, you will now need to use CMake. + +Windows +------- +Instead of using the VS2005 and VS2008 directories, you now need +to generate the Visual Studio project files using CMake. diff --git a/build/__init__.py b/build/__init__.py index e1fb17d2..400e7d84 100644 --- a/build/__init__.py +++ b/build/__init__.py @@ -1,14 +1,14 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License # along with this program. If not, see . \ No newline at end of file diff --git a/build/commands.py b/build/commands.py index 6a10181e..e3d46184 100644 --- a/build/commands.py +++ b/build/commands.py @@ -1,931 +1,931 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# TODO: split this file up, it's too long! - -import sys, os, ConfigParser, subprocess, shutil, re, ftputil - -class InternalCommands: - - project = 'synergy-plus' - setup_version = 4 # increment to force setup/config - website_url = 'http://code.google.com/p/synergy-plus' - - this_cmd = 'hm' - cmake_cmd = 'cmake' - qmake_cmd = 'qmake' - make_cmd = 'make' - xcodebuild_cmd = 'xcodebuild' - w32_make_cmd = 'mingw32-make' - w32_qt_version = '4.6.2' - - source_dir = '..' # Source, relative to build. - cmake_dir = 'cmake' - bin_dir = 'bin' - gui_dir = 'gui' - doc_dir = 'doc' - - sln_filename = '%s.sln' % project - xcodeproj_filename = '%s.xcodeproj' % project - config_filename = '%s.cfg' % this_cmd - qtpro_filename = 'qsynergy.pro' - doxygen_filename = 'doxygen.cfg' - - cmake_url = 'http://www.cmake.org/cmake/resources/software.html' - - # try_chdir(...) and restore_chdir() will use this - prevdir = '' - - # by default, no index specified as arg - generator_id = None - - # by default, prompt user for input - no_prompts = False - - # by default, don't compile the gui - 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', - } - - unix_generators = { - '1' : 'Unix Makefiles', - '2' : 'CodeBlocks - Unix Makefiles', - '3' : 'Eclipse CDT4 - Unix Makefiles', - '4' : 'KDevelop3', - '5' : 'KDevelop3 - Unix Makefiles', - } - - darwin_generators = { - '1' : 'Xcode', - '2' : 'Unix Makefiles', - '3' : 'CodeBlocks - Unix Makefiles', - '4' : 'Eclipse CDT4 - Unix Makefiles', - '5' : 'KDevelop3', - '6' : 'KDevelop3 - Unix Makefiles', - } - - def config_filepath(self): - return '%s/%s' % (self.bin_dir, self.config_filename) - - def sln_filepath(self): - return '%s\%s' % (self.bin_dir, self.sln_filename) - - def xcodeproj_filepath(self): - return '%s/%s' % (self.bin_dir, self.xcodeproj_filename) - - def usage(self): - app = sys.argv[0] - print ('Usage: %s [-g |-v|--no-prompts|]\n' - '\n' - 'Replace [command] with one of:\n' - ' about Show information about this script\n' - ' setup Runs the initial setup for this script\n' - ' conf Runs cmake (generates project files)\n' - ' open Attempts to open the generated project file\n' - ' build Builds using the platform build chain\n' - ' clean Cleans using the platform build chain\n' - ' kill Kills all synergy processes (run as admin)\n' - ' update Updates the source code from repository\n' - ' revision Display the current source code revision\n' - ' package Create a distribution package (e.g. tar.gz)\n' - ' install Installs the program\n' - ' doxygen Builds doxygen documentation\n' - ' reformat Reformat .cpp and .h files using AStyle\n' - ' usage Shows the help screen\n' - '\n' - 'Example: %s build -g 3' - ) % (app, app) - - def configure(self): - self.configure_internal() - - print ('Configure complete!\n\n' - 'Open project now: %s open\n' - 'Command line build: %s build' - ) % (self.this_cmd, self.this_cmd) - - def configure_internal(self): - - # ensure latest setup and do not ask config for generator (only fall - # back to prompt if not specified as arg) - self.ensure_setup_latest() - - # ensure that we have access to cmake - _cmake_cmd = self.persist_cmake() - - # now that we know we've got the latest setup, we can ask the config - # file for the generator (but again, we only fall back to this if not - # specified as arg). - generator = self.get_generator_from_config() - - if generator != '': - cmake_args = '%s -G "%s"' % (self.source_dir, generator) - else: - cmake_args = self.source_dir - - cmake_cmd_string = '%s %s' % (_cmake_cmd, cmake_args) - - print "Configuring with CMake (%s)..." % cmake_cmd_string - - # Run from build dir so we have an out-of-source build. - self.try_chdir(self.bin_dir) - err = os.system(cmake_cmd_string) - self.restore_chdir() - - if err != 0: - raise Exception('CMake encountered error: ' + str(err)) - - # allow user to skip qui compile - if self.enable_make_gui: - - # make sure we have qmake - self.persist_qmake() - - qmake_cmd_string = self.qmake_cmd + ' ' + self.qtpro_filename - print "Configuring with QMake (%s)..." % qmake_cmd_string - - # run qmake from the gui dir - self.try_chdir(self.gui_dir) - err = os.system(qmake_cmd_string) - self.restore_chdir() - - if err != 0: - raise Exception('QMake encountered error: ' + str(err)) - - self.set_conf_run() - - def persist_cmake(self): - # even though we're running `cmake --version`, we're only doing this for the 0 return - # code; we don't care about the version, since CMakeLists worrys about this for us. - err = os.system('%s --version' % self.cmake_cmd) - - if err != 0: - # if return code from cmake is not 0, then either something has - # gone terribly wrong with --version, or it genuinely doesn't exist. - print ('Could not find `%s` in system path.\n' - 'Download the latest version from:\n %s') % ( - self.cmake_cmd, self.cmake_url) - raise Exception('Cannot continue without CMake.') - else: - return self.cmake_cmd - - def persist_qt(self): - self.persist_qmake() - if sys.platform == 'win32': - self.persist_w32_make() - - def persist_qmake(self): - try: - p = subprocess.Popen( - [self.qmake_cmd, '--version'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - except: - print >> sys.stderr, 'Error: Could not find qmake.' - if sys.platform == 'win32': # windows devs usually need hints ;) - print ( - 'Suggestions:\n' - '1. Ensure that qmake.exe exists in your system path.\n' - '2. Try to download Qt (check our dev FAQ for links):\n' - ' qt-sdk-win-opensource-2010.02.exe') - raise Exception('Cannot continue without qmake.') - - stdout, stderr = p.communicate() - if p.returncode != 0: - raise Exception('Could not test for cmake: %s' % stderr) - else: - m = re.search('.*Using Qt version (\d+\.\d+\.\d+).*', stdout) - if m: - if sys.platform == 'win32': - ver = m.group(1) - if ver != self.w32_qt_version: # TODO: test properly - print >> sys.stderr, ( - 'Warning: Not using supported Qt version %s' - ' (your version is %s).' - ) % (self.w32_qt_version, ver) - else: - pass # any version should be ok for other platforms - else: - raise Exception('Could not find qmake version.') - - def persist_w32_make(): - # TODO - pass - - def build(self, targets=[]): - - # if no mode specified, default to debug - if len(targets) == 0: - targets += ['debug',] - - self.ensure_setup_latest() - - if not self.has_conf_run(): - self.configure_internal() - - generator = self.get_generator_from_config() - - if generator == "Unix Makefiles": - - print 'Building with GNU Make...' - self.try_chdir(self.bin_dir) - err = os.system(self.make_cmd) - self.restore_chdir() - - if err != 0: - raise Exception('GNU Make failed: ' + str(err)) - - elif generator.startswith('Visual Studio'): - - for target in targets: - self.run_vcbuild(generator, target) - - elif generator == 'Xcode': - - print 'Building with Xcode...' - self.try_chdir(self.bin_dir) - err = os.system(self.xcodebuild_cmd) - self.restore_chdir() - - if err != 0: - raise Exception('Xcode failed: ' + str(err)) - - else: - raise Exception('Not supported with generator: ' + generator) - - # allow user to skip qui compile - if self.enable_make_gui: - self.make_gui(targets) - - def clean(self, targets=[]): - - # if no mode specified, default to debug - if len(targets) == 0: - targets += ['debug',] - - generator = self.get_generator_from_config() - - if generator == "Unix Makefiles": - - print 'Cleaning with GNU Make...' - self.try_chdir(self.bin_dir) - err = os.system(self.make_cmd + ' clean') - self.restore_chdir() - - if err != 0: - raise Exception('GNU Make failed: ' + str(err)) - - # special case for version 10, use new /target:clean - elif generator.startswith('Visual Studio 10'): - - for target in targets: - self.run_vcbuild(generator, target, '/target:clean') - - # any other version of visual studio, use /clean - elif generator.startswith('Visual Studio'): - - for target in targets: - self.run_vcbuild(generator, target, '/clean') - - elif generator == 'Xcode': - - print 'Cleaning with Xcode...' - self.try_chdir(self.bin_dir) - err = os.system(xcodebuild_cmd + ' clean') - self.restore_chdir() - - if err != 0: - raise Exception('Xcode failed: ' + str(err)) - - else: - raise Exception('Not supported with generator: ' + generator) - - # allow user to skip qui compile - clean_targets = [] - if self.enable_make_gui: - for target in targets: - clean_targets.append(target + '-clean') - - self.make_gui(clean_targets) - - def make_gui(self, targets): - if sys.platform == 'win32': - gui_make_cmd = self.w32_make_cmd - elif sys.platform in ['linux2', 'sunos5', 'freebsd7']: - gui_make_cmd = self.make_cmd - elif sys.platform == 'darwin': - gui_make_cmd = self.xcodebuild_cmd - else: - raise Exception('Unsupported platform: ' + sys.platform) - - print 'Running %s...' % gui_make_cmd - - # HACK: don't know how to build in either debug or release on unix; - # always builds release! - if sys.platform == 'win32': - for target in targets: - self.try_chdir(self.gui_dir) - err = os.system(gui_make_cmd + ' ' + target) - self.restore_chdir() - - if err != 0: - raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) - else: - if sys.platform == 'darwin': - make_dir = self.gui_dir + '/QSynergy.xcodeproj' - else: - make_dir = self.gui_dir - - self.try_chdir(make_dir) - err = os.system(gui_make_cmd) - self.restore_chdir() - - def open(self): - generator = self.get_generator_from_config() - if generator.startswith('Visual Studio'): - print 'Opening with %s...' % generator - self.open_internal(self.sln_filepath()) - - elif generator.startswith('Xcode'): - print 'Opening with %s...' % generator - self.open_internal(self.xcodeproj_filepath(), 'open') - - else: - raise Exception('Not supported with generator: ' + generator) - - def update(self): - print "Running Subversion update..." - err = os.system('svn update') - if err != 0: - raise Exception('Could not update from repository with error code code: ' + str(err)) - - def revision(self): - print self.find_revision() - - def find_revision(self): - p = subprocess.Popen(['svn', 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - - if p.returncode != 0: - raise Exception('Could not get revision - svn info failed with code: ' + str(p.returncode)) - - m = re.search('.*Revision: (\d+).*', stdout) - if not m: - raise Exception('Could not find revision number in svn info output.') - - return m.group(1) - - def kill(self): - if sys.platform == 'win32': - return os.system('taskkill /F /FI "IMAGENAME eq synergy*"') - else: - raise Exception('Not implemented for platform: ' + sys.platform) - - def doxygen(self): - # The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in - if not self.has_conf_run(): - self.configure_internal() - - err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename)) - - if err != 0: - raise Exception('doxygen failed with error code: ' + str(err)) - - def dist(self, type): - - # Package is supported by default. - package_unsupported = False - - if type == None: - self.dist_usage() - return - - elif type == 'src': - if sys.platform in ['linux2', 'darwin']: - self.dist_run('make package_source') - else: - package_unsupported = True - - elif type == 'rpm': - if sys.platform == 'linux2': - self.dist_run('cpack -G RPM') - else: - package_unsupported = True - - elif type == 'deb': - if sys.platform == 'linux2': - self.dist_run('cpack -G DEB') - else: - package_unsupported = True - - elif type == 'win': - if sys.platform == 'win32': - self.dist_run('cpack -G NSIS') - else: - package_unsupported = True - - elif type == 'mac': - if sys.platform == 'darwin': - self.dist_run('cpack -G PackageMaker') - else: - package_unsupported = True - - else: - raise Exception('Package type not supported: ' + type) - - if package_unsupported: - raise Exception( - ("Package type, '%s' is not supported for platform, '%s'") - % (type, sys.platform)) - - - def distftp(self, type, ftp): - if not type: - raise Exception('Type not specified.') - - if not ftp: - raise Exception('FTP info not defined.') - - src = self.dist_name(type) - dest = self.dist_name_rev(type) - print 'Uploading %s to FTP server %s...' % (dest, ftp.host) - ftp.run('bin/' + src, dest) - print 'Done' - - def dist_name(self, type): - ext = None - platform = None - - if type == 'src': - ext = 'tar.gz' - platform = 'Source' - - elif type == 'rpm' or type == 'deb': - - # os_bits should be loaded with '32bit' or '64bit' - import platform - (os_bits, other) = platform.architecture() - - # get platform based on current platform - ext = type - if os_bits == '32bit': - platform = 'Linux-i686' - elif os_bits == '64bit': - platform = 'Linux-x86_64' - - elif type == 'win': - - # get platform based on last generator used - ext = 'exe' - generator = self.get_generator_from_config() - if generator.find('Win64') != -1: - platform = 'Windows-x64' - else: - platform = 'Windows-x86' - - elif type == 'mac': - ext = 'dmg' - platform = 'MacOSX-Universal' - - if not platform: - raise Exception('Unable to detect package platform.') - - pattern = re.escape('synergy-plus-') + '\d\.\d\.\d' + re.escape('-' + platform + '.' + ext) - - for filename in os.listdir(self.bin_dir): - if re.search(pattern, filename): - return filename - - # still here? package probably not created yet. - raise Exception('Could not find package name with pattern: ' + pattern) - - def dist_name_rev(self, type): - # find the version number (we're puting the rev in after this) - pattern = '(.*\d+\.\d+\.\d+)(.*)' - replace = '\g<1>-r' + self.find_revision() + '\g<2>' - return re.sub(pattern, replace, self.dist_name(type)) - - def dist_run(self, command): - self.try_chdir(self.bin_dir) - err = os.system(command) - self.restore_chdir() - if err != 0: - raise Exception('Package failed: ' + str(err)) - - def dist_usage(self): - print ('Usage: %s package [package-type]\n' - '\n' - 'Replace [package-type] with one of:\n' - ' src .tar.gz source (Posix only)\n' - ' rpm .rpm package (Red Hat)\n' - ' deb .deb paclage (Debian)\n' - ' win .exe installer (Windows)\n' - ' mac .dmg package (Mac OS X)\n' - '\n' - 'Example: %s package src-tgz') % (self.this_cmd, self.this_cmd) - - def about(self): - print ('Help Me script, from the Synergy+ project.\n' - '%s\n' - '\n' - 'For help, run: %s help') % (self.website_url, self.this_cmd) - - def try_chdir(self, dir): - - # Ensure temp build dir exists. - if not os.path.exists(dir): - os.mkdir(dir) - - global prevdir - prevdir = os.path.abspath(os.curdir) - - # It will exist by this point, so it's safe to chdir. - os.chdir(dir) - - def restore_chdir(self): - global prevdir - os.chdir(prevdir) - - def open_internal(self, project_filename, application = ''): - - if not os.path.exists(project_filename): - raise Exception('Project file (%s) not found, run hm conf first.' % project_filename) - else: - path = project_filename - - if application != '': - path = application + ' ' + path - - err = os.system(path) - if err != 0: - raise Exception('Could not open project with error code code: ' + str(err)) - - def setup(self): - print "Running setup..." - - # always either get generator from args, or prompt user when - # running setup - generator = self.get_generator_from_prompt() - - # Create build dir, since config file resides there. - if not os.path.exists(self.bin_dir): - os.mkdir(self.bin_dir) - - if os.path.exists(self.config_filepath()): - config = ConfigParser.ConfigParser() - config.read(self.config_filepath()) - else: - config = ConfigParser.ConfigParser() - - if not config.has_section('hm'): - config.add_section('hm') - - if not config.has_section('cmake'): - config.add_section('cmake') - - config.set('hm', 'setup_version', self.setup_version) - - # store the generator so we don't need to ask again - config.set('cmake', 'generator', generator) - - self.write_config(config) - - cmakecache_filename = '%s/CMakeCache.txt' % self.bin_dir - if os.path.exists(cmakecache_filename): - print "Removing %s, since generator changed." % cmakecache_filename - os.remove(cmakecache_filename) - - print "\nSetup complete." - - def write_config(self, config): - configfile = open(self.config_filepath(), 'wb') - config.write(configfile) - - def get_generator_from_config(self): - if self.generator_id: - generators = self.get_generators() - return generators[self.generator_id] - else: - config = ConfigParser.RawConfigParser() - config.read(self.config_filepath()) - return config.get('cmake', 'generator') - - def min_setup_version(self, version): - if os.path.exists(self.config_filepath()): - config = ConfigParser.RawConfigParser() - config.read(self.config_filepath()) - - try: - return config.getint('hm', 'setup_version') >= version - except: - return False - else: - return False - - def has_conf_run(self): - if self.min_setup_version(2): - config = ConfigParser.RawConfigParser() - config.read(self.config_filepath()) - try: - return config.getboolean('hm', 'has_conf_run') - except: - return False - else: - return False - - def set_conf_run(self): - if self.min_setup_version(3): - config = ConfigParser.RawConfigParser() - config.read(self.config_filepath()) - config.set('hm', 'has_conf_run', True) - self.write_config(config) - else: - raise Exception("User does not have correct setup version.") - - def get_generators(self): - if sys.platform == 'win32': - return self.win32_generators - elif sys.platform in ['linux2', 'sunos5', 'freebsd7']: - return self.unix_generators - elif sys.platform == 'darwin': - return self.darwin_generators - else: - raise Exception('Unsupported platform: ' + sys.platform) - - def get_generator_from_prompt(self): - - generators = self.get_generators() - - # 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) - - else: - raise Exception('No generator specified, and cannot prompt user.') - - def setup_generator_prompt(self, generators): - - if self.no_prompts: - raise Exception('User prompting is disabled.') - - prompt = 'Enter a number:' - print prompt, - - generator_id = raw_input() - - if generator_id in generators: - print 'Selected generator:', generators[generator_id] - else: - print 'Invalid number, try again.' - self.setup_generator_prompt(generators) - - return generators[generator_id] - - def get_vcvarsall(self, generator): - import platform, _winreg - - # os_bits should be loaded with '32bit' or '64bit' - (os_bits, other) = platform.architecture() - - # visual studio is a 32-bit app, so when we're on 64-bit, we need to check the WoW dungeon - if os_bits == '64bit': - key_name = r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7' - else: - key_name = r'SOFTWARE\Microsoft\VisualStudio\SxS\VC7' - - try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name) - except: - raise Exception('Unable to open Visual Studio registry key. Application may not be installed.') - - if generator.startswith('Visual Studio 8'): - value,type = _winreg.QueryValueEx(key, '8.0') - elif generator.startswith('Visual Studio 9'): - value,type = _winreg.QueryValueEx(key, '9.0') - elif generator.startswith('Visual Studio 10'): - value,type = _winreg.QueryValueEx(key, '10.0') - else: - raise Exception('Cannot determin vcvarsall.bat location for: ' + generator) - - # not sure why, but the value on 64-bit differs slightly to the original - if os_bits == '64bit': - path = value + r'vc\vcvarsall.bat' - else: - path = value + r'vcvarsall.bat' - - if not os.path.exists(path): - raise Exception("'%s' not found." % path) - - return path - - def run_vcbuild(self, generator, mode, args=''): - import platform - - # os_bits should be loaded with '32bit' or '64bit' - (os_bits, other) = platform.architecture() - # Now we choose the parameters bases on OS 32/64 and our target 32/64 - # http://msdn.microsoft.com/en-us/library/x4d2c09s%28VS.80%29.aspx - - # valid options are only: ia64 amd64 x86_amd64 x86_ia64 - # but calling vcvarsall.bat does not garantee that it will work - # ret code from vcvarsall.bat is always 0 so the only way of knowing that I worked is by analysing the text output - # ms bugg: install VS9, FeaturePack, VS9SP1 and you'll obtain a vcvarsall.bat that fails. - if generator.find('Win64') != -1: - # target = 64bit - if os_bits == '32bit': - vcvars_platform = 'x86_amd64' # 32bit OS building 64bit app - else: - vcvars_platform = 'amd64' # 64bit OS building 64bit app - config_platform = 'x64' - else: # target = 32bit - vcvars_platform = 'x86' # 32/64bit OS building 32bit app - config_platform = 'Win32' - if mode == 'release': - config = 'Release' - else: - config = 'Debug' - - if generator.startswith('Visual Studio 10'): - cmd = ('@echo off\n' - 'call "%s" %s \n' - 'msbuild /nologo %s /p:Configuration="%s" /p:Platform="%s" "%s"' - ) % (self.get_vcvarsall(generator), vcvars_platform, args, config, config_platform, self.sln_filepath()) - else: - config = config + '|' + config_platform - cmd = ('@echo off\n' - 'call "%s" %s \n' - 'vcbuild /nologo %s "%s" "%s"' - ) % (self.get_vcvarsall(generator), vcvars_platform, args, self.sln_filepath(), config) - - # Generate a batch file, since we can't use environment variables directly. - temp_bat = self.bin_dir + r'\vcbuild.bat' - file = open(temp_bat, 'w') - file.write(cmd) - file.close() - - err = os.system(temp_bat) - if err != 0: - raise Exception('Microsoft compiler failed with error code: ' + str(err)) - - def ensure_setup_latest(self): - if not self.min_setup_version(self.setup_version): - self.setup() - - def reformat(self): - err = os.system( - r'tool\astyle\AStyle.exe ' - '--quiet --suffix=none --style=java --indent=force-tab=4 --recursive ' - 'lib/*.cpp lib/*.h cmd/*.cpp cmd/*.h') - - if err != 0: - raise Exception('Reformat failed with error code: ' + str(err)) - -# 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 -# commands class. -class CommandHandler: - ic = InternalCommands() - build_targets = [] - - def __init__(self, argv, opts, args, verbose): - - self.ic.verbose = verbose - - self.opts = opts - self.args = args - - for o, a in self.opts: - if o == '--no-prompts': - self.ic.no_prompts = True - elif o in ('-g', '--generator'): - self.ic.generator_id = a - elif o == '--make-gui': - self.ic.enable_make_gui = True - elif o in ('-d', '--debug'): - self.build_targets += ['debug',] - elif o in ('-r', '--release'): - self.build_targets += ['release',] - - def about(self): - self.ic.about() - - def setup(self): - self.ic.setup() - - def configure(self): - self.ic.configure() - - def build(self): - self.ic.build(self.build_targets) - - def clean(self): - self.ic.clean(self.build_targets) - - def update(self): - self.ic.update() - - def install(self): - print 'Not yet implemented: install' - - def doxygen(self): - self.ic.doxygen () - - def dist(self): - - type = None - if len(self.args) > 0: - type = self.args[0] - - self.ic.dist(type) - - def distftp(self): - type = None - host = None - user = None - password = None - dir = None - - if len(self.args) > 0: - type = self.args[0] - - for o, a in self.opts: - if o == '--host': - host = a - elif o == '--user': - user = a - elif o == '--pass': - password = a - elif o == '--dir': - dir = a - - ftp = None - if host: - ftp = ftputil.FtpUploader( - host, user, password, dir) - - self.ic.distftp(type, ftp) - - def destroy(self): - self.ic.destroy() - - def kill(self): - self.ic.kill() - - def usage(self): - self.ic.usage() - - def revision(self): - self.ic.revision() - - def hammer(self): - self.ic.hammer() - - def reformat(self): - self.ic.reformat() - - def open(self): - self.ic.open() +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# TODO: split this file up, it's too long! + +import sys, os, ConfigParser, subprocess, shutil, re, ftputil + +class InternalCommands: + + project = 'synergy-plus' + setup_version = 4 # increment to force setup/config + website_url = 'http://code.google.com/p/synergy-plus' + + this_cmd = 'hm' + cmake_cmd = 'cmake' + qmake_cmd = 'qmake' + make_cmd = 'make' + xcodebuild_cmd = 'xcodebuild' + w32_make_cmd = 'mingw32-make' + w32_qt_version = '4.6.2' + + source_dir = '..' # Source, relative to build. + cmake_dir = 'cmake' + bin_dir = 'bin' + gui_dir = 'gui' + doc_dir = 'doc' + + sln_filename = '%s.sln' % project + xcodeproj_filename = '%s.xcodeproj' % project + config_filename = '%s.cfg' % this_cmd + qtpro_filename = 'qsynergy.pro' + doxygen_filename = 'doxygen.cfg' + + cmake_url = 'http://www.cmake.org/cmake/resources/software.html' + + # try_chdir(...) and restore_chdir() will use this + prevdir = '' + + # by default, no index specified as arg + generator_id = None + + # by default, prompt user for input + no_prompts = False + + # by default, don't compile the gui + 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', + } + + unix_generators = { + '1' : 'Unix Makefiles', + '2' : 'CodeBlocks - Unix Makefiles', + '3' : 'Eclipse CDT4 - Unix Makefiles', + '4' : 'KDevelop3', + '5' : 'KDevelop3 - Unix Makefiles', + } + + darwin_generators = { + '1' : 'Xcode', + '2' : 'Unix Makefiles', + '3' : 'CodeBlocks - Unix Makefiles', + '4' : 'Eclipse CDT4 - Unix Makefiles', + '5' : 'KDevelop3', + '6' : 'KDevelop3 - Unix Makefiles', + } + + def config_filepath(self): + return '%s/%s' % (self.bin_dir, self.config_filename) + + def sln_filepath(self): + return '%s\%s' % (self.bin_dir, self.sln_filename) + + def xcodeproj_filepath(self): + return '%s/%s' % (self.bin_dir, self.xcodeproj_filename) + + def usage(self): + app = sys.argv[0] + print ('Usage: %s [-g |-v|--no-prompts|]\n' + '\n' + 'Replace [command] with one of:\n' + ' about Show information about this script\n' + ' setup Runs the initial setup for this script\n' + ' conf Runs cmake (generates project files)\n' + ' open Attempts to open the generated project file\n' + ' build Builds using the platform build chain\n' + ' clean Cleans using the platform build chain\n' + ' kill Kills all synergy processes (run as admin)\n' + ' update Updates the source code from repository\n' + ' revision Display the current source code revision\n' + ' package Create a distribution package (e.g. tar.gz)\n' + ' install Installs the program\n' + ' doxygen Builds doxygen documentation\n' + ' reformat Reformat .cpp and .h files using AStyle\n' + ' usage Shows the help screen\n' + '\n' + 'Example: %s build -g 3' + ) % (app, app) + + def configure(self): + self.configure_internal() + + print ('Configure complete!\n\n' + 'Open project now: %s open\n' + 'Command line build: %s build' + ) % (self.this_cmd, self.this_cmd) + + def configure_internal(self): + + # ensure latest setup and do not ask config for generator (only fall + # back to prompt if not specified as arg) + self.ensure_setup_latest() + + # ensure that we have access to cmake + _cmake_cmd = self.persist_cmake() + + # now that we know we've got the latest setup, we can ask the config + # file for the generator (but again, we only fall back to this if not + # specified as arg). + generator = self.get_generator_from_config() + + if generator != '': + cmake_args = '%s -G "%s"' % (self.source_dir, generator) + else: + cmake_args = self.source_dir + + cmake_cmd_string = '%s %s' % (_cmake_cmd, cmake_args) + + print "Configuring with CMake (%s)..." % cmake_cmd_string + + # Run from build dir so we have an out-of-source build. + self.try_chdir(self.bin_dir) + err = os.system(cmake_cmd_string) + self.restore_chdir() + + if err != 0: + raise Exception('CMake encountered error: ' + str(err)) + + # allow user to skip qui compile + if self.enable_make_gui: + + # make sure we have qmake + self.persist_qmake() + + qmake_cmd_string = self.qmake_cmd + ' ' + self.qtpro_filename + print "Configuring with QMake (%s)..." % qmake_cmd_string + + # run qmake from the gui dir + self.try_chdir(self.gui_dir) + err = os.system(qmake_cmd_string) + self.restore_chdir() + + if err != 0: + raise Exception('QMake encountered error: ' + str(err)) + + self.set_conf_run() + + def persist_cmake(self): + # even though we're running `cmake --version`, we're only doing this for the 0 return + # code; we don't care about the version, since CMakeLists worrys about this for us. + err = os.system('%s --version' % self.cmake_cmd) + + if err != 0: + # if return code from cmake is not 0, then either something has + # gone terribly wrong with --version, or it genuinely doesn't exist. + print ('Could not find `%s` in system path.\n' + 'Download the latest version from:\n %s') % ( + self.cmake_cmd, self.cmake_url) + raise Exception('Cannot continue without CMake.') + else: + return self.cmake_cmd + + def persist_qt(self): + self.persist_qmake() + if sys.platform == 'win32': + self.persist_w32_make() + + def persist_qmake(self): + try: + p = subprocess.Popen( + [self.qmake_cmd, '--version'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + except: + print >> sys.stderr, 'Error: Could not find qmake.' + if sys.platform == 'win32': # windows devs usually need hints ;) + print ( + 'Suggestions:\n' + '1. Ensure that qmake.exe exists in your system path.\n' + '2. Try to download Qt (check our dev FAQ for links):\n' + ' qt-sdk-win-opensource-2010.02.exe') + raise Exception('Cannot continue without qmake.') + + stdout, stderr = p.communicate() + if p.returncode != 0: + raise Exception('Could not test for cmake: %s' % stderr) + else: + m = re.search('.*Using Qt version (\d+\.\d+\.\d+).*', stdout) + if m: + if sys.platform == 'win32': + ver = m.group(1) + if ver != self.w32_qt_version: # TODO: test properly + print >> sys.stderr, ( + 'Warning: Not using supported Qt version %s' + ' (your version is %s).' + ) % (self.w32_qt_version, ver) + else: + pass # any version should be ok for other platforms + else: + raise Exception('Could not find qmake version.') + + def persist_w32_make(): + # TODO + pass + + def build(self, targets=[]): + + # if no mode specified, default to debug + if len(targets) == 0: + targets += ['debug',] + + self.ensure_setup_latest() + + if not self.has_conf_run(): + self.configure_internal() + + generator = self.get_generator_from_config() + + if generator == "Unix Makefiles": + + print 'Building with GNU Make...' + self.try_chdir(self.bin_dir) + err = os.system(self.make_cmd) + self.restore_chdir() + + if err != 0: + raise Exception('GNU Make failed: ' + str(err)) + + elif generator.startswith('Visual Studio'): + + for target in targets: + self.run_vcbuild(generator, target) + + elif generator == 'Xcode': + + print 'Building with Xcode...' + self.try_chdir(self.bin_dir) + err = os.system(self.xcodebuild_cmd) + self.restore_chdir() + + if err != 0: + raise Exception('Xcode failed: ' + str(err)) + + else: + raise Exception('Not supported with generator: ' + generator) + + # allow user to skip qui compile + if self.enable_make_gui: + self.make_gui(targets) + + def clean(self, targets=[]): + + # if no mode specified, default to debug + if len(targets) == 0: + targets += ['debug',] + + generator = self.get_generator_from_config() + + if generator == "Unix Makefiles": + + print 'Cleaning with GNU Make...' + self.try_chdir(self.bin_dir) + err = os.system(self.make_cmd + ' clean') + self.restore_chdir() + + if err != 0: + raise Exception('GNU Make failed: ' + str(err)) + + # special case for version 10, use new /target:clean + elif generator.startswith('Visual Studio 10'): + + for target in targets: + self.run_vcbuild(generator, target, '/target:clean') + + # any other version of visual studio, use /clean + elif generator.startswith('Visual Studio'): + + for target in targets: + self.run_vcbuild(generator, target, '/clean') + + elif generator == 'Xcode': + + print 'Cleaning with Xcode...' + self.try_chdir(self.bin_dir) + err = os.system(xcodebuild_cmd + ' clean') + self.restore_chdir() + + if err != 0: + raise Exception('Xcode failed: ' + str(err)) + + else: + raise Exception('Not supported with generator: ' + generator) + + # allow user to skip qui compile + clean_targets = [] + if self.enable_make_gui: + for target in targets: + clean_targets.append(target + '-clean') + + self.make_gui(clean_targets) + + def make_gui(self, targets): + if sys.platform == 'win32': + gui_make_cmd = self.w32_make_cmd + elif sys.platform in ['linux2', 'sunos5', 'freebsd7']: + gui_make_cmd = self.make_cmd + elif sys.platform == 'darwin': + gui_make_cmd = self.xcodebuild_cmd + else: + raise Exception('Unsupported platform: ' + sys.platform) + + print 'Running %s...' % gui_make_cmd + + # HACK: don't know how to build in either debug or release on unix; + # always builds release! + if sys.platform == 'win32': + for target in targets: + self.try_chdir(self.gui_dir) + err = os.system(gui_make_cmd + ' ' + target) + self.restore_chdir() + + if err != 0: + raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) + else: + if sys.platform == 'darwin': + make_dir = self.gui_dir + '/QSynergy.xcodeproj' + else: + make_dir = self.gui_dir + + self.try_chdir(make_dir) + err = os.system(gui_make_cmd) + self.restore_chdir() + + def open(self): + generator = self.get_generator_from_config() + if generator.startswith('Visual Studio'): + print 'Opening with %s...' % generator + self.open_internal(self.sln_filepath()) + + elif generator.startswith('Xcode'): + print 'Opening with %s...' % generator + self.open_internal(self.xcodeproj_filepath(), 'open') + + else: + raise Exception('Not supported with generator: ' + generator) + + def update(self): + print "Running Subversion update..." + err = os.system('svn update') + if err != 0: + raise Exception('Could not update from repository with error code code: ' + str(err)) + + def revision(self): + print self.find_revision() + + def find_revision(self): + p = subprocess.Popen(['svn', 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + + if p.returncode != 0: + raise Exception('Could not get revision - svn info failed with code: ' + str(p.returncode)) + + m = re.search('.*Revision: (\d+).*', stdout) + if not m: + raise Exception('Could not find revision number in svn info output.') + + return m.group(1) + + def kill(self): + if sys.platform == 'win32': + return os.system('taskkill /F /FI "IMAGENAME eq synergy*"') + else: + raise Exception('Not implemented for platform: ' + sys.platform) + + def doxygen(self): + # The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in + if not self.has_conf_run(): + self.configure_internal() + + err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename)) + + if err != 0: + raise Exception('doxygen failed with error code: ' + str(err)) + + def dist(self, type): + + # Package is supported by default. + package_unsupported = False + + if type == None: + self.dist_usage() + return + + elif type == 'src': + if sys.platform in ['linux2', 'darwin']: + self.dist_run('make package_source') + else: + package_unsupported = True + + elif type == 'rpm': + if sys.platform == 'linux2': + self.dist_run('cpack -G RPM') + else: + package_unsupported = True + + elif type == 'deb': + if sys.platform == 'linux2': + self.dist_run('cpack -G DEB') + else: + package_unsupported = True + + elif type == 'win': + if sys.platform == 'win32': + self.dist_run('cpack -G NSIS') + else: + package_unsupported = True + + elif type == 'mac': + if sys.platform == 'darwin': + self.dist_run('cpack -G PackageMaker') + else: + package_unsupported = True + + else: + raise Exception('Package type not supported: ' + type) + + if package_unsupported: + raise Exception( + ("Package type, '%s' is not supported for platform, '%s'") + % (type, sys.platform)) + + + def distftp(self, type, ftp): + if not type: + raise Exception('Type not specified.') + + if not ftp: + raise Exception('FTP info not defined.') + + src = self.dist_name(type) + dest = self.dist_name_rev(type) + print 'Uploading %s to FTP server %s...' % (dest, ftp.host) + ftp.run('bin/' + src, dest) + print 'Done' + + def dist_name(self, type): + ext = None + platform = None + + if type == 'src': + ext = 'tar.gz' + platform = 'Source' + + elif type == 'rpm' or type == 'deb': + + # os_bits should be loaded with '32bit' or '64bit' + import platform + (os_bits, other) = platform.architecture() + + # get platform based on current platform + ext = type + if os_bits == '32bit': + platform = 'Linux-i686' + elif os_bits == '64bit': + platform = 'Linux-x86_64' + + elif type == 'win': + + # get platform based on last generator used + ext = 'exe' + generator = self.get_generator_from_config() + if generator.find('Win64') != -1: + platform = 'Windows-x64' + else: + platform = 'Windows-x86' + + elif type == 'mac': + ext = 'dmg' + platform = 'MacOSX-Universal' + + if not platform: + raise Exception('Unable to detect package platform.') + + pattern = re.escape('synergy-plus-') + '\d\.\d\.\d' + re.escape('-' + platform + '.' + ext) + + for filename in os.listdir(self.bin_dir): + if re.search(pattern, filename): + return filename + + # still here? package probably not created yet. + raise Exception('Could not find package name with pattern: ' + pattern) + + def dist_name_rev(self, type): + # find the version number (we're puting the rev in after this) + pattern = '(.*\d+\.\d+\.\d+)(.*)' + replace = '\g<1>-r' + self.find_revision() + '\g<2>' + return re.sub(pattern, replace, self.dist_name(type)) + + def dist_run(self, command): + self.try_chdir(self.bin_dir) + err = os.system(command) + self.restore_chdir() + if err != 0: + raise Exception('Package failed: ' + str(err)) + + def dist_usage(self): + print ('Usage: %s package [package-type]\n' + '\n' + 'Replace [package-type] with one of:\n' + ' src .tar.gz source (Posix only)\n' + ' rpm .rpm package (Red Hat)\n' + ' deb .deb paclage (Debian)\n' + ' win .exe installer (Windows)\n' + ' mac .dmg package (Mac OS X)\n' + '\n' + 'Example: %s package src-tgz') % (self.this_cmd, self.this_cmd) + + def about(self): + print ('Help Me script, from the Synergy+ project.\n' + '%s\n' + '\n' + 'For help, run: %s help') % (self.website_url, self.this_cmd) + + def try_chdir(self, dir): + + # Ensure temp build dir exists. + if not os.path.exists(dir): + os.mkdir(dir) + + global prevdir + prevdir = os.path.abspath(os.curdir) + + # It will exist by this point, so it's safe to chdir. + os.chdir(dir) + + def restore_chdir(self): + global prevdir + os.chdir(prevdir) + + def open_internal(self, project_filename, application = ''): + + if not os.path.exists(project_filename): + raise Exception('Project file (%s) not found, run hm conf first.' % project_filename) + else: + path = project_filename + + if application != '': + path = application + ' ' + path + + err = os.system(path) + if err != 0: + raise Exception('Could not open project with error code code: ' + str(err)) + + def setup(self): + print "Running setup..." + + # always either get generator from args, or prompt user when + # running setup + generator = self.get_generator_from_prompt() + + # Create build dir, since config file resides there. + if not os.path.exists(self.bin_dir): + os.mkdir(self.bin_dir) + + if os.path.exists(self.config_filepath()): + config = ConfigParser.ConfigParser() + config.read(self.config_filepath()) + else: + config = ConfigParser.ConfigParser() + + if not config.has_section('hm'): + config.add_section('hm') + + if not config.has_section('cmake'): + config.add_section('cmake') + + config.set('hm', 'setup_version', self.setup_version) + + # store the generator so we don't need to ask again + config.set('cmake', 'generator', generator) + + self.write_config(config) + + cmakecache_filename = '%s/CMakeCache.txt' % self.bin_dir + if os.path.exists(cmakecache_filename): + print "Removing %s, since generator changed." % cmakecache_filename + os.remove(cmakecache_filename) + + print "\nSetup complete." + + def write_config(self, config): + configfile = open(self.config_filepath(), 'wb') + config.write(configfile) + + def get_generator_from_config(self): + if self.generator_id: + generators = self.get_generators() + return generators[self.generator_id] + else: + config = ConfigParser.RawConfigParser() + config.read(self.config_filepath()) + return config.get('cmake', 'generator') + + def min_setup_version(self, version): + if os.path.exists(self.config_filepath()): + config = ConfigParser.RawConfigParser() + config.read(self.config_filepath()) + + try: + return config.getint('hm', 'setup_version') >= version + except: + return False + else: + return False + + def has_conf_run(self): + if self.min_setup_version(2): + config = ConfigParser.RawConfigParser() + config.read(self.config_filepath()) + try: + return config.getboolean('hm', 'has_conf_run') + except: + return False + else: + return False + + def set_conf_run(self): + if self.min_setup_version(3): + config = ConfigParser.RawConfigParser() + config.read(self.config_filepath()) + config.set('hm', 'has_conf_run', True) + self.write_config(config) + else: + raise Exception("User does not have correct setup version.") + + def get_generators(self): + if sys.platform == 'win32': + return self.win32_generators + elif sys.platform in ['linux2', 'sunos5', 'freebsd7']: + return self.unix_generators + elif sys.platform == 'darwin': + return self.darwin_generators + else: + raise Exception('Unsupported platform: ' + sys.platform) + + def get_generator_from_prompt(self): + + generators = self.get_generators() + + # 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) + + else: + raise Exception('No generator specified, and cannot prompt user.') + + def setup_generator_prompt(self, generators): + + if self.no_prompts: + raise Exception('User prompting is disabled.') + + prompt = 'Enter a number:' + print prompt, + + generator_id = raw_input() + + if generator_id in generators: + print 'Selected generator:', generators[generator_id] + else: + print 'Invalid number, try again.' + self.setup_generator_prompt(generators) + + return generators[generator_id] + + def get_vcvarsall(self, generator): + import platform, _winreg + + # os_bits should be loaded with '32bit' or '64bit' + (os_bits, other) = platform.architecture() + + # visual studio is a 32-bit app, so when we're on 64-bit, we need to check the WoW dungeon + if os_bits == '64bit': + key_name = r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7' + else: + key_name = r'SOFTWARE\Microsoft\VisualStudio\SxS\VC7' + + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name) + except: + raise Exception('Unable to open Visual Studio registry key. Application may not be installed.') + + if generator.startswith('Visual Studio 8'): + value,type = _winreg.QueryValueEx(key, '8.0') + elif generator.startswith('Visual Studio 9'): + value,type = _winreg.QueryValueEx(key, '9.0') + elif generator.startswith('Visual Studio 10'): + value,type = _winreg.QueryValueEx(key, '10.0') + else: + raise Exception('Cannot determin vcvarsall.bat location for: ' + generator) + + # not sure why, but the value on 64-bit differs slightly to the original + if os_bits == '64bit': + path = value + r'vc\vcvarsall.bat' + else: + path = value + r'vcvarsall.bat' + + if not os.path.exists(path): + raise Exception("'%s' not found." % path) + + return path + + def run_vcbuild(self, generator, mode, args=''): + import platform + + # os_bits should be loaded with '32bit' or '64bit' + (os_bits, other) = platform.architecture() + # Now we choose the parameters bases on OS 32/64 and our target 32/64 + # http://msdn.microsoft.com/en-us/library/x4d2c09s%28VS.80%29.aspx + + # valid options are only: ia64 amd64 x86_amd64 x86_ia64 + # but calling vcvarsall.bat does not garantee that it will work + # ret code from vcvarsall.bat is always 0 so the only way of knowing that I worked is by analysing the text output + # ms bugg: install VS9, FeaturePack, VS9SP1 and you'll obtain a vcvarsall.bat that fails. + if generator.find('Win64') != -1: + # target = 64bit + if os_bits == '32bit': + vcvars_platform = 'x86_amd64' # 32bit OS building 64bit app + else: + vcvars_platform = 'amd64' # 64bit OS building 64bit app + config_platform = 'x64' + else: # target = 32bit + vcvars_platform = 'x86' # 32/64bit OS building 32bit app + config_platform = 'Win32' + if mode == 'release': + config = 'Release' + else: + config = 'Debug' + + if generator.startswith('Visual Studio 10'): + cmd = ('@echo off\n' + 'call "%s" %s \n' + 'msbuild /nologo %s /p:Configuration="%s" /p:Platform="%s" "%s"' + ) % (self.get_vcvarsall(generator), vcvars_platform, args, config, config_platform, self.sln_filepath()) + else: + config = config + '|' + config_platform + cmd = ('@echo off\n' + 'call "%s" %s \n' + 'vcbuild /nologo %s "%s" "%s"' + ) % (self.get_vcvarsall(generator), vcvars_platform, args, self.sln_filepath(), config) + + # Generate a batch file, since we can't use environment variables directly. + temp_bat = self.bin_dir + r'\vcbuild.bat' + file = open(temp_bat, 'w') + file.write(cmd) + file.close() + + err = os.system(temp_bat) + if err != 0: + raise Exception('Microsoft compiler failed with error code: ' + str(err)) + + def ensure_setup_latest(self): + if not self.min_setup_version(self.setup_version): + self.setup() + + def reformat(self): + err = os.system( + r'tool\astyle\AStyle.exe ' + '--quiet --suffix=none --style=java --indent=force-tab=4 --recursive ' + 'lib/*.cpp lib/*.h cmd/*.cpp cmd/*.h') + + if err != 0: + raise Exception('Reformat failed with error code: ' + str(err)) + +# 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 +# commands class. +class CommandHandler: + ic = InternalCommands() + build_targets = [] + + def __init__(self, argv, opts, args, verbose): + + self.ic.verbose = verbose + + self.opts = opts + self.args = args + + for o, a in self.opts: + if o == '--no-prompts': + self.ic.no_prompts = True + elif o in ('-g', '--generator'): + self.ic.generator_id = a + elif o == '--make-gui': + self.ic.enable_make_gui = True + elif o in ('-d', '--debug'): + self.build_targets += ['debug',] + elif o in ('-r', '--release'): + self.build_targets += ['release',] + + def about(self): + self.ic.about() + + def setup(self): + self.ic.setup() + + def configure(self): + self.ic.configure() + + def build(self): + self.ic.build(self.build_targets) + + def clean(self): + self.ic.clean(self.build_targets) + + def update(self): + self.ic.update() + + def install(self): + print 'Not yet implemented: install' + + def doxygen(self): + self.ic.doxygen () + + def dist(self): + + type = None + if len(self.args) > 0: + type = self.args[0] + + self.ic.dist(type) + + def distftp(self): + type = None + host = None + user = None + password = None + dir = None + + if len(self.args) > 0: + type = self.args[0] + + for o, a in self.opts: + if o == '--host': + host = a + elif o == '--user': + user = a + elif o == '--pass': + password = a + elif o == '--dir': + dir = a + + ftp = None + if host: + ftp = ftputil.FtpUploader( + host, user, password, dir) + + self.ic.distftp(type, ftp) + + def destroy(self): + self.ic.destroy() + + def kill(self): + self.ic.kill() + + def usage(self): + self.ic.usage() + + def revision(self): + self.ic.revision() + + def hammer(self): + self.ic.hammer() + + def reformat(self): + self.ic.reformat() + + def open(self): + self.ic.open() diff --git a/build/ftputil.py b/build/ftputil.py index 7b0c592a..40cf62bd 100644 --- a/build/ftputil.py +++ b/build/ftputil.py @@ -1,42 +1,42 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2010 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from ftplib import FTP - -class FtpUploader: - def __init__(self, host, user, password, dir): - self.host = host - self.user = user - self.password = password - self.dir = dir - - def run(self, src, dest, replace=False): - - ftp = FTP(self.host, self.user, self.password) - ftp.cwd(self.dir) - - # check to see if we should stop here - if not replace: - files = ftp.nlst() - if dest in files: - print 'Already exists, skipping.' - ftp.close() - return - - f = open(src, 'rb') - ftp.storbinary('STOR ' + dest, f) - f.close() - - ftp.close() +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2010 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from ftplib import FTP + +class FtpUploader: + def __init__(self, host, user, password, dir): + self.host = host + self.user = user + self.password = password + self.dir = dir + + def run(self, src, dest, replace=False): + + ftp = FTP(self.host, self.user, self.password) + ftp.cwd(self.dir) + + # check to see if we should stop here + if not replace: + files = ftp.nlst() + if dest in files: + print 'Already exists, skipping.' + ftp.close() + return + + f = open(src, 'rb') + ftp.storbinary('STOR ' + dest, f) + f.close() + + ftp.close() diff --git a/cmake/CMakeLists_config.txt b/cmake/CMakeLists_config.txt index 4254fb86..6312ba44 100644 --- a/cmake/CMakeLists_config.txt +++ b/cmake/CMakeLists_config.txt @@ -1,20 +1,20 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Declare libs, so we can use list in linker later. There's probably -# a more elegant way of doing this; with SCons, when you check for the +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Declare libs, so we can use list in linker later. There's probably +# a more elegant way of doing this; with SCons, when you check for the # lib, it is automatically passed to the linker. SET(libs) @@ -209,8 +209,8 @@ IF(UNIX) ENDIF(APPLE) ELSE(UNIX) - - LIST(APPEND libs Wtsapi32 Userenv) + + LIST(APPEND libs Wtsapi32 Userenv) ADD_DEFINITIONS( /DWIN32 diff --git a/cmake/CMakeLists_cpack.txt b/cmake/CMakeLists_cpack.txt index 56a1c43c..dd470f3a 100644 --- a/cmake/CMakeLists_cpack.txt +++ b/cmake/CMakeLists_cpack.txt @@ -1,135 +1,135 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# List of CPack variables: -# http://www.vtk.org/Wiki/CMake:CPackConfiguration - -# CPack files common to all platforms. -SET(cpack_targets synergys synergyc) - -IF(WIN32) - # Windows has an extra GUI and DLL. - LIST(APPEND cpack_targets launcher synrgyhk) -ENDIF(WIN32) - -INSTALL( - TARGETS ${cpack_targets} - RUNTIME DESTINATION bin) - -IF(WIN32) - INSTALL( - FILES - bin/Release/qsynergy.exe - DESTINATION bin) -ELSE(WIN32) - IF(APPLE) - # TODO: how the hell do we distribute mac apps? - #INSTALL( - # MACOSX_BUNDLE - # bin/QSynergy.app - # DESTINATION bin) - ELSE(APPLE) - INSTALL( - FILES - bin/qsynergy - DESTINATION bin) - ENDIF(APPLE) -ENDIF(WIN32) - -# The default CPack behaviour is not to append the system processor -# type, which is undesirable in our case, since we want to support -# both 32-bit and 64-bit processors. -SET(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}) - -# Hack: When running CMake on 64-bit Windows 7, the value of -# CMAKE_SYSTEM_PROCESSOR always seems to be x86, regardless of if the -# CMake build is 32-bit or 64-bit. As a work around, we will prefix either -# x86 or x64 (in the same style as Microsoft do with their installers). -# However, some confusion may be caused when the user sees that Synergy+ -# is installed in the x86 Program Files directory (even though it's a -# 64-bit build). This is caused by NSIS only supporting the 32-bit -# installs structure (also uses 32-bit registry key locations). -IF(WIN32) - IF(CMAKE_CL_64) - SET(CPACK_SYSTEM_NAME Windows-x64) - ELSE(CMAKE_CL_64) - SET(CPACK_SYSTEM_NAME Windows-x86) - ENDIF(CMAKE_CL_64) -ENDIF(WIN32) - -# For source code, use .tar.gz on Unix, and .zip on Windows -IF(UNIX) - SET(CPACK_SOURCE_GENERATOR TGZ) -ELSE(UNIX) - SET(CPACK_SOURCE_GENERATOR ZIP) +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# List of CPack variables: +# http://www.vtk.org/Wiki/CMake:CPackConfiguration + +# CPack files common to all platforms. +SET(cpack_targets synergys synergyc) + +IF(WIN32) + # Windows has an extra GUI and DLL. + LIST(APPEND cpack_targets launcher synrgyhk) +ENDIF(WIN32) + +INSTALL( + TARGETS ${cpack_targets} + RUNTIME DESTINATION bin) + +IF(WIN32) + INSTALL( + FILES + bin/Release/qsynergy.exe + DESTINATION bin) +ELSE(WIN32) + IF(APPLE) + # TODO: how the hell do we distribute mac apps? + #INSTALL( + # MACOSX_BUNDLE + # bin/QSynergy.app + # DESTINATION bin) + ELSE(APPLE) + INSTALL( + FILES + bin/qsynergy + DESTINATION bin) + ENDIF(APPLE) +ENDIF(WIN32) + +# The default CPack behaviour is not to append the system processor +# type, which is undesirable in our case, since we want to support +# both 32-bit and 64-bit processors. +SET(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}) + +# Hack: When running CMake on 64-bit Windows 7, the value of +# CMAKE_SYSTEM_PROCESSOR always seems to be x86, regardless of if the +# CMake build is 32-bit or 64-bit. As a work around, we will prefix either +# x86 or x64 (in the same style as Microsoft do with their installers). +# However, some confusion may be caused when the user sees that Synergy+ +# is installed in the x86 Program Files directory (even though it's a +# 64-bit build). This is caused by NSIS only supporting the 32-bit +# installs structure (also uses 32-bit registry key locations). +IF(WIN32) + IF(CMAKE_CL_64) + SET(CPACK_SYSTEM_NAME Windows-x64) + ELSE(CMAKE_CL_64) + SET(CPACK_SYSTEM_NAME Windows-x86) + ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +# For source code, use .tar.gz on Unix, and .zip on Windows +IF(UNIX) + SET(CPACK_SOURCE_GENERATOR TGZ) +ELSE(UNIX) + SET(CPACK_SOURCE_GENERATOR ZIP) ENDIF(UNIX) if(APPLE) set(CPACK_SYSTEM_NAME "MacOSX-Universal") -endif(APPLE) - -SET(CPACK_PACKAGE_NAME "synergy-plus") -SET(CPACK_PACKAGE_VENDOR "The Synergy+ Project") -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installs Synergy+ server and client") -SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) -SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) -SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_REV}) -SET(CPACK_PACKAGE_VERSION ${VERSION}) -SET(CPACK_PACKAGE_CONTACT http://code.google.com/p/synergy-plus/) -SET(CPACK_RESOURCE_FILE_LICENSE "${cmake_dir}/License.rtf") -SET(CPACK_RESOURCE_FILE_README "${cmake_dir}/Readme.txt") - -IF(WIN32) - SET(WIN32_ICON "${root_dir}/cmd/launcher/synergy.ico") - SET(CPACK_NSIS_MUI_ICON ${WIN32_ICON}) - SET(CPACK_NSIS_MUI_UNIICON ${WIN32_ICON}) - SET(CPACK_NSIS_INSTALLED_ICON_NAME launcher) - SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Synergy+") - SET(CPACK_PACKAGE_EXECUTABLES qsynergy;Synergy+) -ENDIF(WIN32) - -# files to exclude from src package (regex patterns) -# to escape, use 4 backslashes (\\\\) -- yuck! -SET(CPACK_SOURCE_IGNORE_FILES - # temp output dir in root - "/bin/" - - # generated config.h file - "/config\\\\.h$" - - # buildbot stuff - "\\\\.buildbot\\\\-sourcedata$" - - # qt temp build dir - "/gui/tmp/.*" - - # qt make file - "/gui/Makefile$" - - # qt generated ui headers - "/gui/ui_.*\\\\.h$" - - # compiled python files - ".*\\\\.pyc$" - - # subversion caches (all dirs) - ".*/\\\\.svn/.*" - - # emacs temporary files - ".*~$" -) - -# Must be last (since it relies of CPACK_ vars). -INCLUDE(CPack) +endif(APPLE) + +SET(CPACK_PACKAGE_NAME "synergy-plus") +SET(CPACK_PACKAGE_VENDOR "The Synergy+ Project") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installs Synergy+ server and client") +SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_REV}) +SET(CPACK_PACKAGE_VERSION ${VERSION}) +SET(CPACK_PACKAGE_CONTACT http://code.google.com/p/synergy-plus/) +SET(CPACK_RESOURCE_FILE_LICENSE "${cmake_dir}/License.rtf") +SET(CPACK_RESOURCE_FILE_README "${cmake_dir}/Readme.txt") + +IF(WIN32) + SET(WIN32_ICON "${root_dir}/cmd/launcher/synergy.ico") + SET(CPACK_NSIS_MUI_ICON ${WIN32_ICON}) + SET(CPACK_NSIS_MUI_UNIICON ${WIN32_ICON}) + SET(CPACK_NSIS_INSTALLED_ICON_NAME launcher) + SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Synergy+") + SET(CPACK_PACKAGE_EXECUTABLES qsynergy;Synergy+) +ENDIF(WIN32) + +# files to exclude from src package (regex patterns) +# to escape, use 4 backslashes (\\\\) -- yuck! +SET(CPACK_SOURCE_IGNORE_FILES + # temp output dir in root + "/bin/" + + # generated config.h file + "/config\\\\.h$" + + # buildbot stuff + "\\\\.buildbot\\\\-sourcedata$" + + # qt temp build dir + "/gui/tmp/.*" + + # qt make file + "/gui/Makefile$" + + # qt generated ui headers + "/gui/ui_.*\\\\.h$" + + # compiled python files + ".*\\\\.pyc$" + + # subversion caches (all dirs) + ".*/\\\\.svn/.*" + + # emacs temporary files + ".*~$" +) + +# Must be last (since it relies of CPACK_ vars). +INCLUDE(CPack) diff --git a/cmake/CMakeLists_launcher.txt b/cmake/CMakeLists_launcher.txt index 09131ca2..3037fe7f 100644 --- a/cmake/CMakeLists_launcher.txt +++ b/cmake/CMakeLists_launcher.txt @@ -1,84 +1,84 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -IF(WIN32) - SET(root_cmd_launcher ${root_dir}/cmd/launcher) - - SET(src_cmd_launcher_mswindows - ${root_cmd_launcher}/CAddScreen.cpp - ${root_cmd_launcher}/CAdvancedOptions.cpp - ${root_cmd_launcher}/CAutoStart.cpp - ${root_cmd_launcher}/CGlobalOptions.cpp - ${root_cmd_launcher}/CHotkeyOptions.cpp - ${root_cmd_launcher}/CInfo.cpp - ${root_cmd_launcher}/CScreensLinks.cpp - ${root_cmd_launcher}/LaunchUtil.cpp - ${root_cmd_launcher}/launcher.cpp - ) - - SET(inc_cmd_launcher_mswindows - ${root_cmd_launcher}/CAddScreen.h - ${root_cmd_launcher}/CAdvancedOptions.h - ${root_cmd_launcher}/CAutoStart.h - ${root_cmd_launcher}/CGlobalOptions.h - ${root_cmd_launcher}/CHotkeyOptions.h - ${root_cmd_launcher}/CInfo.h - ${root_cmd_launcher}/CScreensLinks.h - ${root_cmd_launcher}/LaunchUtil.h - ${root_cmd_launcher}/resource.h - ) - - SET(res_cmd_launcher_mswindows - ${root_cmd_launcher}/launcher.rc - ${root_cmd_launcher}/synergy.ico - ) - - SET(src_cmd_launcher) - - IF(UNIX) - IF(APPLE) - LIST(APPEND src_cmd_launcher ${src_cmd_launcher_carbon}) - ELSE(APPLE) - LIST(APPEND src_cmd_launcher ${src_cmd_launcher_xwindows}) - ENDIF(APPLE) - ENDIF(UNIX) - - IF(WIN32) - LIST(APPEND src_cmd_launcher - ${inc_cmd_launcher_mswindows} - ${res_cmd_launcher_mswindows} - ${src_cmd_launcher_mswindows} - ) - ENDIF(WIN32) - - SET(inc_dirs_cmd_launcher - ${root_dir} - ${root_dir}/lib - ${root_dir}/lib/arch - ${root_dir}/lib/base - ${root_dir}/lib/common - ${root_dir}/lib/io - ${root_dir}/lib/mt - ${root_dir}/lib/net - ${root_dir}/lib/platform - ${root_dir}/lib/synergy - ${root_dir}/lib/server - ) - - INCLUDE_DIRECTORIES(${inc_dirs_cmd_launcher}) - ADD_EXECUTABLE(launcher WIN32 ${src_cmd_launcher}) - TARGET_LINK_LIBRARIES(launcher synergy ${libs}) - -ENDIF(WIN32) +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +IF(WIN32) + SET(root_cmd_launcher ${root_dir}/cmd/launcher) + + SET(src_cmd_launcher_mswindows + ${root_cmd_launcher}/CAddScreen.cpp + ${root_cmd_launcher}/CAdvancedOptions.cpp + ${root_cmd_launcher}/CAutoStart.cpp + ${root_cmd_launcher}/CGlobalOptions.cpp + ${root_cmd_launcher}/CHotkeyOptions.cpp + ${root_cmd_launcher}/CInfo.cpp + ${root_cmd_launcher}/CScreensLinks.cpp + ${root_cmd_launcher}/LaunchUtil.cpp + ${root_cmd_launcher}/launcher.cpp + ) + + SET(inc_cmd_launcher_mswindows + ${root_cmd_launcher}/CAddScreen.h + ${root_cmd_launcher}/CAdvancedOptions.h + ${root_cmd_launcher}/CAutoStart.h + ${root_cmd_launcher}/CGlobalOptions.h + ${root_cmd_launcher}/CHotkeyOptions.h + ${root_cmd_launcher}/CInfo.h + ${root_cmd_launcher}/CScreensLinks.h + ${root_cmd_launcher}/LaunchUtil.h + ${root_cmd_launcher}/resource.h + ) + + SET(res_cmd_launcher_mswindows + ${root_cmd_launcher}/launcher.rc + ${root_cmd_launcher}/synergy.ico + ) + + SET(src_cmd_launcher) + + IF(UNIX) + IF(APPLE) + LIST(APPEND src_cmd_launcher ${src_cmd_launcher_carbon}) + ELSE(APPLE) + LIST(APPEND src_cmd_launcher ${src_cmd_launcher_xwindows}) + ENDIF(APPLE) + ENDIF(UNIX) + + IF(WIN32) + LIST(APPEND src_cmd_launcher + ${inc_cmd_launcher_mswindows} + ${res_cmd_launcher_mswindows} + ${src_cmd_launcher_mswindows} + ) + ENDIF(WIN32) + + SET(inc_dirs_cmd_launcher + ${root_dir} + ${root_dir}/lib + ${root_dir}/lib/arch + ${root_dir}/lib/base + ${root_dir}/lib/common + ${root_dir}/lib/io + ${root_dir}/lib/mt + ${root_dir}/lib/net + ${root_dir}/lib/platform + ${root_dir}/lib/synergy + ${root_dir}/lib/server + ) + + INCLUDE_DIRECTORIES(${inc_dirs_cmd_launcher}) + ADD_EXECUTABLE(launcher WIN32 ${src_cmd_launcher}) + TARGET_LINK_LIBRARIES(launcher synergy ${libs}) + +ENDIF(WIN32) diff --git a/cmake/CMakeLists_lib.txt b/cmake/CMakeLists_lib.txt index 9e847cd9..97ef137c 100644 --- a/cmake/CMakeLists_lib.txt +++ b/cmake/CMakeLists_lib.txt @@ -1,415 +1,415 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -SET(root_lib ${root_dir}/lib) - -SET(src_lib_arch - ${root_lib}/arch/CArchAppUtil.cpp - ${root_lib}/arch/CArch.cpp - ${root_lib}/arch/CArchDaemonNone.cpp - ${root_lib}/arch/XArch.cpp - ${root_lib}/arch/CArchConsoleStd.cpp -) - -SET(src_lib_arch_unix - ${root_lib}/arch/CArchAppUtilUnix.cpp - ${root_lib}/arch/CArchConsoleUnix.cpp - ${root_lib}/arch/CArchDaemonUnix.cpp - ${root_lib}/arch/CArchFileUnix.cpp - ${root_lib}/arch/CArchLogUnix.cpp - ${root_lib}/arch/CArchMultithreadPosix.cpp - ${root_lib}/arch/CArchNetworkBSD.cpp - ${root_lib}/arch/CArchSleepUnix.cpp - ${root_lib}/arch/CArchStringUnix.cpp - ${root_lib}/arch/CArchSystemUnix.cpp - ${root_lib}/arch/CArchTaskBarXWindows.cpp - ${root_lib}/arch/CArchTimeUnix.cpp - ${root_lib}/arch/XArchUnix.cpp -) - -SET(src_lib_arch_windows - ${root_lib}/arch/CArchAppUtilWindows.cpp - ${root_lib}/arch/CArchConsoleWindows.cpp - ${root_lib}/arch/CArchDaemonWindows.cpp - ${root_lib}/arch/CArchFileWindows.cpp - ${root_lib}/arch/CArchLogWindows.cpp - ${root_lib}/arch/CArchMiscWindows.cpp - ${root_lib}/arch/CArchMultithreadWindows.cpp - ${root_lib}/arch/CArchNetworkWinsock.cpp - ${root_lib}/arch/CArchSleepWindows.cpp - ${root_lib}/arch/CArchStringWindows.cpp - ${root_lib}/arch/CArchSystemWindows.cpp - ${root_lib}/arch/CArchTaskBarWindows.cpp - ${root_lib}/arch/CArchTimeWindows.cpp - ${root_lib}/arch/XArchWindows.cpp -) - -SET(inc_lib_arch_windows - ${root_lib}/arch/CArchAppUtil.h - ${root_lib}/arch/CArchAppUtilWindows.h - ${root_lib}/arch/CArchConsoleWindows.h - ${root_lib}/arch/CArchDaemonWindows.h - ${root_lib}/arch/CArchFileWindows.h - ${root_lib}/arch/CArchLogWindows.h - ${root_lib}/arch/CArchMiscWindows.h - ${root_lib}/arch/CArchMultithreadWindows.h - ${root_lib}/arch/CArchNetworkWinsock.h - ${root_lib}/arch/CArchSleepWindows.h - ${root_lib}/arch/CArchStringWindows.h - ${root_lib}/arch/CArchSystemWindows.h - ${root_lib}/arch/CArchTaskBarWindows.h - ${root_lib}/arch/CArchTimeWindows.h - ${root_lib}/arch/CArchConsoleStd.h - ${root_lib}/arch/IArchAppUtil.h - ${root_lib}/arch/XArchWindows.h -) - -SET(src_lib_base - ${root_lib}/base/CEvent.cpp - ${root_lib}/base/CEventQueue.cpp - ${root_lib}/base/CFunctionEventJob.cpp - ${root_lib}/base/CFunctionJob.cpp - ${root_lib}/base/CLog.cpp - ${root_lib}/base/CSimpleEventQueueBuffer.cpp - ${root_lib}/base/CStopwatch.cpp - ${root_lib}/base/CStringUtil.cpp - ${root_lib}/base/CUnicode.cpp - ${root_lib}/base/IEventQueue.cpp - ${root_lib}/base/LogOutputters.cpp - ${root_lib}/base/XBase.cpp -) - -SET(inc_lib_base - ${root_lib}/base/CEvent.h - ${root_lib}/base/CEventQueue.h - ${root_lib}/base/CFunctionEventJob.h - ${root_lib}/base/CFunctionJob.h - ${root_lib}/base/CLog.h - ${root_lib}/base/CPriorityQueue.h - ${root_lib}/base/CSimpleEventQueueBuffer.h - ${root_lib}/base/CStopwatch.h - ${root_lib}/base/CString.h - ${root_lib}/base/CStringUtil.h - ${root_lib}/base/CUnicode.h - ${root_lib}/base/IEventJob.h - ${root_lib}/base/IEventQueue.h - ${root_lib}/base/IEventQueueBuffer.h - ${root_lib}/base/IJob.h - ${root_lib}/base/ILogOutputter.h - ${root_lib}/base/LogOutputters.h - ${root_lib}/base/TMethodEventJob.h - ${root_lib}/base/TMethodJob.h - ${root_lib}/base/XBase.h -) - -SET(src_lib_client - ${root_lib}/client/CClient.cpp - ${root_lib}/client/CServerProxy.cpp -) - -SET(inc_lib_client - ${root_lib}/client/CClient.h - ${root_lib}/client/CServerProxy.h -) - -SET(src_lib_common - ${root_lib}/common/Version.cpp -) - -SET(inc_lib_common - ${root_lib}/common/Version.h -) - -SET(src_lib_io - ${root_lib}/io/CStreamBuffer.cpp - ${root_lib}/io/CStreamFilter.cpp - ${root_lib}/io/IStream.cpp - ${root_lib}/io/XIO.cpp -) - -SET(inc_lib_io - ${root_lib}/io/CStreamBuffer.h - ${root_lib}/io/CStreamFilter.h - ${root_lib}/io/IStream.h - ${root_lib}/io/IStreamFilterFactory.h - ${root_lib}/io/XIO.h -) - -SET(src_lib_mt - ${root_lib}/mt/CCondVar.cpp - ${root_lib}/mt/CLock.cpp - ${root_lib}/mt/CMutex.cpp - ${root_lib}/mt/CThread.cpp - ${root_lib}/mt/XMT.cpp -) - -SET(inc_lib_mt - ${root_lib}/mt/CCondVar.h - ${root_lib}/mt/CLock.h - ${root_lib}/mt/CMutex.h - ${root_lib}/mt/CThread.h - ${root_lib}/mt/XMT.h - ${root_lib}/mt/XThread.h -) - -SET(src_lib_net - ${root_lib}/net/CNetworkAddress.cpp - ${root_lib}/net/CSocketMultiplexer.cpp - ${root_lib}/net/CTCPListenSocket.cpp - ${root_lib}/net/CTCPSocket.cpp - ${root_lib}/net/CTCPSocketFactory.cpp - ${root_lib}/net/IDataSocket.cpp - ${root_lib}/net/IListenSocket.cpp - ${root_lib}/net/ISocket.cpp - ${root_lib}/net/XSocket.cpp -) - -SET(inc_lib_net - ${root_lib}/net/CNetworkAddress.h - ${root_lib}/net/CSocketMultiplexer.h - ${root_lib}/net/CTCPListenSocket.h - ${root_lib}/net/CTCPSocket.h - ${root_lib}/net/CTCPSocketFactory.h - ${root_lib}/net/IDataSocket.h - ${root_lib}/net/IListenSocket.h - ${root_lib}/net/ISocket.h - ${root_lib}/net/ISocketFactory.h - ${root_lib}/net/ISocketMultiplexerJob.h - ${root_lib}/net/TSocketMultiplexerMethodJob.h - ${root_lib}/net/XSocket.h -) - -SET(src_lib_platform_xwindows - ${root_lib}/platform/CXWindowsClipboard.cpp - ${root_lib}/platform/CXWindowsClipboardAnyBitmapConverter.cpp - ${root_lib}/platform/CXWindowsClipboardBMPConverter.cpp - ${root_lib}/platform/CXWindowsClipboardHTMLConverter.cpp - ${root_lib}/platform/CXWindowsClipboardTextConverter.cpp - ${root_lib}/platform/CXWindowsClipboardUCS2Converter.cpp - ${root_lib}/platform/CXWindowsClipboardUTF8Converter.cpp - ${root_lib}/platform/CXWindowsEventQueueBuffer.cpp - ${root_lib}/platform/CXWindowsKeyState.cpp - ${root_lib}/platform/CXWindowsScreen.cpp - ${root_lib}/platform/CXWindowsScreenSaver.cpp - ${root_lib}/platform/CXWindowsUtil.cpp -) - -SET(src_lib_platform_mswindows - ${root_lib}/platform/CMSWindowsClipboard.cpp - ${root_lib}/platform/CMSWindowsClipboardAnyTextConverter.cpp - ${root_lib}/platform/CMSWindowsClipboardBitmapConverter.cpp - ${root_lib}/platform/CMSWindowsClipboardHTMLConverter.cpp - ${root_lib}/platform/CMSWindowsClipboardTextConverter.cpp - ${root_lib}/platform/CMSWindowsClipboardUTF16Converter.cpp - ${root_lib}/platform/CMSWindowsDesks.cpp - ${root_lib}/platform/CMSWindowsEventQueueBuffer.cpp - ${root_lib}/platform/CMSWindowsKeyState.cpp - ${root_lib}/platform/CMSWindowsScreen.cpp - ${root_lib}/platform/CMSWindowsScreenSaver.cpp - ${root_lib}/platform/CMSWindowsUtil.cpp - ${root_lib}/platform/CMSWindowsRelauncher.cpp -) - -SET(inc_lib_platform_mswindows - ${root_lib}/platform/CMSWindowsClipboard.h - ${root_lib}/platform/CMSWindowsClipboardAnyTextConverter.h - ${root_lib}/platform/CMSWindowsClipboardBitmapConverter.h - ${root_lib}/platform/CMSWindowsClipboardHTMLConverter.h - ${root_lib}/platform/CMSWindowsClipboardTextConverter.h - ${root_lib}/platform/CMSWindowsClipboardUTF16Converter.h - ${root_lib}/platform/CMSWindowsDesks.h - ${root_lib}/platform/CMSWindowsEventQueueBuffer.h - ${root_lib}/platform/CMSWindowsKeyState.h - ${root_lib}/platform/CMSWindowsScreen.h - ${root_lib}/platform/CMSWindowsScreenSaver.h - ${root_lib}/platform/CMSWindowsUtil.h - ${root_lib}/platform/CMSWindowsRelauncher.h -) - -SET(src_lib_platform_hook - ${root_lib}/platform/CSynergyHook.cpp -) - -SET(inc_lib_platform_hook - ${root_lib}/platform/CSynergyHook.h -) - -SET(src_lib_platform_carbon - ${root_lib}/platform/COSXClipboard.cpp - ${root_lib}/platform/COSXClipboardAnyTextConverter.cpp - ${root_lib}/platform/COSXClipboardTextConverter.cpp - ${root_lib}/platform/COSXClipboardUTF16Converter.cpp - ${root_lib}/platform/COSXEventQueueBuffer.cpp - ${root_lib}/platform/COSXKeyState.cpp - ${root_lib}/platform/COSXScreen.cpp - ${root_lib}/platform/COSXScreenSaver.cpp - ${root_lib}/platform/COSXScreenSaverUtil.m -) - -SET(src_lib_server - ${root_lib}/server/CBaseClientProxy.cpp - ${root_lib}/server/CClientListener.cpp - ${root_lib}/server/CClientProxy.cpp - ${root_lib}/server/CClientProxy1_0.cpp - ${root_lib}/server/CClientProxy1_1.cpp - ${root_lib}/server/CClientProxy1_2.cpp - ${root_lib}/server/CClientProxy1_3.cpp - ${root_lib}/server/CClientProxyUnknown.cpp - ${root_lib}/server/CConfig.cpp - ${root_lib}/server/CInputFilter.cpp - ${root_lib}/server/CPrimaryClient.cpp - ${root_lib}/server/CServer.cpp -) - -SET(inc_lib_server - ${root_lib}/server/CBaseClientProxy.h - ${root_lib}/server/CClientListener.h - ${root_lib}/server/CClientProxy.h - ${root_lib}/server/CClientProxy1_0.h - ${root_lib}/server/CClientProxy1_1.h - ${root_lib}/server/CClientProxy1_2.h - ${root_lib}/server/CClientProxy1_3.h - ${root_lib}/server/CClientProxyUnknown.h - ${root_lib}/server/CConfig.h - ${root_lib}/server/CInputFilter.h - ${root_lib}/server/CPrimaryClient.h - ${root_lib}/server/CServer.h -) - -SET(src_lib_synergy - ${root_lib}/synergy/CClientTaskBarReceiver.cpp - ${root_lib}/synergy/CServerTaskBarReceiver.cpp - ${root_lib}/synergy/CApp.cpp - ${root_lib}/synergy/CClientApp.cpp - ${root_lib}/synergy/CServerApp.cpp - ${root_lib}/synergy/CClipboard.cpp - ${root_lib}/synergy/CKeyMap.cpp - ${root_lib}/synergy/CKeyState.cpp - ${root_lib}/synergy/CPacketStreamFilter.cpp - ${root_lib}/synergy/CPlatformScreen.cpp - ${root_lib}/synergy/CProtocolUtil.cpp - ${root_lib}/synergy/CScreen.cpp - ${root_lib}/synergy/IClipboard.cpp - ${root_lib}/synergy/IKeyState.cpp - ${root_lib}/synergy/IPrimaryScreen.cpp - ${root_lib}/synergy/IScreen.cpp - ${root_lib}/synergy/KeyTypes.cpp - ${root_lib}/synergy/ProtocolTypes.cpp - ${root_lib}/synergy/XScreen.cpp - ${root_lib}/synergy/XSynergy.cpp -) - -SET(inc_lib_synergy - ${root_lib}/synergy/CClientTaskBarReceiver.h - ${root_lib}/synergy/CServerTaskBarReceiver.h - ${root_lib}/synergy/CApp.h - ${root_lib}/synergy/CClientApp.h - ${root_lib}/synergy/CServerApp.h - ${root_lib}/synergy/CClipboard.h - ${root_lib}/synergy/CKeyMap.h - ${root_lib}/synergy/CKeyState.h - ${root_lib}/synergy/CPacketStreamFilter.h - ${root_lib}/synergy/CPlatformScreen.h - ${root_lib}/synergy/CProtocolUtil.h - ${root_lib}/synergy/CScreen.h - ${root_lib}/synergy/ClipboardTypes.h - ${root_lib}/synergy/IClient.h - ${root_lib}/synergy/IClipboard.h - ${root_lib}/synergy/IKeyState.h - ${root_lib}/synergy/IPlatformScreen.h - ${root_lib}/synergy/IPrimaryScreen.h - ${root_lib}/synergy/IScreen.h - ${root_lib}/synergy/IScreenSaver.h - ${root_lib}/synergy/ISecondaryScreen.h - ${root_lib}/synergy/KeyTypes.h - ${root_lib}/synergy/MouseTypes.h - ${root_lib}/synergy/OptionTypes.h - ${root_lib}/synergy/ProtocolTypes.h - ${root_lib}/synergy/XScreen.h - ${root_lib}/synergy/XSynergy.h -) - -# Create default `src`, with cross-platform sources. -SET(src_lib - ${src_lib_arch} - ${src_lib_base} - ${src_lib_client} - ${src_lib_common} - ${src_lib_io} - ${src_lib_mt} - ${src_lib_net} - ${src_lib_server} - ${src_lib_synergy} -) - -# Append to `src_lib`, the platform specific sources. -IF(UNIX) - LIST(APPEND src_lib ${src_lib_arch_unix}) - - IF(APPLE) - LIST(APPEND src_lib - ${src_lib_platform_carbon} - ${inc_lib_synergy_carbon} - ${src_lib_synergy_carbon} - ) - ELSE(APPLE) - LIST(APPEND src_lib - ${src_lib_platform_xwindows} - ${inc_lib_synergy_xwindows} - ${src_lib_synergy_xwindows} - ) - ENDIF(APPLE) - -ENDIF(UNIX) - -IF(WIN32) - LIST(APPEND src_lib - ${inc_lib_base} - ${inc_lib_client} - ${inc_lib_common} - ${inc_lib_io} - ${inc_lib_mt} - ${inc_lib_net} - ${inc_lib_server} - ${inc_lib_synergy} - ${inc_lib_arch_windows} - ${src_lib_arch_windows} - ${inc_lib_platform_mswindows} - ${src_lib_platform_mswindows} - ${inc_lib_synergy_mswindows} - ${src_lib_synergy_mswindows} - ) -ENDIF(WIN32) - -SET(inc_lib_dirs - {$root_dir} - {$root_dir}/lib/arch - {$root_dir}/lib/base - {$root_dir}/lib/client - {$root_dir}/lib/common - {$root_dir}/lib/io - {$root_dir}/lib/mt - {$root_dir}/lib/net - {$root_dir}/lib/platform - {$root_dir}/lib/server - {$root_dir}/lib/synergy -) - -INCLUDE_DIRECTORIES(${inc_lib_dirs}) -ADD_LIBRARY(synergy STATIC ${src_lib}) - -IF(WIN32) - ADD_LIBRARY(synrgyhk SHARED ${inc_lib_platform_hook} ${src_lib_platform_hook}) -ENDIF(WIN32) +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +SET(root_lib ${root_dir}/lib) + +SET(src_lib_arch + ${root_lib}/arch/CArchAppUtil.cpp + ${root_lib}/arch/CArch.cpp + ${root_lib}/arch/CArchDaemonNone.cpp + ${root_lib}/arch/XArch.cpp + ${root_lib}/arch/CArchConsoleStd.cpp +) + +SET(src_lib_arch_unix + ${root_lib}/arch/CArchAppUtilUnix.cpp + ${root_lib}/arch/CArchConsoleUnix.cpp + ${root_lib}/arch/CArchDaemonUnix.cpp + ${root_lib}/arch/CArchFileUnix.cpp + ${root_lib}/arch/CArchLogUnix.cpp + ${root_lib}/arch/CArchMultithreadPosix.cpp + ${root_lib}/arch/CArchNetworkBSD.cpp + ${root_lib}/arch/CArchSleepUnix.cpp + ${root_lib}/arch/CArchStringUnix.cpp + ${root_lib}/arch/CArchSystemUnix.cpp + ${root_lib}/arch/CArchTaskBarXWindows.cpp + ${root_lib}/arch/CArchTimeUnix.cpp + ${root_lib}/arch/XArchUnix.cpp +) + +SET(src_lib_arch_windows + ${root_lib}/arch/CArchAppUtilWindows.cpp + ${root_lib}/arch/CArchConsoleWindows.cpp + ${root_lib}/arch/CArchDaemonWindows.cpp + ${root_lib}/arch/CArchFileWindows.cpp + ${root_lib}/arch/CArchLogWindows.cpp + ${root_lib}/arch/CArchMiscWindows.cpp + ${root_lib}/arch/CArchMultithreadWindows.cpp + ${root_lib}/arch/CArchNetworkWinsock.cpp + ${root_lib}/arch/CArchSleepWindows.cpp + ${root_lib}/arch/CArchStringWindows.cpp + ${root_lib}/arch/CArchSystemWindows.cpp + ${root_lib}/arch/CArchTaskBarWindows.cpp + ${root_lib}/arch/CArchTimeWindows.cpp + ${root_lib}/arch/XArchWindows.cpp +) + +SET(inc_lib_arch_windows + ${root_lib}/arch/CArchAppUtil.h + ${root_lib}/arch/CArchAppUtilWindows.h + ${root_lib}/arch/CArchConsoleWindows.h + ${root_lib}/arch/CArchDaemonWindows.h + ${root_lib}/arch/CArchFileWindows.h + ${root_lib}/arch/CArchLogWindows.h + ${root_lib}/arch/CArchMiscWindows.h + ${root_lib}/arch/CArchMultithreadWindows.h + ${root_lib}/arch/CArchNetworkWinsock.h + ${root_lib}/arch/CArchSleepWindows.h + ${root_lib}/arch/CArchStringWindows.h + ${root_lib}/arch/CArchSystemWindows.h + ${root_lib}/arch/CArchTaskBarWindows.h + ${root_lib}/arch/CArchTimeWindows.h + ${root_lib}/arch/CArchConsoleStd.h + ${root_lib}/arch/IArchAppUtil.h + ${root_lib}/arch/XArchWindows.h +) + +SET(src_lib_base + ${root_lib}/base/CEvent.cpp + ${root_lib}/base/CEventQueue.cpp + ${root_lib}/base/CFunctionEventJob.cpp + ${root_lib}/base/CFunctionJob.cpp + ${root_lib}/base/CLog.cpp + ${root_lib}/base/CSimpleEventQueueBuffer.cpp + ${root_lib}/base/CStopwatch.cpp + ${root_lib}/base/CStringUtil.cpp + ${root_lib}/base/CUnicode.cpp + ${root_lib}/base/IEventQueue.cpp + ${root_lib}/base/LogOutputters.cpp + ${root_lib}/base/XBase.cpp +) + +SET(inc_lib_base + ${root_lib}/base/CEvent.h + ${root_lib}/base/CEventQueue.h + ${root_lib}/base/CFunctionEventJob.h + ${root_lib}/base/CFunctionJob.h + ${root_lib}/base/CLog.h + ${root_lib}/base/CPriorityQueue.h + ${root_lib}/base/CSimpleEventQueueBuffer.h + ${root_lib}/base/CStopwatch.h + ${root_lib}/base/CString.h + ${root_lib}/base/CStringUtil.h + ${root_lib}/base/CUnicode.h + ${root_lib}/base/IEventJob.h + ${root_lib}/base/IEventQueue.h + ${root_lib}/base/IEventQueueBuffer.h + ${root_lib}/base/IJob.h + ${root_lib}/base/ILogOutputter.h + ${root_lib}/base/LogOutputters.h + ${root_lib}/base/TMethodEventJob.h + ${root_lib}/base/TMethodJob.h + ${root_lib}/base/XBase.h +) + +SET(src_lib_client + ${root_lib}/client/CClient.cpp + ${root_lib}/client/CServerProxy.cpp +) + +SET(inc_lib_client + ${root_lib}/client/CClient.h + ${root_lib}/client/CServerProxy.h +) + +SET(src_lib_common + ${root_lib}/common/Version.cpp +) + +SET(inc_lib_common + ${root_lib}/common/Version.h +) + +SET(src_lib_io + ${root_lib}/io/CStreamBuffer.cpp + ${root_lib}/io/CStreamFilter.cpp + ${root_lib}/io/IStream.cpp + ${root_lib}/io/XIO.cpp +) + +SET(inc_lib_io + ${root_lib}/io/CStreamBuffer.h + ${root_lib}/io/CStreamFilter.h + ${root_lib}/io/IStream.h + ${root_lib}/io/IStreamFilterFactory.h + ${root_lib}/io/XIO.h +) + +SET(src_lib_mt + ${root_lib}/mt/CCondVar.cpp + ${root_lib}/mt/CLock.cpp + ${root_lib}/mt/CMutex.cpp + ${root_lib}/mt/CThread.cpp + ${root_lib}/mt/XMT.cpp +) + +SET(inc_lib_mt + ${root_lib}/mt/CCondVar.h + ${root_lib}/mt/CLock.h + ${root_lib}/mt/CMutex.h + ${root_lib}/mt/CThread.h + ${root_lib}/mt/XMT.h + ${root_lib}/mt/XThread.h +) + +SET(src_lib_net + ${root_lib}/net/CNetworkAddress.cpp + ${root_lib}/net/CSocketMultiplexer.cpp + ${root_lib}/net/CTCPListenSocket.cpp + ${root_lib}/net/CTCPSocket.cpp + ${root_lib}/net/CTCPSocketFactory.cpp + ${root_lib}/net/IDataSocket.cpp + ${root_lib}/net/IListenSocket.cpp + ${root_lib}/net/ISocket.cpp + ${root_lib}/net/XSocket.cpp +) + +SET(inc_lib_net + ${root_lib}/net/CNetworkAddress.h + ${root_lib}/net/CSocketMultiplexer.h + ${root_lib}/net/CTCPListenSocket.h + ${root_lib}/net/CTCPSocket.h + ${root_lib}/net/CTCPSocketFactory.h + ${root_lib}/net/IDataSocket.h + ${root_lib}/net/IListenSocket.h + ${root_lib}/net/ISocket.h + ${root_lib}/net/ISocketFactory.h + ${root_lib}/net/ISocketMultiplexerJob.h + ${root_lib}/net/TSocketMultiplexerMethodJob.h + ${root_lib}/net/XSocket.h +) + +SET(src_lib_platform_xwindows + ${root_lib}/platform/CXWindowsClipboard.cpp + ${root_lib}/platform/CXWindowsClipboardAnyBitmapConverter.cpp + ${root_lib}/platform/CXWindowsClipboardBMPConverter.cpp + ${root_lib}/platform/CXWindowsClipboardHTMLConverter.cpp + ${root_lib}/platform/CXWindowsClipboardTextConverter.cpp + ${root_lib}/platform/CXWindowsClipboardUCS2Converter.cpp + ${root_lib}/platform/CXWindowsClipboardUTF8Converter.cpp + ${root_lib}/platform/CXWindowsEventQueueBuffer.cpp + ${root_lib}/platform/CXWindowsKeyState.cpp + ${root_lib}/platform/CXWindowsScreen.cpp + ${root_lib}/platform/CXWindowsScreenSaver.cpp + ${root_lib}/platform/CXWindowsUtil.cpp +) + +SET(src_lib_platform_mswindows + ${root_lib}/platform/CMSWindowsClipboard.cpp + ${root_lib}/platform/CMSWindowsClipboardAnyTextConverter.cpp + ${root_lib}/platform/CMSWindowsClipboardBitmapConverter.cpp + ${root_lib}/platform/CMSWindowsClipboardHTMLConverter.cpp + ${root_lib}/platform/CMSWindowsClipboardTextConverter.cpp + ${root_lib}/platform/CMSWindowsClipboardUTF16Converter.cpp + ${root_lib}/platform/CMSWindowsDesks.cpp + ${root_lib}/platform/CMSWindowsEventQueueBuffer.cpp + ${root_lib}/platform/CMSWindowsKeyState.cpp + ${root_lib}/platform/CMSWindowsScreen.cpp + ${root_lib}/platform/CMSWindowsScreenSaver.cpp + ${root_lib}/platform/CMSWindowsUtil.cpp + ${root_lib}/platform/CMSWindowsRelauncher.cpp +) + +SET(inc_lib_platform_mswindows + ${root_lib}/platform/CMSWindowsClipboard.h + ${root_lib}/platform/CMSWindowsClipboardAnyTextConverter.h + ${root_lib}/platform/CMSWindowsClipboardBitmapConverter.h + ${root_lib}/platform/CMSWindowsClipboardHTMLConverter.h + ${root_lib}/platform/CMSWindowsClipboardTextConverter.h + ${root_lib}/platform/CMSWindowsClipboardUTF16Converter.h + ${root_lib}/platform/CMSWindowsDesks.h + ${root_lib}/platform/CMSWindowsEventQueueBuffer.h + ${root_lib}/platform/CMSWindowsKeyState.h + ${root_lib}/platform/CMSWindowsScreen.h + ${root_lib}/platform/CMSWindowsScreenSaver.h + ${root_lib}/platform/CMSWindowsUtil.h + ${root_lib}/platform/CMSWindowsRelauncher.h +) + +SET(src_lib_platform_hook + ${root_lib}/platform/CSynergyHook.cpp +) + +SET(inc_lib_platform_hook + ${root_lib}/platform/CSynergyHook.h +) + +SET(src_lib_platform_carbon + ${root_lib}/platform/COSXClipboard.cpp + ${root_lib}/platform/COSXClipboardAnyTextConverter.cpp + ${root_lib}/platform/COSXClipboardTextConverter.cpp + ${root_lib}/platform/COSXClipboardUTF16Converter.cpp + ${root_lib}/platform/COSXEventQueueBuffer.cpp + ${root_lib}/platform/COSXKeyState.cpp + ${root_lib}/platform/COSXScreen.cpp + ${root_lib}/platform/COSXScreenSaver.cpp + ${root_lib}/platform/COSXScreenSaverUtil.m +) + +SET(src_lib_server + ${root_lib}/server/CBaseClientProxy.cpp + ${root_lib}/server/CClientListener.cpp + ${root_lib}/server/CClientProxy.cpp + ${root_lib}/server/CClientProxy1_0.cpp + ${root_lib}/server/CClientProxy1_1.cpp + ${root_lib}/server/CClientProxy1_2.cpp + ${root_lib}/server/CClientProxy1_3.cpp + ${root_lib}/server/CClientProxyUnknown.cpp + ${root_lib}/server/CConfig.cpp + ${root_lib}/server/CInputFilter.cpp + ${root_lib}/server/CPrimaryClient.cpp + ${root_lib}/server/CServer.cpp +) + +SET(inc_lib_server + ${root_lib}/server/CBaseClientProxy.h + ${root_lib}/server/CClientListener.h + ${root_lib}/server/CClientProxy.h + ${root_lib}/server/CClientProxy1_0.h + ${root_lib}/server/CClientProxy1_1.h + ${root_lib}/server/CClientProxy1_2.h + ${root_lib}/server/CClientProxy1_3.h + ${root_lib}/server/CClientProxyUnknown.h + ${root_lib}/server/CConfig.h + ${root_lib}/server/CInputFilter.h + ${root_lib}/server/CPrimaryClient.h + ${root_lib}/server/CServer.h +) + +SET(src_lib_synergy + ${root_lib}/synergy/CClientTaskBarReceiver.cpp + ${root_lib}/synergy/CServerTaskBarReceiver.cpp + ${root_lib}/synergy/CApp.cpp + ${root_lib}/synergy/CClientApp.cpp + ${root_lib}/synergy/CServerApp.cpp + ${root_lib}/synergy/CClipboard.cpp + ${root_lib}/synergy/CKeyMap.cpp + ${root_lib}/synergy/CKeyState.cpp + ${root_lib}/synergy/CPacketStreamFilter.cpp + ${root_lib}/synergy/CPlatformScreen.cpp + ${root_lib}/synergy/CProtocolUtil.cpp + ${root_lib}/synergy/CScreen.cpp + ${root_lib}/synergy/IClipboard.cpp + ${root_lib}/synergy/IKeyState.cpp + ${root_lib}/synergy/IPrimaryScreen.cpp + ${root_lib}/synergy/IScreen.cpp + ${root_lib}/synergy/KeyTypes.cpp + ${root_lib}/synergy/ProtocolTypes.cpp + ${root_lib}/synergy/XScreen.cpp + ${root_lib}/synergy/XSynergy.cpp +) + +SET(inc_lib_synergy + ${root_lib}/synergy/CClientTaskBarReceiver.h + ${root_lib}/synergy/CServerTaskBarReceiver.h + ${root_lib}/synergy/CApp.h + ${root_lib}/synergy/CClientApp.h + ${root_lib}/synergy/CServerApp.h + ${root_lib}/synergy/CClipboard.h + ${root_lib}/synergy/CKeyMap.h + ${root_lib}/synergy/CKeyState.h + ${root_lib}/synergy/CPacketStreamFilter.h + ${root_lib}/synergy/CPlatformScreen.h + ${root_lib}/synergy/CProtocolUtil.h + ${root_lib}/synergy/CScreen.h + ${root_lib}/synergy/ClipboardTypes.h + ${root_lib}/synergy/IClient.h + ${root_lib}/synergy/IClipboard.h + ${root_lib}/synergy/IKeyState.h + ${root_lib}/synergy/IPlatformScreen.h + ${root_lib}/synergy/IPrimaryScreen.h + ${root_lib}/synergy/IScreen.h + ${root_lib}/synergy/IScreenSaver.h + ${root_lib}/synergy/ISecondaryScreen.h + ${root_lib}/synergy/KeyTypes.h + ${root_lib}/synergy/MouseTypes.h + ${root_lib}/synergy/OptionTypes.h + ${root_lib}/synergy/ProtocolTypes.h + ${root_lib}/synergy/XScreen.h + ${root_lib}/synergy/XSynergy.h +) + +# Create default `src`, with cross-platform sources. +SET(src_lib + ${src_lib_arch} + ${src_lib_base} + ${src_lib_client} + ${src_lib_common} + ${src_lib_io} + ${src_lib_mt} + ${src_lib_net} + ${src_lib_server} + ${src_lib_synergy} +) + +# Append to `src_lib`, the platform specific sources. +IF(UNIX) + LIST(APPEND src_lib ${src_lib_arch_unix}) + + IF(APPLE) + LIST(APPEND src_lib + ${src_lib_platform_carbon} + ${inc_lib_synergy_carbon} + ${src_lib_synergy_carbon} + ) + ELSE(APPLE) + LIST(APPEND src_lib + ${src_lib_platform_xwindows} + ${inc_lib_synergy_xwindows} + ${src_lib_synergy_xwindows} + ) + ENDIF(APPLE) + +ENDIF(UNIX) + +IF(WIN32) + LIST(APPEND src_lib + ${inc_lib_base} + ${inc_lib_client} + ${inc_lib_common} + ${inc_lib_io} + ${inc_lib_mt} + ${inc_lib_net} + ${inc_lib_server} + ${inc_lib_synergy} + ${inc_lib_arch_windows} + ${src_lib_arch_windows} + ${inc_lib_platform_mswindows} + ${src_lib_platform_mswindows} + ${inc_lib_synergy_mswindows} + ${src_lib_synergy_mswindows} + ) +ENDIF(WIN32) + +SET(inc_lib_dirs + {$root_dir} + {$root_dir}/lib/arch + {$root_dir}/lib/base + {$root_dir}/lib/client + {$root_dir}/lib/common + {$root_dir}/lib/io + {$root_dir}/lib/mt + {$root_dir}/lib/net + {$root_dir}/lib/platform + {$root_dir}/lib/server + {$root_dir}/lib/synergy +) + +INCLUDE_DIRECTORIES(${inc_lib_dirs}) +ADD_LIBRARY(synergy STATIC ${src_lib}) + +IF(WIN32) + ADD_LIBRARY(synrgyhk SHARED ${inc_lib_platform_hook} ${src_lib_platform_hook}) +ENDIF(WIN32) diff --git a/cmake/CMakeLists_synergyc.txt b/cmake/CMakeLists_synergyc.txt index f7cfda7c..55a8a4d0 100644 --- a/cmake/CMakeLists_synergyc.txt +++ b/cmake/CMakeLists_synergyc.txt @@ -1,84 +1,84 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -SET(root_cmd_synergyc ${root_dir}/cmd/synergyc) - -SET(src_cmd_synergyc_common - ${root_cmd_synergyc}/synergyc.cpp -) - -SET(src_cmd_synergyc_xwindows - ${root_cmd_synergyc}/CXWindowsClientTaskBarReceiver.cpp -) - -SET(src_cmd_synergyc_mswindows - ${root_cmd_synergyc}/CMSWindowsClientTaskBarReceiver.cpp -) - -SET(inc_cmd_synergyc_mswindows - ${root_cmd_synergyc}/CMSWindowsClientTaskBarReceiver.h - ${root_cmd_synergyc}/resource.h -) - -SET(res_cmd_synergyc_mswindows - ${root_cmd_synergyc}/synergyc.ico - ${root_cmd_synergyc}/synergyc.rc - ${root_cmd_synergyc}/tb_error.ico - ${root_cmd_synergyc}/tb_idle.ico - ${root_cmd_synergyc}/tb_run.ico - ${root_cmd_synergyc}/tb_wait.ico -) - -SET(src_cmd_synergyc_carbon - ${root_cmd_synergyc}/COSXClientTaskBarReceiver.cpp -) - -SET(src_cmd_synergyc ${src_cmd_synergyc_common}) - -IF(UNIX) - - IF(APPLE) - LIST(APPEND src_cmd_synergyc ${src_cmd_synergyc_carbon}) - ELSE(APPLE) - LIST(APPEND src_cmd_synergyc ${src_cmd_synergyc_xwindows}) - ENDIF(APPLE) - -ELSE(UNIX) - - LIST(APPEND src_cmd_synergyc - ${inc_cmd_synergyc_mswindows} - ${res_cmd_synergyc_mswindows} - ${src_cmd_synergyc_mswindows} - ) - -ENDIF(UNIX) - -SET(inc_dirs_cmd_synergyc - ${root_dir} - ${root_dir}/lib - ${root_dir}/lib/arch - ${root_dir}/lib/base - ${root_dir}/lib/client - ${root_dir}/lib/common - ${root_dir}/lib/io - ${root_dir}/lib/mt - ${root_dir}/lib/net - ${root_dir}/lib/platform - ${root_dir}/lib/synergy -) - -INCLUDE_DIRECTORIES(${inc_dirs_cmd_synergyc}) -ADD_EXECUTABLE(synergyc ${src_cmd_synergyc}) -TARGET_LINK_LIBRARIES(synergyc synergy ${libs}) +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +SET(root_cmd_synergyc ${root_dir}/cmd/synergyc) + +SET(src_cmd_synergyc_common + ${root_cmd_synergyc}/synergyc.cpp +) + +SET(src_cmd_synergyc_xwindows + ${root_cmd_synergyc}/CXWindowsClientTaskBarReceiver.cpp +) + +SET(src_cmd_synergyc_mswindows + ${root_cmd_synergyc}/CMSWindowsClientTaskBarReceiver.cpp +) + +SET(inc_cmd_synergyc_mswindows + ${root_cmd_synergyc}/CMSWindowsClientTaskBarReceiver.h + ${root_cmd_synergyc}/resource.h +) + +SET(res_cmd_synergyc_mswindows + ${root_cmd_synergyc}/synergyc.ico + ${root_cmd_synergyc}/synergyc.rc + ${root_cmd_synergyc}/tb_error.ico + ${root_cmd_synergyc}/tb_idle.ico + ${root_cmd_synergyc}/tb_run.ico + ${root_cmd_synergyc}/tb_wait.ico +) + +SET(src_cmd_synergyc_carbon + ${root_cmd_synergyc}/COSXClientTaskBarReceiver.cpp +) + +SET(src_cmd_synergyc ${src_cmd_synergyc_common}) + +IF(UNIX) + + IF(APPLE) + LIST(APPEND src_cmd_synergyc ${src_cmd_synergyc_carbon}) + ELSE(APPLE) + LIST(APPEND src_cmd_synergyc ${src_cmd_synergyc_xwindows}) + ENDIF(APPLE) + +ELSE(UNIX) + + LIST(APPEND src_cmd_synergyc + ${inc_cmd_synergyc_mswindows} + ${res_cmd_synergyc_mswindows} + ${src_cmd_synergyc_mswindows} + ) + +ENDIF(UNIX) + +SET(inc_dirs_cmd_synergyc + ${root_dir} + ${root_dir}/lib + ${root_dir}/lib/arch + ${root_dir}/lib/base + ${root_dir}/lib/client + ${root_dir}/lib/common + ${root_dir}/lib/io + ${root_dir}/lib/mt + ${root_dir}/lib/net + ${root_dir}/lib/platform + ${root_dir}/lib/synergy +) + +INCLUDE_DIRECTORIES(${inc_dirs_cmd_synergyc}) +ADD_EXECUTABLE(synergyc ${src_cmd_synergyc}) +TARGET_LINK_LIBRARIES(synergyc synergy ${libs}) diff --git a/cmake/CMakeLists_synergys.txt b/cmake/CMakeLists_synergys.txt index 2d17fe46..5778bab8 100644 --- a/cmake/CMakeLists_synergys.txt +++ b/cmake/CMakeLists_synergys.txt @@ -1,84 +1,84 @@ -# synergy-plus -- mouse and keyboard sharing utility -# Copyright (C) 2009 The Synergy+ Project -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -SET(root_cmd_synergys ${root_dir}/cmd/synergys) - -SET(src_cmd_synergys_common - ${root_cmd_synergys}/synergys.cpp -) - -SET(src_cmd_synergys_xwindows - ${root_cmd_synergys}/CXWindowsServerTaskBarReceiver.cpp -) - -SET(src_cmd_synergys_mswindows - ${root_cmd_synergys}/CMSWindowsServerTaskBarReceiver.cpp -) - -SET(inc_cmd_synergys_mswindows - ${root_cmd_synergys}/CMSWindowsServerTaskBarReceiver.h - ${root_cmd_synergys}/resource.h -) - -SET(res_cmd_synergys_mswindows - ${root_cmd_synergys}/synergys.ico - ${root_cmd_synergys}/synergys.rc - ${root_cmd_synergys}/tb_error.ico - ${root_cmd_synergys}/tb_idle.ico - ${root_cmd_synergys}/tb_run.ico - ${root_cmd_synergys}/tb_wait.ico -) - -SET(src_cmd_synergys_carbon - ${root_cmd_synergys}/COSXServerTaskBarReceiver.cpp -) - -SET(src_cmd_synergys ${src_cmd_synergys_common}) - -IF(UNIX) - - IF(APPLE) - LIST(APPEND src_cmd_synergys ${src_cmd_synergys_carbon}) - ELSE(APPLE) - LIST(APPEND src_cmd_synergys ${src_cmd_synergys_xwindows}) - ENDIF(APPLE) - -ELSE(UNIX) - - LIST(APPEND src_cmd_synergys - ${inc_cmd_synergys_mswindows} - ${res_cmd_synergys_mswindows} - ${src_cmd_synergys_mswindows} - ) - -ENDIF(UNIX) - -SET(inc_dirs_cmd_synergys - ${root_dir} - ${root_dir}/lib - ${root_dir}/lib/arch - ${root_dir}/lib/base - ${root_dir}/lib/common - ${root_dir}/lib/io - ${root_dir}/lib/mt - ${root_dir}/lib/net - ${root_dir}/lib/platform - ${root_dir}/lib/synergy - ${root_dir}/lib/server -) - -INCLUDE_DIRECTORIES(${inc_dirs_cmd_synergys}) -ADD_EXECUTABLE(synergys ${src_cmd_synergys}) -TARGET_LINK_LIBRARIES(synergys synergy ${libs}) +# synergy-plus -- mouse and keyboard sharing utility +# Copyright (C) 2009 The Synergy+ Project +# +# This package is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# found in the file COPYING that should have accompanied this file. +# +# This package is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +SET(root_cmd_synergys ${root_dir}/cmd/synergys) + +SET(src_cmd_synergys_common + ${root_cmd_synergys}/synergys.cpp +) + +SET(src_cmd_synergys_xwindows + ${root_cmd_synergys}/CXWindowsServerTaskBarReceiver.cpp +) + +SET(src_cmd_synergys_mswindows + ${root_cmd_synergys}/CMSWindowsServerTaskBarReceiver.cpp +) + +SET(inc_cmd_synergys_mswindows + ${root_cmd_synergys}/CMSWindowsServerTaskBarReceiver.h + ${root_cmd_synergys}/resource.h +) + +SET(res_cmd_synergys_mswindows + ${root_cmd_synergys}/synergys.ico + ${root_cmd_synergys}/synergys.rc + ${root_cmd_synergys}/tb_error.ico + ${root_cmd_synergys}/tb_idle.ico + ${root_cmd_synergys}/tb_run.ico + ${root_cmd_synergys}/tb_wait.ico +) + +SET(src_cmd_synergys_carbon + ${root_cmd_synergys}/COSXServerTaskBarReceiver.cpp +) + +SET(src_cmd_synergys ${src_cmd_synergys_common}) + +IF(UNIX) + + IF(APPLE) + LIST(APPEND src_cmd_synergys ${src_cmd_synergys_carbon}) + ELSE(APPLE) + LIST(APPEND src_cmd_synergys ${src_cmd_synergys_xwindows}) + ENDIF(APPLE) + +ELSE(UNIX) + + LIST(APPEND src_cmd_synergys + ${inc_cmd_synergys_mswindows} + ${res_cmd_synergys_mswindows} + ${src_cmd_synergys_mswindows} + ) + +ENDIF(UNIX) + +SET(inc_dirs_cmd_synergys + ${root_dir} + ${root_dir}/lib + ${root_dir}/lib/arch + ${root_dir}/lib/base + ${root_dir}/lib/common + ${root_dir}/lib/io + ${root_dir}/lib/mt + ${root_dir}/lib/net + ${root_dir}/lib/platform + ${root_dir}/lib/synergy + ${root_dir}/lib/server +) + +INCLUDE_DIRECTORIES(${inc_dirs_cmd_synergys}) +ADD_EXECUTABLE(synergys ${src_cmd_synergys}) +TARGET_LINK_LIBRARIES(synergys synergy ${libs}) diff --git a/cmd/synergys/resource.h b/cmd/synergys/resource.h index 5720df80..1cc1e8b9 100644 --- a/cmd/synergys/resource.h +++ b/cmd/synergys/resource.h @@ -1,42 +1,42 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by synergys.rc -// -#define IDS_FAILED 1 -#define IDS_INIT_FAILED 2 -#define IDS_UNCAUGHT_EXCEPTION 3 -#define IDI_SYNERGY 101 -#define IDI_TASKBAR_NOT_RUNNING 102 -#define IDI_TASKBAR_NOT_WORKING 103 -#define IDI_TASKBAR_NOT_CONNECTED 104 -#define IDI_TASKBAR_CONNECTED 105 -#define IDR_TASKBAR 107 -#define IDD_TASKBAR_STATUS 108 -#define IDC_TASKBAR_STATUS_STATUS 1000 -#define IDC_TASKBAR_STATUS_CLIENTS 1001 -#define IDC_TASKBAR_QUIT 40003 -#define IDC_TASKBAR_STATUS 40004 -#define IDC_TASKBAR_LOG 40005 -#define IDC_RELOAD_CONFIG 40006 -#define IDC_FORCE_RECONNECT 40007 -#define IDC_TASKBAR_SHOW_LOG 40008 -#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009 -#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010 -#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011 -#define IDC_TASKBAR_LOG_LEVEL_INFO 40012 -#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013 -#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014 -#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015 -#define ID_SYNERGY_RELOADSYSTEM 40016 -#define ID_SYNERGY_RESETSERVER 40017 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 109 -#define _APS_NEXT_COMMAND_VALUE 40018 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by synergys.rc +// +#define IDS_FAILED 1 +#define IDS_INIT_FAILED 2 +#define IDS_UNCAUGHT_EXCEPTION 3 +#define IDI_SYNERGY 101 +#define IDI_TASKBAR_NOT_RUNNING 102 +#define IDI_TASKBAR_NOT_WORKING 103 +#define IDI_TASKBAR_NOT_CONNECTED 104 +#define IDI_TASKBAR_CONNECTED 105 +#define IDR_TASKBAR 107 +#define IDD_TASKBAR_STATUS 108 +#define IDC_TASKBAR_STATUS_STATUS 1000 +#define IDC_TASKBAR_STATUS_CLIENTS 1001 +#define IDC_TASKBAR_QUIT 40003 +#define IDC_TASKBAR_STATUS 40004 +#define IDC_TASKBAR_LOG 40005 +#define IDC_RELOAD_CONFIG 40006 +#define IDC_FORCE_RECONNECT 40007 +#define IDC_TASKBAR_SHOW_LOG 40008 +#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009 +#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010 +#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011 +#define IDC_TASKBAR_LOG_LEVEL_INFO 40012 +#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013 +#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014 +#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015 +#define ID_SYNERGY_RELOADSYSTEM 40016 +#define ID_SYNERGY_RESETSERVER 40017 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_COMMAND_VALUE 40018 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/gui/COPYING b/gui/COPYING index 3e1cf82c..7941e42c 100644 --- a/gui/COPYING +++ b/gui/COPYING @@ -1,283 +1,283 @@ -QSynergy is free software and published under the following -license: - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS +QSynergy is free software and published under the following +license: + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/gui/README b/gui/README index 69b29c36..0f0de0c2 100644 --- a/gui/README +++ b/gui/README @@ -1,97 +1,97 @@ -QSynergy -======== - -Version 0.9.0 -http://www.volker-lanz.de/en/software/qsynergy/ - - -About QSynergy --------------- -QSynergy is a graphical front end for Synergy. Synergy lets a user control more -than one computer with a single mouse and keyboard (and has lots and lots of -extra features on top of that). Learn more about Synergy itself or get it from: -http://synergy2.sourceforge.net - -Synergy only has a GUI for MS Windows. QSynergy was written to step in and fill -this gap for users on Mac and Unix platforms. Of course, QSynergy can also be -used on MS Windows. - - -Running and using QSynergy --------------------------- -- Because QSynergy is a graphical frontend for Synergy, it does not make much - sense to run it without having Synergy installed. So if you have not done so - already, get it from http://synergy2.sourceforge.net and install it. - -- See the Synergy documentation (http://synergy2.sourceforge.net/) for all - topics concerning what you can do with Synergy. - -- In QSynergy, first, go to Edit -> Settings and check if the path names for - synergys (the Synergy server binary) and synergyc (the client) are correct. - If they are not, set them by hand or browse to their locations. - -- QSynergy knows three modes: - - 1. Run Synergy as a client (so the computer QSynergy runs on will be - controlled from another computer). - - 2. Run Synergy as a server with an existing configuration you have written - already (that's just like running Synergy from the command line with the "-c" - option). - - 3. Interactively and graphically create a server configuration and run - Synergy with this configuration. Herein lies the main benefit of using - QSynergy instead of the command line Synergy version for Unix and Mac. - -- Running as a client: Simply tick the "be a client" checkbox, enter the name - of the computer to connect to and push the "Start" button. - -- Running as a server with an existing configuration: Tick the "be a server" - checkbox and the radio button that says you would like to use your own - configuration file. Then enter the path to this configuration file (or browse - for it). Finally, push the "Start" button. - -- Using QSynergy to configure the Synergy server: Tick the "be a server" - checkbox and the radio button that says you would like to interactively - configure Synergy. Then push the "Configure server" button. After you have - finished setting up your configuration, push the "Start" button. QSynergy - will remember your configuration across restarts, so there is no need to - configure again the next time you run QSynergy -- unless you change your - computer setup, of course. - -- On MS Windows and X11, QSynergy will minimize to the tray if you close the - main window or pick the Window -> Minimize menu entry. Double click on the - icon in the tray or right click on this icon and pick Restore to restore the - window. - -- On X11, QSynergy will be restarted with X11 if your X11 server correctly - implements session handling. On MS Windows, you will have to add QSynergy to - your Autostart folder. On the Mac, set it to automatically run when the - Finder starts. - - -Known bugs and limitations --------------------------- -- It is not possible to configure partial links (e.g., only 50% of a screen's - edge linking to another screen) - -- If you configure a hotkey for a specific screen and later delete this screen, - QSynergy does not warn you that this will lead to an invalid configuration. - -- Importing existing synery server configuration files is not possible. - -- There is no true communication channel between Synergy itself and QSynergy. - This means that QSynergy cannot really know if Synergy itself is working or - has encountered any problems. QSynergy only knows "Synergy is running" or - "Synergy has quit with an error". - -- Mac OS X only: The look and feel of QSynergy is not quite right for the - platform. This is due to limitations in Qt. - - -License -------- -QSynergy is written using the Qt Toolkit. It is free software released under -the GPLv2. - - +QSynergy +======== + +Version 0.9.0 +http://www.volker-lanz.de/en/software/qsynergy/ + + +About QSynergy +-------------- +QSynergy is a graphical front end for Synergy. Synergy lets a user control more +than one computer with a single mouse and keyboard (and has lots and lots of +extra features on top of that). Learn more about Synergy itself or get it from: +http://synergy2.sourceforge.net + +Synergy only has a GUI for MS Windows. QSynergy was written to step in and fill +this gap for users on Mac and Unix platforms. Of course, QSynergy can also be +used on MS Windows. + + +Running and using QSynergy +-------------------------- +- Because QSynergy is a graphical frontend for Synergy, it does not make much + sense to run it without having Synergy installed. So if you have not done so + already, get it from http://synergy2.sourceforge.net and install it. + +- See the Synergy documentation (http://synergy2.sourceforge.net/) for all + topics concerning what you can do with Synergy. + +- In QSynergy, first, go to Edit -> Settings and check if the path names for + synergys (the Synergy server binary) and synergyc (the client) are correct. + If they are not, set them by hand or browse to their locations. + +- QSynergy knows three modes: + + 1. Run Synergy as a client (so the computer QSynergy runs on will be + controlled from another computer). + + 2. Run Synergy as a server with an existing configuration you have written + already (that's just like running Synergy from the command line with the "-c" + option). + + 3. Interactively and graphically create a server configuration and run + Synergy with this configuration. Herein lies the main benefit of using + QSynergy instead of the command line Synergy version for Unix and Mac. + +- Running as a client: Simply tick the "be a client" checkbox, enter the name + of the computer to connect to and push the "Start" button. + +- Running as a server with an existing configuration: Tick the "be a server" + checkbox and the radio button that says you would like to use your own + configuration file. Then enter the path to this configuration file (or browse + for it). Finally, push the "Start" button. + +- Using QSynergy to configure the Synergy server: Tick the "be a server" + checkbox and the radio button that says you would like to interactively + configure Synergy. Then push the "Configure server" button. After you have + finished setting up your configuration, push the "Start" button. QSynergy + will remember your configuration across restarts, so there is no need to + configure again the next time you run QSynergy -- unless you change your + computer setup, of course. + +- On MS Windows and X11, QSynergy will minimize to the tray if you close the + main window or pick the Window -> Minimize menu entry. Double click on the + icon in the tray or right click on this icon and pick Restore to restore the + window. + +- On X11, QSynergy will be restarted with X11 if your X11 server correctly + implements session handling. On MS Windows, you will have to add QSynergy to + your Autostart folder. On the Mac, set it to automatically run when the + Finder starts. + + +Known bugs and limitations +-------------------------- +- It is not possible to configure partial links (e.g., only 50% of a screen's + edge linking to another screen) + +- If you configure a hotkey for a specific screen and later delete this screen, + QSynergy does not warn you that this will lead to an invalid configuration. + +- Importing existing synery server configuration files is not possible. + +- There is no true communication channel between Synergy itself and QSynergy. + This means that QSynergy cannot really know if Synergy itself is working or + has encountered any problems. QSynergy only knows "Synergy is running" or + "Synergy has quit with an error". + +- Mac OS X only: The look and feel of QSynergy is not quite right for the + platform. This is due to limitations in Qt. + + +License +------- +QSynergy is written using the Qt Toolkit. It is free software released under +the GPLv2. + + diff --git a/gui/src/WindowsServices.cpp b/gui/src/WindowsServices.cpp index f55bc6ab..8a30a695 100644 --- a/gui/src/WindowsServices.cpp +++ b/gui/src/WindowsServices.cpp @@ -1,148 +1,148 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2008 Volker Lanz (vl@fidra.de) - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "WindowsServices.h" -#include "AppConfig.h" -#include "MainWindow.h" -#include "LogDialog.h" - -#include -#include -#include -#include - -WindowsServices::WindowsServices(QWidget* parent, AppConfig& appConfig) : - QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), - Ui::WindowsServicesBase(), - m_appConfig(appConfig), - m_log(new LogDialog(this, process())) -{ - setupUi(this); -} - -void WindowsServices::runProc(const QString& app, const QStringList& args, QPushButton* button) -{ - // disable until we know we've finished - button->setEnabled(false); - - // clear contents so user doesn't get confused by previous messages - m_log->clear(); - - // deleted at end of function - QProcess proc(this); - m_process = &proc; - - // send output to log window - connect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput())); - connect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput())); - - m_process->start(app, args); - m_log->show(); - - // service management should be instant - m_process->waitForFinished(); - - if (m_process->exitCode() == 0) - { - QMessageBox::information(m_log, "Service manager", "Completed successfully."); - } - else - { - QMessageBox::critical( - m_log, "Service manager error", - QString("Unable to install or uninstall service. Error code: " + - QString::number(m_process->exitCode()))); - } - - disconnect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput())); - disconnect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput())); - - button->setEnabled(true); -} - -void WindowsServices::on_m_pInstallServer_clicked() -{ - QString app = mainWindow()->appPath( - appConfig().synergysName(), appConfig().synergys()); - - QStringList args; - args << - "--service" << "install" << - "--relaunch" << - "--debug" << appConfig().logLevelText() << - "-c" << mainWindow()->configFilename() << - "--address" << mainWindow()->address(); - - if (appConfig().logToFile()) - { - appConfig().persistLogDir(); - args << "--log" << appConfig().logFilename(); - } - - runProc(app, args, m_pInstallServer); -} - -void WindowsServices::on_m_pUninstallServer_clicked() -{ - QString app = mainWindow()->appPath( - appConfig().synergysName(), appConfig().synergys()); - - QStringList args; - args << "--service" << "uninstall"; - runProc(app, args, m_pInstallServer); -} - -void WindowsServices::on_m_pInstallClient_clicked() -{ - if (mainWindow()->hostname().isEmpty()) - { - QMessageBox::critical( - this, "Service manager error", "Hostname was not specified on main screen."); - return; - } - - QString app = mainWindow()->appPath( - appConfig().synergycName(), appConfig().synergyc()); - - QStringList args; - args << - "--service" << "install" << - "--relaunch" << - "--debug" << appConfig().logLevelText(); - - if (appConfig().logToFile()) - { - appConfig().persistLogDir(); - args << "--log" << appConfig().logFilename(); - } - - // hostname must come last to be a valid arg - args << mainWindow()->hostname(); - - runProc(app, args, m_pInstallServer); -} - -void WindowsServices::on_m_pUninstallClient_clicked() -{ - QString app = mainWindow()->appPath( - appConfig().synergycName(), appConfig().synergyc()); - - QStringList args; - args << "--service" << "uninstall"; - runProc(app, args, m_pInstallServer); -} +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2008 Volker Lanz (vl@fidra.de) + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "WindowsServices.h" +#include "AppConfig.h" +#include "MainWindow.h" +#include "LogDialog.h" + +#include +#include +#include +#include + +WindowsServices::WindowsServices(QWidget* parent, AppConfig& appConfig) : + QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), + Ui::WindowsServicesBase(), + m_appConfig(appConfig), + m_log(new LogDialog(this, process())) +{ + setupUi(this); +} + +void WindowsServices::runProc(const QString& app, const QStringList& args, QPushButton* button) +{ + // disable until we know we've finished + button->setEnabled(false); + + // clear contents so user doesn't get confused by previous messages + m_log->clear(); + + // deleted at end of function + QProcess proc(this); + m_process = &proc; + + // send output to log window + connect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput())); + connect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput())); + + m_process->start(app, args); + m_log->show(); + + // service management should be instant + m_process->waitForFinished(); + + if (m_process->exitCode() == 0) + { + QMessageBox::information(m_log, "Service manager", "Completed successfully."); + } + else + { + QMessageBox::critical( + m_log, "Service manager error", + QString("Unable to install or uninstall service. Error code: " + + QString::number(m_process->exitCode()))); + } + + disconnect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput())); + disconnect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput())); + + button->setEnabled(true); +} + +void WindowsServices::on_m_pInstallServer_clicked() +{ + QString app = mainWindow()->appPath( + appConfig().synergysName(), appConfig().synergys()); + + QStringList args; + args << + "--service" << "install" << + "--relaunch" << + "--debug" << appConfig().logLevelText() << + "-c" << mainWindow()->configFilename() << + "--address" << mainWindow()->address(); + + if (appConfig().logToFile()) + { + appConfig().persistLogDir(); + args << "--log" << appConfig().logFilename(); + } + + runProc(app, args, m_pInstallServer); +} + +void WindowsServices::on_m_pUninstallServer_clicked() +{ + QString app = mainWindow()->appPath( + appConfig().synergysName(), appConfig().synergys()); + + QStringList args; + args << "--service" << "uninstall"; + runProc(app, args, m_pInstallServer); +} + +void WindowsServices::on_m_pInstallClient_clicked() +{ + if (mainWindow()->hostname().isEmpty()) + { + QMessageBox::critical( + this, "Service manager error", "Hostname was not specified on main screen."); + return; + } + + QString app = mainWindow()->appPath( + appConfig().synergycName(), appConfig().synergyc()); + + QStringList args; + args << + "--service" << "install" << + "--relaunch" << + "--debug" << appConfig().logLevelText(); + + if (appConfig().logToFile()) + { + appConfig().persistLogDir(); + args << "--log" << appConfig().logFilename(); + } + + // hostname must come last to be a valid arg + args << mainWindow()->hostname(); + + runProc(app, args, m_pInstallServer); +} + +void WindowsServices::on_m_pUninstallClient_clicked() +{ + QString app = mainWindow()->appPath( + appConfig().synergycName(), appConfig().synergyc()); + + QStringList args; + args << "--service" << "uninstall"; + runProc(app, args, m_pInstallServer); +} diff --git a/gui/src/WindowsServices.h b/gui/src/WindowsServices.h index b6ec1487..d66f9075 100644 --- a/gui/src/WindowsServices.h +++ b/gui/src/WindowsServices.h @@ -1,59 +1,59 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2008 Volker Lanz (vl@fidra.de) - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef WINDOWSSERVICES_H -#define WINDOWSSERVICES_H - -#include "ui_WindowsServicesBase.h" - -class QWidget; -class QProcess; -class QPushButton; -class QProcess; - -class AppConfig; -class MainWindow; -class LogDialog; - -class WindowsServices : public QDialog, public Ui::WindowsServicesBase -{ - Q_OBJECT - - public: - WindowsServices(QWidget* parent, AppConfig& appConfig); - - protected: - AppConfig &appConfig() const { return m_appConfig; } - MainWindow* mainWindow() const { return (MainWindow*)parent(); } - QProcess*& process() { return m_process; } - void runProc(const QString& app, const QStringList& args, QPushButton* button); - - private: - QString m_app; - AppConfig &m_appConfig; - QProcess* m_process; - LogDialog* m_log; - - private slots: - void on_m_pUninstallClient_clicked(); - void on_m_pInstallClient_clicked(); - void on_m_pUninstallServer_clicked(); - void on_m_pInstallServer_clicked(); -}; - -#endif // WINDOWSSERVICES_H +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2008 Volker Lanz (vl@fidra.de) + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WINDOWSSERVICES_H +#define WINDOWSSERVICES_H + +#include "ui_WindowsServicesBase.h" + +class QWidget; +class QProcess; +class QPushButton; +class QProcess; + +class AppConfig; +class MainWindow; +class LogDialog; + +class WindowsServices : public QDialog, public Ui::WindowsServicesBase +{ + Q_OBJECT + + public: + WindowsServices(QWidget* parent, AppConfig& appConfig); + + protected: + AppConfig &appConfig() const { return m_appConfig; } + MainWindow* mainWindow() const { return (MainWindow*)parent(); } + QProcess*& process() { return m_process; } + void runProc(const QString& app, const QStringList& args, QPushButton* button); + + private: + QString m_app; + AppConfig &m_appConfig; + QProcess* m_process; + LogDialog* m_log; + + private slots: + void on_m_pUninstallClient_clicked(); + void on_m_pInstallClient_clicked(); + void on_m_pUninstallServer_clicked(); + void on_m_pInstallServer_clicked(); +}; + +#endif // WINDOWSSERVICES_H diff --git a/lib/arch/CArch.h b/lib/arch/CArch.h index dcacda86..79288173 100644 --- a/lib/arch/CArch.h +++ b/lib/arch/CArch.h @@ -189,12 +189,12 @@ public: // IArchAppUtil overrides virtual bool parseArg(const int& argc, const char* const* argv, int& i); virtual void adoptApp(CApp* app); - virtual CApp& app() const; + virtual CApp& app() const; virtual int run(int argc, char** argv); virtual void beforeAppExit(); // expose util so we don't need to re-implement all the functions - IArchAppUtil& util() const { return *m_appUtil; } + IArchAppUtil& util() const { return *m_appUtil; } IArchDaemon& daemon() const { return *m_daemon; } private: diff --git a/lib/arch/CArchAppUtil.cpp b/lib/arch/CArchAppUtil.cpp index 898dce0a..504dcf4e 100644 --- a/lib/arch/CArchAppUtil.cpp +++ b/lib/arch/CArchAppUtil.cpp @@ -1,60 +1,60 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CArchAppUtil.h" -#include "CApp.h" - -CArchAppUtil* CArchAppUtil::s_instance = nullptr; - -CArchAppUtil::CArchAppUtil() : -m_app(nullptr) -{ - s_instance = this; -} - -CArchAppUtil::~CArchAppUtil() -{ -} +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CArchAppUtil.h" +#include "CApp.h" -bool -CArchAppUtil::parseArg(const int& argc, const char* const* argv, int& i) -{ - // no common platform args (yet) - return false; -} - -void -CArchAppUtil::adoptApp(CApp* app) -{ - app->m_bye = &exitAppStatic; - m_app = app; -} - -CApp& -CArchAppUtil::app() const -{ - assert(m_app != nullptr); - return *m_app; -} - -CArchAppUtil& -CArchAppUtil::instance() -{ - assert(s_instance != nullptr); - return *s_instance; -} +CArchAppUtil* CArchAppUtil::s_instance = nullptr; + +CArchAppUtil::CArchAppUtil() : +m_app(nullptr) +{ + s_instance = this; +} + +CArchAppUtil::~CArchAppUtil() +{ +} + +bool +CArchAppUtil::parseArg(const int& argc, const char* const* argv, int& i) +{ + // no common platform args (yet) + return false; +} + +void +CArchAppUtil::adoptApp(CApp* app) +{ + app->m_bye = &exitAppStatic; + m_app = app; +} + +CApp& +CArchAppUtil::app() const +{ + assert(m_app != nullptr); + return *m_app; +} + +CArchAppUtil& +CArchAppUtil::instance() +{ + assert(s_instance != nullptr); + return *s_instance; +} diff --git a/lib/arch/CArchAppUtil.h b/lib/arch/CArchAppUtil.h index 25a09e80..e2cf5d4f 100644 --- a/lib/arch/CArchAppUtil.h +++ b/lib/arch/CArchAppUtil.h @@ -1,41 +1,41 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "IArchAppUtil.h" -#include "XSynergy.h" - -class CArchAppUtil : public IArchAppUtil { -public: - CArchAppUtil(); - virtual ~CArchAppUtil(); - - virtual bool parseArg(const int& argc, const char* const* argv, int& i); - virtual void adoptApp(CApp* app); - CApp& app() const; - virtual void exitApp(int code) { throw XExitApp(code); } - - static CArchAppUtil& instance(); - static void exitAppStatic(int code) { instance().exitApp(code); } - virtual void beforeAppExit() {} - -private: - CApp* m_app; - static CArchAppUtil* s_instance; -}; +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "IArchAppUtil.h" +#include "XSynergy.h" + +class CArchAppUtil : public IArchAppUtil { +public: + CArchAppUtil(); + virtual ~CArchAppUtil(); + + virtual bool parseArg(const int& argc, const char* const* argv, int& i); + virtual void adoptApp(CApp* app); + CApp& app() const; + virtual void exitApp(int code) { throw XExitApp(code); } + + static CArchAppUtil& instance(); + static void exitAppStatic(int code) { instance().exitApp(code); } + virtual void beforeAppExit() {} + +private: + CApp* m_app; + static CArchAppUtil* s_instance; +}; diff --git a/lib/arch/CArchAppUtilUnix.cpp b/lib/arch/CArchAppUtilUnix.cpp index 26eaeca8..bf4c613d 100644 --- a/lib/arch/CArchAppUtilUnix.cpp +++ b/lib/arch/CArchAppUtilUnix.cpp @@ -1,57 +1,57 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CArchAppUtilUnix.h" - -CArchAppUtilUnix::CArchAppUtilUnix() -{ -} - -CArchAppUtilUnix::~CArchAppUtilUnix() -{ -} - -bool -CArchAppUtilUnix::parseArg(const int& argc, const char* const* argv, int& i) -{ -#if WINAPI_XWINDOWS - if (app().isArg(i, argc, argv, "-display", "--display", 1)) { - // use alternative display - app().argsBase().m_display = argv[++i]; - } - - else { - // option not supported here - return false; - } - - return true; -#else - // no options for carbon - return false; -#endif +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CArchAppUtilUnix.h" + +CArchAppUtilUnix::CArchAppUtilUnix() +{ +} + +CArchAppUtilUnix::~CArchAppUtilUnix() +{ +} + +bool +CArchAppUtilUnix::parseArg(const int& argc, const char* const* argv, int& i) +{ +#if WINAPI_XWINDOWS + if (app().isArg(i, argc, argv, "-display", "--display", 1)) { + // use alternative display + app().argsBase().m_display = argv[++i]; + } + + else { + // option not supported here + return false; + } + + return true; +#else + // no options for carbon + return false; +#endif } int standardStartupStatic(int argc, char** argv) { return CArchAppUtil::instance().app().standardStartup(argc, argv); -} +} int CArchAppUtilUnix::run(int argc, char** argv) diff --git a/lib/arch/CArchAppUtilUnix.h b/lib/arch/CArchAppUtilUnix.h index 0380f09f..ef06837a 100644 --- a/lib/arch/CArchAppUtilUnix.h +++ b/lib/arch/CArchAppUtilUnix.h @@ -1,33 +1,33 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "CArchAppUtil.h" - -#define ARCH_APPUTIL CArchAppUtilUnix - -class CArchAppUtilUnix : public CArchAppUtil { -public: - CArchAppUtilUnix(); - virtual ~CArchAppUtilUnix(); - - bool parseArg(const int& argc, const char* const* argv, int& i); - int run(int argc, char** argv); - void startNode(); -}; +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "CArchAppUtil.h" + +#define ARCH_APPUTIL CArchAppUtilUnix + +class CArchAppUtilUnix : public CArchAppUtil { +public: + CArchAppUtilUnix(); + virtual ~CArchAppUtilUnix(); + + bool parseArg(const int& argc, const char* const* argv, int& i); + int run(int argc, char** argv); + void startNode(); +}; diff --git a/lib/arch/CArchAppUtilWindows.cpp b/lib/arch/CArchAppUtilWindows.cpp index 123d1d52..c8ae6e00 100644 --- a/lib/arch/CArchAppUtilWindows.cpp +++ b/lib/arch/CArchAppUtilWindows.cpp @@ -1,338 +1,338 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CArchAppUtilWindows.h" -#include "Version.h" -#include "CLog.h" -#include "XArchWindows.h" -#include "CArchMiscWindows.h" -#include "CApp.h" -#include "LogOutputters.h" -#include "CMSWindowsScreen.h" -#include "XSynergy.h" -#include "IArchTaskBarReceiver.h" -#include "CMSWindowsRelauncher.h" -#include "CScreen.h" - -#include -#include -#include - -CArchAppUtilWindows::CArchAppUtilWindows() : -m_exitMode(kExitModeNormal) -{ - if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE) == FALSE) - { - throw XArchEvalWindows(); - } -} - -CArchAppUtilWindows::~CArchAppUtilWindows() -{ -} - -BOOL WINAPI CArchAppUtilWindows::consoleHandler(DWORD CEvent) -{ - if (instance().app().m_taskBarReceiver) - { - // HACK: it would be nice to delete the s_taskBarReceiver object, but - // this is best done by the CApp destructor; however i don't feel like - // opening up that can of worms today... i need sleep. - instance().app().m_taskBarReceiver->cleanup(); - } - - ExitProcess(kExitTerminated); - return TRUE; -} - -bool -CArchAppUtilWindows::parseArg(const int& argc, const char* const* argv, int& i) -{ - if (app().isArg(i, argc, argv, NULL, "--service")) { - - const char* action = argv[++i]; - - if (_stricmp(action, "install") == 0) { - installService(); - } - else if (_stricmp(action, "uninstall") == 0) { - uninstallService(); - } - else if (_stricmp(action, "start") == 0) { - startService(); - } - else if (_stricmp(action, "stop") == 0) { - stopService(); - } - else { - LOG((CLOG_ERR "unknown service action: %s", action)); - app().m_bye(kExitArgs); - } - app().m_bye(kExitSuccess); - } - else if (app().isArg(i, argc, argv, NULL, "--debug-service-wait")) { - - app().argsBase().m_debugServiceWait = true; +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CArchAppUtilWindows.h" +#include "Version.h" +#include "CLog.h" +#include "XArchWindows.h" +#include "CArchMiscWindows.h" +#include "CApp.h" +#include "LogOutputters.h" +#include "CMSWindowsScreen.h" +#include "XSynergy.h" +#include "IArchTaskBarReceiver.h" +#include "CMSWindowsRelauncher.h" +#include "CScreen.h" + +#include +#include +#include + +CArchAppUtilWindows::CArchAppUtilWindows() : +m_exitMode(kExitModeNormal) +{ + if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE) == FALSE) + { + throw XArchEvalWindows(); + } +} + +CArchAppUtilWindows::~CArchAppUtilWindows() +{ +} + +BOOL WINAPI CArchAppUtilWindows::consoleHandler(DWORD CEvent) +{ + if (instance().app().m_taskBarReceiver) + { + // HACK: it would be nice to delete the s_taskBarReceiver object, but + // this is best done by the CApp destructor; however i don't feel like + // opening up that can of worms today... i need sleep. + instance().app().m_taskBarReceiver->cleanup(); + } + + ExitProcess(kExitTerminated); + return TRUE; +} + +bool +CArchAppUtilWindows::parseArg(const int& argc, const char* const* argv, int& i) +{ + if (app().isArg(i, argc, argv, NULL, "--service")) { + + const char* action = argv[++i]; + + if (_stricmp(action, "install") == 0) { + installService(); + } + else if (_stricmp(action, "uninstall") == 0) { + uninstallService(); + } + else if (_stricmp(action, "start") == 0) { + startService(); + } + else if (_stricmp(action, "stop") == 0) { + stopService(); + } + else { + LOG((CLOG_ERR "unknown service action: %s", action)); + app().m_bye(kExitArgs); + } + app().m_bye(kExitSuccess); + } + else if (app().isArg(i, argc, argv, NULL, "--debug-service-wait")) { + + app().argsBase().m_debugServiceWait = true; } else if (app().isArg(i, argc, argv, NULL, "--relaunch")) { app().argsBase().m_relaunchMode = true; - } - else if (app().isArg(i, argc, argv, NULL, "--exit-pause")) { - - app().argsBase().m_pauseOnExit = true; - } - else if (app().isArg(i, argc, argv, NULL, "--no-tray")) { - - app().argsBase().m_disableTray = true; - } - else { - // option not supported here - return false; - } - - return true; -} - -CString -CArchAppUtilWindows::getServiceArgs() const -{ - std::stringstream argBuf; - for (int i = 1; i < __argc; i++) { - const char* arg = __argv[i]; - - // ignore service setup args - if (_stricmp(arg, "--service") == 0) { - // ignore and skip the next arg also (service action) - i++; - } - else { - if (strchr(arg, ' ') != NULL) { - // surround argument with quotes if it contains a space - argBuf << " \"" << arg << "\""; - } else { - argBuf << " " << arg; - } - } - } - return argBuf.str(); -} - -void -CArchAppUtilWindows::installService() -{ - CString args = getServiceArgs(); - - // get the path of this program - char thisPath[MAX_PATH]; - GetModuleFileName(CArchMiscWindows::instanceWin32(), thisPath, MAX_PATH); - - ARCH->installDaemon( - app().daemonName(), app().daemonInfo(), - thisPath, args.c_str(), NULL, true); - - LOG((CLOG_INFO "service '%s' installed with args: %s", - app().daemonName(), args != "" ? args.c_str() : "none" )); -} - -void -CArchAppUtilWindows::uninstallService() -{ - ARCH->uninstallDaemon(app().daemonName(), true); - LOG((CLOG_INFO "service '%s' uninstalled", app().daemonName())); -} - -void -CArchAppUtilWindows::startService() -{ - // open service manager - SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ); - if (mgr == NULL) { - throw XArchDaemonFailed(new XArchEvalWindows()); - } - - // open the service - SC_HANDLE service = OpenService( - mgr, app().daemonName(), SERVICE_START); - - if (service == NULL) { - CloseServiceHandle(mgr); - throw XArchDaemonFailed(new XArchEvalWindows()); - } - - // start the service - if (StartService(service, 0, NULL)) { - LOG((CLOG_INFO "service '%s' started", app().daemonName())); - } - else { - throw XArchDaemonFailed(new XArchEvalWindows()); - } -} - -void -CArchAppUtilWindows::stopService() -{ - // open service manager - SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ); - if (mgr == NULL) { - throw XArchDaemonFailed(new XArchEvalWindows()); - } - - // open the service - SC_HANDLE service = OpenService( - mgr, app().daemonName(), - SERVICE_STOP | SERVICE_QUERY_STATUS); - - if (service == NULL) { - CloseServiceHandle(mgr); - throw XArchDaemonFailed(new XArchEvalWindows()); - } - - // ask the service to stop, asynchronously - SERVICE_STATUS ss; - if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) { - DWORD dwErrCode = GetLastError(); - if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) { - LOG((CLOG_ERR "cannot stop service '%s'", app().daemonName())); - throw XArchDaemonFailed(new XArchEvalWindows()); - } - } - - LOG((CLOG_INFO "service '%s' stopping asynchronously", app().daemonName())); -} - -static -int -mainLoopStatic() -{ - return CArchAppUtil::instance().app().mainLoop(); -} - -int -CArchAppUtilWindows::daemonNTMainLoop(int argc, const char** argv) -{ - app().initApp(argc, argv); - debugServiceWait(); - - // NB: what the hell does this do?! - app().argsBase().m_backend = false; - - return CArchMiscWindows::runDaemon(mainLoopStatic); -} - -void -CArchAppUtilWindows::exitApp(int code) -{ - switch (m_exitMode) { - - case kExitModeDaemon: - CArchMiscWindows::daemonFailed(code); - break; - - default: - throw XExitApp(code); - } -} - -int daemonNTMainLoopStatic(int argc, const char** argv) -{ - return CArchAppUtilWindows::instance().daemonNTMainLoop(argc, argv); -} - -int -CArchAppUtilWindows::daemonNTStartup(int, char**) -{ - CSystemLogger sysLogger(app().daemonName(), false); - m_exitMode = kExitModeDaemon; - return ARCH->daemonize(app().daemonName(), daemonNTMainLoopStatic); -} - -static -int -daemonNTStartupStatic(int argc, char** argv) -{ - return CArchAppUtilWindows::instance().daemonNTStartup(argc, argv); -} - -static -int -foregroundStartupStatic(int argc, char** argv) -{ - return CArchAppUtil::instance().app().foregroundStartup(argc, argv); -} - -void -CArchAppUtilWindows::beforeAppExit() -{ - // this can be handy for debugging, since the application is launched in - // a new console window, and will normally close on exit (making it so - // that we can't see error messages). - if (app().argsBase().m_pauseOnExit) { - std::cout << std::endl << "Press any key to exit..." << std::endl; - int c = _getch(); - } -} - -int -CArchAppUtilWindows::run(int argc, char** argv) -{ - // record window instance for tray icon, etc - CArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); - - CMSWindowsScreen::init(CArchMiscWindows::instanceWin32()); - CThread::getCurrentThread().setPriority(-14); - - StartupFunc startup; - if (CArchMiscWindows::wasLaunchedAsService()) { - startup = &daemonNTStartupStatic; - } else { - startup = &foregroundStartupStatic; - app().argsBase().m_daemon = false; - } - - return app().runInner(argc, argv, NULL, startup); -} - -CArchAppUtilWindows& -CArchAppUtilWindows::instance() -{ - return (CArchAppUtilWindows&)CArchAppUtil::instance(); -} - -void -CArchAppUtilWindows::debugServiceWait() -{ - if (app().argsBase().m_debugServiceWait) - { - while(true) - { - // this code is only executed when the process is launched via the - // windows service controller (and --debug-service-wait arg is - // used). to debug, set a breakpoint on this line so that - // execution is delayed until the debugger is attached. - ARCH->sleep(1); - LOG((CLOG_INFO "waiting for debugger to attach")); - } - } -} - -void -CArchAppUtilWindows::startNode() + } + else if (app().isArg(i, argc, argv, NULL, "--exit-pause")) { + + app().argsBase().m_pauseOnExit = true; + } + else if (app().isArg(i, argc, argv, NULL, "--no-tray")) { + + app().argsBase().m_disableTray = true; + } + else { + // option not supported here + return false; + } + + return true; +} + +CString +CArchAppUtilWindows::getServiceArgs() const +{ + std::stringstream argBuf; + for (int i = 1; i < __argc; i++) { + const char* arg = __argv[i]; + + // ignore service setup args + if (_stricmp(arg, "--service") == 0) { + // ignore and skip the next arg also (service action) + i++; + } + else { + if (strchr(arg, ' ') != NULL) { + // surround argument with quotes if it contains a space + argBuf << " \"" << arg << "\""; + } else { + argBuf << " " << arg; + } + } + } + return argBuf.str(); +} + +void +CArchAppUtilWindows::installService() +{ + CString args = getServiceArgs(); + + // get the path of this program + char thisPath[MAX_PATH]; + GetModuleFileName(CArchMiscWindows::instanceWin32(), thisPath, MAX_PATH); + + ARCH->installDaemon( + app().daemonName(), app().daemonInfo(), + thisPath, args.c_str(), NULL, true); + + LOG((CLOG_INFO "service '%s' installed with args: %s", + app().daemonName(), args != "" ? args.c_str() : "none" )); +} + +void +CArchAppUtilWindows::uninstallService() +{ + ARCH->uninstallDaemon(app().daemonName(), true); + LOG((CLOG_INFO "service '%s' uninstalled", app().daemonName())); +} + +void +CArchAppUtilWindows::startService() +{ + // open service manager + SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ); + if (mgr == NULL) { + throw XArchDaemonFailed(new XArchEvalWindows()); + } + + // open the service + SC_HANDLE service = OpenService( + mgr, app().daemonName(), SERVICE_START); + + if (service == NULL) { + CloseServiceHandle(mgr); + throw XArchDaemonFailed(new XArchEvalWindows()); + } + + // start the service + if (StartService(service, 0, NULL)) { + LOG((CLOG_INFO "service '%s' started", app().daemonName())); + } + else { + throw XArchDaemonFailed(new XArchEvalWindows()); + } +} + +void +CArchAppUtilWindows::stopService() +{ + // open service manager + SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ); + if (mgr == NULL) { + throw XArchDaemonFailed(new XArchEvalWindows()); + } + + // open the service + SC_HANDLE service = OpenService( + mgr, app().daemonName(), + SERVICE_STOP | SERVICE_QUERY_STATUS); + + if (service == NULL) { + CloseServiceHandle(mgr); + throw XArchDaemonFailed(new XArchEvalWindows()); + } + + // ask the service to stop, asynchronously + SERVICE_STATUS ss; + if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) { + DWORD dwErrCode = GetLastError(); + if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) { + LOG((CLOG_ERR "cannot stop service '%s'", app().daemonName())); + throw XArchDaemonFailed(new XArchEvalWindows()); + } + } + + LOG((CLOG_INFO "service '%s' stopping asynchronously", app().daemonName())); +} + +static +int +mainLoopStatic() +{ + return CArchAppUtil::instance().app().mainLoop(); +} + +int +CArchAppUtilWindows::daemonNTMainLoop(int argc, const char** argv) +{ + app().initApp(argc, argv); + debugServiceWait(); + + // NB: what the hell does this do?! + app().argsBase().m_backend = false; + + return CArchMiscWindows::runDaemon(mainLoopStatic); +} + +void +CArchAppUtilWindows::exitApp(int code) +{ + switch (m_exitMode) { + + case kExitModeDaemon: + CArchMiscWindows::daemonFailed(code); + break; + + default: + throw XExitApp(code); + } +} + +int daemonNTMainLoopStatic(int argc, const char** argv) +{ + return CArchAppUtilWindows::instance().daemonNTMainLoop(argc, argv); +} + +int +CArchAppUtilWindows::daemonNTStartup(int, char**) +{ + CSystemLogger sysLogger(app().daemonName(), false); + m_exitMode = kExitModeDaemon; + return ARCH->daemonize(app().daemonName(), daemonNTMainLoopStatic); +} + +static +int +daemonNTStartupStatic(int argc, char** argv) +{ + return CArchAppUtilWindows::instance().daemonNTStartup(argc, argv); +} + +static +int +foregroundStartupStatic(int argc, char** argv) +{ + return CArchAppUtil::instance().app().foregroundStartup(argc, argv); +} + +void +CArchAppUtilWindows::beforeAppExit() +{ + // this can be handy for debugging, since the application is launched in + // a new console window, and will normally close on exit (making it so + // that we can't see error messages). + if (app().argsBase().m_pauseOnExit) { + std::cout << std::endl << "Press any key to exit..." << std::endl; + int c = _getch(); + } +} + +int +CArchAppUtilWindows::run(int argc, char** argv) +{ + // record window instance for tray icon, etc + CArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); + + CMSWindowsScreen::init(CArchMiscWindows::instanceWin32()); + CThread::getCurrentThread().setPriority(-14); + + StartupFunc startup; + if (CArchMiscWindows::wasLaunchedAsService()) { + startup = &daemonNTStartupStatic; + } else { + startup = &foregroundStartupStatic; + app().argsBase().m_daemon = false; + } + + return app().runInner(argc, argv, NULL, startup); +} + +CArchAppUtilWindows& +CArchAppUtilWindows::instance() +{ + return (CArchAppUtilWindows&)CArchAppUtil::instance(); +} + +void +CArchAppUtilWindows::debugServiceWait() +{ + if (app().argsBase().m_debugServiceWait) + { + while(true) + { + // this code is only executed when the process is launched via the + // windows service controller (and --debug-service-wait arg is + // used). to debug, set a breakpoint on this line so that + // execution is delayed until the debugger is attached. + ARCH->sleep(1); + LOG((CLOG_INFO "waiting for debugger to attach")); + } + } +} + +void +CArchAppUtilWindows::startNode() { if (app().argsBase().m_relaunchMode) { @@ -346,5 +346,5 @@ CArchAppUtilWindows::startNode() } else { app().startNode(); - } -} + } +} diff --git a/lib/arch/CArchAppUtilWindows.h b/lib/arch/CArchAppUtilWindows.h index 4b904c3c..6c798419 100644 --- a/lib/arch/CArchAppUtilWindows.h +++ b/lib/arch/CArchAppUtilWindows.h @@ -1,78 +1,78 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "CArchAppUtil.h" -#include "CString.h" - -#define WIN32_LEAN_AND_MEAN -#include "Windows.h" - -#define ARCH_APPUTIL CArchAppUtilWindows - -enum AppExitMode { - kExitModeNormal, - kExitModeDaemon -}; - -class CArchAppUtilWindows : public CArchAppUtil { -public: - CArchAppUtilWindows(); - virtual ~CArchAppUtilWindows(); - - // Gets the arguments to be used with a service. - CString getServiceArgs() const; - - // Install application as Windows service. - void installService(); - - // Uninstall a Windows service with matching daemon name. - void uninstallService(); - - // Start a Windows service with matching daemon name. - void startService(); - - // Stop a Windows service with matching daemon name. - void stopService(); - - // Will install, uninstall, start, or stop the service depending on arg. - void handleServiceArg(const char* serviceAction); - +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "CArchAppUtil.h" +#include "CString.h" + +#define WIN32_LEAN_AND_MEAN +#include "Windows.h" + +#define ARCH_APPUTIL CArchAppUtilWindows + +enum AppExitMode { + kExitModeNormal, + kExitModeDaemon +}; + +class CArchAppUtilWindows : public CArchAppUtil { +public: + CArchAppUtilWindows(); + virtual ~CArchAppUtilWindows(); + + // Gets the arguments to be used with a service. + CString getServiceArgs() const; + + // Install application as Windows service. + void installService(); + + // Uninstall a Windows service with matching daemon name. + void uninstallService(); + + // Start a Windows service with matching daemon name. + void startService(); + + // Stop a Windows service with matching daemon name. + void stopService(); + + // Will install, uninstall, start, or stop the service depending on arg. + void handleServiceArg(const char* serviceAction); + bool parseArg(const int& argc, const char* const* argv, int& i); int daemonNTStartup(int, char**); - - int daemonNTMainLoop(int argc, const char** argv); - - void debugServiceWait(); - + + int daemonNTMainLoop(int argc, const char** argv); + + void debugServiceWait(); + int run(int argc, char** argv); - void exitApp(int code); - - void beforeAppExit(); - - static CArchAppUtilWindows& instance(); - - void startNode(); - -private: - AppExitMode m_exitMode; - static BOOL WINAPI consoleHandler(DWORD CEvent); -}; + void exitApp(int code); + + void beforeAppExit(); + + static CArchAppUtilWindows& instance(); + + void startNode(); + +private: + AppExitMode m_exitMode; + static BOOL WINAPI consoleHandler(DWORD CEvent); +}; diff --git a/lib/arch/CArchMiscWindows.cpp b/lib/arch/CArchMiscWindows.cpp index ca71050e..399591ba 100644 --- a/lib/arch/CArchMiscWindows.cpp +++ b/lib/arch/CArchMiscWindows.cpp @@ -1,555 +1,555 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CArchMiscWindows.h" -#include "CArchDaemonWindows.h" -#include "CLog.h" - -#include -#pragma warning(disable: 4099) -#include -#pragma warning(default: 4099) -#include "Version.h" - -// parent process name for services in Vista -#define SERVICE_LAUNCHER "services.exe" - -#ifndef ES_SYSTEM_REQUIRED -#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001) -#endif -#ifndef ES_DISPLAY_REQUIRED -#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002) -#endif -#ifndef ES_CONTINUOUS -#define ES_CONTINUOUS ((DWORD)0x80000000) -#endif -typedef DWORD EXECUTION_STATE; - -// -// CArchMiscWindows -// - -CArchMiscWindows::CDialogs* CArchMiscWindows::s_dialogs = NULL; -DWORD CArchMiscWindows::s_busyState = 0; -CArchMiscWindows::STES_t CArchMiscWindows::s_stes = NULL; -HICON CArchMiscWindows::s_largeIcon = NULL; -HICON CArchMiscWindows::s_smallIcon = NULL; -HINSTANCE CArchMiscWindows::s_instanceWin32 = NULL; - -void -CArchMiscWindows::init() -{ - s_dialogs = new CDialogs; - isWindows95Family(); -} - -bool -CArchMiscWindows::isWindows95Family() -{ - static bool init = false; - static bool result = false; - - if (!init) { - OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof(version); - if (GetVersionEx(&version) == 0) { - // cannot determine OS; assume windows 95 family - result = true; - } - else { - result = (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); - } - init = true; - } - return result; -} - -bool -CArchMiscWindows::isWindowsModern() -{ - static bool init = false; - static bool result = false; - - if (!init) { - OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof(version); - if (GetVersionEx(&version) == 0) { - // cannot determine OS; assume not modern - result = false; - } - else { - result = ((version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - version.dwMajorVersion == 4 && - version.dwMinorVersion > 0) || - (version.dwPlatformId == VER_PLATFORM_WIN32_NT && - version.dwMajorVersion > 4)); - } - init = true; - } - return result; -} - -void -CArchMiscWindows::setIcons(HICON largeIcon, HICON smallIcon) -{ - s_largeIcon = largeIcon; - s_smallIcon = smallIcon; -} - -void -CArchMiscWindows::getIcons(HICON& largeIcon, HICON& smallIcon) -{ - largeIcon = s_largeIcon; - smallIcon = s_smallIcon; -} - -int -CArchMiscWindows::runDaemon(RunFunc runFunc) -{ - return CArchDaemonWindows::runDaemon(runFunc); -} - -void -CArchMiscWindows::daemonRunning(bool running) -{ - CArchDaemonWindows::daemonRunning(running); -} - -void -CArchMiscWindows::daemonFailed(int result) -{ - CArchDaemonWindows::daemonFailed(result); -} - -UINT -CArchMiscWindows::getDaemonQuitMessage() -{ - return CArchDaemonWindows::getDaemonQuitMessage(); -} - -HKEY -CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName) -{ - return openKey(key, keyName, false); -} - -HKEY -CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames) -{ - return openKey(key, keyNames, false); -} - -HKEY -CArchMiscWindows::addKey(HKEY key, const TCHAR* keyName) -{ - return openKey(key, keyName, true); -} - -HKEY -CArchMiscWindows::addKey(HKEY key, const TCHAR* const* keyNames) -{ - return openKey(key, keyNames, true); -} - -HKEY -CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName, bool create) -{ - // ignore if parent is NULL - if (key == NULL) { - return NULL; - } - - // open next key - HKEY newKey; - LONG result = RegOpenKeyEx(key, keyName, 0, - KEY_WRITE | KEY_QUERY_VALUE, &newKey); - if (result != ERROR_SUCCESS && create) { - DWORD disp; - result = RegCreateKeyEx(key, keyName, 0, TEXT(""), - 0, KEY_WRITE | KEY_QUERY_VALUE, - NULL, &newKey, &disp); - } - if (result != ERROR_SUCCESS) { - RegCloseKey(key); - return NULL; - } - - // switch to new key - RegCloseKey(key); - return newKey; -} - -HKEY -CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames, bool create) -{ - for (size_t i = 0; key != NULL && keyNames[i] != NULL; ++i) { - // open next key - key = openKey(key, keyNames[i], create); - } - return key; -} - -void -CArchMiscWindows::closeKey(HKEY key) -{ - assert(key != NULL); - if (key==NULL) return; - RegCloseKey(key); -} - -void -CArchMiscWindows::deleteKey(HKEY key, const TCHAR* name) -{ - assert(key != NULL); - assert(name != NULL); - if (key==NULL || name==NULL) return; - RegDeleteKey(key, name); -} - -void -CArchMiscWindows::deleteValue(HKEY key, const TCHAR* name) -{ - assert(key != NULL); - assert(name != NULL); - if (key==NULL || name==NULL) return; - RegDeleteValue(key, name); -} - -bool -CArchMiscWindows::hasValue(HKEY key, const TCHAR* name) -{ - DWORD type; - LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL); - return (result == ERROR_SUCCESS && - (type == REG_DWORD || type == REG_SZ)); -} - -CArchMiscWindows::EValueType -CArchMiscWindows::typeOfValue(HKEY key, const TCHAR* name) -{ - DWORD type; - LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL); - if (result != ERROR_SUCCESS) { - return kNO_VALUE; - } - switch (type) { - case REG_DWORD: - return kUINT; - - case REG_SZ: - return kSTRING; - - case REG_BINARY: - return kBINARY; - - default: - return kUNKNOWN; - } -} - -void -CArchMiscWindows::setValue(HKEY key, - const TCHAR* name, const std::string& value) -{ - assert(key != NULL); - assert(name != NULL); - if(key ==NULL || name==NULL) return; // TODO: throw exception - RegSetValueEx(key, name, 0, REG_SZ, - reinterpret_cast(value.c_str()), - (DWORD)value.size() + 1); -} - -void -CArchMiscWindows::setValue(HKEY key, const TCHAR* name, DWORD value) -{ - assert(key != NULL); - assert(name != NULL); - if(key ==NULL || name==NULL) return; // TODO: throw exception - RegSetValueEx(key, name, 0, REG_DWORD, - reinterpret_cast(&value), - sizeof(DWORD)); -} - -void -CArchMiscWindows::setValueBinary(HKEY key, - const TCHAR* name, const std::string& value) -{ - assert(key != NULL); - assert(name != NULL); - if(key ==NULL || name==NULL) return; // TODO: throw exception - RegSetValueEx(key, name, 0, REG_BINARY, - reinterpret_cast(value.data()), - (DWORD)value.size()); -} - -std::string -CArchMiscWindows::readBinaryOrString(HKEY key, const TCHAR* name, DWORD type) -{ - // get the size of the string - DWORD actualType; - DWORD size = 0; - LONG result = RegQueryValueEx(key, name, 0, &actualType, NULL, &size); - if (result != ERROR_SUCCESS || actualType != type) { - return std::string(); - } - - // if zero size then return empty string - if (size == 0) { - return std::string(); - } - - // allocate space - char* buffer = new char[size]; - - // read it - result = RegQueryValueEx(key, name, 0, &actualType, - reinterpret_cast(buffer), &size); - if (result != ERROR_SUCCESS || actualType != type) { - delete[] buffer; - return std::string(); - } - - // clean up and return value - if (type == REG_SZ && buffer[size - 1] == '\0') { - // don't include terminating nul; std::string will add one. - --size; - } - std::string value(buffer, size); - delete[] buffer; - return value; -} - -std::string -CArchMiscWindows::readValueString(HKEY key, const TCHAR* name) -{ - return readBinaryOrString(key, name, REG_SZ); -} - -std::string -CArchMiscWindows::readValueBinary(HKEY key, const TCHAR* name) -{ - return readBinaryOrString(key, name, REG_BINARY); -} - -DWORD -CArchMiscWindows::readValueInt(HKEY key, const TCHAR* name) -{ - DWORD type; - DWORD value; - DWORD size = sizeof(value); - LONG result = RegQueryValueEx(key, name, 0, &type, - reinterpret_cast(&value), &size); - if (result != ERROR_SUCCESS || type != REG_DWORD) { - return 0; - } - return value; -} - -void -CArchMiscWindows::addDialog(HWND hwnd) -{ - s_dialogs->insert(hwnd); -} - -void -CArchMiscWindows::removeDialog(HWND hwnd) -{ - s_dialogs->erase(hwnd); -} - -bool -CArchMiscWindows::processDialog(MSG* msg) -{ - for (CDialogs::const_iterator index = s_dialogs->begin(); - index != s_dialogs->end(); ++index) { - if (IsDialogMessage(*index, msg)) { - return true; - } - } - return false; -} - -void -CArchMiscWindows::addBusyState(DWORD busyModes) -{ - s_busyState |= busyModes; - setThreadExecutionState(s_busyState); -} - -void -CArchMiscWindows::removeBusyState(DWORD busyModes) -{ - s_busyState &= ~busyModes; - setThreadExecutionState(s_busyState); -} - -void -CArchMiscWindows::setThreadExecutionState(DWORD busyModes) -{ - // look up function dynamically so we work on older systems - if (s_stes == NULL) { - HINSTANCE kernel = LoadLibrary("kernel32.dll"); - if (kernel != NULL) { - s_stes = reinterpret_cast(GetProcAddress(kernel, - "SetThreadExecutionState")); - } - if (s_stes == NULL) { - s_stes = &CArchMiscWindows::dummySetThreadExecutionState; - } - } - - // convert to STES form - EXECUTION_STATE state = 0; - if ((busyModes & kSYSTEM) != 0) { - state |= ES_SYSTEM_REQUIRED; - } - if ((busyModes & kDISPLAY) != 0) { - state |= ES_DISPLAY_REQUIRED; - } - if (state != 0) { - state |= ES_CONTINUOUS; - } - - // do it - s_stes(state); -} - -DWORD -CArchMiscWindows::dummySetThreadExecutionState(DWORD) -{ - // do nothing - return 0; -} - -void -CArchMiscWindows::wakeupDisplay() -{ - // We can't use ::setThreadExecutionState here because it sets - // ES_CONTINUOUS, which we don't want. - - if (s_stes == NULL) { - HINSTANCE kernel = LoadLibrary("kernel32.dll"); - if (kernel != NULL) { - s_stes = reinterpret_cast(GetProcAddress(kernel, - "SetThreadExecutionState")); - } - if (s_stes == NULL) { - s_stes = &CArchMiscWindows::dummySetThreadExecutionState; - } - } - - s_stes(ES_DISPLAY_REQUIRED); - - // restore the original execution states - setThreadExecutionState(s_busyState); -} - -bool -CArchMiscWindows::wasLaunchedAsService() -{ - CString name; - if (!getParentProcessName(name)) { - LOG((CLOG_ERR "cannot determine if process was launched as service")); - return false; - } - - return (name == SERVICE_LAUNCHER); -} - -bool -CArchMiscWindows::getParentProcessName(CString &name) -{ - PROCESSENTRY32 parentEntry; - if (!getParentProcessEntry(parentEntry)){ - LOG((CLOG_ERR "could not get entry for parent process")); - return false; - } - - name = parentEntry.szExeFile; - return true; -} - -BOOL WINAPI -CArchMiscWindows::getSelfProcessEntry(PROCESSENTRY32& entry) -{ - // get entry from current PID - return getProcessEntry(entry, GetCurrentProcessId()); -} - -BOOL WINAPI -CArchMiscWindows::getParentProcessEntry(PROCESSENTRY32& entry) -{ - // get the current process, so we can get parent PID - PROCESSENTRY32 selfEntry; - if (!getSelfProcessEntry(selfEntry)) { - return FALSE; - } - - // get entry from parent PID - return getProcessEntry(entry, selfEntry.th32ParentProcessID); -} - -BOOL WINAPI -CArchMiscWindows::getProcessEntry(PROCESSENTRY32& entry, DWORD processID) -{ - // first we need to take a snapshot of the running processes - HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snapshot == INVALID_HANDLE_VALUE) { - LOG((CLOG_ERR "could not get process snapshot (error: %i)", - GetLastError())); - return FALSE; - } - - entry.dwSize = sizeof(PROCESSENTRY32); - - // get the first process, and if we can't do that then it's - // unlikely we can go any further - BOOL gotEntry = Process32First(snapshot, &entry); - if (!gotEntry) { - LOG((CLOG_ERR "could not get first process entry (error: %i)", - GetLastError())); - return FALSE; - } - - while(gotEntry) { - - if (entry.th32ProcessID == processID) { - // found current process - return TRUE; - } - - // now move on to the next entry (when we reach end, loop will stop) - gotEntry = Process32Next(snapshot, &entry); - } - - return FALSE; -} - -HINSTANCE -CArchMiscWindows::instanceWin32() -{ - assert(s_instanceWin32 != NULL); - return s_instanceWin32; -} - -void -CArchMiscWindows::setInstanceWin32(HINSTANCE instance) -{ - assert(instance != NULL); - s_instanceWin32 = instance; +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CArchMiscWindows.h" +#include "CArchDaemonWindows.h" +#include "CLog.h" + +#include +#pragma warning(disable: 4099) +#include +#pragma warning(default: 4099) +#include "Version.h" + +// parent process name for services in Vista +#define SERVICE_LAUNCHER "services.exe" + +#ifndef ES_SYSTEM_REQUIRED +#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001) +#endif +#ifndef ES_DISPLAY_REQUIRED +#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002) +#endif +#ifndef ES_CONTINUOUS +#define ES_CONTINUOUS ((DWORD)0x80000000) +#endif +typedef DWORD EXECUTION_STATE; + +// +// CArchMiscWindows +// + +CArchMiscWindows::CDialogs* CArchMiscWindows::s_dialogs = NULL; +DWORD CArchMiscWindows::s_busyState = 0; +CArchMiscWindows::STES_t CArchMiscWindows::s_stes = NULL; +HICON CArchMiscWindows::s_largeIcon = NULL; +HICON CArchMiscWindows::s_smallIcon = NULL; +HINSTANCE CArchMiscWindows::s_instanceWin32 = NULL; + +void +CArchMiscWindows::init() +{ + s_dialogs = new CDialogs; + isWindows95Family(); +} + +bool +CArchMiscWindows::isWindows95Family() +{ + static bool init = false; + static bool result = false; + + if (!init) { + OSVERSIONINFO version; + version.dwOSVersionInfoSize = sizeof(version); + if (GetVersionEx(&version) == 0) { + // cannot determine OS; assume windows 95 family + result = true; + } + else { + result = (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); + } + init = true; + } + return result; +} + +bool +CArchMiscWindows::isWindowsModern() +{ + static bool init = false; + static bool result = false; + + if (!init) { + OSVERSIONINFO version; + version.dwOSVersionInfoSize = sizeof(version); + if (GetVersionEx(&version) == 0) { + // cannot determine OS; assume not modern + result = false; + } + else { + result = ((version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && + version.dwMajorVersion == 4 && + version.dwMinorVersion > 0) || + (version.dwPlatformId == VER_PLATFORM_WIN32_NT && + version.dwMajorVersion > 4)); + } + init = true; + } + return result; +} + +void +CArchMiscWindows::setIcons(HICON largeIcon, HICON smallIcon) +{ + s_largeIcon = largeIcon; + s_smallIcon = smallIcon; +} + +void +CArchMiscWindows::getIcons(HICON& largeIcon, HICON& smallIcon) +{ + largeIcon = s_largeIcon; + smallIcon = s_smallIcon; +} + +int +CArchMiscWindows::runDaemon(RunFunc runFunc) +{ + return CArchDaemonWindows::runDaemon(runFunc); +} + +void +CArchMiscWindows::daemonRunning(bool running) +{ + CArchDaemonWindows::daemonRunning(running); +} + +void +CArchMiscWindows::daemonFailed(int result) +{ + CArchDaemonWindows::daemonFailed(result); +} + +UINT +CArchMiscWindows::getDaemonQuitMessage() +{ + return CArchDaemonWindows::getDaemonQuitMessage(); +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName) +{ + return openKey(key, keyName, false); +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames) +{ + return openKey(key, keyNames, false); +} + +HKEY +CArchMiscWindows::addKey(HKEY key, const TCHAR* keyName) +{ + return openKey(key, keyName, true); +} + +HKEY +CArchMiscWindows::addKey(HKEY key, const TCHAR* const* keyNames) +{ + return openKey(key, keyNames, true); +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName, bool create) +{ + // ignore if parent is NULL + if (key == NULL) { + return NULL; + } + + // open next key + HKEY newKey; + LONG result = RegOpenKeyEx(key, keyName, 0, + KEY_WRITE | KEY_QUERY_VALUE, &newKey); + if (result != ERROR_SUCCESS && create) { + DWORD disp; + result = RegCreateKeyEx(key, keyName, 0, TEXT(""), + 0, KEY_WRITE | KEY_QUERY_VALUE, + NULL, &newKey, &disp); + } + if (result != ERROR_SUCCESS) { + RegCloseKey(key); + return NULL; + } + + // switch to new key + RegCloseKey(key); + return newKey; +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames, bool create) +{ + for (size_t i = 0; key != NULL && keyNames[i] != NULL; ++i) { + // open next key + key = openKey(key, keyNames[i], create); + } + return key; +} + +void +CArchMiscWindows::closeKey(HKEY key) +{ + assert(key != NULL); + if (key==NULL) return; + RegCloseKey(key); +} + +void +CArchMiscWindows::deleteKey(HKEY key, const TCHAR* name) +{ + assert(key != NULL); + assert(name != NULL); + if (key==NULL || name==NULL) return; + RegDeleteKey(key, name); +} + +void +CArchMiscWindows::deleteValue(HKEY key, const TCHAR* name) +{ + assert(key != NULL); + assert(name != NULL); + if (key==NULL || name==NULL) return; + RegDeleteValue(key, name); +} + +bool +CArchMiscWindows::hasValue(HKEY key, const TCHAR* name) +{ + DWORD type; + LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL); + return (result == ERROR_SUCCESS && + (type == REG_DWORD || type == REG_SZ)); +} + +CArchMiscWindows::EValueType +CArchMiscWindows::typeOfValue(HKEY key, const TCHAR* name) +{ + DWORD type; + LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL); + if (result != ERROR_SUCCESS) { + return kNO_VALUE; + } + switch (type) { + case REG_DWORD: + return kUINT; + + case REG_SZ: + return kSTRING; + + case REG_BINARY: + return kBINARY; + + default: + return kUNKNOWN; + } +} + +void +CArchMiscWindows::setValue(HKEY key, + const TCHAR* name, const std::string& value) +{ + assert(key != NULL); + assert(name != NULL); + if(key ==NULL || name==NULL) return; // TODO: throw exception + RegSetValueEx(key, name, 0, REG_SZ, + reinterpret_cast(value.c_str()), + (DWORD)value.size() + 1); +} + +void +CArchMiscWindows::setValue(HKEY key, const TCHAR* name, DWORD value) +{ + assert(key != NULL); + assert(name != NULL); + if(key ==NULL || name==NULL) return; // TODO: throw exception + RegSetValueEx(key, name, 0, REG_DWORD, + reinterpret_cast(&value), + sizeof(DWORD)); +} + +void +CArchMiscWindows::setValueBinary(HKEY key, + const TCHAR* name, const std::string& value) +{ + assert(key != NULL); + assert(name != NULL); + if(key ==NULL || name==NULL) return; // TODO: throw exception + RegSetValueEx(key, name, 0, REG_BINARY, + reinterpret_cast(value.data()), + (DWORD)value.size()); +} + +std::string +CArchMiscWindows::readBinaryOrString(HKEY key, const TCHAR* name, DWORD type) +{ + // get the size of the string + DWORD actualType; + DWORD size = 0; + LONG result = RegQueryValueEx(key, name, 0, &actualType, NULL, &size); + if (result != ERROR_SUCCESS || actualType != type) { + return std::string(); + } + + // if zero size then return empty string + if (size == 0) { + return std::string(); + } + + // allocate space + char* buffer = new char[size]; + + // read it + result = RegQueryValueEx(key, name, 0, &actualType, + reinterpret_cast(buffer), &size); + if (result != ERROR_SUCCESS || actualType != type) { + delete[] buffer; + return std::string(); + } + + // clean up and return value + if (type == REG_SZ && buffer[size - 1] == '\0') { + // don't include terminating nul; std::string will add one. + --size; + } + std::string value(buffer, size); + delete[] buffer; + return value; +} + +std::string +CArchMiscWindows::readValueString(HKEY key, const TCHAR* name) +{ + return readBinaryOrString(key, name, REG_SZ); +} + +std::string +CArchMiscWindows::readValueBinary(HKEY key, const TCHAR* name) +{ + return readBinaryOrString(key, name, REG_BINARY); +} + +DWORD +CArchMiscWindows::readValueInt(HKEY key, const TCHAR* name) +{ + DWORD type; + DWORD value; + DWORD size = sizeof(value); + LONG result = RegQueryValueEx(key, name, 0, &type, + reinterpret_cast(&value), &size); + if (result != ERROR_SUCCESS || type != REG_DWORD) { + return 0; + } + return value; +} + +void +CArchMiscWindows::addDialog(HWND hwnd) +{ + s_dialogs->insert(hwnd); +} + +void +CArchMiscWindows::removeDialog(HWND hwnd) +{ + s_dialogs->erase(hwnd); +} + +bool +CArchMiscWindows::processDialog(MSG* msg) +{ + for (CDialogs::const_iterator index = s_dialogs->begin(); + index != s_dialogs->end(); ++index) { + if (IsDialogMessage(*index, msg)) { + return true; + } + } + return false; +} + +void +CArchMiscWindows::addBusyState(DWORD busyModes) +{ + s_busyState |= busyModes; + setThreadExecutionState(s_busyState); +} + +void +CArchMiscWindows::removeBusyState(DWORD busyModes) +{ + s_busyState &= ~busyModes; + setThreadExecutionState(s_busyState); +} + +void +CArchMiscWindows::setThreadExecutionState(DWORD busyModes) +{ + // look up function dynamically so we work on older systems + if (s_stes == NULL) { + HINSTANCE kernel = LoadLibrary("kernel32.dll"); + if (kernel != NULL) { + s_stes = reinterpret_cast(GetProcAddress(kernel, + "SetThreadExecutionState")); + } + if (s_stes == NULL) { + s_stes = &CArchMiscWindows::dummySetThreadExecutionState; + } + } + + // convert to STES form + EXECUTION_STATE state = 0; + if ((busyModes & kSYSTEM) != 0) { + state |= ES_SYSTEM_REQUIRED; + } + if ((busyModes & kDISPLAY) != 0) { + state |= ES_DISPLAY_REQUIRED; + } + if (state != 0) { + state |= ES_CONTINUOUS; + } + + // do it + s_stes(state); +} + +DWORD +CArchMiscWindows::dummySetThreadExecutionState(DWORD) +{ + // do nothing + return 0; +} + +void +CArchMiscWindows::wakeupDisplay() +{ + // We can't use ::setThreadExecutionState here because it sets + // ES_CONTINUOUS, which we don't want. + + if (s_stes == NULL) { + HINSTANCE kernel = LoadLibrary("kernel32.dll"); + if (kernel != NULL) { + s_stes = reinterpret_cast(GetProcAddress(kernel, + "SetThreadExecutionState")); + } + if (s_stes == NULL) { + s_stes = &CArchMiscWindows::dummySetThreadExecutionState; + } + } + + s_stes(ES_DISPLAY_REQUIRED); + + // restore the original execution states + setThreadExecutionState(s_busyState); +} + +bool +CArchMiscWindows::wasLaunchedAsService() +{ + CString name; + if (!getParentProcessName(name)) { + LOG((CLOG_ERR "cannot determine if process was launched as service")); + return false; + } + + return (name == SERVICE_LAUNCHER); +} + +bool +CArchMiscWindows::getParentProcessName(CString &name) +{ + PROCESSENTRY32 parentEntry; + if (!getParentProcessEntry(parentEntry)){ + LOG((CLOG_ERR "could not get entry for parent process")); + return false; + } + + name = parentEntry.szExeFile; + return true; +} + +BOOL WINAPI +CArchMiscWindows::getSelfProcessEntry(PROCESSENTRY32& entry) +{ + // get entry from current PID + return getProcessEntry(entry, GetCurrentProcessId()); +} + +BOOL WINAPI +CArchMiscWindows::getParentProcessEntry(PROCESSENTRY32& entry) +{ + // get the current process, so we can get parent PID + PROCESSENTRY32 selfEntry; + if (!getSelfProcessEntry(selfEntry)) { + return FALSE; + } + + // get entry from parent PID + return getProcessEntry(entry, selfEntry.th32ParentProcessID); +} + +BOOL WINAPI +CArchMiscWindows::getProcessEntry(PROCESSENTRY32& entry, DWORD processID) +{ + // first we need to take a snapshot of the running processes + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot == INVALID_HANDLE_VALUE) { + LOG((CLOG_ERR "could not get process snapshot (error: %i)", + GetLastError())); + return FALSE; + } + + entry.dwSize = sizeof(PROCESSENTRY32); + + // get the first process, and if we can't do that then it's + // unlikely we can go any further + BOOL gotEntry = Process32First(snapshot, &entry); + if (!gotEntry) { + LOG((CLOG_ERR "could not get first process entry (error: %i)", + GetLastError())); + return FALSE; + } + + while(gotEntry) { + + if (entry.th32ProcessID == processID) { + // found current process + return TRUE; + } + + // now move on to the next entry (when we reach end, loop will stop) + gotEntry = Process32Next(snapshot, &entry); + } + + return FALSE; +} + +HINSTANCE +CArchMiscWindows::instanceWin32() +{ + assert(s_instanceWin32 != NULL); + return s_instanceWin32; +} + +void +CArchMiscWindows::setInstanceWin32(HINSTANCE instance) +{ + assert(instance != NULL); + s_instanceWin32 = instance; } \ No newline at end of file diff --git a/lib/arch/CArchMiscWindows.h b/lib/arch/CArchMiscWindows.h index e0c405b4..089429ac 100644 --- a/lib/arch/CArchMiscWindows.h +++ b/lib/arch/CArchMiscWindows.h @@ -24,7 +24,7 @@ #include "common.h" #include "stdstring.h" #include "stdset.h" -#include +#include #include #include "CString.h" @@ -174,10 +174,10 @@ public: static bool wasLaunchedAsService(); //! Returns true if we got the parent process name. - static bool getParentProcessName(CString &name); - - static HINSTANCE instanceWin32(); - + static bool getParentProcessName(CString &name); + + static HINSTANCE instanceWin32(); + static void setInstanceWin32(HINSTANCE instance); private: diff --git a/lib/arch/IArchAppUtil.h b/lib/arch/IArchAppUtil.h index 2617d323..fa487723 100644 --- a/lib/arch/IArchAppUtil.h +++ b/lib/arch/IArchAppUtil.h @@ -1,35 +1,35 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "IInterface.h" - -// TODO: replace with forward declaration if possible -// we need to decouple these classes! -#include "CApp.h" - -class IArchAppUtil : public IInterface { +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "IInterface.h" + +// TODO: replace with forward declaration if possible +// we need to decouple these classes! +#include "CApp.h" + +class IArchAppUtil : public IInterface { public: - virtual bool parseArg(const int& argc, const char* const* argv, int& i) = 0; - virtual void adoptApp(CApp* app) = 0; - virtual CApp& app() const = 0; - virtual int run(int argc, char** argv) = 0; - virtual void beforeAppExit() = 0; - virtual void startNode() = 0; -}; + virtual bool parseArg(const int& argc, const char* const* argv, int& i) = 0; + virtual void adoptApp(CApp* app) = 0; + virtual CApp& app() const = 0; + virtual int run(int argc, char** argv) = 0; + virtual void beforeAppExit() = 0; + virtual void startNode() = 0; +}; diff --git a/lib/platform/CMSWindowsRelauncher.cpp b/lib/platform/CMSWindowsRelauncher.cpp index 7415d8e3..c89de268 100644 --- a/lib/platform/CMSWindowsRelauncher.cpp +++ b/lib/platform/CMSWindowsRelauncher.cpp @@ -1,326 +1,326 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2010 The Synergy+ Project - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CMSWindowsRelauncher.h" -#include "CThread.h" -#include "TMethodJob.h" -#include "CLog.h" -#include "CArch.h" -#include "Version.h" -#include "CArchDaemonWindows.h" - -#include -#include -#include - -CMSWindowsRelauncher::CMSWindowsRelauncher() : - m_thread(NULL) -{ -} - -CMSWindowsRelauncher::~CMSWindowsRelauncher() -{ - delete m_thread; -} - -void -CMSWindowsRelauncher::startAsync() -{ +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2010 The Synergy+ Project + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CMSWindowsRelauncher.h" +#include "CThread.h" +#include "TMethodJob.h" +#include "CLog.h" +#include "CArch.h" +#include "Version.h" +#include "CArchDaemonWindows.h" + +#include +#include +#include + +CMSWindowsRelauncher::CMSWindowsRelauncher() : + m_thread(NULL) +{ +} + +CMSWindowsRelauncher::~CMSWindowsRelauncher() +{ + delete m_thread; +} + +void +CMSWindowsRelauncher::startAsync() +{ m_thread = new CThread(new TMethodJob( - this, &CMSWindowsRelauncher::startThread, nullptr)); -} - -void -CMSWindowsRelauncher::startThread(void*) -{ - LOG((CLOG_NOTE "starting relaunch service")); - int ret = relaunchLoop(); - - // HACK: this actually throws an exception to exit with 0 (nasty) - ARCH->util().app().m_bye(ret); -} - -// this still gets the physical session (the one the keyboard and -// mouse is connected to), sometimes this returns -1 but not sure why -DWORD -CMSWindowsRelauncher::getSessionId() -{ - return WTSGetActiveConsoleSessionId(); -} - -BOOL -CMSWindowsRelauncher::winlogonInSession(DWORD sessionId, PHANDLE process) -{ - // first we need to take a snapshot of the running processes - HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snapshot == INVALID_HANDLE_VALUE) { - LOG((CLOG_ERR "could not get process snapshot (error: %i)", - GetLastError())); - return 0; - } - - PROCESSENTRY32 entry; - entry.dwSize = sizeof(PROCESSENTRY32); - - // get the first process, and if we can't do that then it's - // unlikely we can go any further - BOOL gotEntry = Process32First(snapshot, &entry); - if (!gotEntry) { - LOG((CLOG_ERR "could not get first process entry (error: %i)", - GetLastError())); - return 0; - } - - // used to record process names for debug info - std::list nameList; - - // now just iterate until we can find winlogon.exe pid - DWORD pid = 0; - while(gotEntry) { - - // make sure we're not checking the system process - if (entry.th32ProcessID != 0) { - - DWORD processSessionId; - BOOL pidToSidRet = ProcessIdToSessionId( - entry.th32ProcessID, &processSessionId); - - if (!pidToSidRet) { - LOG((CLOG_ERR "could not get session id for process id %i (error: %i)", - entry.th32ProcessID, GetLastError())); - return 0; - } - - // only pay attention to processes in the active session - if (processSessionId == sessionId) { - - // store the names so we can record them for debug - nameList.push_back(entry.szExeFile); - - if (_stricmp(entry.szExeFile, "winlogon.exe") == 0) { - pid = entry.th32ProcessID; - break; - } - } - } - - // now move on to the next entry (if we're not at the end) - gotEntry = Process32Next(snapshot, &entry); - if (!gotEntry) { - - DWORD err = GetLastError(); - if (err != ERROR_NO_MORE_FILES) { - - // only worry about error if it's not the end of the snapshot - LOG((CLOG_ERR "could not get subsiquent process entry (error: %i)", - GetLastError())); - return 0; - } - } - } - - std::string nameListJoin; - for(std::list::iterator it = nameList.begin(); - it != nameList.end(); it++) { - nameListJoin.append(*it); - nameListJoin.append(", "); - } - - LOG((CLOG_DEBUG "checked processes while looking for winlogon.exe: %s", - nameListJoin.c_str())); - - CloseHandle(snapshot); - - if (pid) { - // now get the process so we can get the process, with which - // we'll use to get the process token. - *process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid); - return true; - } - else { - LOG((CLOG_DEBUG "could not find winlogon.exe in session %i", sessionId)); - return false; - } -} - -// gets the current user (so we can launch under their session) -HANDLE -CMSWindowsRelauncher::getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security) -{ - HANDLE currentToken; - HANDLE winlogonProcess; - - if (winlogonInSession(sessionId, &winlogonProcess)) { - - LOG((CLOG_DEBUG "session %i has winlogon.exe", sessionId)); - - // get the token, so we can re-launch with this token - // -- do we really need all these access bits? - BOOL tokenRet = OpenProcessToken( - winlogonProcess, - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | - TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | - TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, - ¤tToken); - } - else { - - LOG((CLOG_ERR "session %i does not have winlogon.exe " - "which is needed for re-launch", sessionId)); - return 0; - } - - HANDLE primaryToken; - BOOL duplicateRet = DuplicateTokenEx( - currentToken, MAXIMUM_ALLOWED, security, - SecurityImpersonation, TokenPrimary, &primaryToken); - - if (!duplicateRet) { - LOG((CLOG_ERR "could not duplicate token %i (error: %i)", - currentToken, GetLastError())); - return 0; - } - - return primaryToken; -} - -int -CMSWindowsRelauncher::relaunchLoop() -{ - // start with invalid id (gets re-assigned on first loop) - DWORD sessionId = -1; - - // keep here so we can check if proc running -- huh? - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - - int returnCode = kExitSuccess; - bool launched = false; - - // TODO: fix this hack BEFORE release; we need to exit gracefully instead - // of being force killed! - bool loopRunning = true; - while (loopRunning) { - - DWORD newSessionId = getSessionId(); - - // only enter here when id changes, and the session isn't -1, which - // may mean that there is no active session. - if ((newSessionId != sessionId) && (newSessionId != -1)) { - - // HACK: doesn't close process in a nice way - // TODO: use CloseMainWindow instead - if (launched) { - TerminateProcess(pi.hProcess, kExitSuccess); - LOG((CLOG_DEBUG "terminated existing process to make way for new one")); - launched = false; - } - - // ok, this is now the active session (forget the old one if any) - sessionId = newSessionId; - - SECURITY_ATTRIBUTES sa; - ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); - - // get the token for the user in active session, which is the - // one receiving input from mouse and keyboard. - HANDLE userToken = getCurrentUserToken(sessionId, &sa); - - if (userToken != 0) { - LOG((CLOG_DEBUG "got user token to launch new process")); - - std::string cmd = getCommand(); - - // in case reusing process info struct - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - - STARTUPINFO si; - ZeroMemory(&si, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); - si.lpDesktop = "winsta0\\default"; - - LPVOID environment; - BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE); - if (!blockRet) { - LOG((CLOG_ERR "could not create environment block (error: %i)", - GetLastError())); - - returnCode = kExitFailed; - loopRunning = false; // stop loop - } - else { - - DWORD creationFlags = - NORMAL_PRIORITY_CLASS | - CREATE_NO_WINDOW | - CREATE_UNICODE_ENVIRONMENT; - - // re-launch in current active user session - BOOL createRet = CreateProcessAsUser( - userToken, NULL, LPSTR(cmd.c_str()), - &sa, NULL, TRUE, creationFlags, - environment, NULL, &si, &pi); - - DestroyEnvironmentBlock(environment); - CloseHandle(userToken); - - if (!createRet) { - LOG((CLOG_ERR "could not launch (error: %i)", GetLastError())); - returnCode = kExitFailed; - loopRunning = false; - } - else { - LOG((CLOG_DEBUG "launched in session %i (cmd: %s)", - sessionId, cmd.c_str())); - launched = true; - } - } - } - } - - // check for session change every second - ARCH->sleep(1); - } - - if (launched) { - // HACK: kill just in case process it has survived somehow - TerminateProcess(pi.hProcess, kExitSuccess); - } - - return kExitSuccess; -} - -std::string CMSWindowsRelauncher::getCommand() -{ - // seems like a fairly convoluted way to get the process name - const char* launchName = ARCH->util().app().argsBase().m_pname; - std::string args = ((CArchDaemonWindows&)ARCH->daemon()).commandLine(); - - // build up a full command line - std::stringstream cmdTemp; - cmdTemp << launchName << /*" --debug-data session-" << sessionId <<*/ args; - - std::string cmd = cmdTemp.str(); - - size_t i; - std::string find = "--relaunch"; - while((i = cmd.find(find)) != std::string::npos) { - cmd.replace(i, find.length(), ""); - } - - return cmd; -} + this, &CMSWindowsRelauncher::startThread, nullptr)); +} + +void +CMSWindowsRelauncher::startThread(void*) +{ + LOG((CLOG_NOTE "starting relaunch service")); + int ret = relaunchLoop(); + + // HACK: this actually throws an exception to exit with 0 (nasty) + ARCH->util().app().m_bye(ret); +} + +// this still gets the physical session (the one the keyboard and +// mouse is connected to), sometimes this returns -1 but not sure why +DWORD +CMSWindowsRelauncher::getSessionId() +{ + return WTSGetActiveConsoleSessionId(); +} + +BOOL +CMSWindowsRelauncher::winlogonInSession(DWORD sessionId, PHANDLE process) +{ + // first we need to take a snapshot of the running processes + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot == INVALID_HANDLE_VALUE) { + LOG((CLOG_ERR "could not get process snapshot (error: %i)", + GetLastError())); + return 0; + } + + PROCESSENTRY32 entry; + entry.dwSize = sizeof(PROCESSENTRY32); + + // get the first process, and if we can't do that then it's + // unlikely we can go any further + BOOL gotEntry = Process32First(snapshot, &entry); + if (!gotEntry) { + LOG((CLOG_ERR "could not get first process entry (error: %i)", + GetLastError())); + return 0; + } + + // used to record process names for debug info + std::list nameList; + + // now just iterate until we can find winlogon.exe pid + DWORD pid = 0; + while(gotEntry) { + + // make sure we're not checking the system process + if (entry.th32ProcessID != 0) { + + DWORD processSessionId; + BOOL pidToSidRet = ProcessIdToSessionId( + entry.th32ProcessID, &processSessionId); + + if (!pidToSidRet) { + LOG((CLOG_ERR "could not get session id for process id %i (error: %i)", + entry.th32ProcessID, GetLastError())); + return 0; + } + + // only pay attention to processes in the active session + if (processSessionId == sessionId) { + + // store the names so we can record them for debug + nameList.push_back(entry.szExeFile); + + if (_stricmp(entry.szExeFile, "winlogon.exe") == 0) { + pid = entry.th32ProcessID; + break; + } + } + } + + // now move on to the next entry (if we're not at the end) + gotEntry = Process32Next(snapshot, &entry); + if (!gotEntry) { + + DWORD err = GetLastError(); + if (err != ERROR_NO_MORE_FILES) { + + // only worry about error if it's not the end of the snapshot + LOG((CLOG_ERR "could not get subsiquent process entry (error: %i)", + GetLastError())); + return 0; + } + } + } + + std::string nameListJoin; + for(std::list::iterator it = nameList.begin(); + it != nameList.end(); it++) { + nameListJoin.append(*it); + nameListJoin.append(", "); + } + + LOG((CLOG_DEBUG "checked processes while looking for winlogon.exe: %s", + nameListJoin.c_str())); + + CloseHandle(snapshot); + + if (pid) { + // now get the process so we can get the process, with which + // we'll use to get the process token. + *process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid); + return true; + } + else { + LOG((CLOG_DEBUG "could not find winlogon.exe in session %i", sessionId)); + return false; + } +} + +// gets the current user (so we can launch under their session) +HANDLE +CMSWindowsRelauncher::getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security) +{ + HANDLE currentToken; + HANDLE winlogonProcess; + + if (winlogonInSession(sessionId, &winlogonProcess)) { + + LOG((CLOG_DEBUG "session %i has winlogon.exe", sessionId)); + + // get the token, so we can re-launch with this token + // -- do we really need all these access bits? + BOOL tokenRet = OpenProcessToken( + winlogonProcess, + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | + TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | + TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, + ¤tToken); + } + else { + + LOG((CLOG_ERR "session %i does not have winlogon.exe " + "which is needed for re-launch", sessionId)); + return 0; + } + + HANDLE primaryToken; + BOOL duplicateRet = DuplicateTokenEx( + currentToken, MAXIMUM_ALLOWED, security, + SecurityImpersonation, TokenPrimary, &primaryToken); + + if (!duplicateRet) { + LOG((CLOG_ERR "could not duplicate token %i (error: %i)", + currentToken, GetLastError())); + return 0; + } + + return primaryToken; +} + +int +CMSWindowsRelauncher::relaunchLoop() +{ + // start with invalid id (gets re-assigned on first loop) + DWORD sessionId = -1; + + // keep here so we can check if proc running -- huh? + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + int returnCode = kExitSuccess; + bool launched = false; + + // TODO: fix this hack BEFORE release; we need to exit gracefully instead + // of being force killed! + bool loopRunning = true; + while (loopRunning) { + + DWORD newSessionId = getSessionId(); + + // only enter here when id changes, and the session isn't -1, which + // may mean that there is no active session. + if ((newSessionId != sessionId) && (newSessionId != -1)) { + + // HACK: doesn't close process in a nice way + // TODO: use CloseMainWindow instead + if (launched) { + TerminateProcess(pi.hProcess, kExitSuccess); + LOG((CLOG_DEBUG "terminated existing process to make way for new one")); + launched = false; + } + + // ok, this is now the active session (forget the old one if any) + sessionId = newSessionId; + + SECURITY_ATTRIBUTES sa; + ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); + + // get the token for the user in active session, which is the + // one receiving input from mouse and keyboard. + HANDLE userToken = getCurrentUserToken(sessionId, &sa); + + if (userToken != 0) { + LOG((CLOG_DEBUG "got user token to launch new process")); + + std::string cmd = getCommand(); + + // in case reusing process info struct + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + STARTUPINFO si; + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.lpDesktop = "winsta0\\default"; + + LPVOID environment; + BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE); + if (!blockRet) { + LOG((CLOG_ERR "could not create environment block (error: %i)", + GetLastError())); + + returnCode = kExitFailed; + loopRunning = false; // stop loop + } + else { + + DWORD creationFlags = + NORMAL_PRIORITY_CLASS | + CREATE_NO_WINDOW | + CREATE_UNICODE_ENVIRONMENT; + + // re-launch in current active user session + BOOL createRet = CreateProcessAsUser( + userToken, NULL, LPSTR(cmd.c_str()), + &sa, NULL, TRUE, creationFlags, + environment, NULL, &si, &pi); + + DestroyEnvironmentBlock(environment); + CloseHandle(userToken); + + if (!createRet) { + LOG((CLOG_ERR "could not launch (error: %i)", GetLastError())); + returnCode = kExitFailed; + loopRunning = false; + } + else { + LOG((CLOG_DEBUG "launched in session %i (cmd: %s)", + sessionId, cmd.c_str())); + launched = true; + } + } + } + } + + // check for session change every second + ARCH->sleep(1); + } + + if (launched) { + // HACK: kill just in case process it has survived somehow + TerminateProcess(pi.hProcess, kExitSuccess); + } + + return kExitSuccess; +} + +std::string CMSWindowsRelauncher::getCommand() +{ + // seems like a fairly convoluted way to get the process name + const char* launchName = ARCH->util().app().argsBase().m_pname; + std::string args = ((CArchDaemonWindows&)ARCH->daemon()).commandLine(); + + // build up a full command line + std::stringstream cmdTemp; + cmdTemp << launchName << /*" --debug-data session-" << sessionId <<*/ args; + + std::string cmd = cmdTemp.str(); + + size_t i; + std::string find = "--relaunch"; + while((i = cmd.find(find)) != std::string::npos) { + cmd.replace(i, find.length(), ""); + } + + return cmd; +} diff --git a/lib/platform/CMSWindowsRelauncher.h b/lib/platform/CMSWindowsRelauncher.h index 6577a276..918158e9 100644 --- a/lib/platform/CMSWindowsRelauncher.h +++ b/lib/platform/CMSWindowsRelauncher.h @@ -1,38 +1,38 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2010 The Synergy+ Project - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2010 The Synergy+ Project + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ -#define WIN32_LEAN_AND_MEAN -#include -#include - -class CThread; - -class CMSWindowsRelauncher { -public: - CMSWindowsRelauncher(); - virtual ~CMSWindowsRelauncher(); - void startAsync(); - CThread* m_thread; - void startThread(void*); - BOOL winlogonInSession(DWORD sessionId, PHANDLE process); - DWORD getSessionId(); - HANDLE getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security); - int relaunchLoop(); - std::string getCommand(); -}; +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include +#include + +class CThread; + +class CMSWindowsRelauncher { +public: + CMSWindowsRelauncher(); + virtual ~CMSWindowsRelauncher(); + void startAsync(); + CThread* m_thread; + void startThread(void*); + BOOL winlogonInSession(DWORD sessionId, PHANDLE process); + DWORD getSessionId(); + HANDLE getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security); + int relaunchLoop(); + std::string getCommand(); +}; diff --git a/lib/platform/CSynergyHook.h b/lib/platform/CSynergyHook.h index a8f79d51..f54ef4a2 100644 --- a/lib/platform/CSynergyHook.h +++ b/lib/platform/CSynergyHook.h @@ -19,25 +19,25 @@ #ifndef CSYNERGYHOOK_H #define CSYNERGYHOOK_H -// hack: vs2005 doesn't declare _WIN32_WINNT, so we need to hard code it. -// however, some say that this should be hard coded since it defines the -// target system, but since this is suposed to compile on pre-XP, maybe -// we should just leave it like this. -#if _MSC_VER == 1400 -#define _WIN32_WINNT 0x0400 -#endif - -#include "BasicTypes.h" -#define WIN32_LEAN_AND_MEAN -#include - -// fix: cmake defines the library name in lower case (synrgyhk_EXPORTS) as -// opposed to upper case (SYNRGYHK_EXPORTS), so rather than figuring out -// how to change cmake's behaviour, it's easier to just change the code. -#if defined(synrgyhk_EXPORTS) -#define CSYNERGYHOOK_API __declspec(dllexport) -#else -#define CSYNERGYHOOK_API __declspec(dllimport) +// hack: vs2005 doesn't declare _WIN32_WINNT, so we need to hard code it. +// however, some say that this should be hard coded since it defines the +// target system, but since this is suposed to compile on pre-XP, maybe +// we should just leave it like this. +#if _MSC_VER == 1400 +#define _WIN32_WINNT 0x0400 +#endif + +#include "BasicTypes.h" +#define WIN32_LEAN_AND_MEAN +#include + +// fix: cmake defines the library name in lower case (synrgyhk_EXPORTS) as +// opposed to upper case (SYNRGYHK_EXPORTS), so rather than figuring out +// how to change cmake's behaviour, it's easier to just change the code. +#if defined(synrgyhk_EXPORTS) +#define CSYNERGYHOOK_API __declspec(dllexport) +#else +#define CSYNERGYHOOK_API __declspec(dllimport) #endif #define SYNERGY_MSG_MARK WM_APP + 0x0011 // mark id; diff --git a/lib/synergy/CApp.h b/lib/synergy/CApp.h index 47435e1f..eafa5e02 100644 --- a/lib/synergy/CApp.h +++ b/lib/synergy/CApp.h @@ -160,8 +160,8 @@ private: // unix daemon mode args # define HELP_SYS_ARGS \ " [--daemon|--no-daemon]" -# define HELP_SYS_INFO \ - " -f, --no-daemon run in the foreground.\n" \ +# define HELP_SYS_INFO \ + " -f, --no-daemon run in the foreground.\n" \ "* --daemon run as a daemon.\n" #elif SYSAPI_WIN32 diff --git a/lib/synergy/INode.h b/lib/synergy/INode.h index ebd066df..bcc9acf5 100644 --- a/lib/synergy/INode.h +++ b/lib/synergy/INode.h @@ -1,23 +1,23 @@ -/* - * synergy-plus -- mouse and keyboard sharing utility - * Copyright (C) 2009 The Synergy+ Project - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "IInterface.h" - -class INode : IInterface { - -}; +/* + * synergy-plus -- mouse and keyboard sharing utility + * Copyright (C) 2009 The Synergy+ Project + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "IInterface.h" + +class INode : IInterface { + +};