diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index fa15485af..b1f62c9bf 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,7 @@ ### Operating Systems ### -Client: Applesoft Windy OS 10 - Server: microOS Tiara +Client: Applesoft Windy OS 10 **READ ME, DELETE ME**: On Windows, hold the Windows key and press 'r', type 'winver' and hit return to get your OS version. On Mac, hit the Apple menu (top left of the screen) and check 'About this Mac'. Linux users... you know what you're using ;) @@ -28,4 +27,6 @@ Server: microOS Tiara * Is there a way to work around it? No/Yes, you can... * Does this bug prevent you from using Synergy entirely? Yes/No +Please follow the link below to send us logs from both your server and client sides if it's appropriate. https://github.com/symless/synergy/wiki/Sending-logs + Put anything else you can think of here. diff --git a/.gitignore b/.gitignore index fae40b009..347b91b17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ config.h +.DS_Store *.pyc +*.o *~ \.*.swp +*build-gui-Desktop_Qt* /bin /lib /build diff --git a/CMakeLists.txt b/CMakeLists.txt index 963d84e36..94c474e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ # Version number for Synergy set(VERSION_MAJOR 1) set(VERSION_MINOR 8) -set(VERSION_REV 3) +set(VERSION_REV 8) set(VERSION_STAGE stable) set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV}") @@ -74,11 +74,6 @@ endif() # Depending on the platform, pass in the required defines. if (UNIX) - - # warnings as errors: - # we have a problem with people checking in code with warnings. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-unused-local-typedef") - if (NOT APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() @@ -205,7 +200,10 @@ if (UNIX) set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include") set(XKBlib "X11/Xlib.h;X11/XKBlib.h") - check_symbol_exists("XRRNotifyEvent" "${XKBlib};X11/extensions/Xrandr.h" HAVE_X11_EXTENSIONS_XRANDR_H) + set(CMAKE_EXTRA_INCLUDE_FILES "${XKBlib};X11/extensions/Xrandr.h") + check_type_size("XRRNotifyEvent" X11_EXTENSIONS_XRANDR_H) + set(HAVE_X11_EXTENSIONS_XRANDR_H "${X11_EXTENSIONS_XRANDR_H}") + set(CMAKE_EXTRA_INCLUDE_FILES) check_include_files("${XKBlib};X11/extensions/dpms.h" HAVE_X11_EXTENSIONS_DPMS_H) check_include_files("X11/extensions/Xinerama.h" HAVE_X11_EXTENSIONS_XINERAMA_H) diff --git a/ChangeLog b/ChangeLog index 270668f52..dbb3b088c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +v1.8.8 +========== +Bug #5196 - Some keys on Korean and Japanese keyboards have the same keycode +Bug #5578 - Pressing Hangul key results in alt+'a' +Bug #5785 - Can't switch screens when cursor is in a corner +Bug #3992 - macOS: Dragging is broken in Unity 3D +Bug #5075 - macOS: Build fails on macOS 10.9 due to unknown compiler flag +Bug #5809 - macOS: No version number is shown in the App Info dialog +Bug #3197 - Linux: switchDoubleTap option is not working +Bug #4477 - Linux: Mouse buttons higher than id 10 result in crash +Bug #5832 - Linux: Screen size misdetected on multi-monitor display +Enhancement #4504 - Improved Korean language description +Enhancement #5525 - Added support for precise screen positioning in config file +Enhancement #4290 - Windows: Removed annoying alt+print screen functionality + +v1.8.7-stable +============= +Bug #5784 - Edition changes when reopening GUI + +v1.8.6-stable +============= +Bug #5592 - Some keys don't work for macOS Sierra clients +Bug #5186 - Cursor stuck on client when using multi-DPI server +Bug #5722 - Malformed serial key in registry will crash GUI on startup +Bug #5752 - Tab order is incorrect on Settings dialog +Enhancement #5699 - Unified installers on macOS +Feature #4836 - macOS Sierra build + +v1.8.5-stable +============= +Bug #5680 - Server crashes when disconnecting SSL clients +Bug #5626 - Build fails using Xcode 8 and macOS SDK 10.12 +Feature #5657 - Trial version support +Feature #5707 - User upgrade statistics + +v1.8.4-stable +============= +Bug #5183 - Slowly moving the cursor has no effect on high DPI clients +Bug #4041 - UHD/4K DPI scaling broken on Windows servers +Bug #4420 - When XRandR adds a screen, it is inaccessible +Bug #5603 - Activation notification depends on existence of /etc/os-release +Bug #5624 - Update notification sometimes requests a downgrade +Bug #5329 - Current date is shown for build date in the about dialog +Enhancement #5617 - Remove redundant plugin infrastructure +Enhancement #5627 - Move SSL certificate generation to main window +Enhancement #5628 - Move SSL implementation into core binary +Enhancement #5629 - Move activation from wizard into new dialog window + v1.8.3-stable ============= Bug #2765 - A letter appears on macOS clients when the spacebar is pressed diff --git a/doc/MacReadme.txt b/doc/MacReadme.txt index 49e6d93a2..dfa33fa92 100755 --- a/doc/MacReadme.txt +++ b/doc/MacReadme.txt @@ -5,10 +5,10 @@ To install on Mac OS X with the .zip distribution (first seen in 1.3.6) you must 1. Extract the zip file to any location (usually double click will do this) 2. Open Terminal, and cd to the extracted directory (e.g. /Users/my-name/Downloads/extracted-dir/) - 3. Change to super user (use the su command) - 4. Copy the binaries to /usr/bin using: cp synergy* /usr/bin + 3. Copy the binaries to /usr/bin using: sudo cp synergy* /usr/bin + 4. Correct the permissions and ownership: sudo chown root:wheel /usr/bin/synergy*; sudo chmod 555 /usr/bin/synergy* -How to enable the root user in Mac OS X: +Alternatively, you can copy the binaries as root. How to enable the root user in Mac OS X: http://support.apple.com/en-us/ht1528 Once the binaries have been copied to /usr/bin, you should follow the configuration guide: diff --git a/ext/toolchain/commands1.py b/ext/toolchain/commands1.py index 79cfc6f1b..f32ec4835 100644 --- a/ext/toolchain/commands1.py +++ b/ext/toolchain/commands1.py @@ -41,7 +41,7 @@ class Toolchain: cmd_opt_dict = { 'about' : ['', []], 'setup' : ['g:', ['generator=']], - 'configure' : ['g:dr', ['generator=', 'debug', 'release', 'mac-sdk=', 'mac-identity=']], + 'configure' : ['g:dr', ['generator=', 'debug', 'release', 'mac-sdk=', 'mac-deploy=', 'mac-identity=']], 'build' : ['dr', ['debug', 'release']], 'clean' : ['dr', ['debug', 'release']], 'update' : ['', []], @@ -244,6 +244,9 @@ class InternalCommands: # by default, unknown macSdk = None + # by default, unknown + macDeploy = None + # by default, unknown macIdentity = None @@ -306,7 +309,7 @@ def usage(self): ' genlist Shows the list of available platform generators\n' ' usage Shows the help screen\n' '\n' - 'Example: %s build -g 3' + 'Example: %s conf -g 3' ) % (app, app) def configureAll(self, targets, extraArgs=''): @@ -365,7 +368,7 @@ def configure(self, target='', extraArgs=''): # ensure latest setup and do not ask config for generator (only fall # back to prompt if not specified as arg) self.ensure_setup_latest() - + if sys.platform == "darwin": config = self.getConfig() @@ -374,6 +377,11 @@ def configure(self, target='', extraArgs=''): elif config.has_option("hm", "macSdk"): self.macSdk = config.get('hm', 'macSdk') + if self.macDeploy: + config.set('hm', 'macDeploy', self.macDeploy) + elif config.has_option("hm", "macDeploy"): + self.macSdk = config.get('hm', 'macDeploy') + if self.macIdentity: config.set('hm', 'macIdentity', self.macIdentity) elif config.has_option("hm", "macIdentity"): @@ -383,7 +391,10 @@ def configure(self, target='', extraArgs=''): if not self.macSdk: raise Exception("Arg missing: --mac-sdk "); - + + if not self.macDeploy: + self.macDeploy = self.macSdk + if not self.macIdentity: raise Exception("Arg missing: --mac-identity "); @@ -430,14 +441,16 @@ def configureCore(self, target="", extraArgs=""): if generator.cmakeName.find('Unix Makefiles') != -1: cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize() - elif sys.platform == "darwin": + if sys.platform == "darwin": macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk) if not macSdkMatch: raise Exception("unknown osx version: " + self.macSdk) - sdkDir = self.getMacSdkDir() - cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir - cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macSdk + if generator.cmakeName.find('Unix Makefiles') == -1: + sdkDir = self.getMacSdkDir() + cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir + cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macDeploy + cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1) cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2) @@ -496,8 +509,8 @@ def configureGui(self, target="", extraArgs=""): sdkDir = self.getMacSdkDir() shortForm = "macosx" + self.macSdk version = str(major) + "." + str(minor) - - qmake_cmd_string += " QMAKE_MACOSX_DEPLOYMENT_TARGET=" + version + + qmake_cmd_string += " QMAKE_MACOSX_DEPLOYMENT_TARGET=" + self.macDeploy (qMajor, qMinor, qRev) = self.getQmakeVersion() if qMajor <= 4: @@ -551,6 +564,7 @@ def getMacSdkDir(self): if os.path.exists(sdkPath): return sdkPath + # return os.popen('xcodebuild -version -sdk macosx' + self.macSdk + ' Path').read().strip() return "/Developer/SDKs/" + sdkDirName + ".sdk" # http://tinyurl.com/cs2rxxb @@ -653,6 +667,9 @@ def loadConfig(self): if config.has_option("hm", "macSdk"): self.macSdk = config.get("hm", "macSdk") + + if config.has_option("hm", "macDeploy"): + self.macDeploy = config.get("hm", "macDeploy") if config.has_option("hm", "macIdentity"): self.macIdentity = config.get("hm", "macIdentity") @@ -741,16 +758,6 @@ def macPostGuiMake(self, target): shutil.copy(targetDir + "/synergys", bundleBinDir) shutil.copy(targetDir + "/syntool", bundleBinDir) - # Copy all generated plugins to the package - bundlePluginDir = bundleBinDir + "plugins" - pluginDir = targetDir + "/plugins" - print "Copying plugins dirtree: " + pluginDir - if os.path.isdir(pluginDir): - print "Copying to: " + bundlePluginDir - shutil.copytree(pluginDir, bundlePluginDir) - else: - print "pluginDir doesn't exist, skipping" - self.loadConfig() if not self.macIdentity: raise Exception("run config with --mac-identity") @@ -1151,14 +1158,12 @@ def distDeb(self): controlFile.close() targetBin = '%s/%s/usr/bin' % (debDir, package) - targetPlugin = '%s/%s/usr/lib/synergy/plugins' % (debDir, package) targetShare = '%s/%s/usr/share' % (debDir, package) targetApplications = "%s/applications" % targetShare targetIcons = "%s/icons" % targetShare targetDocs = "%s/doc/%s" % (targetShare, self.project) os.makedirs(targetBin) - os.makedirs(targetPlugin) os.makedirs(targetApplications) os.makedirs(targetIcons) os.makedirs(targetDocs) @@ -1176,17 +1181,6 @@ def distDeb(self): if err != 0: raise Exception('strip failed: ' + str(err)) - pluginDir = "%s/plugins" % binDir - - pluginFiles = [ 'libns.so'] - for f in pluginFiles: - shutil.copy("%s/%s" % (pluginDir, f), targetPlugin) - target = "%s/%s" % (targetPlugin, f) - os.chmod(target, 0o0644) - err = os.system("strip " + target) - if err != 0: - raise Exception('strip failed: ' + str(err)) - shutil.copy("%s/synergy.desktop" % resDir, targetApplications) shutil.copy("%s/synergy.ico" % resDir, targetIcons) @@ -1402,13 +1396,6 @@ def distftp(self, type, ftp): packageTarget = filename ftp.upload(packageSource, packageTarget) - if type != 'src': - pluginsDir = binDir + '/plugins' - nsPluginSource = self.findLibraryFile(type, pluginsDir, 'ns') - if nsPluginSource: - nsPluginTarget = self.getLibraryDistFilename(type, pluginsDir, 'ns') - ftp.upload(nsPluginSource, nsPluginTarget, "plugins") - def getLibraryDistFilename(self, type, dir, name): (platform, packageExt, libraryExt) = self.getDistributePlatformInfo(type) firstPart = '%s-%s-%s' % (name, self.getVersionForFilename(), platform) @@ -1870,7 +1857,10 @@ def getMacPackageName(self): # version is major and minor with no dots (e.g. 106) version = str(major) + str(minor) - return "MacOSX%s-%s" % (version, arch) + if (self.macDeploy == self.macSdk): + return "MacOSX%s-%s" % (version, arch) + else: + return "MacOSX-%s" % arch def reset(self): if os.path.exists('build'): @@ -1925,6 +1915,8 @@ def __init__(self, argv, opts, args, verbose): self.qtDir = a elif o == '--mac-sdk': self.ic.macSdk = a + elif o == '--mac-deploy': + self.ic.macDeploy = a elif o == '--mac-identity': self.ic.macIdentity = a diff --git a/res/banner.bmp b/res/banner.bmp index f5838d857..418746c86 100644 Binary files a/res/banner.bmp and b/res/banner.bmp differ diff --git a/res/dialog.bmp b/res/dialog.bmp index 4899e5833..683f4fe5e 100644 Binary files a/res/dialog.bmp and b/res/dialog.bmp differ diff --git a/res/synergy.spec.in b/res/synergy.spec.in index 16b695e3e..3f0c88f93 100644 --- a/res/synergy.spec.in +++ b/res/synergy.spec.in @@ -20,7 +20,6 @@ source=%{_topdir}/../.. mkdir -p %{buildroot}/%{_datarootdir}/applications mkdir -p %{buildroot}/%{_datarootdir}/icons mkdir -p %{buildroot}/%{_bindir} -mkdir -p %{buildroot}/%{_bindir}/../lib/synergy/plugins cp $source/bin/synergy %{buildroot}%{_bindir} cp $source/bin/synergyc %{buildroot}%{_bindir} @@ -29,7 +28,6 @@ cp $source/bin/synergyd %{buildroot}%{_bindir} cp $source/bin/syntool %{buildroot}%{_bindir} cp $source/res/synergy.desktop %{buildroot}%{_datarootdir}/applications cp $source/res/synergy.ico %{buildroot}%{_datarootdir}/icons -cp $source/bin/plugins/* %{buildroot}%{_bindir}/../lib/synergy/plugins %files %defattr(755,root,root,-) @@ -40,7 +38,6 @@ cp $source/bin/plugins/* %{buildroot}%{_bindir}/../lib/synergy/plugins %{_bindir}/syntool %attr(644,-,-) %{_datarootdir}/applications/synergy.desktop %attr(644,-,-) %{_datarootdir}/icons/synergy.ico -%attr(644,-,-) %{_bindir}/../lib/synergy/plugins/* %changelog * Thu Mar 20 2014 Nick Bolton diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d75c0adcc..237ba4843 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,38 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +if (WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(OPENSSL_PLAT_DIR openssl-win64) + else() + set(OPENSSL_PLAT_DIR openssl-win32) + endif() + set(OPENSSL_INCLUDE ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/inc32) +endif() + +if (APPLE) + set(OPENSSL_PLAT_DIR openssl-osx) + set(OPENSSL_INCLUDE ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/include) +endif() + +if (WIN32) + set(OPENSSL_LIBS + ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/out32dll/libeay32.lib + ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/out32dll/ssleay32.lib + ) +endif() + +if (UNIX) + if (APPLE) + set(OPENSSL_LIBS + ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/libssl.a + ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/libcrypto.a + ) + else() + set(OPENSSL_LIBS ssl crypto) + endif() +endif() + add_subdirectory(lib) add_subdirectory(cmd) add_subdirectory(micro) diff --git a/src/cmd/synergyc/CMakeLists.txt b/src/cmd/synergyc/CMakeLists.txt index 11d428d44..22bbe2573 100644 --- a/src/cmd/synergyc/CMakeLists.txt +++ b/src/cmd/synergyc/CMakeLists.txt @@ -58,7 +58,7 @@ endif() add_executable(synergyc ${sources}) target_link_libraries(synergyc - arch base client common io mt net ipc platform server synergy ${libs}) + arch base client common io mt net ipc platform server synergy ${libs} ${OPENSSL_LIBS}) if (CONF_CPACK) install(TARGETS diff --git a/src/cmd/synergyc/MSWindowsClientTaskBarReceiver.cpp b/src/cmd/synergyc/MSWindowsClientTaskBarReceiver.cpp index 039246cc0..fc3ed94ee 100644 --- a/src/cmd/synergyc/MSWindowsClientTaskBarReceiver.cpp +++ b/src/cmd/synergyc/MSWindowsClientTaskBarReceiver.cpp @@ -221,7 +221,7 @@ MSWindowsClientTaskBarReceiver::primaryAction() const IArchTaskBarReceiver::Icon MSWindowsClientTaskBarReceiver::getIcon() const { - return reinterpret_cast(m_icon[getStatus()]); + return static_cast(m_icon[getStatus()]); } void @@ -263,7 +263,7 @@ MSWindowsClientTaskBarReceiver::loadIcon(UINT id) IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); - return reinterpret_cast(icon); + return static_cast(icon); } void @@ -288,7 +288,7 @@ MSWindowsClientTaskBarReceiver::createWindow() NULL, (DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc, reinterpret_cast( - reinterpret_cast(this))); + static_cast(this))); // window should appear on top of everything, including (especially) // the task bar. @@ -337,7 +337,7 @@ MSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd, // and put it in the extra window data then forward the call. MSWindowsClientTaskBarReceiver* self = NULL; if (msg == WM_INITDIALOG) { - self = reinterpret_cast( + self = static_cast( reinterpret_cast(lParam)); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) lParam); } diff --git a/src/cmd/synergyd/CMakeLists.txt b/src/cmd/synergyd/CMakeLists.txt index 1caa35b52..a63bee676 100644 --- a/src/cmd/synergyd/CMakeLists.txt +++ b/src/cmd/synergyd/CMakeLists.txt @@ -1,11 +1,11 @@ # synergy -- mouse and keyboard sharing utility # Copyright (C) 2012-2016 Symless Ltd. # Copyright (C) 2012 Nick Bolton -# +# # 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 LICENSE 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 @@ -35,7 +35,7 @@ else() endif() target_link_libraries(synergyd - arch base common io ipc mt net platform synergy ${libs}) + arch base common io ipc mt net platform synergy shared ${libs} ${OPENSSL_LIBS}) if (CONF_CPACK) install(TARGETS diff --git a/src/cmd/synergyp/CMakeLists.txt b/src/cmd/synergyp/CMakeLists.txt index 171ef9990..c99892528 100644 --- a/src/cmd/synergyp/CMakeLists.txt +++ b/src/cmd/synergyp/CMakeLists.txt @@ -63,7 +63,7 @@ else() endif() target_link_libraries(synergyp - arch base client common io mt net ipc platform server synergy client ${libs}) + arch base client common io mt net ipc platform server synergy client ${libs} ${OPENSSL_LIBS}) if (CONF_CPACK) install(TARGETS diff --git a/src/cmd/synergyp/MSWindowsPortableTaskBarReceiver.cpp b/src/cmd/synergyp/MSWindowsPortableTaskBarReceiver.cpp index 4f35fe4f2..ae7b0ee49 100644 --- a/src/cmd/synergyp/MSWindowsPortableTaskBarReceiver.cpp +++ b/src/cmd/synergyp/MSWindowsPortableTaskBarReceiver.cpp @@ -238,7 +238,7 @@ MSWindowsPortableTaskBarReceiver::primaryAction() const IArchTaskBarReceiver::Icon MSWindowsPortableTaskBarReceiver::getIcon() const { - return reinterpret_cast(m_icon[getStatus()]); + return static_cast(m_icon[getStatus()]); } void @@ -280,7 +280,7 @@ MSWindowsPortableTaskBarReceiver::loadIcon(UINT id) IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); - return reinterpret_cast(icon); + return static_cast(icon); } void @@ -305,7 +305,7 @@ MSWindowsPortableTaskBarReceiver::createWindow() NULL, (DLGPROC)&MSWindowsPortableTaskBarReceiver::staticDlgProc, reinterpret_cast( - reinterpret_cast(this))); + static_cast(this))); // window should appear on top of everything, including (especially) // the task bar. @@ -354,15 +354,15 @@ MSWindowsPortableTaskBarReceiver::staticDlgProc(HWND hwnd, // and put it in the extra window data then forward the call. MSWindowsPortableTaskBarReceiver* self = NULL; if (msg == WM_INITDIALOG) { - self = reinterpret_cast( + self = static_cast( reinterpret_cast(lParam)); SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); } else { // get the extra window data and forward the call - LONG data = (LONG)GetWindowLongPtr(hwnd, GWLP_USERDATA); + LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA); if (data != 0) { - self = reinterpret_cast( + self = static_cast( reinterpret_cast(data)); } } diff --git a/src/cmd/synergys/CMakeLists.txt b/src/cmd/synergys/CMakeLists.txt index c749e09a8..2474bcc67 100644 --- a/src/cmd/synergys/CMakeLists.txt +++ b/src/cmd/synergys/CMakeLists.txt @@ -58,7 +58,7 @@ endif() add_executable(synergys ${sources}) target_link_libraries(synergys - arch base client common io mt net ipc platform server synergy ${libs}) + arch base client common io mt net ipc platform server synergy ${libs} ${OPENSSL_LIBS}) if (CONF_CPACK) install(TARGETS diff --git a/src/cmd/synergys/MSWindowsServerTaskBarReceiver.cpp b/src/cmd/synergys/MSWindowsServerTaskBarReceiver.cpp index f65e2a352..b2d304a15 100644 --- a/src/cmd/synergys/MSWindowsServerTaskBarReceiver.cpp +++ b/src/cmd/synergys/MSWindowsServerTaskBarReceiver.cpp @@ -252,7 +252,7 @@ MSWindowsServerTaskBarReceiver::primaryAction() const IArchTaskBarReceiver::Icon MSWindowsServerTaskBarReceiver::getIcon() const { - return reinterpret_cast(m_icon[getStatus()]); + return static_cast(m_icon[getStatus()]); } void @@ -294,7 +294,7 @@ MSWindowsServerTaskBarReceiver::loadIcon(UINT id) IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); - return reinterpret_cast(icon); + return static_cast(icon); } void @@ -319,7 +319,7 @@ MSWindowsServerTaskBarReceiver::createWindow() NULL, (DLGPROC)&MSWindowsServerTaskBarReceiver::staticDlgProc, reinterpret_cast( - reinterpret_cast(this))); + static_cast(this))); // window should appear on top of everything, including (especially) // the task bar. @@ -368,15 +368,15 @@ MSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd, // and put it in the extra window data then forward the call. MSWindowsServerTaskBarReceiver* self = NULL; if (msg == WM_INITDIALOG) { - self = reinterpret_cast( + self = static_cast( reinterpret_cast(lParam)); SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); } else { // get the extra window data and forward the call - LONG data = (LONG)GetWindowLongPtr(hwnd, GWLP_USERDATA); + LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA); if (data != 0) { - self = reinterpret_cast( + self = static_cast( reinterpret_cast(data)); } } diff --git a/src/cmd/syntool/CMakeLists.txt b/src/cmd/syntool/CMakeLists.txt index 7f10c010b..ffbb61aa0 100644 --- a/src/cmd/syntool/CMakeLists.txt +++ b/src/cmd/syntool/CMakeLists.txt @@ -29,7 +29,7 @@ endif() add_executable(syntool ${sources}) target_link_libraries(syntool - synergy arch base client common io ipc mt net platform server ${libs}) + synergy arch base client common io ipc mt net platform server ${libs} ${OPENSSL_LIBS}) if (CONF_CPACK) install(TARGETS diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 408d44dda..b60c280d7 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -7,7 +7,8 @@ DEFINES += VERSION_REVISION=\\\"$$QMAKE_VERSION_REVISION\\\" DEPENDPATH += . \ res INCLUDEPATH += . \ - src + src \ + ../lib/shared/ FORMS += res/MainWindowBase.ui \ res/AboutDialogBase.ui \ res/ServerConfigDialogBase.ui \ @@ -17,7 +18,9 @@ FORMS += res/MainWindowBase.ui \ res/SettingsDialogBase.ui \ res/SetupWizardBase.ui \ res/AddClientDialogBase.ui \ - res/PluginWizardPageBase.ui + res/ActivationDialog.ui \ + res/CancelActivationDialog.ui \ + res/FailedLoginDialog.ui SOURCES += src/main.cpp \ src/MainWindow.cpp \ src/AboutDialog.cpp \ @@ -54,16 +57,16 @@ SOURCES += src/main.cpp \ src/DataDownloader.cpp \ src/AddClientDialog.cpp \ src/CommandProcess.cpp \ - src/PluginWizardPage.cpp \ - src/PluginManager.cpp \ src/CoreInterface.cpp \ src/Fingerprint.cpp \ src/SslCertificate.cpp \ - src/Plugin.cpp \ src/WebClient.cpp \ - ../lib/common/PluginVersion.cpp \ - src/SubscriptionManager.cpp \ - src/ActivationNotifier.cpp + src/ActivationNotifier.cpp \ + src/ActivationDialog.cpp \ + src/CancelActivationDialog.cpp \ + src/FailedLoginDialog.cpp \ + ../lib/shared/SerialKey.cpp \ + src/LicenseManager.cpp HEADERS += src/MainWindow.h \ src/AboutDialog.h \ src/ServerConfig.h \ @@ -100,19 +103,19 @@ HEADERS += src/MainWindow.h \ src/DataDownloader.h \ src/AddClientDialog.h \ src/CommandProcess.h \ - src/EditionType.h \ - src/PluginWizardPage.h \ src/ProcessorArch.h \ - src/PluginManager.h \ src/CoreInterface.h \ src/Fingerprint.h \ src/SslCertificate.h \ - src/Plugin.h \ src/WebClient.h \ - ../lib/common/PluginVersion.h \ - src/SubscriptionManager.h \ src/ActivationNotifier.h \ - src/ElevateMode.h + src/ElevateMode.h \ + src/ActivationDialog.h \ + src/CancelActivationDialog.h \ + src/FailedLoginDialog.h \ + ../lib/shared/EditionType.h \ + ../lib/shared/SerialKey.h \ + src/LicenseManager.h RESOURCES += res/Synergy.qrc RC_FILE = res/win/Synergy.rc macx { diff --git a/src/gui/res/ActivationDialog.ui b/src/gui/res/ActivationDialog.ui new file mode 100644 index 000000000..86fea30d0 --- /dev/null +++ b/src/gui/res/ActivationDialog.ui @@ -0,0 +1,163 @@ + + + ActivationDialog + + + + 0 + 0 + 410 + 211 + + + + Activate Synergy + + + + + + + 75 + true + + + + Serial key + + + + + + + <html><head/><body><p>This can be found on your <a href="https://symless.com/account/?source=gui"><span style=" text-decoration: underline; color:#0000ff;">account</span></a> page.</p></body></html> + + + true + + + + + + + true + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + false + + + + + + + + 2 + + + 0 + + + 0 + + + 8 + + + + + + + + :/res/icons/16x16/money.png + + + + + + + <html><head/><body><p>Your trial has expired. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html> + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + m_pTextEditSerialKey + + + + + + + buttonBox + accepted() + ActivationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ActivationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/gui/res/CancelActivationDialog.ui b/src/gui/res/CancelActivationDialog.ui new file mode 100644 index 000000000..054b3fe6f --- /dev/null +++ b/src/gui/res/CancelActivationDialog.ui @@ -0,0 +1,89 @@ + + + CancelActivationDialog + + + + 0 + 0 + 400 + 165 + + + + Cancel Activation + + + + + + Are you sure? + +If you don't activate Synergy you'll be missing out on some great features. + + + true + + + true + + + + + + + <html><head/><body><p><a href="https://symless.com/pricing?source=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now</span></a></p></body></html> + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + + + buttonBox + accepted() + CancelActivationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CancelActivationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/gui/res/FailedLoginDialog.ui b/src/gui/res/FailedLoginDialog.ui new file mode 100644 index 000000000..d3c6b5077 --- /dev/null +++ b/src/gui/res/FailedLoginDialog.ui @@ -0,0 +1,108 @@ + + + FailedLoginDialog + + + + 0 + 0 + 400 + 165 + + + + Activation Error + + + + + 50 + 120 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + 10 + 90 + 382 + 30 + + + + <html><head/><body><p><a href="https://symless.com/account/reset/?source=gui"><span style=" text-decoration: underline; color:#0000ff;">Forgotten your password?</span></a></p></body></html> + + + true + + + + + + 10 + 10 + 382 + 72 + + + + An error occurred while trying to activate Synergy. The Symless server returned the following error: + +%1 + + + true + + + true + + + label_2 + messageLabel + buttonBox + + + + + buttonBox + accepted() + FailedLoginDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FailedLoginDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/gui/res/MainWindowBase.ui b/src/gui/res/MainWindowBase.ui index 0a47e0d35..b3fb0a75b 100644 --- a/src/gui/res/MainWindowBase.ui +++ b/src/gui/res/MainWindowBase.ui @@ -1,4 +1,4 @@ - + MainWindowBase @@ -27,6 +27,57 @@ + + + + + 2 + + + 0 + + + 0 + + + 8 + + + + + + + + :/res/icons/16x16/warning.png + + + + + + + <html><head/><body><p><span style=" font-weight:600;">%1</span> days of your Synergy Pro trial remain. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html> + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -40,7 +91,7 @@ 0 - 7 + 8 @@ -128,7 +179,7 @@ - Fingerprint: + SSL Fingerprint: @@ -481,12 +532,12 @@ - + - Run Wizard + Activate - - + + Activate diff --git a/src/gui/res/PluginWizardPageBase.ui b/src/gui/res/PluginWizardPageBase.ui deleted file mode 100644 index dfb7a9782..000000000 --- a/src/gui/res/PluginWizardPageBase.ui +++ /dev/null @@ -1,137 +0,0 @@ - - - PluginWizardPage - - - - 0 - 0 - 400 - 300 - - - - Setup Synergy - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Please wait... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/src/gui/res/ServerConfigDialogBase.ui b/src/gui/res/ServerConfigDialogBase.ui index 1cc4d2b53..5478f3601 100644 --- a/src/gui/res/ServerConfigDialogBase.ui +++ b/src/gui/res/ServerConfigDialogBase.ui @@ -17,7 +17,7 @@ - 2 + 0 diff --git a/src/gui/res/SettingsDialogBase.ui b/src/gui/res/SettingsDialogBase.ui index 1cd828016..f604cf7a2 100644 --- a/src/gui/res/SettingsDialogBase.ui +++ b/src/gui/res/SettingsDialogBase.ui @@ -176,8 +176,11 @@ + + false + - Use &SSL encryption (unique certificate) + Use &SSL encryption @@ -327,11 +330,13 @@ m_pLineEditScreenName m_pSpinBoxPort m_pLineEditInterface + m_pComboElevate + m_pCheckBoxAutoHide + m_pCheckBoxEnableCrypto m_pComboLogLevel m_pCheckBoxLogToFile m_pLineEditLogFilename m_pButtonBrowseLog - buttonBox diff --git a/src/gui/res/SetupWizardBase.ui b/src/gui/res/SetupWizardBase.ui index 6788a3d53..8c0898861 100644 --- a/src/gui/res/SetupWizardBase.ui +++ b/src/gui/res/SetupWizardBase.ui @@ -120,214 +120,6 @@ - - - Activate - - - - - - Enable your <a href="http://symless.com/pricing?source=gui">Synergy Pro</a> and Synergy Basic features. - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - 75 - true - - - - &Account login - - - true - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - 20 - - - 10 - - - - - Email: - - - - - - - - 0 - 0 - - - - - 200 - 20 - - - - QLineEdit::Normal - - - - - - - Password: - - - - - - - - 0 - 0 - - - - - 200 - 20 - - - - QLineEdit::Password - - - - - - - <a href="https://symless.com/account/reset/?source=gui">Forgot password</a> - - - true - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - 75 - true - - - - &Serial key - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - S&kip activation - - - - - - - color: rgb(100, 100, 100); - - - You will see UNREGISTERED in the window title (not recommended). - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 500 - - - - - - diff --git a/src/gui/res/lang/Languages.xml b/src/gui/res/lang/Languages.xml index 0a7f3d98a..5948f9c6f 100644 --- a/src/gui/res/lang/Languages.xml +++ b/src/gui/res/lang/Languages.xml @@ -36,11 +36,11 @@ - + - + diff --git a/src/gui/res/mac/Info.plist b/src/gui/res/mac/Info.plist index 5cd23eaf8..b2d87e095 100644 --- a/src/gui/res/mac/Info.plist +++ b/src/gui/res/mac/Info.plist @@ -1,20 +1,28 @@ - - + - - CFBundleInfoDictionaryVersion - 6.0 - NSPrincipalClass - NSApplication - CFBundleIconFile - Synergy.icns - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleExecutable - Synergy - CFBundleIdentifier - synergy - + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + Synergy + CFBundleExecutable + Synergy + CFBundleIconFile + Synergy.icns + CFBundleIdentifier + synergy + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Synergy + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.8.8 + CFBundleVersion + 1.8.8 + NSHumanReadableCopyright + © 2012-2016, Symless Ltd + diff --git a/src/gui/src/AboutDialog.cpp b/src/gui/src/AboutDialog.cpp index 6fc1d57ed..1d2f5888e 100644 --- a/src/gui/src/AboutDialog.cpp +++ b/src/gui/src/AboutDialog.cpp @@ -32,7 +32,9 @@ AboutDialog::AboutDialog(QWidget* parent, const QString& synergyApp) : version = version + '-' + VERSION_STAGE + '-' + VERSION_REVISION; m_pLabelSynergyVersion->setText(version); - m_pLabelBuildDate->setText(QDate::currentDate().toString()); + QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); + QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); + m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate)); // change default size based on os #if defined(Q_OS_MAC) diff --git a/src/gui/src/ActivationDialog.cpp b/src/gui/src/ActivationDialog.cpp new file mode 100644 index 000000000..6035dfa88 --- /dev/null +++ b/src/gui/src/ActivationDialog.cpp @@ -0,0 +1,123 @@ +#include "ActivationDialog.h" +#include "ui_ActivationDialog.h" +#include "CancelActivationDialog.h" +#include "AppConfig.h" +#include "WebClient.h" +#include "EditionType.h" +#include "ActivationNotifier.h" +#include "MainWindow.h" +#include "QUtility.h" +#include "LicenseManager.h" +#include "FailedLoginDialog.h" + +#include +#include +#include + +ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig, + LicenseManager& licenseManager) : + QDialog(parent), + ui(new Ui::ActivationDialog), + m_appConfig(&appConfig), + m_LicenseManager (&licenseManager) +{ + ui->setupUi(this); + refreshSerialKey(); + time_t currentTime = ::time(0); + if (!m_LicenseManager->serialKey().isExpired(currentTime)) { + ui->m_trialWidget->hide(); + } +} + +void ActivationDialog::refreshSerialKey() +{ + ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey()); + ui->m_pTextEditSerialKey->setFocus(); + ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End); + ui->m_trialLabel->setText(tr("

Your trial has " + "expired. Buy now!" + "

") + .arg (m_appConfig->serialKey())); +} + +ActivationDialog::~ActivationDialog() +{ + delete ui; +} + +void ActivationDialog::reject() +{ + if (m_LicenseManager->activeEdition() == kUnregistered) { + CancelActivationDialog cancelActivationDialog(this); + if (QDialog::Accepted == cancelActivationDialog.exec()) { + m_LicenseManager->skipActivation(); + m_appConfig->activationHasRun(true); + m_appConfig->saveSettings(); + } else { + return; + } + } + QDialog::reject(); +} + +void ActivationDialog::accept() +{ + QMessageBox message; + m_appConfig->activationHasRun(true); + m_appConfig->saveSettings(); + + std::pair result; + try { + SerialKey serialKey (ui->m_pTextEditSerialKey->toPlainText(). + trimmed().toStdString()); + result = m_LicenseManager->setSerialKey(serialKey); + } + catch (std::exception& e) { + message.critical(this, "Unknown Error", + tr("An error occurred while trying to activate Synergy. " + "Please contact the helpdesk, and provide the " + "following information:\n\n%1").arg(e.what())); + refreshSerialKey(); + return; + } + + if (!result.first) { + message.critical(this, "Activation failed", + tr("%1").arg(result.second)); + refreshSerialKey(); + return; + } + + m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey()); + Edition edition = m_LicenseManager->activeEdition(); + time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0)); + if (edition != kUnregistered) { + QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of " + "your trial remain%4"). + arg (m_LicenseManager->getEditionName(edition)). + arg (daysLeft). + arg ((daysLeft == 1) ? "" : "s"). + arg ((daysLeft == 1) ? "s" : ""); + + if (edition == kPro) { + thanksMessage = thanksMessage.arg("If you're using SSL, " + "remember to activate all of your devices."); + } else { + thanksMessage = thanksMessage.arg(""); + } + + if (m_LicenseManager->serialKey().isTrial()) { + message.information(this, "Thanks!", thanksMessage); + } + else { + message.information(this, "Activated!", + tr("Thanks for activating %1!").arg + (m_LicenseManager->getEditionName(edition))); + } + } + + QDialog::accept(); +} diff --git a/src/gui/src/ActivationDialog.h b/src/gui/src/ActivationDialog.h new file mode 100644 index 000000000..1cc459330 --- /dev/null +++ b/src/gui/src/ActivationDialog.h @@ -0,0 +1,35 @@ +#ifndef ACTIVATIONDIALOG_H +#define ACTIVATIONDIALOG_H + +#include +#include + +namespace Ui { +class ActivationDialog; +} + +class AppConfig; + +class ActivationDialog : public QDialog +{ + Q_OBJECT + +public: + ActivationDialog(QWidget *parent, AppConfig& appConfig, + LicenseManager& licenseManager); + ~ActivationDialog(); + +public slots: + void reject(); + void accept(); + +protected: + void refreshSerialKey(); + +private: + Ui::ActivationDialog *ui; + AppConfig* m_appConfig; + LicenseManager* m_LicenseManager; +}; + +#endif // ACTIVATIONDIALOG_H diff --git a/src/gui/src/ActivationNotifier.cpp b/src/gui/src/ActivationNotifier.cpp index fb2fd465e..0786d90cb 100644 --- a/src/gui/src/ActivationNotifier.cpp +++ b/src/gui/src/ActivationNotifier.cpp @@ -20,7 +20,7 @@ #include "CoreInterface.h" ActivationNotifier::ActivationNotifier(QObject *parent) : - QObject(parent) + QObject(parent) { } @@ -29,6 +29,15 @@ void ActivationNotifier::setIdentity(QString identity) m_Identity = identity; } +void ActivationNotifier::setUpdateInfo(QString const& fromVersion, + QString const& toVersion, + QString const& serialKey) +{ + m_fromVersion = fromVersion; + m_toVersion = toVersion; + m_serialKey = serialKey; +} + void ActivationNotifier::notify() { CoreInterface coreInterface; @@ -39,3 +48,13 @@ void ActivationNotifier::notify() // catch all exceptions and fails silently } } + +void ActivationNotifier::notifyUpdate() +{ + try { + CoreInterface coreInterface; + coreInterface.notifyUpdate(m_fromVersion, m_toVersion, + m_serialKey); + } catch (...) { + } +} diff --git a/src/gui/src/ActivationNotifier.h b/src/gui/src/ActivationNotifier.h index d245cd278..2ac216c7f 100644 --- a/src/gui/src/ActivationNotifier.h +++ b/src/gui/src/ActivationNotifier.h @@ -24,18 +24,24 @@ class ActivationNotifier : public QObject { Q_OBJECT public: - explicit ActivationNotifier(QObject *parent = 0); + explicit ActivationNotifier(QObject *parent = 0); void setIdentity(QString identity); + void setUpdateInfo(QString const& fromVersion, + QString const& toVersion, QString const& serialKey); public slots: void notify(); + void notifyUpdate(); signals: void finished(); private: QString m_Identity; + QString m_fromVersion; + QString m_toVersion; + QString m_serialKey; }; #endif // ACTIVATIONNOTIFIER_H diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index a48bbc04c..e6d15e63d 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -2,11 +2,11 @@ * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * 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 LICENSE 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 @@ -73,6 +73,18 @@ AppConfig::~AppConfig() saveSettings(); } +const QString &AppConfig::screenName() const { return m_ScreenName; } + +int AppConfig::port() const { return m_Port; } + +const QString &AppConfig::interface() const { return m_Interface; } + +int AppConfig::logLevel() const { return m_LogLevel; } + +bool AppConfig::logToFile() const { return m_LogToFile; } + +const QString &AppConfig::logFilename() const { return m_LogFilename; } + QString AppConfig::synergyLogDir() const { #if defined(Q_OS_WIN) @@ -116,6 +128,16 @@ QString AppConfig::logLevelText() const return logLevelNames[logLevel()]; } +ProcessMode AppConfig::processMode() const { return m_ProcessMode; } + +bool AppConfig::wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; } + +const QString &AppConfig::language() const { return m_Language; } + +bool AppConfig::startedBefore() const { return m_StartedBefore; } + +bool AppConfig::autoConfig() const { return m_AutoConfig; } + void AppConfig::loadSettings() { m_ScreenName = settings().value("screenName", QHostInfo::localHostName()).toString(); @@ -131,16 +153,18 @@ void AppConfig::loadSettings() QVariant elevateMode = settings().value("elevateModeEnum"); if (!elevateMode.isValid()) { elevateMode = settings().value ("elevateMode", - QVariant(static_cast(defaultElevateMode))); + QVariant(static_cast(defaultElevateMode))); } m_ElevateMode = static_cast(elevateMode.toInt()); m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); - m_Edition = settings().value("edition", Unknown).toInt(); + m_Edition = static_cast(settings().value("edition", kUnregistered).toInt()); m_ActivateEmail = settings().value("activateEmail", "").toString(); - m_CryptoEnabled = settings().value("cryptoEnabled", false).toBool(); + m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool(); m_AutoHide = settings().value("autoHide", false).toBool(); - m_Serialkey = settings().value("serialKey", "").toString(); + m_Serialkey = settings().value("serialKey", "").toString().trimmed(); + m_lastVersion = settings().value("lastVersion", "Unknown").toString(); m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt(); + m_ActivationHasRun = settings().value("activationHasRun", false).toBool(); } void AppConfig::saveSettings() @@ -155,30 +179,116 @@ void AppConfig::saveSettings() settings().setValue("language", m_Language); settings().setValue("startedBefore", m_StartedBefore); settings().setValue("autoConfig", m_AutoConfig); - // Refer to enum ElevateMode declaration for insight in to why this - // flag is mapped this way + // Refer to enum ElevateMode declaration for insight in to why this + // flag is mapped this way settings().setValue("elevateMode", m_ElevateMode == ElevateAlways); settings().setValue("elevateModeEnum", static_cast(m_ElevateMode)); settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("edition", m_Edition); - settings().setValue("activateEmail", m_ActivateEmail); settings().setValue("cryptoEnabled", m_CryptoEnabled); settings().setValue("autoHide", m_AutoHide); settings().setValue("serialKey", m_Serialkey); + settings().setValue("lastVersion", m_lastVersion); settings().setValue("lastExpiringWarningTime", m_LastExpiringWarningTime); + settings().setValue("activationHasRun", m_ActivationHasRun); + settings().sync(); +} + +bool AppConfig::activationHasRun() const +{ + return m_ActivationHasRun; +} + +AppConfig& AppConfig::activationHasRun(bool value) +{ + m_ActivationHasRun = value; + return *this; +} + +QString AppConfig::lastVersion() const +{ + return m_lastVersion; +} + +void AppConfig::setLastVersion(QString version) { + m_lastVersion = version; } +QSettings &AppConfig::settings() { return *m_pSettings; } + +void AppConfig::setScreenName(const QString &s) { m_ScreenName = s; } + +void AppConfig::setPort(int i) { m_Port = i; } + +void AppConfig::setInterface(const QString &s) { m_Interface = s; } + +void AppConfig::setLogLevel(int i) { m_LogLevel = i; } + +void AppConfig::setLogToFile(bool b) { m_LogToFile = b; } + +void AppConfig::setLogFilename(const QString &s) { m_LogFilename = s; } + +void AppConfig::setWizardHasRun() { m_WizardLastRun = kWizardVersion; } + +void AppConfig::setLanguage(const QString language) { m_Language = language; } + +void AppConfig::setStartedBefore(bool b) { m_StartedBefore = b; } + +void AppConfig::setElevateMode(ElevateMode em) { m_ElevateMode = em; } + void AppConfig::setAutoConfig(bool autoConfig) { m_AutoConfig = autoConfig; } +bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; } + void AppConfig::setAutoConfigPrompted(bool prompted) { m_AutoConfigPrompted = prompted; } +void AppConfig::setEdition(Edition e) { + m_Edition = e; +} + +Edition AppConfig::edition() const { return m_Edition; } + +QString AppConfig::setSerialKey(QString serial) { + using std::swap; + swap (serial, m_Serialkey); + return serial; +} + +void AppConfig::clearSerialKey() +{ + m_Serialkey.clear(); +} + +QString AppConfig::serialKey() { return m_Serialkey; } + +int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; } + +void AppConfig::setLastExpiringWarningTime(int t) { m_LastExpiringWarningTime = t; } + +QString AppConfig::synergysName() const { return m_SynergysName; } + +QString AppConfig::synergycName() const { return m_SynergycName; } + ElevateMode AppConfig::elevateMode() { return m_ElevateMode; } + +void AppConfig::setCryptoEnabled(bool e) { + m_CryptoEnabled = e; + emit sslToggled(e); +} + +bool AppConfig::getCryptoEnabled() const { + return (edition() == kPro) && m_CryptoEnabled; +} + +void AppConfig::setAutoHide(bool b) { m_AutoHide = b; } + +bool AppConfig::getAutoHide() { return m_AutoHide; } diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 43e35c7fc..4dcd4572b 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -2,11 +2,11 @@ * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * 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 LICENSE 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 @@ -20,8 +20,10 @@ #define APPCONFIG_H +#include #include #include "ElevateMode.h" +#include // this should be incremented each time a new page is added. this is // saved to settings when the user finishes running the wizard. if @@ -47,8 +49,10 @@ enum ProcessMode { Desktop }; -class AppConfig +class AppConfig: public QObject { + Q_OBJECT + friend class SettingsDialog; friend class MainWindow; friend class SetupWizard; @@ -58,33 +62,32 @@ class AppConfig ~AppConfig(); public: - const QString& screenName() const { return m_ScreenName; } - int port() const { return m_Port; } - const QString& interface() const { return m_Interface; } - int logLevel() const { return m_LogLevel; } - bool logToFile() const { return m_LogToFile; } - const QString& logFilename() const { return m_LogFilename; } + const QString& screenName() const; + int port() const; + const QString& interface() const; + int logLevel() const; + bool logToFile() const; + const QString& logFilename() const; const QString logFilenameCmd() const; QString logLevelText() const; - ProcessMode processMode() const { return m_ProcessMode; } - bool wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; } - const QString& language() const { return m_Language; } - bool startedBefore() const { return m_StartedBefore; } - bool autoConfig() const { return m_AutoConfig; } + ProcessMode processMode() const; + bool wizardShouldRun() const; + const QString& language() const; + bool startedBefore() const; + bool autoConfig() const; void setAutoConfig(bool autoConfig); - bool autoConfigPrompted() { return m_AutoConfigPrompted; } + bool autoConfigPrompted(); void setAutoConfigPrompted(bool prompted); - void setEdition(int e) { m_Edition = e; } - int edition() { return m_Edition; } - void setActivateEmail(QString e) { m_ActivateEmail = e; } - QString activateEmail() { return m_ActivateEmail; } - void setSerialKey(QString serial) { m_Serialkey = serial; } - QString serialKey() { return m_Serialkey; } - int lastExpiringWarningTime() const { return m_LastExpiringWarningTime; } - void setLastExpiringWarningTime(int t) { m_LastExpiringWarningTime = t; } - - QString synergysName() const { return m_SynergysName; } - QString synergycName() const { return m_SynergycName; } + void setEdition(Edition); + Edition edition() const; + QString setSerialKey(QString serial); + void clearSerialKey(); + QString serialKey(); + int lastExpiringWarningTime() const; + void setLastExpiringWarningTime(int t); + + QString synergysName() const; + QString synergycName() const; QString synergyProgramDir() const; QString synergyLogDir() const; @@ -92,26 +95,32 @@ class AppConfig void persistLogDir(); ElevateMode elevateMode(); - void setCryptoEnabled(bool e) { m_CryptoEnabled = e; } - bool getCryptoEnabled() { return m_CryptoEnabled; } - void setAutoHide(bool b) { m_AutoHide = b; } - bool getAutoHide() { return m_AutoHide; } + void setCryptoEnabled(bool e); + bool getCryptoEnabled() const; - void saveSettings(); + void setAutoHide(bool b); + bool getAutoHide(); - protected: - QSettings& settings() { return *m_pSettings; } - void setScreenName(const QString& s) { m_ScreenName = s; } - void setPort(int i) { m_Port = i; } - void setInterface(const QString& s) { m_Interface = s; } - void setLogLevel(int i) { m_LogLevel = i; } - void setLogToFile(bool b) { m_LogToFile = b; } - void setLogFilename(const QString& s) { m_LogFilename = s; } - void setWizardHasRun() { m_WizardLastRun = kWizardVersion; } - void setLanguage(const QString language) { m_Language = language; } - void setStartedBefore(bool b) { m_StartedBefore = b; } - void setElevateMode(ElevateMode em) { m_ElevateMode = em; } + bool activationHasRun() const; + AppConfig& activationHasRun(bool value); + QString lastVersion() const; + + void saveSettings(); + void setLastVersion(QString version); + +protected: + QSettings& settings(); + void setScreenName(const QString& s); + void setPort(int i); + void setInterface(const QString& s); + void setLogLevel(int i); + void setLogToFile(bool b); + void setLogFilename(const QString& s); + void setWizardHasRun(); + void setLanguage(const QString language); + void setStartedBefore(bool b); + void setElevateMode(ElevateMode em); void loadSettings(); private: @@ -129,16 +138,21 @@ class AppConfig bool m_AutoConfig; ElevateMode m_ElevateMode; bool m_AutoConfigPrompted; - int m_Edition; + Edition m_Edition; QString m_ActivateEmail; bool m_CryptoEnabled; bool m_AutoHide; QString m_Serialkey; + QString m_lastVersion; int m_LastExpiringWarningTime; + bool m_ActivationHasRun; static const char m_SynergysName[]; static const char m_SynergycName[]; static const char m_SynergyLogDir[]; + + signals: + void sslToggled(bool enabled); }; #endif diff --git a/src/gui/src/CancelActivationDialog.cpp b/src/gui/src/CancelActivationDialog.cpp new file mode 100644 index 000000000..074b76bbd --- /dev/null +++ b/src/gui/src/CancelActivationDialog.cpp @@ -0,0 +1,14 @@ +#include "CancelActivationDialog.h" +#include "ui_CancelActivationDialog.h" + +CancelActivationDialog::CancelActivationDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CancelActivationDialog) +{ + ui->setupUi(this); +} + +CancelActivationDialog::~CancelActivationDialog() +{ + delete ui; +} diff --git a/src/gui/src/CancelActivationDialog.h b/src/gui/src/CancelActivationDialog.h new file mode 100644 index 000000000..b90af0839 --- /dev/null +++ b/src/gui/src/CancelActivationDialog.h @@ -0,0 +1,22 @@ +#ifndef CANCELACTIVATIONDIALOG_H +#define CANCELACTIVATIONDIALOG_H + +#include + +namespace Ui { +class CancelActivationDialog; +} + +class CancelActivationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CancelActivationDialog(QWidget *parent = 0); + ~CancelActivationDialog(); + +private: + Ui::CancelActivationDialog *ui; +}; + +#endif // CANCELACTIVATIONDIALOG_H diff --git a/src/gui/src/CoreInterface.cpp b/src/gui/src/CoreInterface.cpp index d537a24f7..e560fc455 100644 --- a/src/gui/src/CoreInterface.cpp +++ b/src/gui/src/CoreInterface.cpp @@ -22,18 +22,20 @@ #include #include +#include +#include #include static const char kCoreBinary[] = "syntool"; -CoreInterface::CoreInterface() -{ -} +#ifdef Q_WS_WIN +static const char kSerialKeyFilename[] = "Synergy.subkey"; +#else +static const char kSerialKeyFilename[] = ".synergy.subkey"; +#endif -QString CoreInterface::getPluginDir() +CoreInterface::CoreInterface() { - QStringList args("--get-plugin-dir"); - return run(args); } QString CoreInterface::getProfileDir() @@ -54,24 +56,19 @@ QString CoreInterface::getArch() return run(args); } -QString CoreInterface::getSubscriptionFilename() +QString CoreInterface::getSerialKeyFilePath() { - QStringList args("--get-subscription-filename"); - return run(args); + QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename; + return filename; } -QString CoreInterface::activateSerial(const QString& serial) -{ - QStringList args("--subscription-serial"); - args << serial; - - return run(args); -} - -QString CoreInterface::checkSubscription() -{ - QStringList args("--check-subscription"); - return run(args); +QString CoreInterface::notifyUpdate (QString const& fromVersion, + QString const& toVersion, + QString const& serialKey) { + QStringList args("--notify-update"); + QString input(fromVersion + ":" + toVersion + ":" + serialKey); + input.append("\n"); + return run(args, input); } QString CoreInterface::notifyActivation(const QString& identity) diff --git a/src/gui/src/CoreInterface.h b/src/gui/src/CoreInterface.h index 13e8fd873..98a84f57a 100644 --- a/src/gui/src/CoreInterface.h +++ b/src/gui/src/CoreInterface.h @@ -24,13 +24,13 @@ class CoreInterface public: CoreInterface(); - QString getPluginDir(); QString getProfileDir(); QString getInstalledDir(); QString getArch(); - QString getSubscriptionFilename(); - QString activateSerial(const QString& serial); - QString checkSubscription(); + QString getSerialKeyFilePath(); QString notifyActivation(const QString& identity); + QString notifyUpdate (QString const& fromVersion, + QString const& toVersion, + QString const& serialKey); QString run(const QStringList& args, const QString& input = ""); }; diff --git a/src/gui/src/FailedLoginDialog.cpp b/src/gui/src/FailedLoginDialog.cpp new file mode 100644 index 000000000..07ec6bdcd --- /dev/null +++ b/src/gui/src/FailedLoginDialog.cpp @@ -0,0 +1,15 @@ +#include "FailedLoginDialog.h" +#include "ui_FailedLoginDialog.h" + +FailedLoginDialog::FailedLoginDialog(QWidget *parent, QString message): + QDialog(parent), + ui(new Ui::FailedLoginDialog) +{ + ui->setupUi(this); + ui->messageLabel->setText(ui->messageLabel->text().arg(message)); +} + +FailedLoginDialog::~FailedLoginDialog() +{ + delete ui; +} diff --git a/src/gui/src/FailedLoginDialog.h b/src/gui/src/FailedLoginDialog.h new file mode 100644 index 000000000..2eb676346 --- /dev/null +++ b/src/gui/src/FailedLoginDialog.h @@ -0,0 +1,23 @@ +#ifndef FAILEDLOGINDIALOG_H +#define FAILEDLOGINDIALOG_H + +#include +#include + +namespace Ui { +class FailedLoginDialog; +} + +class FailedLoginDialog : public QDialog +{ + Q_OBJECT + +public: + explicit FailedLoginDialog(QWidget *parent = 0, QString message = ""); + ~FailedLoginDialog(); + +private: + Ui::FailedLoginDialog *ui; +}; + +#endif // FAILEDLOGINDIALOG_H diff --git a/src/gui/src/LicenseManager.cpp b/src/gui/src/LicenseManager.cpp new file mode 100644 index 000000000..6f761135e --- /dev/null +++ b/src/gui/src/LicenseManager.cpp @@ -0,0 +1,169 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Seamless Inc. + * + * 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 LICENSE 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 "LicenseManager.h" +#include "EditionType.h" +#include "AppConfig.h" +#include +#include +#include +#include + +LicenseManager::LicenseManager(AppConfig* appConfig) : + m_AppConfig(appConfig), + m_serialKey(appConfig->edition()) { +} + +std::pair +LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) +{ + std::pair ret (true, ""); + time_t currentTime = ::time(0); + + if (!acceptExpired && serialKey.isExpired(currentTime)) { + ret.first = false; + ret.second = "Serial key expired"; + return ret; + } + + if (serialKey != m_serialKey) { + using std::swap; + swap (serialKey, m_serialKey); + m_AppConfig->setSerialKey(QString::fromStdString + (m_serialKey.toString())); + emit serialKeyChanged(m_serialKey); + + if (serialKey.isTrial()) { + emit endTrial(false); + } + + if (m_serialKey.edition() != serialKey.edition()) { + m_AppConfig->setEdition(m_serialKey.edition()); + emit editionChanged(m_serialKey.edition()); + } + + if (m_serialKey.isTrial()) { + if (m_serialKey.isExpired(currentTime)) { + emit endTrial(true); + } else { + emit beginTrial(m_serialKey.isExpiring(currentTime)); + } + } + + m_AppConfig->saveSettings(); + } + + return ret; +} + +void +LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) { + if ((fromVersion == "Unknown") + && (m_serialKey == SerialKey(kUnregistered))) { + return; + } + + ActivationNotifier* notifier = new ActivationNotifier(); + notifier->setUpdateInfo (fromVersion, toVersion, + QString::fromStdString(m_serialKey.toString())); + + QThread* thread = new QThread(); + connect(notifier, SIGNAL(finished()), thread, SLOT(quit())); + connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater())); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + notifier->moveToThread(thread); + thread->start(); + + QMetaObject::invokeMethod(notifier, "notifyUpdate", + Qt::QueuedConnection); +} + +Edition +LicenseManager::activeEdition() const +{ + return m_serialKey.edition(); +} + +QString +LicenseManager::activeEditionName() const +{ + return getEditionName(activeEdition(), m_serialKey.isTrial()); +} + +SerialKey +LicenseManager::serialKey() const +{ + return m_serialKey; +} + +void LicenseManager::refresh() +{ + if (!m_AppConfig->serialKey().isEmpty()) { + try { + SerialKey serialKey (m_AppConfig->serialKey().toStdString()); + setSerialKey(serialKey, true); + } catch (...) { + m_AppConfig->clearSerialKey(); + m_AppConfig->saveSettings(); + } + } + if (m_serialKey.isExpired(::time(0))) { + emit endTrial(true); + } +} + +void LicenseManager::skipActivation() +{ + notifyActivation ("skip:unknown"); +} + +QString +LicenseManager::getEditionName(Edition const edition, bool trial) +{ + std::string name ("Synergy"); + switch (edition) { + case kUnregistered: + name += " (UNREGISTERED)"; + return QString::fromUtf8 (name.c_str(), name.size()); + case kBasic: + name += " Basic"; + break; + default: + name += " Pro"; + } + if (trial) { + name += " (Trial)"; + } + return QString::fromUtf8 (name.c_str(), name.size()); +} + +void LicenseManager::notifyActivation(QString identity) +{ + ActivationNotifier* notifier = new ActivationNotifier(); + notifier->setIdentity(identity); + + QThread* thread = new QThread(); + connect(notifier, SIGNAL(finished()), thread, SLOT(quit())); + connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater())); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + notifier->moveToThread(thread); + thread->start(); + + QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection); +} diff --git a/src/gui/src/LicenseManager.h b/src/gui/src/LicenseManager.h new file mode 100644 index 000000000..7ece4e23c --- /dev/null +++ b/src/gui/src/LicenseManager.h @@ -0,0 +1,53 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Seamless Inc. + * + * 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 LICENSE 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 +#include +#include +#include + +class AppConfig; + +class LicenseManager: public QObject +{ + Q_OBJECT + +public: + LicenseManager(AppConfig* appConfig); + std::pair setSerialKey(SerialKey serialKey, + bool acceptExpired = false); + void refresh(); + Edition activeEdition() const; + QString activeEditionName() const; + SerialKey serialKey() const; + void skipActivation(); + void notifyUpdate(QString fromVersion, QString toVersion); + static QString getEditionName(Edition edition, bool trial = false); + void notifyActivation(QString identity); + +private: + AppConfig* m_AppConfig; + SerialKey m_serialKey; + +signals: + void serialKeyChanged (SerialKey) const; + void editionChanged (Edition) const; + void beginTrial (bool expiring) const; + void endTrial (bool expired) const; +}; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 332fcbd65..e13328c0f 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -23,18 +23,18 @@ #include "MainWindow.h" #include "Fingerprint.h" -#include "PluginManager.h" #include "AboutDialog.h" #include "ServerConfigDialog.h" #include "SettingsDialog.h" -#include "SetupWizard.h" +#include "ActivationDialog.h" #include "ZeroconfService.h" #include "DataDownloader.h" #include "CommandProcess.h" -#include "SubscriptionManager.h" +#include "LicenseManager.h" #include "EditionType.h" #include "QUtility.h" #include "ProcessorArch.h" +#include "SslCertificate.h" #include #include @@ -76,12 +76,14 @@ static const char* synergyIconFiles[] = ":/res/icons/16x16/synergy-transfering.png" }; -MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) : +MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig, + LicenseManager& licenseManager) : m_Settings(settings), - m_AppConfig(appConfig), + m_AppConfig(&appConfig), + m_LicenseManager(&licenseManager), m_pSynergy(NULL), m_SynergyState(synergyDisconnected), - m_ServerConfig(&m_Settings, 5, 3, m_AppConfig.screenName(), this), + m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this), m_pTempConfigFile(NULL), m_pTrayIcon(NULL), m_pTrayIconMenu(NULL), @@ -98,7 +100,9 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) : m_SuppressAutoConfigWarning(false), m_BonjourInstall(NULL), m_SuppressEmptyServerWarning(false), - m_ExpectedRunningState(kStopped) + m_ExpectedRunningState(kStopped), + m_pSslCertificate(NULL), + m_ActivationDialogRunning(false) { setupUi(this); @@ -133,12 +137,34 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) : m_SuppressAutoConfigWarning = false; m_pComboServerList->hide(); + m_pLabelPadlock->hide(); + m_trialWidget->hide(); - setEdition(m_AppConfig.edition()); + connect (this, SIGNAL(windowShown()), + this, SLOT(on_windowShown()), Qt::QueuedConnection); - m_pLabelPadlock->hide(); + connect (m_LicenseManager, SIGNAL(editionChanged(Edition)), + this, SLOT(setEdition(Edition)), Qt::QueuedConnection); - updateLocalFingerprint(); + connect (m_LicenseManager, SIGNAL(beginTrial(bool)), + this, SLOT(beginTrial(bool)), Qt::QueuedConnection); + + connect (m_LicenseManager, SIGNAL(endTrial(bool)), + this, SLOT(endTrial(bool)), Qt::QueuedConnection); + + connect (m_AppConfig, SIGNAL(sslToggled(bool)), + this, SLOT(sslToggled(bool)), Qt::QueuedConnection); + + setWindowTitle (m_LicenseManager->activeEditionName()); + m_LicenseManager->refresh(); + + QString lastVersion = m_AppConfig->lastVersion(); + QString currentVersion = m_VersionChecker.getVersion(); + if (lastVersion != currentVersion) { + m_AppConfig->setLastVersion (currentVersion); + m_AppConfig->saveSettings(); + m_LicenseManager->notifyUpdate (lastVersion, currentVersion); + } } MainWindow::~MainWindow() @@ -159,6 +185,8 @@ MainWindow::~MainWindow() if (m_BonjourInstall != NULL) { delete m_BonjourInstall; } + + delete m_pSslCertificate; } void MainWindow::open() @@ -263,7 +291,8 @@ void MainWindow::createMenuBar() m_pMenuFile->addAction(m_pActionStartSynergy); m_pMenuFile->addAction(m_pActionStopSynergy); m_pMenuFile->addSeparator(); - m_pMenuFile->addAction(m_pActionWizard); + m_pMenuFile->addAction(m_pActivate); + m_pMenuFile->addSeparator(); m_pMenuFile->addAction(m_pActionSave); m_pMenuFile->addSeparator(); m_pMenuFile->addAction(m_pActionQuit); @@ -392,15 +421,17 @@ void MainWindow::appendLogRaw(const QString& text) foreach(QString line, text.split(QRegExp("\r|\n|\r\n"))) { if (!line.isEmpty()) { m_pLogOutput->append(line); - updateStateFromLogLine(line); + updateFromLogLine(line); } } } -void MainWindow::updateStateFromLogLine(const QString &line) +void MainWindow::updateFromLogLine(const QString &line) { + // TODO: this code makes Andrew cry checkConnected(line); checkFingerprint(line); + checkLicense(line); } void MainWindow::checkConnected(const QString& line) @@ -425,6 +456,14 @@ void MainWindow::checkConnected(const QString& line) } } +void MainWindow::checkLicense(const QString &line) +{ + if (line.contains("trial has expired")) { + licenseManager().refresh(); + raiseActivationDialog(); + } +} + void MainWindow::checkFingerprint(const QString& line) { QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)"); @@ -493,13 +532,19 @@ void MainWindow::restartSynergy() void MainWindow::proofreadInfo() { - setEdition(m_AppConfig.edition()); + setEdition(m_AppConfig->edition()); // Why is this here? int oldState = m_SynergyState; m_SynergyState = synergyDisconnected; setSynergyState((qSynergyState)oldState); } +void MainWindow::showEvent(QShowEvent* event) +{ + QMainWindow::showEvent(event); + emit windowShown(); +} + void MainWindow::clearLog() { m_pLogOutput->clear(); @@ -507,6 +552,14 @@ void MainWindow::clearLog() void MainWindow::startSynergy() { + SerialKey serialKey = m_LicenseManager->serialKey(); + time_t currentTime = ::time(0); + if (serialKey.isExpired(currentTime)) { + if (QDialog::Rejected == raiseActivationDialog()) { + return; + } + } + bool desktopMode = appConfig().processMode() == Desktop; bool serviceMode = appConfig().processMode() == Service; @@ -555,7 +608,7 @@ void MainWindow::startSynergy() #endif - if (m_AppConfig.getCryptoEnabled()) { + if (m_AppConfig->getCryptoEnabled()) { args << "--enable-crypto"; } @@ -618,6 +671,16 @@ void MainWindow::startSynergy() } } +void +MainWindow::sslToggled (bool enabled) +{ + if (enabled) { + m_pSslCertificate = new SslCertificate(this); + m_pSslCertificate->generateCertificate(); + } + updateLocalFingerprint(); +} + bool MainWindow::clientArgs(QStringList& args, QString& app) { app = appPath(appConfig().synergycName()); @@ -713,19 +776,6 @@ QString MainWindow::appPath(const QString& name) bool MainWindow::serverArgs(QStringList& args, QString& app) { - int edition; - SubscriptionManager subscriptionManager(this, appConfig(), edition); - if (subscriptionManager.fileExists()) - { - if (!subscriptionManager.checkSubscription()) { - return false; - } - else { - setEdition(edition); - } - } - - app = appPath(appConfig().synergysName()); if (!QFile::exists(app)) @@ -754,25 +804,10 @@ bool MainWindow::serverArgs(QStringList& args, QString& app) #endif args << "-c" << configFilename << "--address" << address(); -#if defined(Q_OS_WIN) - // pass in physical resolution and primary screen center - // TODO: get this information in the core binary even when - // high DPI is used - int height = QApplication::desktop()->height(); - int width = QApplication::desktop()->width(); - - QRect rec = QApplication::desktop()->screenGeometry(); - int heightCenter = rec.height() / 2; - int widthCenter = rec.width() / 2; - - appendLogDebug(tr("screen resolution: %1 %2 primary screen center: %3 %4") - .arg(width).arg(height).arg(widthCenter).arg(heightCenter)); - - args << "--res-w" << QString::number(width); - args << "--res-h" << QString::number(height); - args << "--prm-wc" << QString::number(widthCenter); - args << "--prm-hc" << QString::number(heightCenter); - #endif + if (!appConfig().serialKey().isEmpty()) { + args << "--serial-key" << appConfig().serialKey(); + } + return true; } @@ -874,7 +909,7 @@ void MainWindow::setSynergyState(qSynergyState state) switch (state) { case synergyConnected: { - if (m_AppConfig.getCryptoEnabled()) { + if (m_AppConfig->getCryptoEnabled()) { m_pLabelPadlock->show(); } else { @@ -989,13 +1024,13 @@ void MainWindow::updateZeroconfService() QMutexLocker locker(&m_UpdateZeroconfMutex); if (isBonjourRunning()) { - if (!m_AppConfig.wizardShouldRun()) { + if (!m_AppConfig->wizardShouldRun()) { if (m_pZeroconfService) { delete m_pZeroconfService; m_pZeroconfService = NULL; } - if (m_AppConfig.autoConfig() || synergyType() == synergyServer) { + if (m_AppConfig->autoConfig() || synergyType() == synergyServer) { m_pZeroconfService = new ZeroconfService(this); } } @@ -1014,28 +1049,71 @@ void MainWindow::serverDetected(const QString name) } } -void MainWindow::setEdition(int type) +void MainWindow::setEdition(Edition edition) { - QString title; - if (type == Basic) { - title = "Synergy Basic"; - } - else if (type == Pro) { - title = "Synergy Pro"; - } - else if (type == Trial) { - title = "Synergy Trial"; - } - else { - title = "Synergy (UNREGISTERED)"; + setWindowTitle(m_LicenseManager->getEditionName (edition)); + if (m_AppConfig->getCryptoEnabled()) { + m_pSslCertificate = new SslCertificate(this); + m_pSslCertificate->generateCertificate(); } + updateLocalFingerprint(); + saveSettings(); +} - setWindowTitle(title); +void MainWindow::beginTrial(bool isExpiring) +{ + //Hack + //if (isExpiring) { + time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0)); + QString expiringNotice ("

%1 day%3 of " + "your %2 trial remain%5. " + "Buy now!" + "

"); + expiringNotice = expiringNotice + .arg (daysLeft) + .arg (LicenseManager::getEditionName + (m_LicenseManager->activeEdition())) + .arg ((daysLeft == 1) ? "" : "s") + .arg (QString::fromStdString + (m_LicenseManager->serialKey().toString())) + .arg ((daysLeft == 1) ? "s" : ""); + this->m_trialLabel->setText(expiringNotice); + this->m_trialWidget->show(); + //} + setWindowTitle (m_LicenseManager->activeEditionName()); +} + +void MainWindow::endTrial(bool isExpired) +{ + if (isExpired) { + QString expiredNotice ( + "

Your %1 trial has expired. " + "" + "Buy now!

" + ); + expiredNotice = expiredNotice + .arg(LicenseManager::getEditionName + (m_LicenseManager->activeEdition())) + .arg(QString::fromStdString + (m_LicenseManager->serialKey().toString())); + + this->m_trialLabel->setText(expiredNotice); + this->m_trialWidget->show(); + stopSynergy(); + m_AppConfig->activationHasRun(false); + } else { + this->m_trialWidget->hide(); + } + setWindowTitle (m_LicenseManager->activeEditionName()); } void MainWindow::updateLocalFingerprint() { - if (Fingerprint::local().fileExists()) { + if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) { m_pLabelFingerprint->setVisible(true); m_pLabelLocalFingerprint->setVisible(true); m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst()); @@ -1046,6 +1124,12 @@ void MainWindow::updateLocalFingerprint() } } +LicenseManager& +MainWindow::licenseManager() const +{ + return *m_LicenseManager; +} + void MainWindow::on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); @@ -1110,6 +1194,14 @@ void MainWindow::on_m_pActionSettings_triggered() void MainWindow::autoAddScreen(const QString name) { if (!m_ServerConfig.ignoreAutoConfigClient()) { + if (m_ActivationDialogRunning) { + // TODO: refactor this code + // add this screen to the pending list and check this list until + // users finish activation dialog + m_PendingClientNames.append(name); + return; + } + int r = m_ServerConfig.autoAddScreen(name); if (r != kAutoAddScreenOk) { switch (r) { @@ -1145,10 +1237,9 @@ void MainWindow::on_m_pButtonConfigureServer_clicked() showConfigureServer(); } -void MainWindow::on_m_pActionWizard_triggered() +void MainWindow::on_m_pActivate_triggered() { - SetupWizard wizard(*this, false); - wizard.exec(); + raiseActivationDialog(); } void MainWindow::on_m_pButtonApply_clicked() @@ -1308,16 +1399,16 @@ void MainWindow::promptAutoConfig() QMessageBox::Yes | QMessageBox::No); if (r == QMessageBox::Yes) { - m_AppConfig.setAutoConfig(true); + m_AppConfig->setAutoConfig(true); downloadBonjour(); } else { - m_AppConfig.setAutoConfig(false); + m_AppConfig->setAutoConfig(false); m_pCheckBoxAutoConfig->setChecked(false); } } - m_AppConfig.setAutoConfigPrompted(true); + m_AppConfig->setAutoConfigPrompted(true); } void MainWindow::on_m_pComboServerList_currentIndexChanged(QString ) @@ -1363,6 +1454,40 @@ void MainWindow::bonjourInstallFinished() m_pCheckBoxAutoConfig->setChecked(true); } +int MainWindow::raiseActivationDialog() +{ + if (m_ActivationDialogRunning) { + return QDialog::Rejected; + } + ActivationDialog activationDialog (this, appConfig(), licenseManager()); + m_ActivationDialogRunning = true; + connect (&activationDialog, SIGNAL(finished(int)), + this, SLOT(on_activationDialogFinish()), Qt::QueuedConnection); + int result = activationDialog.exec(); + m_ActivationDialogRunning = false; + if (!m_PendingClientNames.empty()) { + foreach (const QString& name, m_PendingClientNames) { + autoAddScreen(name); + } + + m_PendingClientNames.clear(); + } + if (result == QDialog::Accepted) { + restartSynergy(); + } + return result; +} + +void MainWindow::on_windowShown() +{ + time_t currentTime = ::time(0); + if (!m_AppConfig->activationHasRun() + && ((m_AppConfig->edition() == kUnregistered) || + (m_LicenseManager->serialKey().isExpired(currentTime)))) { + raiseActivationDialog(); + } +} + QString MainWindow::getProfileRootForArg() { CoreInterface coreInterface; diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 87380f963..2ca3e711b 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -33,6 +33,7 @@ #include "VersionChecker.h" #include "IpcClient.h" #include "Ipc.h" +#include "ActivationDialog.h" #include @@ -56,6 +57,8 @@ class SetupWizard; class ZeroconfService; class DataDownloader; class CommandProcess; +class SslCertificate; +class LicenseManager; class MainWindow : public QMainWindow, public Ui::MainWindowBase { @@ -63,7 +66,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase friend class QSynergyApplication; friend class SetupWizard; - friend class PluginWizardPage; + friend class ActivationDialog; + friend class SettingsDialog; public: enum qSynergyState @@ -91,7 +95,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase }; public: - MainWindow(QSettings& settings, AppConfig& appConfig); + MainWindow(QSettings& settings, AppConfig& appConfig, + LicenseManager& licenseManager); ~MainWindow(); public: @@ -112,10 +117,15 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void autoAddScreen(const QString name); void updateZeroconfService(); void serverDetected(const QString name); - void setEdition(int type); void updateLocalFingerprint(); + LicenseManager& licenseManager() const; - public slots: + int raiseActivationDialog(); + +public slots: + void setEdition(Edition edition); + void beginTrial(bool isExpiring); + void endTrial(bool isExpired); void appendLogRaw(const QString& text); void appendLogInfo(const QString& text); void appendLogDebug(const QString& text); @@ -123,6 +133,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void startSynergy(); protected slots: + void sslToggled(bool enabled); void on_m_pGroupClient_toggled(bool on); void on_m_pGroupServer_toggled(bool on); bool on_m_pButtonBrowseConfigFile_clicked(); @@ -130,7 +141,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase bool on_m_pActionSave_triggered(); void on_m_pActionAbout_triggered(); void on_m_pActionSettings_triggered(); - void on_m_pActionWizard_triggered(); + void on_m_pActivate_triggered(); void synergyFinished(int exitCode, QProcess::ExitStatus); void trayActivated(QSystemTrayIcon::ActivationReason reason); void stopSynergy(); @@ -141,7 +152,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase protected: QSettings& settings() { return m_Settings; } - AppConfig& appConfig() { return m_AppConfig; } + AppConfig& appConfig() { return *m_AppConfig; } QProcess* synergyProcess() { return m_pSynergy; } void setSynergyProcess(QProcess* p) { m_pSynergy = p; } void initConnections(); @@ -158,7 +169,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void setStatus(const QString& status); void sendIpcMessage(qIpcMessageType type, const char* buffer, bool showErrors); void onModeChanged(bool startDesktop, bool applyService); - void updateStateFromLogLine(const QString& line); + void updateFromLogLine(const QString& line); QString getIPAddresses(); void stopService(); void stopDesktop(); @@ -174,15 +185,19 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void promptAutoConfig(); QString getProfileRootForArg(); void checkConnected(const QString& line); + void checkLicense(const QString& line); void checkFingerprint(const QString& line); bool autoHide(); QString getTimeStamp(); void restartSynergy(); void proofreadInfo(); + void showEvent (QShowEvent*); + private: QSettings& m_Settings; - AppConfig& m_AppConfig; + AppConfig* m_AppConfig; + LicenseManager* m_LicenseManager; QProcess* m_pSynergy; int m_SynergyState; ServerConfig m_ServerConfig; @@ -207,12 +222,19 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase bool m_SuppressEmptyServerWarning; qRuningState m_ExpectedRunningState; QMutex m_StopDesktopMutex; + SslCertificate* m_pSslCertificate; + bool m_ActivationDialogRunning; + QStringList m_PendingClientNames; private slots: void on_m_pCheckBoxAutoConfig_toggled(bool checked); void on_m_pComboServerList_currentIndexChanged(QString ); void on_m_pButtonApply_clicked(); void installBonjour(); + void on_windowShown(); + +signals: + void windowShown(); }; #endif diff --git a/src/gui/src/Plugin.cpp b/src/gui/src/Plugin.cpp deleted file mode 100644 index 50079da24..000000000 --- a/src/gui/src/Plugin.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 "Plugin.h" - -#include "CoreInterface.h" - -static const char kBaseUrl[] = "http://symless.com/files"; -static const char kDefaultVersion[] = "1.1"; -static const char kWinPackagePlatform32[] = "Windows-x86"; -static const char kWinPackagePlatform64[] = "Windows-x64"; -static const char kMacPackagePlatform[] = "MacOSX%1-i386"; -static const char kLinuxPackagePlatformDeb32[] = "Linux-i686-deb"; -static const char kLinuxPackagePlatformDeb64[] = "Linux-x86_64-deb"; -static const char kLinuxPackagePlatformRpm32[] = "Linux-i686-rpm"; -static const char kLinuxPackagePlatformRpm64[] = "Linux-x86_64-rpm"; - -#if defined(Q_OS_WIN) -static const char kWinPluginExt[] = ".dll"; -static const char kInstallerPluginLocation[] = "Plugins"; -#elif defined(Q_OS_MAC) -static const char kMacPluginPrefix[] = "lib"; -static const char kMacPluginExt[] = ".dylib"; -static const char kInstallerPluginLocation[] = "plugins"; // TODO: Fix for mac -#else -static const char kLinuxPluginPrefix[] = "lib"; -static const char kLinuxPluginExt[] = ".so"; -// /usr/bin becomes /usr/bin/../lib/syn... -static const char kInstallerPluginLocation[] = "../lib/synergy/plugins"; -#endif - -QString Plugin::getOsSpecificExt() -{ - -#if defined(Q_OS_WIN) - return kWinPluginExt; -#elif defined(Q_OS_MAC) - return kMacPluginExt; -#else - return kLinuxPluginExt; -#endif -} - -QString Plugin::getOsSpecificName(const QString& pluginName) -{ - QString result = pluginName; -#if defined(Q_OS_WIN) - result.append(getOsSpecificExt()); -#elif defined(Q_OS_MAC) - result = kMacPluginPrefix + pluginName + getOsSpecificExt(); -#else - result = kLinuxPluginPrefix + pluginName + getOsSpecificExt(); -#endif - return result; -} - -QString Plugin::getOsSpecificInstallerLocation() { - return kInstallerPluginLocation; -} diff --git a/src/gui/src/Plugin.h b/src/gui/src/Plugin.h deleted file mode 100644 index bec6a1c22..000000000 --- a/src/gui/src/Plugin.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 PLUGIN_H -#define PLUGIN_H - -#include -#include -#include - -#include "SslCertificate.h" -#include "CoreInterface.h" -#include "DataDownloader.h" - -class Plugin : public QObject -{ - Q_OBJECT - -public: - //Plugin(); - //~PluginManager(); - - static QString getOsSpecificName(const QString& pluginName); - static QString getOsSpecificExt(); - static QString getOsSpecificLocation(); - static QString getOsSpecificInstallerLocation(); - static QString getOsSpecificUserLocation(); - -public slots: - -private: -// CoreInterface m_CoreInterface; - -signals: - -private: - -}; - -#endif // PLUGIN_H diff --git a/src/gui/src/PluginManager.cpp b/src/gui/src/PluginManager.cpp deleted file mode 100644 index b498751a7..000000000 --- a/src/gui/src/PluginManager.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 "PluginManager.h" - -#include "CoreInterface.h" -#include "DataDownloader.h" -#include "QUtility.h" -#include "ProcessorArch.h" -#include "Fingerprint.h" -#include "Plugin.h" -#include "../lib/common/PluginVersion.h" - -#include - -#include -#include -#include -#include - - -PluginManager::PluginManager() : - m_PluginList() -{ - init(); -} - -PluginManager::~PluginManager() -{ -} - -void PluginManager::init() -{ - m_PluginDir = m_CoreInterface.getPluginDir(); - if (m_PluginDir.isEmpty()) { - emit error(tr("Failed to get plugin directory.")); - } - - m_ProfileDir = m_CoreInterface.getProfileDir(); - if (m_ProfileDir.isEmpty()) { - emit error(tr("Failed to get profile directory.")); - } - - m_InstalledDir = m_CoreInterface.getInstalledDir(); - if (m_InstalledDir.isEmpty()) { - emit error(tr("Failed to get installed directory.")); - } -} - -bool PluginManager::exist(QString name) -{ - CoreInterface coreInterface; - QString PluginDir = coreInterface.getPluginDir(); - QString pluginName = Plugin::getOsSpecificName(name); - QString filename; - filename.append(PluginDir); - filename.append(QDir::separator()).append(pluginName); - QFile file(filename); - bool exist = false; - if (file.exists()) { - exist = true; - } - - return exist; -} - -void PluginManager::copyPlugins() -{ - try { - // Get the Directory where plugins are put on installation - // If it doesn't exist, there is nothing to do - QString srcDirName(m_InstalledDir.append(QDir::separator()) - .append(Plugin::getOsSpecificInstallerLocation())); - - QDir srcDir(srcDirName); - if (!srcDir.exists()) { - emit info( - tr("No plugins found to copy from %1") - .arg(srcDirName)); - emit copyFinished(); - } - - // Get the directory where Plugins are installed into Synergy - // If it doesn't exist make it - QString destDirName = m_PluginDir; - - QDir destDir(destDirName); - if (!destDir.exists()) { - destDir.mkpath("."); - } - // Run through the list of plugins and copy them - for ( int i = 0 ; i < m_PluginList.size() ; i++ ) { - // Get a file entry for the plugin using the full path - QFile file(srcDirName + QDir::separator() + m_PluginList.at(i)); - - // construct the destination file name - QString newName(destDirName + QDir::separator() + m_PluginList.at(i)); - - // Check to see if the plugin already exists - QFile newFile(newName); - if(newFile.exists()) { - // If it does, delete it. TODO: Check to see if same and leave - bool result = newFile.remove(); - if( !result ) { - emit error( - tr( "Unable to delete plugin:\n%1\n" - "Please stop synergy and run the wizard again.") - .arg(newName)); - return; - } - } - // make a copy of the plugin in the new location - #if defined(Q_OS_WIN) - bool result = file.copy(newName); - #else - bool result = file.link(newName); - #endif - if ( !result ) { - emit error( - tr("Failed to copy plugin '%1' to: %2\n%3\n" - "Please stop synergy and run the wizard again.") - .arg(m_PluginList.at(i)) - .arg(newName) - .arg(file.errorString())); - return; - } - else { - emit info( - tr("Copying '%1' plugin (%2/%3)...") - .arg(m_PluginList.at(i)) - .arg(i+1) - .arg(m_PluginList.size())); - } - } - } - catch (std::exception& e) - { - emit error(tr( "An error occurred while trying to copy the " - "plugin list. Please contact the help desk, and " - "provide the following details.\n\n%1").arg(e.what())); - } - - emit copyFinished(); - return; -} - -void PluginManager::queryPluginList() -{ - try { - setDone(false); - QString extension = "*" + Plugin::getOsSpecificExt(); - QStringList nameFilter(extension); - - QString installDir(m_CoreInterface.getInstalledDir() - .append(QDir::separator()) - .append(Plugin::getOsSpecificInstallerLocation())); - - QString searchDirectory(installDir); - QDir directory(searchDirectory); - m_PluginList = directory.entryList(nameFilter); - setDone(true); - } - catch (std::exception& e) - { - setDone(true); - emit error(tr( "An error occurred while trying to load the " - "plugin list. Please contact the help desk, and " - "provide the following details.\n\n%1").arg(e.what())); - } - emit queryPluginDone(); - return; -} diff --git a/src/gui/src/PluginManager.h b/src/gui/src/PluginManager.h deleted file mode 100644 index b1450fda2..000000000 --- a/src/gui/src/PluginManager.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 PLUGINMANAGER_H -#define PLUGINMANAGER_H - -#include -#include -#include - -#include "SslCertificate.h" -#include "CoreInterface.h" -#include "DataDownloader.h" -#include "Plugin.h" - -class PluginManager : public QObject -{ - Q_OBJECT - -public: - PluginManager(); - ~PluginManager(); - - void init(); - - int pluginCount() { return m_PluginList.count(); } - QStringList& getPluginList() { return m_PluginList; } - - bool isDone() { return done; } - void setDone(bool b) { done = b; } - static bool exist(QString name); - -public slots: - void copyPlugins(); - void queryPluginList(); - -private: - QString getPluginUrl(const QString& pluginName); - bool runProgram( - const QString& program, - const QStringList& args, - const QStringList& env); - -signals: - void error(QString e); - void info(QString i); - void updateCopyStatus(int); - void copyFinished(); - void queryPluginDone(); - -private: - QStringList m_PluginList; - QString m_PluginDir; - QString m_ProfileDir; - QString m_InstalledDir; - CoreInterface m_CoreInterface; - SslCertificate m_SslCertificate; - bool done; -}; - -#endif // PLUGINMANAGER_H diff --git a/src/gui/src/PluginWizardPage.cpp b/src/gui/src/PluginWizardPage.cpp deleted file mode 100644 index 8be207520..000000000 --- a/src/gui/src/PluginWizardPage.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 "PluginWizardPage.h" -#include "ui_PluginWizardPageBase.h" - -#include "SslCertificate.h" -#include "PluginManager.h" -#include "MainWindow.h" -#include "EditionType.h" - -#include -#include -#include - -PluginWizardPage::PluginWizardPage(MainWindow& mainWindow, QWidget *parent) : - QWizardPage(parent), - m_Finished(false), - m_Edition(Unknown), - m_pSslCertificate(NULL), - m_mainWindow(mainWindow) -{ - setupUi(this); - - QMovie *movie = new QMovie(":/res/image/spinning-wheel.gif"); - m_pLabelSpinning->setMovie(movie); - movie->start(); - - m_pSslCertificate = new SslCertificate(this); -} - -PluginWizardPage::~PluginWizardPage() -{ - delete m_pSslCertificate; -} - -void PluginWizardPage::changeEvent(QEvent *e) -{ - QWizardPage::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - retranslateUi(this); - break; - default: - break; - } -} - -void PluginWizardPage::initializePage() -{ - QWizardPage::initializePage(); - - if (m_Edition != Pro) { - updateStatus(tr("Setup complete.")); - showFinished(); - return; - } - - m_pLabelSpinning->show(); - - QThread* thread = new QThread; - - connect(&m_PluginManager, - SIGNAL(error(QString)), - this, - SLOT(showError(QString))); - - connect(&m_PluginManager, - SIGNAL(info(QString)), - this, - SLOT(updateStatus(QString))); - - connect(&m_PluginManager, - SIGNAL(queryPluginDone()), - this, - SLOT(queryPluginDone())); - - connect(&m_PluginManager, - SIGNAL(queryPluginDone()), - thread, - SLOT(quit())); - - connect(&m_PluginManager, - SIGNAL(error(QString)), - thread, - SLOT(quit())); - - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - - m_PluginManager.moveToThread(thread); - thread->start(); - - QMetaObject::invokeMethod(&m_PluginManager, "queryPluginList", Qt::QueuedConnection); -} - -void PluginWizardPage::queryPluginDone() -{ - QStringList pluginList = m_PluginManager.getPluginList(); - if (pluginList.isEmpty()) { - updateStatus(tr("Setup complete.")); - showFinished(); - } - else { - m_mainWindow.stopSynergy(); - copyPlugins(); - m_mainWindow.startSynergy(); - } -} - -void PluginWizardPage::copyPlugins() -{ - m_pThread = new QThread; - - connect(&m_PluginManager, - SIGNAL(copyFinished()), - this, - SLOT(generateCertificate())); - - connect(&m_PluginManager, - SIGNAL(error(QString)), - m_pThread, - SLOT(quit())); - - connect(m_pThread, - SIGNAL(finished()), - m_pThread, - SLOT(deleteLater())); - - updateStatus( - tr("Copying plugins...")); - - m_PluginManager.moveToThread(m_pThread); - m_pThread->start(); - - QMetaObject::invokeMethod( - &m_PluginManager, - "copyPlugins", - Qt::QueuedConnection); -} - -void PluginWizardPage::generateCertificate() -{ - connect(m_pSslCertificate, - SIGNAL(generateFinished()), - this, - SLOT(finished())); - - connect(m_pSslCertificate, - SIGNAL(generateFinished()), - m_pThread, - SLOT(quit())); - - updateStatus(tr("Generating SSL certificate...")); - - QMetaObject::invokeMethod( - m_pSslCertificate, - "generateCertificate", - Qt::QueuedConnection); -} - -void PluginWizardPage::showError(QString error) -{ - updateStatus(tr("Error: %1").arg(error)); - showFinished(); -} - - -void PluginWizardPage::updateStatus(QString info) -{ - m_pLabelStatus->setText(info); -} - -void PluginWizardPage::finished() -{ - // TODO: we should check if ns plugin exists - m_mainWindow.appConfig().setCryptoEnabled(true); - - updateStatus(tr("Plugins installed successfully.")); - showFinished(); -} - -void PluginWizardPage::showFinished() -{ - m_pLabelSpinning->hide(); - m_Finished = true; - emit completeChanged(); -} - -bool PluginWizardPage::isComplete() const -{ - return m_Finished; -} diff --git a/src/gui/src/PluginWizardPage.h b/src/gui/src/PluginWizardPage.h deleted file mode 100644 index d43197865..000000000 --- a/src/gui/src/PluginWizardPage.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 PLUGINWIZARDPAGE_H -#define PLUGINWIZARDPAGE_H - -#include "AppConfig.h" - -#include "ui_PluginWizardPageBase.h" -#include "PluginManager.h" -#include - -class SslCertificate; -class MainWindow; - -class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage { - - Q_OBJECT - -public: - PluginWizardPage(MainWindow& mainWindow, QWidget *parent = 0); - ~PluginWizardPage(); - - void setFinished(bool b) { m_Finished = b; } - void setEdition(int edition) { m_Edition = edition; } - - bool isComplete() const; - void initializePage(); - -protected: - void changeEvent(QEvent *e); - -protected slots: - void showError(QString error); - void updateStatus(QString info); - void queryPluginDone(); - void generateCertificate(); - void finished(); - -private: - void copyPlugins(); - void showFinished(); - -private: - bool m_Finished; - int m_Edition; - PluginManager m_PluginManager; - SslCertificate* m_pSslCertificate; - QThread* m_pThread; - MainWindow& m_mainWindow; -}; -#endif // PLUGINWIZARDPAGE_H diff --git a/src/gui/src/QUtility.cpp b/src/gui/src/QUtility.cpp index a21343ec6..589e74cfd 100644 --- a/src/gui/src/QUtility.cpp +++ b/src/gui/src/QUtility.cpp @@ -19,6 +19,7 @@ #include "ProcessorArch.h" #include "CommandProcess.h" +#include "EditionType.h" #if defined(Q_OS_LINUX) #include @@ -97,15 +98,18 @@ QString getOSInformation() QString result; #if defined(Q_OS_LINUX) - QStringList arguments; - arguments.append("/etc/os-release"); - CommandProcess cp("/bin/cat", arguments); - QString output = cp.run(); + result = "Linux"; + try { + QStringList arguments; + arguments.append("/etc/os-release"); + CommandProcess cp("/bin/cat", arguments); + QString output = cp.run(); - QRegExp resultRegex(".*PRETTY_NAME=\"([^\"]+)\".*"); - if (resultRegex.exactMatch(output)) { - QString OSInfo = resultRegex.cap(1); - result = OSInfo; + QRegExp resultRegex(".*PRETTY_NAME=\"([^\"]+)\".*"); + if (resultRegex.exactMatch(output)) { + result = resultRegex.cap(1); + } + } catch (...) { } #endif diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 5d5b53d26..ddbeae4d4 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -18,12 +18,14 @@ #include "SettingsDialog.h" -#include "PluginManager.h" #include "CoreInterface.h" #include "SynergyLocale.h" #include "QSynergyApplication.h" #include "QUtility.h" #include "AppConfig.h" +#include "EditionType.h" +#include "SslCertificate.h" +#include "MainWindow.h" #include #include @@ -36,7 +38,7 @@ static const char networkSecurity[] = "ns"; SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), Ui::SettingsDialogBase(), - m_AppConfig(config) + m_appConfig(config) { setupUi(this); @@ -61,13 +63,8 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_pComboElevate->hide(); #endif - if (!PluginManager::exist(networkSecurity)) { - m_pGroupNetworkSecurity->setEnabled(false); - m_pCheckBoxEnableCrypto->setChecked(false); - } - else { - m_pCheckBoxEnableCrypto->setChecked(m_AppConfig.getCryptoEnabled()); - } + m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled()); + m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro); } void SettingsDialog::accept() @@ -147,5 +144,12 @@ void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index) void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked) { - m_AppConfig.setCryptoEnabled(checked); + m_appConfig.setCryptoEnabled(checked); + m_appConfig.saveSettings(); + if (checked) { + SslCertificate sslCertificate; + sslCertificate.generateCertificate(); + MainWindow& mainWindow = dynamic_cast (*this->parent()); + mainWindow.updateLocalFingerprint(); + } } diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h index 656323a6b..841ffff82 100644 --- a/src/gui/src/SettingsDialog.h +++ b/src/gui/src/SettingsDialog.h @@ -40,10 +40,10 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase void accept(); void reject(); void changeEvent(QEvent* event); - AppConfig& appConfig() { return m_AppConfig; } + AppConfig& appConfig() { return m_appConfig; } private: - AppConfig& m_AppConfig; + AppConfig& m_appConfig; SynergyLocale m_Locale; CoreInterface m_CoreInterface; diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index 3d23b017f..da3ff8c3c 100644 --- a/src/gui/src/SetupWizard.cpp +++ b/src/gui/src/SetupWizard.cpp @@ -19,7 +19,7 @@ #include "MainWindow.h" #include "WebClient.h" #include "ActivationNotifier.h" -#include "SubscriptionManager.h" +#include "LicenseManager.h" #include "EditionType.h" #include "QSynergyApplication.h" #include "QUtility.h" @@ -28,13 +28,9 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) : m_MainWindow(mainWindow), - m_StartMain(startMain), - m_Edition(Unknown), - m_LoginAttemps(0) + m_StartMain(startMain) { setupUi(this); - m_pPluginPage = new PluginWizardPage(mainWindow); - addPage(m_pPluginPage); #if defined(Q_OS_MAC) @@ -59,13 +55,6 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) : m_Locale.fillLanguageComboBox(m_pComboLanguage); setIndexFromItemData(m_pComboLanguage, m_MainWindow.appConfig().language()); - AppConfig& appConfig = m_MainWindow.appConfig(); - - m_pLineEditEmail->setText(appConfig.activateEmail()); - m_pTextEditSerialKey->setText(appConfig.serialKey()); - - m_pTextEditSerialKey->setEnabled(false); - } SetupWizard::~SetupWizard() @@ -78,70 +67,7 @@ bool SetupWizard::validateCurrentPage() message.setWindowTitle(tr("Setup Synergy")); message.setIcon(QMessageBox::Information); - if (currentPage() == m_pActivatePage) - { - if (m_pRadioButtonActivate->isChecked()) { - if (m_pLineEditEmail->text().isEmpty() || - m_pLineEditPassword->text().isEmpty()) { - message.setText(tr("Please enter your email address and password.")); - message.exec(); - return false; - } - else { - WebClient webClient; - m_Edition = webClient.getEdition( - m_pLineEditEmail->text(), - m_pLineEditPassword->text(), - message, - this); - - if (m_Edition == Unknown) { - m_LoginAttemps++; - if (m_LoginAttemps == kMaximiumLoginAttemps) { - m_LoginAttemps = 0; - - QMessageBox::StandardButton reply = - QMessageBox::information( - this, tr("Setup Synergy"), - tr("Would you like to use your serial key instead?"), - QMessageBox::Yes | QMessageBox::No); - - if (reply == QMessageBox::Yes) { - m_pRadioButtonSubscription->setChecked(true); - } - } - - return false; - } - else { - m_pPluginPage->setEdition(m_Edition); - return true; - } - } - } - else if (m_pRadioButtonSubscription->isChecked()) { - if (m_pTextEditSerialKey->toPlainText().isEmpty()) { - message.setText(tr("Please enter your subscription serial key.")); - message.exec(); - return false; - } - else { - // create subscription file in profile directory - SubscriptionManager subscriptionManager(this, m_MainWindow.appConfig(), m_Edition); - if (!subscriptionManager.activateSerial(m_pTextEditSerialKey->toPlainText())) { - return false; - } - - m_pPluginPage->setEdition(m_Edition); - - return true; - } - } - else { - return true; - } - } - else if (currentPage() == m_pNodePage) + if (currentPage() == m_pNodePage) { bool result = m_pClientRadioButton->isChecked() || m_pServerRadioButton->isChecked(); @@ -198,31 +124,6 @@ void SetupWizard::accept() settings.setValue("groupServerChecked", false); } - if (m_pRadioButtonActivate->isChecked()) { - appConfig.setActivateEmail(m_pLineEditEmail->text()); - - notifyActivation("login:" + m_pLineEditEmail->text()); - } - - if (m_pRadioButtonSubscription->isChecked()) - { - appConfig.setSerialKey(m_pTextEditSerialKey->toPlainText()); - - notifyActivation("serial:" + m_pTextEditSerialKey->toPlainText()); - } - - if (m_pRadioButtonSkip->isChecked()) - { - notifyActivation("skip:unknown"); - } - - appConfig.setEdition(m_Edition); - m_MainWindow.setEdition(m_Edition); - m_MainWindow.updateLocalFingerprint(); - - appConfig.saveSettings(); - settings.sync(); - QWizard::accept(); if (m_StartMain) @@ -238,60 +139,14 @@ void SetupWizard::reject() if (m_StartMain) { - m_MainWindow.setEdition(m_Edition); m_MainWindow.open(); } - // treat cancel as skip - notifyActivation("skip:unknown"); - QWizard::reject(); } -void SetupWizard::notifyActivation(QString identity) -{ - ActivationNotifier* notifier = new ActivationNotifier(); - notifier->setIdentity(identity); - QThread* thread = new QThread; - connect(notifier, SIGNAL(finished()), thread, SLOT(quit())); - connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater())); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - - notifier->moveToThread(thread); - thread->start(); - - QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection); -} - void SetupWizard::on_m_pComboLanguage_currentIndexChanged(int index) { QString ietfCode = m_pComboLanguage->itemData(index).toString(); QSynergyApplication::getInstance()->switchTranslator(ietfCode); } - -void SetupWizard::on_m_pRadioButtonSkip_toggled(bool checked) -{ - if (checked) { - m_pLineEditEmail->setEnabled(false); - m_pLineEditPassword->setEnabled(false); - m_pTextEditSerialKey->setEnabled(false); - } -} - -void SetupWizard::on_m_pRadioButtonActivate_toggled(bool checked) -{ - if (checked) { - m_pLineEditEmail->setEnabled(true); - m_pLineEditPassword->setEnabled(true); - m_pTextEditSerialKey->setEnabled(false); - } -} - -void SetupWizard::on_m_pRadioButtonSubscription_toggled(bool checked) -{ - if (checked) { - m_pLineEditEmail->setEnabled(false); - m_pLineEditPassword->setEnabled(false); - m_pTextEditSerialKey->setEnabled(true); - } -} diff --git a/src/gui/src/SetupWizard.h b/src/gui/src/SetupWizard.h index 34b301a25..009939b23 100644 --- a/src/gui/src/SetupWizard.h +++ b/src/gui/src/SetupWizard.h @@ -19,7 +19,6 @@ #include "ui_SetupWizardBase.h" #include "SynergyLocale.h" -#include "PluginWizardPage.h" #include #include @@ -43,19 +42,12 @@ class SetupWizard : public QWizard, public Ui::SetupWizardBase void changeEvent(QEvent* event); void accept(); void reject(); - void notifyActivation(QString identity); private: MainWindow& m_MainWindow; bool m_StartMain; SynergyLocale m_Locale; - int m_Edition; - PluginWizardPage* m_pPluginPage; - int m_LoginAttemps; private slots: - void on_m_pRadioButtonSubscription_toggled(bool checked); - void on_m_pRadioButtonActivate_toggled(bool checked); - void on_m_pRadioButtonSkip_toggled(bool checked); void on_m_pComboLanguage_currentIndexChanged(int index); }; diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 7a8403c05..a669c5f6f 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -90,55 +90,58 @@ bool SslCertificate::runTool(const QStringList& args) void SslCertificate::generateCertificate() { - QStringList arguments; - - // self signed certificate - arguments.append("req"); - arguments.append("-x509"); - arguments.append("-nodes"); - - // valide duration - arguments.append("-days"); - arguments.append(kCertificateLifetime); - - // subject information - arguments.append("-subj"); - - QString subInfo(kCertificateSubjectInfo); - arguments.append(subInfo); - - // private key - arguments.append("-newkey"); - arguments.append("rsa:1024"); - QString sslDirPath = QString("%1%2%3") .arg(m_ProfileDir) .arg(QDir::separator()) .arg(kSslDir); - QDir sslDir(sslDirPath); - if (!sslDir.exists()) { - sslDir.mkpath("."); - } - QString filename = QString("%1%2%3") .arg(sslDirPath) .arg(QDir::separator()) .arg(kCertificateFilename); - // key output filename - arguments.append("-keyout"); - arguments.append(filename); + QFile file(filename); + if (!file.exists()) { + QStringList arguments; - // certificate output filename - arguments.append("-out"); - arguments.append(filename); + // self signed certificate + arguments.append("req"); + arguments.append("-x509"); + arguments.append("-nodes"); - if (!runTool(arguments)) { - return; - } + // valide duration + arguments.append("-days"); + arguments.append(kCertificateLifetime); + + // subject information + arguments.append("-subj"); + + QString subInfo(kCertificateSubjectInfo); + arguments.append(subInfo); + + // private key + arguments.append("-newkey"); + arguments.append("rsa:1024"); - emit info(tr("SSL certificate generated.")); + QDir sslDir(sslDirPath); + if (!sslDir.exists()) { + sslDir.mkpath("."); + } + + // key output filename + arguments.append("-keyout"); + arguments.append(filename); + + // certificate output filename + arguments.append("-out"); + arguments.append(filename); + + if (!runTool(arguments)) { + return; + } + + emit info(tr("SSL certificate generated.")); + } generateFingerprint(filename); diff --git a/src/gui/src/SubscriptionManager.cpp b/src/gui/src/SubscriptionManager.cpp deleted file mode 100644 index 52096a11a..000000000 --- a/src/gui/src/SubscriptionManager.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "SubscriptionManager.h" - - -#include "CoreInterface.h" -#include "EditionType.h" -#include "AppConfig.h" - -#include -#include -#include -#include -#include - -static const char purchaseURL[] = "https://symless.com/account/"; - -SubscriptionManager::SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition) : - m_pParent(parent), - m_AppConfig(appConfig), - m_Edition(edition) -{ -} - -bool SubscriptionManager::activateSerial(const QString& serial) -{ - m_Edition = Unknown; - persistDirectory(); - CoreInterface coreInterface; - QString output; - - try - { - output = coreInterface.activateSerial(serial); - } - catch (std::exception& e) - { - m_ErrorMessage = e.what(); - checkError(m_ErrorMessage); - return false; - } - - checkOutput(output); - - return true; -} - -bool SubscriptionManager::checkSubscription() -{ - m_Edition = Unknown; - persistDirectory(); - CoreInterface coreInterface; - QString output; - try - { - output = coreInterface.checkSubscription(); - } - catch (std::exception& e) - { - m_ErrorMessage = e.what(); - checkError(m_ErrorMessage); - return false; - } - - checkOutput(output); - - return true; -} - -bool SubscriptionManager::fileExists() -{ - CoreInterface coreInterface; - QString subscriptionFilename = coreInterface.getSubscriptionFilename(); - - return QFile::exists(subscriptionFilename); -} - -void SubscriptionManager::checkError(QString& error) -{ - if (error.contains("trial has expired")) { - QMessageBox::warning(m_pParent, tr("Subscription warning"), - tr("Your trial has expired. Click here to purchase").arg(purchaseURL)); - } - else { - QMessageBox::warning(m_pParent, tr("Subscription error"), - tr("An error occurred while trying to activate using a serial key. " - "Please contact the helpdesk, and provide the " - "following details.\n\n%1").arg(error)); - } -} - -void SubscriptionManager::checkOutput(QString& output) -{ - getEditionType(output); - checkExpiring(output); -} - -void SubscriptionManager::getEditionType(QString& output) -{ - if (output.contains("pro subscription valid")) { - m_Edition = Pro; - } - else if (output.contains("basic subscription valid")) { - m_Edition = Basic; - } - else if (output.contains("trial subscription valid")) { - m_Edition = Trial; - } -} - -void SubscriptionManager::checkExpiring(QString& output) -{ - if (output.contains("trial will end in") && shouldWarnExpiring()) { - QRegExp dayLeftRegex(".*trial will end in ([0-9]+) day.*"); - if (dayLeftRegex.exactMatch(output)) { - QString dayLeft = dayLeftRegex.cap(1); - - QMessageBox::warning(m_pParent, tr("Subscription warning"), - tr("Your trial will end in %1 %2. Click here to purchase") - .arg(dayLeft) - .arg(dayLeft == "1" ? "day" : "days") - .arg(purchaseURL)); - } - } -} - -bool SubscriptionManager::shouldWarnExpiring() -{ - // warn users about expiring subscription once a day - int lastExpiringWarningTime = m_AppConfig.lastExpiringWarningTime(); - QDateTime currentDateTime = QDateTime::currentDateTime(); - int currentTime = currentDateTime.toTime_t(); - const int secondPerDay = 60 * 60 * 24; - bool result = false; - if ((currentTime - lastExpiringWarningTime) > secondPerDay) { - result = true; - m_AppConfig.setLastExpiringWarningTime(currentTime); - } - - return result; -} - -void SubscriptionManager::persistDirectory() -{ - CoreInterface coreInterface; - QString profileDir = coreInterface.getProfileDir(); - - QDir dir(profileDir); - if (!dir.exists()) { - dir.mkpath("."); - } -} diff --git a/src/gui/src/SubscriptionManager.h b/src/gui/src/SubscriptionManager.h deleted file mode 100644 index 594973521..000000000 --- a/src/gui/src/SubscriptionManager.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 - -class AppConfig; - -class SubscriptionManager : public QWidget -{ -public: - SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition); - - bool activateSerial(const QString& serial); - bool checkSubscription(); - bool fileExists(); - QString getLastError(){ return m_ErrorMessage; } - -private: - void checkError(QString& error); - void checkOutput(QString& output); - void getEditionType(QString& output); - void checkExpiring(QString& output); - bool shouldWarnExpiring(); - void persistDirectory(); - -private: - QString m_ErrorMessage; - QWidget* m_pParent; - AppConfig& m_AppConfig; - int& m_Edition; -}; diff --git a/src/gui/src/VersionChecker.cpp b/src/gui/src/VersionChecker.cpp index 1f6980fc8..4ce274332 100644 --- a/src/gui/src/VersionChecker.cpp +++ b/src/gui/src/VersionChecker.cpp @@ -51,8 +51,10 @@ void VersionChecker::replyFinished(QNetworkReply* reply) if (!newestVersion.isEmpty()) { QString currentVersion = getVersion(); - if (compareVersions(currentVersion, newestVersion) > 0) - emit updateFound(newestVersion); + if (currentVersion != "Unknown") { + if (compareVersions(currentVersion, newestVersion) > 0) + emit updateFound(newestVersion); + } } } diff --git a/src/gui/src/WebClient.cpp b/src/gui/src/WebClient.cpp index 4b4b999b4..1d21dc820 100644 --- a/src/gui/src/WebClient.cpp +++ b/src/gui/src/WebClient.cpp @@ -25,76 +25,60 @@ #include #include -int WebClient::getEdition( - const QString& email, - const QString& password, - QMessageBox& message, - QWidget* w) -{ - QString responseJson; - int edition = Unknown; - try { - responseJson = request(email, password); - } - catch (std::exception& e) - { - message.critical( - w, "Error", - tr("An error occurred while trying to sign in. " - "Please contact the helpdesk, and provide the " - "following details.\n\n%1").arg(e.what())); - return edition; - } +bool +WebClient::getEdition (int& edition, QString& errorOut) { + QString responseJson = request(); + + /* TODO: This is horrible and should be ripped out as soon as we move + * to Qt 5. See issue #5630 + */ QRegExp resultRegex(".*\"result\".*:.*(true|false).*"); - if (resultRegex.exactMatch(responseJson)) { + if (resultRegex.exactMatch (responseJson)) { QString boolString = resultRegex.cap(1); if (boolString == "true") { QRegExp editionRegex(".*\"edition\".*:.*\"([^\"]+)\".*"); if (editionRegex.exactMatch(responseJson)) { QString e = editionRegex.cap(1); edition = e.toInt(); + return true; + } else { + throw std::runtime_error ("Unrecognised server response."); } - - return edition; + } else { + errorOut = tr("Login failed. Invalid email address or password."); + return false; } - else if (boolString == "false") { - message.critical( - w, "Error", - tr("Login failed, invalid email or password.")); - - return edition; - } - } - else { + } else { QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*"); - if (errorRegex.exactMatch(responseJson)) { - - // replace "\n" with real new lines. - QString error = errorRegex.cap(1).replace("\\n", "\n"); - message.critical( - w, "Error", - tr("Login failed, an error occurred.\n\n%1").arg(error)); - - return edition; + if (errorRegex.exactMatch (responseJson)) { + errorOut = errorRegex.cap(1).replace("\\n", "\n"); + return false; + } else { + throw std::runtime_error ("Unrecognised server response."); } } +} - message.critical( - w, "Error", - tr("Login failed, an error occurred.\n\nServer response:\n\n%1") - .arg(responseJson)); +bool +WebClient::setEmail (QString email, QString& errorOut) { + if (email.isEmpty()) { + errorOut = tr("Your email address cannot be left blank."); + return false; + } + m_Email = email; + return true; +} - return edition; +bool +WebClient::setPassword (QString password, QString&) { + m_Password = password; + return true; } -QString WebClient::request( - const QString& email, - const QString& password) -{ +QString +WebClient::request() { QStringList args("--login-auth"); - // hash password in case it contains interesting chars. - QString credentials(email + ":" + hash(password) + "\n"); - - return m_CoreInterface.run(args, credentials); + QString credentials (m_Email + ":" + hash(m_Password) + "\n"); + return m_CoreInterface.run (args, credentials); } diff --git a/src/gui/src/WebClient.h b/src/gui/src/WebClient.h index 100b63d12..7ff6e2beb 100644 --- a/src/gui/src/WebClient.h +++ b/src/gui/src/WebClient.h @@ -32,21 +32,15 @@ class WebClient : public QObject Q_OBJECT public: - int getEdition(const QString& email, - const QString& password, - QMessageBox& message, - QWidget* w); - void setEmail(QString& e) { m_Email = e; } - void setPassword(QString& p) { m_Password = p; } - + bool getEdition (int& edition, QString& errorOut); + bool setEmail (QString email, QString& errorOut); + bool setPassword (QString password, QString& errorOut); signals: void error(QString e); private: - QString request(const QString& email, - const QString& password); - -private: + QString request(); + QString m_Email; QString m_Password; CoreInterface m_CoreInterface; diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 0ea2cbfee..cf4d0c1ee 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -2,11 +2,11 @@ * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * 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 LICENSE 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 @@ -20,6 +20,7 @@ #define TRAY_RETRY_WAIT 2000 #include "QSynergyApplication.h" +#include "LicenseManager.h" #include "MainWindow.h" #include "AppConfig.h" #include "SetupWizard.h" @@ -65,7 +66,7 @@ int main(int argc, char* argv[]) "Please drag Synergy to the Applications folder, and open it from there."); return 1; } - + if (!checkMacAssistiveDevices()) { return 1; @@ -82,11 +83,13 @@ int main(int argc, char* argv[]) #endif QSettings settings; - AppConfig appConfig(&settings); + AppConfig appConfig (&settings); + qRegisterMetaType("Edition"); + LicenseManager licenseManager (&appConfig); app.switchTranslator(appConfig.language()); - MainWindow mainWindow(settings, appConfig); + MainWindow mainWindow(settings, appConfig, licenseManager); SetupWizard setupWizard(mainWindow, true); if (appConfig.wizardShouldRun()) @@ -116,8 +119,8 @@ int waitForTray() if (++trayAttempts > TRAY_RETRY_COUNT) { QMessageBox::critical(NULL, "Synergy", - QObject::tr("System tray is unavailable, quitting.")); - return false; + QObject::tr("System tray is unavailable, don't close your window.")); + return true; } QThreadImpl::msleep(TRAY_RETRY_WAIT); @@ -156,7 +159,8 @@ bool checkMacAssistiveDevices() QMessageBox::information( NULL, "Synergy", "Please enable access to assistive devices " - "(System Preferences), then re-open Synergy."); + "System Preferences -> Security & Privacy -> " + "Privacy -> Accessibility, then re-open Synergy."); } return result; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8eba5dffa..f53d9db86 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -23,10 +23,9 @@ add_subdirectory(ipc) add_subdirectory(mt) add_subdirectory(net) add_subdirectory(platform) -add_subdirectory(plugin) add_subdirectory(server) add_subdirectory(synergy) - +add_subdirectory(shared) if (WIN32) add_subdirectory(synwinhk) diff --git a/src/lib/arch/Arch.h b/src/lib/arch/Arch.h index 3c5a23ff2..42be6eb8e 100644 --- a/src/lib/arch/Arch.h +++ b/src/lib/arch/Arch.h @@ -50,7 +50,6 @@ # include "arch/win32/ArchSystemWindows.h" # include "arch/win32/ArchTaskBarWindows.h" # include "arch/win32/ArchTimeWindows.h" -# include "arch/win32/ArchPluginWindows.h" # include "arch/win32/ArchInternetWindows.h" #elif SYSAPI_UNIX # include "arch/unix/ArchConsoleUnix.h" @@ -66,7 +65,6 @@ # include "arch/unix/ArchSystemUnix.h" # include "arch/unix/ArchTaskBarXWindows.h" # include "arch/unix/ArchTimeUnix.h" -# include "arch/unix/ArchPluginUnix.h" # include "arch/unix/ArchInternetUnix.h" #endif @@ -122,12 +120,10 @@ class Arch : public ARCH_CONSOLE, static void setInstance(Arch* s) { s_instance = s; } - ARCH_PLUGIN& plugin() const { return (ARCH_PLUGIN&)m_plugin; } ARCH_INTERNET& internet() const { return (ARCH_INTERNET&)m_internet; } private: static Arch* s_instance; - ARCH_PLUGIN m_plugin; ARCH_INTERNET m_internet; }; diff --git a/src/lib/arch/IArchPlugin.h b/src/lib/arch/IArchPlugin.h deleted file mode 100644 index e91ed65ff..000000000 --- a/src/lib/arch/IArchPlugin.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "common/IInterface.h" -#include "common/stdmap.h" -#include "base/String.h" - -class IEventQueue; - -//! Interface for plugin manager. -/*! -A plugin manager should load all 3rd party plugins from the plugins dir, -and then look for common function names in the plugins. -*/ -class IArchPlugin : public IInterface { -public: - //! @name manipulators - //@{ - - //!Load plugins - /*! - Scan the plugins dir and load plugins. - */ - virtual void load() = 0; - - //!Unload plugins - /*! - Look through the loaded plugins and unload them. - */ - virtual void unload() = 0; - - //! Init the common parts - /*! - Initializes common parts like log and arch. - */ - virtual void init(void* log, void* arch) = 0; - - //! Init the event part - /*! - Initializes event parts. - */ - virtual void initEvent(void* eventTarget, IEventQueue* events) = 0; - - //! Check if exists - /*! - Returns true if the plugin exists and is loaded. - */ - virtual bool exists(const char* name) = 0; - - //! Invoke function - /*! - Invokes a function from the plugin. - */ - virtual void* invoke(const char* plugin, - const char* command, - void** args, - void* library = NULL) = 0; - - //@} - -protected: - typedef std::map PluginTable; -}; diff --git a/src/lib/arch/unix/ArchDaemonUnix.cpp b/src/lib/arch/unix/ArchDaemonUnix.cpp index 91933ab4e..f12ee8f14 100644 --- a/src/lib/arch/unix/ArchDaemonUnix.cpp +++ b/src/lib/arch/unix/ArchDaemonUnix.cpp @@ -117,9 +117,11 @@ ArchDaemonUnix::daemonize(const char* name, DaemonFunc func) open("/dev/null", O_RDWR); int dupErr = dup(1); - if (dupErr) + + if (dupErr < 0) { // NB: file logging actually isn't working at this point! LOG((CLOG_ERR "dup error: %i", dupErr)); + } #ifdef __APPLE__ return execSelfNonDaemonized(); diff --git a/src/lib/arch/unix/ArchInternetUnix.cpp b/src/lib/arch/unix/ArchInternetUnix.cpp index 596000c18..fe4a39bac 100644 --- a/src/lib/arch/unix/ArchInternetUnix.cpp +++ b/src/lib/arch/unix/ArchInternetUnix.cpp @@ -116,7 +116,6 @@ CurlFacade::urlEncode(const String& url) char* resultCStr = curl_easy_escape(m_curl, url.c_str(), 0); if (resultCStr == NULL) { - curl_free(resultCStr); throw XArch("CURL escape failed."); } diff --git a/src/lib/arch/unix/ArchMultithreadPosix.cpp b/src/lib/arch/unix/ArchMultithreadPosix.cpp index 807894e23..33da29b48 100644 --- a/src/lib/arch/unix/ArchMultithreadPosix.cpp +++ b/src/lib/arch/unix/ArchMultithreadPosix.cpp @@ -697,7 +697,7 @@ void* ArchMultithreadPosix::threadFunc(void* vrep) { // get the thread - ArchThreadImpl* thread = reinterpret_cast(vrep); + ArchThreadImpl* thread = static_cast(vrep); // setup pthreads pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); diff --git a/src/lib/arch/unix/ArchNetworkBSD.cpp b/src/lib/arch/unix/ArchNetworkBSD.cpp index c2d692fcf..8913313ec 100644 --- a/src/lib/arch/unix/ArchNetworkBSD.cpp +++ b/src/lib/arch/unix/ArchNetworkBSD.cpp @@ -646,7 +646,7 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family) switch (family) { case kINET: { struct sockaddr_in* ipAddr = - reinterpret_cast(&addr->m_addr); + reinterpret_cast(&addr->m_addr); ipAddr->sin_family = AF_INET; ipAddr->sin_port = 0; ipAddr->sin_addr.s_addr = INADDR_ANY; @@ -737,8 +737,7 @@ ArchNetworkBSD::addrToName(ArchNetAddress addr) // mutexed name lookup (ugh) ARCH->lockMutex(m_mutex); - struct hostent* info = gethostbyaddr( - reinterpret_cast(&addr->m_addr), + struct hostent* info = gethostbyaddr(&addr->m_addr, addr->m_len, addr->m_addr.sa_family); if (info == NULL) { ARCH->unlockMutex(m_mutex); @@ -834,7 +833,7 @@ ArchNetworkBSD::isAnyAddr(ArchNetAddress addr) switch (getAddrFamily(addr)) { case kINET: { struct sockaddr_in* ipAddr = - reinterpret_cast(&addr->m_addr); + reinterpret_cast(&addr->m_addr); return (ipAddr->sin_addr.s_addr == INADDR_ANY && addr->m_len == (socklen_t)sizeof(struct sockaddr_in)); } diff --git a/src/lib/arch/unix/ArchPluginUnix.cpp b/src/lib/arch/unix/ArchPluginUnix.cpp deleted file mode 100644 index edf53d17b..000000000 --- a/src/lib/arch/unix/ArchPluginUnix.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "arch/unix/ArchPluginUnix.h" - -#include "arch/unix/XArchUnix.h" -#include "common/PluginVersion.h" -#include "base/IEventQueue.h" -#include "base/Event.h" -#include "base/Log.h" - -#include -#include -#include -#include - -typedef void (*initFunc)(void*, void*); -typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); -typedef void* (*invokeFunc)(const char*, void*); -typedef void (*cleanupFunc)(); - -void* g_eventTarget = NULL; -IEventQueue* g_events = NULL; - -ArchPluginUnix::ArchPluginUnix() -{ -} - -ArchPluginUnix::~ArchPluginUnix() -{ -} - -void -ArchPluginUnix::load() -{ - String pluginsDir = getPluginsDir(); - LOG((CLOG_DEBUG "plugins dir: %s", pluginsDir.c_str())); - - struct dirent* de = NULL; - DIR* dir = NULL; - - dir = opendir(pluginsDir.c_str()); - if (dir == NULL) { - LOG((CLOG_DEBUG "can't open plugins dir: %s", - pluginsDir.c_str())); - return; - } - - std::vector plugins; - while ((de = readdir(dir)) != NULL) { - // ignore hidden files and diretories like .. and . - if (de->d_name[0] != '.') { - plugins.push_back(de->d_name); - } - } - closedir(dir); - - std::vector::iterator it; - for (it = plugins.begin(); it != plugins.end(); ++it) { - String filename = *it; - String path = synergy::string::sprintf( - "%s/%s", pluginsDir.c_str(), filename.c_str()); - String name = synergy::string::removeFileExt(filename.substr(3)); - - LOG((CLOG_DEBUG "loading plugin: %s", filename.c_str())); - void* handle = dlopen(path.c_str(), RTLD_LAZY); - - if (handle == NULL) { - LOG((CLOG_ERR "failed to load plugin '%s', error: %s", - filename.c_str(), dlerror())); - continue; - } - - - String expectedVersion = getExpectedPluginVersion(name.c_str()); - String currentVersion = getCurrentVersion(name, handle); - - if (currentVersion.empty() || (expectedVersion != currentVersion)) { - LOG((CLOG_ERR - "failed to load plugin '%s', " - "expected version %s but was %s", - filename.c_str(), - expectedVersion.c_str(), - currentVersion.empty() ? "unknown" : currentVersion.c_str())); - - dlclose(handle); - continue; - } - - LOG((CLOG_DEBUG "plugin loaded: %s (version %s)", - filename.c_str(), - currentVersion.c_str())); - - m_pluginTable.insert(std::make_pair(name, handle)); - } -} - -void -ArchPluginUnix::unload() -{ - PluginTable::iterator it; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - cleanupFunc cleanup = (cleanupFunc)dlsym(it->second, "cleanup"); - if (cleanup != NULL) { - cleanup(); - } - else { - LOG((CLOG_DEBUG "no cleanup function in %s", it->first.c_str())); - } - - LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str())); - dlclose(it->second); - } -} - -void -ArchPluginUnix::init(void* log, void* arch) -{ - PluginTable::iterator it; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - initFunc initPlugin = (initFunc)dlsym(it->second, "init"); - if (initPlugin != NULL) { - initPlugin(log, arch); - } - else { - LOG((CLOG_DEBUG "no init function in %s", it->first.c_str())); - } - } -} - -void -ArchPluginUnix::initEvent(void* eventTarget, IEventQueue* events) -{ - g_eventTarget = eventTarget; - g_events = events; - - PluginTable::iterator it; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - initEventFunc initEventPlugin = (initEventFunc)dlsym(it->second, "initEvent"); - if (initEventPlugin != NULL) { - initEventPlugin(&sendEvent); - } - else { - LOG((CLOG_DEBUG "no init event function in %s", it->first.c_str())); - } - } -} - -bool -ArchPluginUnix::exists(const char* name) -{ - PluginTable::iterator it; - it = m_pluginTable.find(name); - return it != m_pluginTable.end() ? true : false; -} - -void* -ArchPluginUnix::invoke( - const char* plugin, - const char* command, - void** args, - void* library) -{ - void* lib = NULL; - - if (library == NULL) { - PluginTable::iterator it; - it = m_pluginTable.find(plugin); - if (it != m_pluginTable.end()) { - lib = it->second; - } - else { - LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", - plugin, command)); - return NULL; - } - } - else { - lib = library; - } - - invokeFunc invokePlugin = (invokeFunc)dlsym(lib, "invoke"); - void* result = NULL; - if (invokePlugin != NULL) { - result = invokePlugin(command, args); - } - else { - LOG((CLOG_DEBUG "no invoke function in %s", plugin)); - } - - return result; -} - -String -ArchPluginUnix::getPluginsDir() -{ - return ARCH->getPluginDirectory(); -} - -String -ArchPluginUnix::getCurrentVersion(const String& name, void* handle) -{ - char* version = (char*)invoke(name.c_str(), "version", NULL, handle); - if (version == NULL) { - return ""; - } - - return version; -} - -void -sendEvent(const char* eventName, void* data) -{ - LOG((CLOG_DEBUG5 "plugin sending event")); - Event::Type type = g_events->getRegisteredType(eventName); - g_events->addEvent(Event(type, g_eventTarget, data)); -} - -void -log(const char* text) -{ - LOG((CLOG_DEBUG "plugin: %s", text)); -} - diff --git a/src/lib/arch/unix/ArchPluginUnix.h b/src/lib/arch/unix/ArchPluginUnix.h deleted file mode 100644 index 84ce185ed..000000000 --- a/src/lib/arch/unix/ArchPluginUnix.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "arch/IArchPlugin.h" - -#define ARCH_PLUGIN ArchPluginUnix - -class IEventQueue; - -//! Unix implementation of IArchPlugin -class ArchPluginUnix : public IArchPlugin { -public: - ArchPluginUnix(); - virtual ~ArchPluginUnix(); - - // IArchPlugin overrides - void load(); - void unload(); - void init(void* log, void* arch); - void initEvent(void* eventTarget, IEventQueue* events); - bool exists(const char* name); - virtual void* invoke(const char* pluginName, - const char* functionName, - void** args, - void* library = NULL); - -private: - String getPluginsDir(); - String getCurrentVersion(const String& name, void* handle); - -private: - PluginTable m_pluginTable; -}; - -void sendEvent(const char* text, void* data); -void log(const char* text); diff --git a/src/lib/arch/unix/ArchSystemUnix.cpp b/src/lib/arch/unix/ArchSystemUnix.cpp index 3eb60cfa8..5bcea6190 100644 --- a/src/lib/arch/unix/ArchSystemUnix.cpp +++ b/src/lib/arch/unix/ArchSystemUnix.cpp @@ -76,5 +76,5 @@ ArchSystemUnix::setting(const std::string&, const std::string&) const std::string ArchSystemUnix::getLibsUsed(void) const { - return "not implmented.\nuse lsof on shell"; + return "not implemented.\nuse lsof on shell"; } diff --git a/src/lib/arch/win32/ArchMultithreadWindows.cpp b/src/lib/arch/win32/ArchMultithreadWindows.cpp index 0768492de..3c131780b 100644 --- a/src/lib/arch/win32/ArchMultithreadWindows.cpp +++ b/src/lib/arch/win32/ArchMultithreadWindows.cpp @@ -661,7 +661,7 @@ unsigned int __stdcall ArchMultithreadWindows::threadFunc(void* vrep) { // get the thread - ArchThreadImpl* thread = reinterpret_cast(vrep); + ArchThreadImpl* thread = static_cast(vrep); // run thread s_instance->doThreadFunc(thread); diff --git a/src/lib/arch/win32/ArchNetworkWinsock.cpp b/src/lib/arch/win32/ArchNetworkWinsock.cpp index 712e1bdc5..b1470aa2c 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.cpp +++ b/src/lib/arch/win32/ArchNetworkWinsock.cpp @@ -805,7 +805,7 @@ ArchNetworkWinsock::setAddrPort(ArchNetAddress addr, int port) case kINET: { struct sockaddr_in* ipAddr = reinterpret_cast(&addr->m_addr); - ipAddr->sin_port = htons_winsock(static_cast(port)); + ipAddr->sin_port = htons_winsock(port); break; } diff --git a/src/lib/arch/win32/ArchPluginWindows.cpp b/src/lib/arch/win32/ArchPluginWindows.cpp deleted file mode 100644 index 7e498cb2a..000000000 --- a/src/lib/arch/win32/ArchPluginWindows.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "arch/win32/ArchPluginWindows.h" -#include "arch/win32/XArchWindows.h" -#include "common/PluginVersion.h" -#include "base/Log.h" -#include "base/IEventQueue.h" -#include "base/Event.h" -#include "synergy/Screen.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include - -typedef void (*initFunc)(void*, void*); -typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); -typedef void* (*invokeFunc)(const char*, void**); -typedef void (*cleanupFunc)(); - -void* g_eventTarget = NULL; -IEventQueue* g_events = NULL; -static const char * kPre174Plugin = "Pre-1.7.v"; - -ArchPluginWindows::ArchPluginWindows() -{ -} - -ArchPluginWindows::~ArchPluginWindows() -{ -} - -void -ArchPluginWindows::load() -{ - String dir = getPluginsDir(); - LOG((CLOG_DEBUG "plugins dir: %s", dir.c_str())); - - String pattern = String(dir).append("\\*.dll"); - std::vector plugins; - getFilenames(pattern, plugins); - - std::vector::iterator it; - for (it = plugins.begin(); it != plugins.end(); ++it) { - String filename = *it; - String name = synergy::string::removeFileExt(filename); - String path = synergy::string::sprintf( - "%s\\%s", dir.c_str(), filename.c_str()); - - LOG((CLOG_DEBUG "loading plugin: %s", filename.c_str())); - HINSTANCE handle = LoadLibrary(path.c_str()); - void* voidHandle = reinterpret_cast(handle); - - if (handle == NULL) { - String error = XArchEvalWindows().eval(); - LOG((CLOG_ERR "failed to load plugin '%s', error: %s", - filename.c_str(), error.c_str())); - continue; - } - - String expectedVersion = getExpectedPluginVersion(name.c_str()); - String currentVersion = getCurrentVersion(name.c_str(), voidHandle); - - if (currentVersion.empty() || (expectedVersion != currentVersion)) { - LOG((CLOG_ERR - "failed to load plugin '%s', " - "expected version %s but was %s", - filename.c_str(), - expectedVersion.c_str(), - currentVersion.empty() ? "unknown" : currentVersion.c_str())); - - FreeLibrary(handle); - continue; - } - - LOG((CLOG_DEBUG "plugin loaded: %s (version %s)", - filename.c_str(), - currentVersion.c_str())); - - m_pluginTable.insert(std::make_pair(name, voidHandle)); - } -} - -void -ArchPluginWindows::unload() -{ - PluginTable::iterator it; - HINSTANCE lib; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - lib = reinterpret_cast(it->second); - cleanupFunc cleanup = (cleanupFunc)GetProcAddress(lib, "cleanup"); - if (cleanup != NULL) { - cleanup(); - } - else { - LOG((CLOG_DEBUG "no cleanup function in %s", it->first.c_str())); - } - - LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str())); - FreeLibrary(lib); - } -} - -void -ArchPluginWindows::init(void* log, void* arch) -{ - PluginTable::iterator it; - HINSTANCE lib; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - lib = reinterpret_cast(it->second); - initFunc initPlugin = (initFunc)GetProcAddress(lib, "init"); - if (initPlugin != NULL) { - initPlugin(log, arch); - } - else { - LOG((CLOG_DEBUG "no init function in %s", it->first.c_str())); - } - } -} - -void -ArchPluginWindows::initEvent(void* eventTarget, IEventQueue* events) -{ - g_eventTarget = eventTarget; - g_events = events; - - PluginTable::iterator it; - HINSTANCE lib; - for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { - lib = reinterpret_cast(it->second); - initEventFunc initEventPlugin = (initEventFunc)GetProcAddress(lib, "initEvent"); - if (initEventPlugin != NULL) { - initEventPlugin(&sendEvent); - } - else { - LOG((CLOG_DEBUG "no init event function in %s", it->first.c_str())); - } - } -} - - -bool -ArchPluginWindows::exists(const char* name) -{ - PluginTable::iterator it; - it = m_pluginTable.find(name); - return it != m_pluginTable.end() ? true : false; -} - -void* -ArchPluginWindows::invoke( - const char* plugin, - const char* command, - void** args, - void* library) -{ - HINSTANCE lib = NULL; - - if (library == NULL) { - PluginTable::iterator it; - it = m_pluginTable.find(plugin); - if (it != m_pluginTable.end()) { - lib = reinterpret_cast(it->second); - } - else { - LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", - plugin, command)); - return NULL; - } - } - else { - lib = reinterpret_cast(library); - } - - invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke"); - void* result = NULL; - if (invokePlugin != NULL) { - result = invokePlugin(command, args); - } - else { - LOG((CLOG_DEBUG "no invoke function in %s", plugin)); - } - - return result; -} - -void -ArchPluginWindows::getFilenames(const String& pattern, std::vector& filenames) -{ - WIN32_FIND_DATA data; - HANDLE find = FindFirstFile(pattern.c_str(), &data); - if (find == INVALID_HANDLE_VALUE) { - FindClose(find); - LOG((CLOG_DEBUG "plugins dir is empty: %s", pattern.c_str())); - return; - } - - do { - filenames.push_back(data.cFileName); - } while (FindNextFile(find, &data)); - - FindClose(find); -} - -String -ArchPluginWindows::getPluginsDir() -{ - return ARCH->getPluginDirectory(); -} - -String -ArchPluginWindows::getCurrentVersion(const String& name, void* handle) -{ - char* version = (char*)invoke(name.c_str(), "version", NULL, handle); - if (version == NULL) { - return ""; - } - - return version; -} - - -void -sendEvent(const char* eventName, void* data) -{ - LOG((CLOG_DEBUG5 "plugin sending event")); - Event::Type type = g_events->getRegisteredType(eventName); - g_events->addEvent(Event(type, g_eventTarget, data)); -} - -void -log(const char* text) -{ - LOG((CLOG_DEBUG "plugin: %s", text)); -} diff --git a/src/lib/arch/win32/ArchPluginWindows.h b/src/lib/arch/win32/ArchPluginWindows.h deleted file mode 100644 index dc61ead98..000000000 --- a/src/lib/arch/win32/ArchPluginWindows.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "arch/IArchPlugin.h" - -#include - -#define ARCH_PLUGIN ArchPluginWindows - -class Screen; -class IEventQueue; - -//! Windows implementation of IArchPlugin -class ArchPluginWindows : public IArchPlugin { -public: - ArchPluginWindows(); - virtual ~ArchPluginWindows(); - - // IArchPlugin overrides - void load(); - void unload(); - void init(void* log, void* arch); - void initEvent(void* eventTarget, IEventQueue* events); - bool exists(const char* name); - void* invoke(const char* pluginName, - const char* functionName, - void** args, - void* library = NULL); - -private: - void getFilenames(const String& pattern, std::vector& filenames); - String getPluginsDir(); - String getCurrentVersion(const String& name, void* handle); - -private: - PluginTable m_pluginTable; -}; - -void sendEvent(const char* text, void* data); -void log(const char* text); diff --git a/src/lib/arch/win32/ArchTaskBarWindows.cpp b/src/lib/arch/win32/ArchTaskBarWindows.cpp index e4154ab25..f87a595b0 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.cpp +++ b/src/lib/arch/win32/ArchTaskBarWindows.cpp @@ -245,7 +245,7 @@ ArchTaskBarWindows::modifyIconNoLock( receiver->lock(); // get icon data - HICON icon = reinterpret_cast( + HICON icon = static_cast( const_cast(receiver->getIcon())); // get tool tip @@ -415,16 +415,15 @@ ArchTaskBarWindows::staticWndProc(HWND hwnd, UINT msg, if (msg == WM_NCCREATE) { CREATESTRUCT* createInfo; createInfo = reinterpret_cast(lParam); - self = reinterpret_cast( + self = static_cast( createInfo->lpCreateParams); - SetWindowLong(hwnd, 0, reinterpret_cast(self)); + SetWindowLongPtr(hwnd, 0, reinterpret_cast(createInfo->lpCreateParams)); } else { // get the extra window data and forward the call - LONG data = GetWindowLong(hwnd, 0); + LONG_PTR data = GetWindowLongPtr(hwnd, 0); if (data != 0) { - self = reinterpret_cast( - reinterpret_cast(data)); + self = static_cast(reinterpret_cast(data)); } } @@ -444,6 +443,7 @@ ArchTaskBarWindows::threadMainLoop() m_taskBarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); // register a window class + LPCTSTR className = TEXT("SynergyTaskBar"); WNDCLASSEX classInfo; classInfo.cbSize = sizeof(classInfo); classInfo.style = CS_NOCLOSE; @@ -455,20 +455,20 @@ ArchTaskBarWindows::threadMainLoop() classInfo.hCursor = NULL; classInfo.hbrBackground = NULL; classInfo.lpszMenuName = NULL; - classInfo.lpszClassName = TEXT("SynergyTaskBar"); + classInfo.lpszClassName = className; classInfo.hIconSm = NULL; ATOM windowClass = RegisterClassEx(&classInfo); // create window m_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, - reinterpret_cast(windowClass), + className, TEXT("Synergy Task Bar"), WS_POPUP, 0, 0, 1, 1, NULL, NULL, instanceWin32(), - reinterpret_cast(this)); + static_cast(this)); // signal ready ARCH->lockMutex(m_mutex); @@ -478,7 +478,7 @@ ArchTaskBarWindows::threadMainLoop() // handle failure if (m_hwnd == NULL) { - UnregisterClass(reinterpret_cast(windowClass), instanceWin32()); + UnregisterClass(className, instanceWin32()); return; } @@ -494,13 +494,13 @@ ArchTaskBarWindows::threadMainLoop() // clean up removeAllIcons(); DestroyWindow(m_hwnd); - UnregisterClass(reinterpret_cast(windowClass), instanceWin32()); + UnregisterClass(className, instanceWin32()); } void* ArchTaskBarWindows::threadEntry(void* self) { - reinterpret_cast(self)->threadMainLoop(); + static_cast(self)->threadMainLoop(); return NULL; } diff --git a/src/lib/arch/win32/ArchTimeWindows.cpp b/src/lib/arch/win32/ArchTimeWindows.cpp index ef3f9ef83..cf48c2a20 100644 --- a/src/lib/arch/win32/ArchTimeWindows.cpp +++ b/src/lib/arch/win32/ArchTimeWindows.cpp @@ -65,7 +65,7 @@ ArchTimeWindows::~ArchTimeWindows() { s_freq = 0.0; if (s_mmInstance == NULL) { - FreeLibrary(reinterpret_cast(s_mmInstance)); + FreeLibrary(static_cast(s_mmInstance)); s_tgt = NULL; s_mmInstance = NULL; } diff --git a/src/lib/base/EventQueue.cpp b/src/lib/base/EventQueue.cpp index 60a163177..5f15293fa 100644 --- a/src/lib/base/EventQueue.cpp +++ b/src/lib/base/EventQueue.cpp @@ -54,7 +54,7 @@ static void interrupt(Arch::ESignal, void* data) { - EventQueue* events = reinterpret_cast(data); + EventQueue* events = static_cast(data); events->addEvent(Event(Event::kQuit)); } diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 748c8cb7c..e0ef9e8b7 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -18,7 +18,6 @@ #include "client/Client.h" -#include "../plugin/ns/SecureSocket.h" #include "client/ServerProxy.h" #include "synergy/Screen.h" #include "synergy/FileChunk.h" @@ -33,12 +32,12 @@ #include "net/TCPSocket.h" #include "net/IDataSocket.h" #include "net/ISocketFactory.h" +#include "net/SecureSocket.h" #include "arch/Arch.h" #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" -#include "common/PluginVersion.h" #include "common/stdexcept.h" #include @@ -72,7 +71,7 @@ Client::Client( m_sendFileThread(NULL), m_writeToDropDirThread(NULL), m_socket(NULL), - m_useSecureNetwork(false), + m_useSecureNetwork(args.m_enableCrypto), m_args(args), m_enableClipboard(true) { @@ -99,13 +98,6 @@ Client::Client( new TMethodEventJob(this, &Client::handleFileRecieveCompleted)); } - - if (m_args.m_enableCrypto) { - m_useSecureNetwork = ARCH->plugin().exists(s_pluginNames[kSecureSocket]); - if (m_useSecureNetwork == false) { - LOG((CLOG_NOTE "crypto disabled because of ns plugin not available")); - } - } } Client::~Client() @@ -160,8 +152,7 @@ Client::connect() // filter socket messages, including a packetizing filter m_stream = socket; - bool adopt = !m_useSecureNetwork; - m_stream = new PacketStreamFilter(m_events, m_stream, adopt); + m_stream = new PacketStreamFilter(m_events, m_stream, true); // connect LOG((CLOG_DEBUG1 "connecting to server")); @@ -439,7 +430,7 @@ Client::sendConnectionFailedEvent(const char* msg) void Client::sendFileChunk(const void* data) { - FileChunk* chunk = reinterpret_cast(const_cast(data)); + FileChunk* chunk = static_cast(const_cast(data)); LOG((CLOG_DEBUG1 "send file chunk")); assert(m_server != NULL); @@ -593,13 +584,6 @@ Client::cleanupStream() { delete m_stream; m_stream = NULL; - - // PacketStreamFilter doen't adopt secure socket, because - // we need to tell the dynamic lib that allocated this object - // to do the deletion. - if (m_useSecureNetwork) { - ARCH->plugin().invoke(s_pluginNames[kSecureSocket], "deleteSocket", NULL); - } } void @@ -621,7 +605,7 @@ void Client::handleConnectionFailed(const Event& event, void*) { IDataSocket::ConnectionFailedInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); cleanupTimer(); cleanupConnecting(); @@ -677,7 +661,7 @@ Client::handleClipboardGrabbed(const Event& event, void*) } const IScreen::ClipboardInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); // grab ownership m_server->onGrabClipboard(info->m_id); @@ -826,14 +810,14 @@ Client::sendFileToServer(const char* filename) m_sendFileThread = new Thread( new TMethodJob( this, &Client::sendFileThread, - reinterpret_cast(const_cast(filename)))); + static_cast(const_cast(filename)))); } void Client::sendFileThread(void* filename) { try { - char* name = reinterpret_cast(filename); + char* name = static_cast(filename); StreamChunker::sendFile(name, m_events, this); } catch (std::runtime_error error) { diff --git a/src/lib/common/PluginVersion.cpp b/src/lib/common/PluginVersion.cpp deleted file mode 100644 index 4ccacead1..000000000 --- a/src/lib/common/PluginVersion.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 "PluginVersion.h" - -#include - -static const char kUnknownVersion[] = "unknown"; -const char* s_pluginNames[] = { "ns" }; -static const char* s_pluginVersions[] = { "1.3" }; - -const char* getExpectedPluginVersion(const char* name) -{ - for (int i = 0; i < kPluginCount; i++) { - if (strcmp(name, s_pluginNames[i]) == 0) { - return s_pluginVersions[i]; - break; - } - } - - return kUnknownVersion; -} diff --git a/src/lib/common/PluginVersion.h b/src/lib/common/PluginVersion.h deleted file mode 100644 index b2f6bae2c..000000000 --- a/src/lib/common/PluginVersion.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * 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 LICENSE 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 - -enum EPluginType { - kSecureSocket, - kPluginCount -}; - -extern const char* s_pluginNames[]; - -//! Get expected plugin version -/*! -Returns the plugin version expected by the plugin loader. -*/ -const char* getExpectedPluginVersion(const char* name); diff --git a/src/lib/io/StreamBuffer.cpp b/src/lib/io/StreamBuffer.cpp index 050adae18..80903ada9 100644 --- a/src/lib/io/StreamBuffer.cpp +++ b/src/lib/io/StreamBuffer.cpp @@ -59,7 +59,7 @@ StreamBuffer::peek(UInt32 n) scan = m_chunks.erase(scan); } - return reinterpret_cast(&(head->begin()[m_headUsed])); + return static_cast(&(head->begin()[m_headUsed])); } void @@ -104,7 +104,7 @@ StreamBuffer::write(const void* vdata, UInt32 n) m_size += n; // cast data to bytes - const UInt8* data = reinterpret_cast(vdata); + const UInt8* data = static_cast(vdata); // point to last chunk if it has space, otherwise append an empty chunk ChunkList::iterator scan = m_chunks.end(); diff --git a/src/lib/io/StreamFilter.cpp b/src/lib/io/StreamFilter.cpp index eb66b9735..468aff847 100644 --- a/src/lib/io/StreamFilter.cpp +++ b/src/lib/io/StreamFilter.cpp @@ -83,7 +83,7 @@ StreamFilter::shutdownOutput() void* StreamFilter::getEventTarget() const { - return const_cast(reinterpret_cast(this)); + return const_cast(static_cast(this)); } bool diff --git a/src/lib/ipc/IpcClientProxy.cpp b/src/lib/ipc/IpcClientProxy.cpp index 8c912a837..5ede6a054 100644 --- a/src/lib/ipc/IpcClientProxy.cpp +++ b/src/lib/ipc/IpcClientProxy.cpp @@ -146,7 +146,7 @@ IpcClientProxy::send(const IpcMessage& message) switch (message.type()) { case kIpcLogLine: { const IpcLogLineMessage& llm = static_cast(message); - String logLine = llm.logLine(); + const String logLine = llm.logLine(); ProtocolUtil::writef(&m_stream, kIpcMsgLogLine, &logLine); break; } diff --git a/src/lib/ipc/IpcServerProxy.cpp b/src/lib/ipc/IpcServerProxy.cpp index 90e87478c..39379f527 100644 --- a/src/lib/ipc/IpcServerProxy.cpp +++ b/src/lib/ipc/IpcServerProxy.cpp @@ -94,7 +94,7 @@ IpcServerProxy::send(const IpcMessage& message) case kIpcCommand: { const IpcCommandMessage& cm = static_cast(message); - String command = cm.command(); + const String command = cm.command(); ProtocolUtil::writef(&m_stream, kIpcMsgCommand, &command); break; } diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp index 0c67e8a99..752aace85 100644 --- a/src/lib/mt/Thread.cpp +++ b/src/lib/mt/Thread.cpp @@ -147,7 +147,7 @@ Thread::threadFunc(void* vjob) } // get job - IJob* job = reinterpret_cast(vjob); + IJob* job = static_cast(vjob); // run job void* result = NULL; diff --git a/src/lib/net/CMakeLists.txt b/src/lib/net/CMakeLists.txt index ee50fe364..10e2cae1e 100644 --- a/src/lib/net/CMakeLists.txt +++ b/src/lib/net/CMakeLists.txt @@ -23,6 +23,7 @@ endif() include_directories( ../ + ${OPENSSL_INCLUDE} ) if (UNIX) @@ -33,6 +34,23 @@ endif() add_library(net STATIC ${sources}) +if (WIN32) + add_custom_command( + TARGET net + POST_BUILD + COMMAND xcopy /Y /Q + ..\\..\\..\\..\\ext\\${OPENSSL_PLAT_DIR}\\out32dll\\libeay32.* + ..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR} + ) + add_custom_command( + TARGET net + POST_BUILD + COMMAND xcopy /Y /Q + ..\\..\\..\\..\\ext\\${OPENSSL_PLAT_DIR}\\out32dll\\ssleay32.* + ..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR} + ) +endif() + if (UNIX) - target_link_libraries(net mt io) + target_link_libraries(net mt io ${OPENSSL_LIBS}) endif() diff --git a/src/lib/net/IListenSocket.h b/src/lib/net/IListenSocket.h index 905ec831f..2cd6fb1bb 100644 --- a/src/lib/net/IListenSocket.h +++ b/src/lib/net/IListenSocket.h @@ -41,14 +41,7 @@ class IListenSocket : public ISocket { */ virtual IDataSocket* accept() = 0; - - //! Delete connection socket - /*! - This is used when the socket was created but not adopted by a client - proxy. - */ - virtual void deleteSocket(void*) = 0; - + //@} // ISocket overrides diff --git a/src/lib/plugin/ns/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp similarity index 91% rename from src/lib/plugin/ns/SecureListenSocket.cpp rename to src/lib/net/SecureListenSocket.cpp index b4c08646e..533ae41a4 100644 --- a/src/lib/plugin/ns/SecureListenSocket.cpp +++ b/src/lib/net/SecureListenSocket.cpp @@ -93,14 +93,3 @@ SecureListenSocket::accept() throw ex; } } - -void -SecureListenSocket::deleteSocket(void* socket) -{ - SecureSocketSet::iterator it; - it = m_secureSocketSet.find((IDataSocket*)socket); - if (it != m_secureSocketSet.end()) { - delete *it; - m_secureSocketSet.erase(it); - } -} diff --git a/src/lib/plugin/ns/SecureListenSocket.h b/src/lib/net/SecureListenSocket.h similarity index 97% rename from src/lib/plugin/ns/SecureListenSocket.h rename to src/lib/net/SecureListenSocket.h index ff19602c4..960a8a263 100644 --- a/src/lib/plugin/ns/SecureListenSocket.h +++ b/src/lib/net/SecureListenSocket.h @@ -33,7 +33,6 @@ class SecureListenSocket : public TCPListenSocket{ // IListenSocket overrides virtual IDataSocket* accept(); - void deleteSocket(void*); private: typedef std::set SecureSocketSet; diff --git a/src/lib/plugin/ns/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp similarity index 100% rename from src/lib/plugin/ns/SecureSocket.cpp rename to src/lib/net/SecureSocket.cpp diff --git a/src/lib/plugin/ns/SecureSocket.h b/src/lib/net/SecureSocket.h similarity index 100% rename from src/lib/plugin/ns/SecureSocket.h rename to src/lib/net/SecureSocket.h diff --git a/src/lib/net/SocketMultiplexer.cpp b/src/lib/net/SocketMultiplexer.cpp index 9ba352a67..bab76b206 100644 --- a/src/lib/net/SocketMultiplexer.cpp +++ b/src/lib/net/SocketMultiplexer.cpp @@ -46,6 +46,7 @@ SocketMultiplexer::SocketMultiplexer() : // this pointer just has to be unique and not NULL. it will // never be dereferenced. it's used to identify cursor nodes // in the jobs list. + // TODO: Remove this evilness m_cursorMark = reinterpret_cast(this); // start thread diff --git a/src/lib/net/TCPListenSocket.cpp b/src/lib/net/TCPListenSocket.cpp index 94760d534..2b20c1249 100644 --- a/src/lib/net/TCPListenSocket.cpp +++ b/src/lib/net/TCPListenSocket.cpp @@ -102,7 +102,7 @@ TCPListenSocket::close() void* TCPListenSocket::getEventTarget() const { - return const_cast(reinterpret_cast(this)); + return const_cast(static_cast(this)); } IDataSocket* diff --git a/src/lib/net/TCPListenSocket.h b/src/lib/net/TCPListenSocket.h index cf4469a0d..413086228 100644 --- a/src/lib/net/TCPListenSocket.h +++ b/src/lib/net/TCPListenSocket.h @@ -43,7 +43,6 @@ class TCPListenSocket : public IListenSocket { // IListenSocket overrides virtual IDataSocket* accept(); - virtual void deleteSocket(void*) { } protected: void setListeningJob(); diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp index ce2cdd099..680e49e57 100644 --- a/src/lib/net/TCPSocket.cpp +++ b/src/lib/net/TCPSocket.cpp @@ -125,7 +125,7 @@ TCPSocket::close() void* TCPSocket::getEventTarget() const { - return const_cast(reinterpret_cast(this)); + return const_cast(static_cast(this)); } UInt32 diff --git a/src/lib/net/TCPSocketFactory.cpp b/src/lib/net/TCPSocketFactory.cpp index 9f8dc0290..e205a9fa2 100644 --- a/src/lib/net/TCPSocketFactory.cpp +++ b/src/lib/net/TCPSocketFactory.cpp @@ -17,11 +17,11 @@ */ #include "net/TCPSocketFactory.h" - #include "net/TCPSocket.h" #include "net/TCPListenSocket.h" +#include "net/SecureSocket.h" +#include "net/SecureListenSocket.h" #include "arch/Arch.h" -#include "common/PluginVersion.h" #include "base/Log.h" // @@ -43,20 +43,14 @@ TCPSocketFactory::~TCPSocketFactory() IDataSocket* TCPSocketFactory::create(bool secure) const { - IDataSocket* socket = NULL; if (secure) { - void* args[2] = { - m_events, - m_socketMultiplexer - }; - socket = static_cast( - ARCH->plugin().invoke(s_pluginNames[kSecureSocket], "getSocket", args)); + SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer); + secureSocket->initSsl (false); + return secureSocket; } else { - socket = new TCPSocket(m_events, m_socketMultiplexer); + return new TCPSocket(m_events, m_socketMultiplexer); } - - return socket; } IListenSocket* @@ -64,12 +58,7 @@ TCPSocketFactory::createListen(bool secure) const { IListenSocket* socket = NULL; if (secure) { - void* args[2] = { - m_events, - m_socketMultiplexer - }; - socket = static_cast( - ARCH->plugin().invoke(s_pluginNames[kSecureSocket], "getListenSocket", args)); + socket = new SecureListenSocket(m_events, m_socketMultiplexer); } else { socket = new TCPListenSocket(m_events, m_socketMultiplexer); diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt index 6c272c214..481d8ef95 100644 --- a/src/lib/platform/CMakeLists.txt +++ b/src/lib/platform/CMakeLists.txt @@ -19,7 +19,7 @@ if (WIN32) file(GLOB sources "MSWindows*.cpp") elseif (APPLE) file(GLOB headers "OSX*.h" "IOSX*.h") - file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m") + file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m" "OSX*.mm") elseif (UNIX) file(GLOB headers "XWindows*.h") file(GLOB sources "XWindows*.cpp") diff --git a/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp b/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp index c78bd3c49..d1676bb0d 100644 --- a/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp +++ b/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp @@ -71,21 +71,21 @@ String MSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const { // get datator - const char* src = (const char*)GlobalLock(data); + LPVOID src = GlobalLock(data); if (src == NULL) { return String(); } UInt32 srcSize = (UInt32)GlobalSize(data); // check image type - const BITMAPINFO* bitmap = reinterpret_cast(src); + const BITMAPINFO* bitmap = static_cast(src); LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount)); if (bitmap->bmiHeader.biPlanes == 1 && (bitmap->bmiHeader.biBitCount == 24 || bitmap->bmiHeader.biBitCount == 32) && bitmap->bmiHeader.biCompression == BI_RGB) { // already in canonical form - String image(src, srcSize); + String image(static_cast(src), srcSize); GlobalUnlock(data); return image; } diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index cb1ed9e98..a5cf4e624 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -656,7 +656,7 @@ MSWindowsDesks::deskThread(void* vdesk) MSG msg; // use given desktop for this thread - Desk* desk = reinterpret_cast(vdesk); + Desk* desk = static_cast(vdesk); desk->m_threadID = GetCurrentThreadId(); desk->m_window = NULL; desk->m_foregroundWindow = NULL; diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index 9c4e729a7..4e093bd35 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -61,11 +61,11 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x012 */ { kKeyAlt_L }, // VK_MENU /* 0x013 */ { kKeyPause }, // VK_PAUSE /* 0x014 */ { kKeyCapsLock }, // VK_CAPITAL - /* 0x015 */ { kKeyHangulKana }, // VK_HANGUL, VK_KANA + /* 0x015 */ { kKeyKana }, // VK_HANGUL, VK_KANA /* 0x016 */ { kKeyNone }, // undefined /* 0x017 */ { kKeyNone }, // VK_JUNJA /* 0x018 */ { kKeyNone }, // VK_FINAL - /* 0x019 */ { kKeyHanjaKanzi }, // VK_KANJI + /* 0x019 */ { kKeyKanzi }, // VK_HANJA, VK_KANJI /* 0x01a */ { kKeyNone }, // undefined /* 0x01b */ { kKeyEscape }, // VK_ESCAPE /* 0x01c */ { kKeyHenkan }, // VK_CONVERT @@ -318,11 +318,11 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x112 */ { kKeyAlt_R }, // VK_MENU /* 0x113 */ { kKeyNone }, // VK_PAUSE /* 0x114 */ { kKeyNone }, // VK_CAPITAL - /* 0x115 */ { kKeyNone }, // VK_KANA - /* 0x116 */ { kKeyNone }, // VK_HANGUL + /* 0x115 */ { kKeyHangul }, // VK_HANGUL + /* 0x116 */ { kKeyNone }, // undefined /* 0x117 */ { kKeyNone }, // VK_JUNJA /* 0x118 */ { kKeyNone }, // VK_FINAL - /* 0x119 */ { kKeyNone }, // VK_KANJI + /* 0x119 */ { kKeyHanja }, // VK_HANJA /* 0x11a */ { kKeyNone }, // undefined /* 0x11b */ { kKeyNone }, // VK_ESCAPE /* 0x11c */ { kKeyNone }, // VK_CONVERT @@ -728,6 +728,10 @@ MSWindowsKeyState::mapKeyFromEvent(WPARAM charAndVirtKey, // that so we clear it. active &= ~s_controlAlt; } + if (id == kKeyHangul) { + // If shift-space is used to change input mode, clear shift modifier. + active &= ~KeyModifierShift; + } *maskOut = active; } @@ -1071,13 +1075,8 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) } } - // add alt+printscreen - if (m_buttonToVK[0x54u] == 0) { - m_buttonToVK[0x54u] = VK_SNAPSHOT; - } - // set virtual key to button table - if (GetKeyboardLayout(0) == m_groups[g]) { + if (activeLayout == m_groups[g]) { for (KeyButton i = 0; i < 512; ++i) { if (m_buttonToVK[i] != 0) { if (m_virtualKeyToButton[m_buttonToVK[i]] == 0) { @@ -1339,8 +1338,20 @@ MSWindowsKeyState::setWindowGroup(SInt32 group) } KeyID -MSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button) +MSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button) const { + // Some virtual keycodes have same values. + // VK_HANGUL == VK_KANA, VK_HANJA == NK_KANJI + // which are used to change the input mode of IME. + // But they have different X11 keysym. So we should distinguish them. + if ((LOWORD(m_keyLayout) & 0xffffu) == 0x0412u) { // 0x0412 : Korean Locale ID + if (virtualKey == VK_HANGUL || virtualKey == VK_HANJA) { + // If shift-space is used to change the input mode, + // the extented bit is not set. So add it to get right key id. + button |= 0x100u; + } + } + if ((button & 0x100u) != 0) { virtualKey += 0x100u; } @@ -1392,3 +1403,4 @@ MSWindowsKeyState::addKeyEntry(synergy::KeyMap& keyMap, synergy::KeyMap::KeyItem m_keyToVKMap[item.m_id] = static_cast(item.m_client); } } + diff --git a/src/lib/platform/MSWindowsKeyState.h b/src/lib/platform/MSWindowsKeyState.h index 4313f741a..fcbd5d98b 100644 --- a/src/lib/platform/MSWindowsKeyState.h +++ b/src/lib/platform/MSWindowsKeyState.h @@ -122,7 +122,7 @@ class MSWindowsKeyState : public KeyState { (button should include the extended key bit), or kKeyNone if there is no such key. */ - static KeyID getKeyID(UINT virtualKey, KeyButton button); + KeyID getKeyID(UINT virtualKey, KeyButton button) const; //! Map button to virtual key /*! diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index de0c7c268..defe2b821 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -31,7 +31,6 @@ #include "synergy/App.h" #include "synergy/ArgsBase.h" #include "synergy/ClientApp.h" -#include "synergy/DpiHelper.h" #include "mt/Lock.h" #include "mt/Thread.h" #include "arch/win32/ArchMiscWindows.h" @@ -145,10 +144,6 @@ MSWindowsScreen::MSWindowsScreen( stopOnDeskSwitch); m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events); - DpiHelper::calculateDpi( - GetSystemMetrics(SM_CXVIRTUALSCREEN), - GetSystemMetrics(SM_CYVIRTUALSCREEN)); - updateScreenShape(); m_class = createWindowClass(); m_window = createWindow(m_class, "Synergy"); @@ -347,8 +342,7 @@ MSWindowsScreen::leave() // warp to center LOG((CLOG_DEBUG1 "warping cursor to center: %+d, %+d", m_xCenter, m_yCenter)); - float dpi = DpiHelper::getDpi(); - warpCursor(m_xCenter / dpi, m_yCenter / dpi); + warpCursor(m_xCenter, m_yCenter); // disable special key sequences on win95 family enableSpecialKeys(false); @@ -941,7 +935,7 @@ MSWindowsScreen::sendClipboardEvent(Event::Type type, ClipboardID id) void MSWindowsScreen::handleSystemEvent(const Event& event, void*) { - MSG* msg = reinterpret_cast(event.getData()); + MSG* msg = static_cast(event.getData()); assert(msg != NULL); if (ArchMiscWindows::processDialog(msg)) { @@ -1353,14 +1347,6 @@ MSWindowsScreen::onMouseButton(WPARAM wParam, LPARAM lParam) bool MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) { - SInt32 originalMX = mx; - SInt32 originalMY = my; - - if (DpiHelper::s_dpiScaled) { - mx = (SInt32)(mx / DpiHelper::getDpi()); - my = (SInt32)(my / DpiHelper::getDpi()); - } - // compute motion delta (relative to the last known // mouse position) SInt32 x = mx - m_xCursor; @@ -1384,7 +1370,7 @@ MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) // motion on primary screen sendEvent( m_events->forIPrimaryScreen().motionOnPrimary(), - MotionInfo::alloc(originalMX, originalMY)); + MotionInfo::alloc(m_xCursor, m_yCursor)); if (m_buttons[kButtonLeft] == true && m_draggingStarted == false) { m_draggingStarted = true; @@ -1397,8 +1383,7 @@ MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) // will always try to return to the original entry point on the // secondary screen. LOG((CLOG_DEBUG5 "warping server cursor to center: %+d,%+d", m_xCenter, m_yCenter)); - float dpi = DpiHelper::getDpi(); - warpCursorNoFlush(m_xCenter / dpi, m_yCenter / dpi); + warpCursorNoFlush(m_xCenter, m_yCenter); // examine the motion. if it's about the distance // from the center of the screen to an edge then @@ -1406,10 +1391,10 @@ MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) // ignore (see warpCursorNoFlush() for a further // description). static SInt32 bogusZoneSize = 10; - if (-x + bogusZoneSize > (m_xCenter - m_x) / dpi || - x + bogusZoneSize > (m_x + m_w - m_xCenter) / dpi || - -y + bogusZoneSize > (m_yCenter - m_y) / dpi || - y + bogusZoneSize > (m_y + m_h - m_yCenter) / dpi) { + if (-x + bogusZoneSize > m_xCenter - m_x || + x + bogusZoneSize > m_x + m_w - m_xCenter || + -y + bogusZoneSize > m_yCenter - m_y || + y + bogusZoneSize > m_y + m_h - m_yCenter) { LOG((CLOG_DEBUG "dropped bogus delta motion: %+d,%+d", x, y)); } @@ -1603,26 +1588,13 @@ void MSWindowsScreen::updateScreenShape() { // get shape and center - if (DpiHelper::s_dpiScaled) { - // use the original resolution size for width and height - m_w = (SInt32)DpiHelper::s_resolutionWidth; - m_h = (SInt32)DpiHelper::s_resolutionHeight; - - // calculate center position according to the original size - m_xCenter = (SInt32)DpiHelper::s_primaryWidthCenter; - m_yCenter = (SInt32)DpiHelper::s_primaryHeightCenter; - } - else { - m_w = GetSystemMetrics(SM_CXVIRTUALSCREEN); - m_h = GetSystemMetrics(SM_CYVIRTUALSCREEN); - - m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1; - m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1; - } - - // get position + m_w = GetSystemMetrics(SM_CXVIRTUALSCREEN); + m_h = GetSystemMetrics(SM_CYVIRTUALSCREEN); m_x = GetSystemMetrics(SM_XVIRTUALSCREEN); m_y = GetSystemMetrics(SM_YVIRTUALSCREEN); + m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1; + m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1; + // check for multiple monitors m_multimon = (m_w != GetSystemMetrics(SM_CXSCREEN) || m_h != GetSystemMetrics(SM_CYSCREEN)); diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index 7e734f85c..b1ae0f944 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -215,7 +215,7 @@ class MSWindowsScreen : public PlatformScreen { // save last position of mouse to compute next delta movement void saveMousePosition(SInt32 x, SInt32 y); - + // check if it is a modifier key repeating message bool isModifierRepeat(KeyModifierMask oldState, KeyModifierMask state, WPARAM wParam) const; diff --git a/src/lib/platform/OSXClipboard.cpp b/src/lib/platform/OSXClipboard.cpp index 84f7c7cec..7dae20816 100644 --- a/src/lib/platform/OSXClipboard.cpp +++ b/src/lib/platform/OSXClipboard.cpp @@ -122,7 +122,7 @@ OSXClipboard::add(EFormat format, const String & data) PasteboardPutItemFlavor( m_pboard, - (PasteboardItemID) 0, + nullptr, flavorType, dataRef, kPasteboardFlavorNoFlags); diff --git a/src/lib/platform/OSXKeyState.cpp b/src/lib/platform/OSXKeyState.cpp index 2071621bf..8ab0bc89a 100644 --- a/src/lib/platform/OSXKeyState.cpp +++ b/src/lib/platform/OSXKeyState.cpp @@ -23,6 +23,7 @@ #include "base/Log.h" #include +#include // Note that some virtual keys codes appear more than once. The // first instance of a virtual key code maps to the KeyID that we @@ -469,6 +470,105 @@ OSXKeyState::getKeyMap(synergy::KeyMap& keyMap) } } +static io_connect_t getEventDriver(void) +{ + static mach_port_t sEventDrvrRef = 0; + mach_port_t masterPort, service, iter; + kern_return_t kr; + + if (!sEventDrvrRef) { + // Get master device port + kr = IOMasterPort(bootstrap_port, &masterPort); + assert(KERN_SUCCESS == kr); + + kr = IOServiceGetMatchingServices(masterPort, + IOServiceMatching(kIOHIDSystemClass), &iter); + assert(KERN_SUCCESS == kr); + + service = IOIteratorNext(iter); + assert(service); + + kr = IOServiceOpen(service, mach_task_self(), + kIOHIDParamConnectType, &sEventDrvrRef); + assert(KERN_SUCCESS == kr); + + IOObjectRelease(service); + IOObjectRelease(iter); + } + + return sEventDrvrRef; +} + +void +OSXKeyState::postHIDVirtualKey(const UInt8 virtualKeyCode, + const bool postDown) +{ + static UInt32 modifiers = 0; + + NXEventData event; + IOGPoint loc = { 0, 0 }; + UInt32 modifiersDelta = 0; + + bzero(&event, sizeof(NXEventData)); + + switch (virtualKeyCode) + { + case s_shiftVK: + case s_superVK: + case s_altVK: + case s_controlVK: + case s_capsLockVK: + switch (virtualKeyCode) + { + case s_shiftVK: + modifiersDelta = NX_SHIFTMASK; + m_shiftPressed = postDown; + break; + case s_superVK: + modifiersDelta = NX_COMMANDMASK; + m_superPressed = postDown; + break; + case s_altVK: + modifiersDelta = NX_ALTERNATEMASK; + m_altPressed = postDown; + break; + case s_controlVK: + modifiersDelta = NX_CONTROLMASK; + m_controlPressed = postDown; + break; + case s_capsLockVK: + modifiersDelta = NX_ALPHASHIFTMASK; + m_capsPressed = postDown; + break; + } + + // update the modifier bit + if (postDown) { + modifiers |= modifiersDelta; + } + else { + modifiers &= ~modifiersDelta; + } + + kern_return_t kr; + kr = IOHIDPostEvent(getEventDriver(), NX_FLAGSCHANGED, loc, + &event, kNXEventDataVersion, modifiers, true); + assert(KERN_SUCCESS == kr); + break; + + default: + event.key.repeat = false; + event.key.keyCode = virtualKeyCode; + event.key.origCharSet = event.key.charSet = NX_ASCIISET; + event.key.origCharCode = event.key.charCode = 0; + kr = IOHIDPostEvent(getEventDriver(), + postDown ? NX_KEYDOWN : NX_KEYUP, + loc, &event, kNXEventDataVersion, 0, false); + assert(KERN_SUCCESS == kr); + break; + } +} + void OSXKeyState::fakeKey(const Keystroke& keystroke) { @@ -477,76 +577,14 @@ OSXKeyState::fakeKey(const Keystroke& keystroke) KeyButton button = keystroke.m_data.m_button.m_button; bool keyDown = keystroke.m_data.m_button.m_press; - UInt32 client = keystroke.m_data.m_button.m_client; - CGEventSourceRef source = 0; CGKeyCode virtualKey = mapKeyButtonToVirtualKey(button); LOG((CLOG_DEBUG1 - " button=0x%04x virtualKey=0x%04x keyDown=%s client=0x%04x", - button, virtualKey, keyDown ? "down" : "up", client)); + " button=0x%04x virtualKey=0x%04x keyDown=%s", + button, virtualKey, keyDown ? "down" : "up")); - CGEventRef ref = CGEventCreateKeyboardEvent( - source, virtualKey, keyDown); - - if (ref == NULL) { - LOG((CLOG_CRIT "unable to create keyboard event for keystroke")); - return; - } - - // persist modifier state. - if (virtualKey == s_shiftVK) { - m_shiftPressed = keyDown; - } - - if (virtualKey == s_controlVK) { - m_controlPressed = keyDown; - } - - if (virtualKey == s_altVK) { - m_altPressed = keyDown; - } - - if (virtualKey == s_superVK) { - m_superPressed = keyDown; - } - - if (virtualKey == s_capsLockVK) { - m_capsPressed = keyDown; - } + postHIDVirtualKey(virtualKey, keyDown); - // set the event flags for special keys - // http://tinyurl.com/pxl742y - CGEventFlags modifiers = 0; - - if (m_shiftPressed) { - modifiers |= kCGEventFlagMaskShift; - } - - if (m_controlPressed) { - modifiers |= kCGEventFlagMaskControl; - } - - if (m_altPressed) { - modifiers |= kCGEventFlagMaskAlternate; - } - - if (m_superPressed) { - modifiers |= kCGEventFlagMaskCommand; - } - - if (m_capsPressed) { - modifiers |= kCGEventFlagMaskAlphaShift; - } - - CGEventSetFlags(ref, modifiers); - CGEventPost(kCGHIDEventTap, ref); - CFRelease(ref); - - // add a delay if client data isn't zero - // FIXME -- why? - if (client != 0) { - ARCH->sleep(0.01); - } break; } diff --git a/src/lib/platform/OSXKeyState.h b/src/lib/platform/OSXKeyState.h index 00dbb5518..a3e16315f 100644 --- a/src/lib/platform/OSXKeyState.h +++ b/src/lib/platform/OSXKeyState.h @@ -149,6 +149,12 @@ class OSXKeyState : public KeyState { static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton); void init(); + + // Post a key event to HID manager. It posts an event to HID client, a + // much lower level than window manager which's the target from carbon + // CGEventPost + void postHIDVirtualKey(const UInt8 virtualKeyCode, + const bool postDown); private: // OS X uses a physical key if 0 for the 'A' key. synergy reserves diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index dce5ac088..0357583e7 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -344,4 +344,6 @@ class OSXScreen : public PlatformScreen { Mutex* m_carbonLoopMutex; CondVar* m_carbonLoopReady; #endif + + class OSXScreenImpl* m_impl; }; diff --git a/src/lib/platform/OSXScreen.cpp b/src/lib/platform/OSXScreen.mm similarity index 98% rename from src/lib/platform/OSXScreen.cpp rename to src/lib/platform/OSXScreen.mm index 7ca761385..992144e44 100644 --- a/src/lib/platform/OSXScreen.cpp +++ b/src/lib/platform/OSXScreen.mm @@ -45,6 +45,8 @@ #include #include +#import + // Set some enums for fast user switching if we're building with an SDK // from before such support was added. #if !defined(MAC_OS_X_VERSION_10_3) || \ @@ -112,7 +114,8 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso m_lastSingleClickYCursor(0), m_autoShowHideCursor(autoShowHideCursor), m_events(events), - m_getDropTargetThread(NULL) + m_getDropTargetThread(NULL), + m_impl(NULL) { try { m_displayID = CGMainDisplayID(); @@ -493,7 +496,23 @@ OSXScreen::postMouseEvent(CGPoint& pos) const // Fix for sticky keys CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags(); CGEventSetFlags(event, modifiers); - + + // Set movement deltas to fix issues with certain 3D programs + SInt64 deltaX = pos.x; + deltaX -= m_xCursor; + + SInt64 deltaY = pos.y; + deltaY -= m_yCursor; + + CGEventSetIntegerValueField(event, kCGMouseEventDeltaX, deltaX); + CGEventSetIntegerValueField(event, kCGMouseEventDeltaY, deltaY); + + double deltaFX = deltaX; + double deltaFY = deltaY; + + CGEventSetDoubleValueField(event, kCGMouseEventDeltaX, deltaFX); + CGEventSetDoubleValueField(event, kCGMouseEventDeltaY, deltaFY); + CGEventPost(kCGHIDEventTap, event); CFRelease(event); @@ -526,9 +545,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) // we define our own defaults. const double maxDiff = sqrt(2) + 0.0001; - - NXEventHandle handle = NXOpenEventStatus(); - double clickTime = NXClickTime(handle); + double clickTime = [NSEvent doubleClickInterval]; // As long as the click is within the time window and distance window // increase clickState (double click, triple click, etc) @@ -986,7 +1003,7 @@ OSXScreen::sendClipboardEvent(Event::Type type, ClipboardID id) const void OSXScreen::handleSystemEvent(const Event& event, void*) { - EventRef* carbonEvent = reinterpret_cast(event.getData()); + EventRef* carbonEvent = static_cast(event.getData()); assert(carbonEvent != NULL); UInt32 eventClass = GetEventClass(*carbonEvent); diff --git a/src/lib/platform/OSXUchrKeyResource.cpp b/src/lib/platform/OSXUchrKeyResource.cpp index 7c362d709..603ba04a9 100644 --- a/src/lib/platform/OSXUchrKeyResource.cpp +++ b/src/lib/platform/OSXUchrKeyResource.cpp @@ -31,7 +31,7 @@ OSXUchrKeyResource::OSXUchrKeyResource(const void* resource, m_sri(NULL), m_st(NULL) { - m_resource = reinterpret_cast(resource); + m_resource = static_cast(resource); if (m_resource == NULL) { return; } @@ -56,7 +56,7 @@ OSXUchrKeyResource::OSXUchrKeyResource(const void* resource, } // get tables for keyboard type - const UInt8* base = reinterpret_cast(m_resource); + const UInt8* const base = reinterpret_cast(m_resource); m_m = reinterpret_cast(base + th->keyModifiersToTableNumOffset); m_cti = reinterpret_cast(base + @@ -134,7 +134,7 @@ OSXUchrKeyResource::getKey(UInt32 table, UInt32 button) const assert(table < getNumTables()); assert(button < getNumButtons()); - const UInt8* base = reinterpret_cast(m_resource); + const UInt8* const base = reinterpret_cast(m_resource); const UCKeyOutput* cPtr = reinterpret_cast(base + m_cti->keyToCharTableOffsets[table]); @@ -211,7 +211,7 @@ bool OSXUchrKeyResource::getKeyRecord( KeySequence& keys, UInt16 index, UInt16& state) const { - const UInt8* base = reinterpret_cast(m_resource); + const UInt8* const base = reinterpret_cast(m_resource); const UCKeyStateRecord* sr = reinterpret_cast(base + m_sri->keyStateRecordOffsets[index]); diff --git a/src/lib/platform/XWindowsClipboard.cpp b/src/lib/platform/XWindowsClipboard.cpp index 6aa3a4cb8..f30cc2c96 100644 --- a/src/lib/platform/XWindowsClipboard.cpp +++ b/src/lib/platform/XWindowsClipboard.cpp @@ -31,6 +31,7 @@ #include "common/stdvector.h" #include +#include #include // @@ -516,7 +517,7 @@ XWindowsClipboard::icccmFillCache() } XWindowsUtil::convertAtomProperty(data); - const Atom* targets = reinterpret_cast(data.data()); + const Atom* targets = reinterpret_cast(data.data()); // TODO: Safe? const UInt32 numTargets = data.size() / sizeof(Atom); LOG((CLOG_DEBUG " available targets: %s", XWindowsUtil::atomsToString(m_display, targets, numTargets).c_str())); @@ -671,11 +672,11 @@ XWindowsClipboard::motifOwnsClipboard() const } // check the owner window against the current clipboard owner - const MotifClipHeader* header = - reinterpret_cast(data.data()); - if (data.size() >= sizeof(MotifClipHeader) && - header->m_id == kMotifClipHeader) { - if (static_cast(header->m_selectionOwner) == owner) { + if (data.size() >= sizeof(MotifClipHeader)) { + MotifClipHeader header; + std::memcpy (&header, data.data(), sizeof(header)); + if ((header.m_id == kMotifClipHeader) && + (static_cast(header.m_selectionOwner) == owner)) { return true; } } @@ -699,18 +700,18 @@ XWindowsClipboard::motifFillCache() return; } - // check that the header is okay - const MotifClipHeader* header = - reinterpret_cast(data.data()); - if (data.size() < sizeof(MotifClipHeader) || - header->m_id != kMotifClipHeader || - header->m_numItems < 1) { + MotifClipHeader header; + if (data.size() < sizeof(header)) { // check that the header is okay + return; + } + std::memcpy (&header, data.data(), sizeof(header)); + if (header.m_id != kMotifClipHeader || header.m_numItems < 1) { return; } // get the Motif item property from the root window char name[18 + 20]; - sprintf(name, "_MOTIF_CLIP_ITEM_%d", header->m_item); + sprintf(name, "_MOTIF_CLIP_ITEM_%d", header.m_item); Atom atomItem = XInternAtom(m_display, name, False); data = ""; if (!XWindowsUtil::getWindowProperty(m_display, root, @@ -719,19 +720,20 @@ XWindowsClipboard::motifFillCache() return; } - // check that the item is okay - const MotifClipItem* item = - reinterpret_cast(data.data()); - if (data.size() < sizeof(MotifClipItem) || - item->m_id != kMotifClipItem || - item->m_numFormats - item->m_numDeletedFormats < 1) { + MotifClipItem item; + if (data.size() < sizeof(item)) { // check that the item is okay + return; + } + std::memcpy (&item, data.data(), sizeof(item)); + if (item.m_id != kMotifClipItem || + item.m_numFormats - item.m_numDeletedFormats < 1) { return; } // format list is after static item structure elements - const SInt32 numFormats = item->m_numFormats - item->m_numDeletedFormats; - const SInt32* formats = reinterpret_cast(item->m_size + - reinterpret_cast(data.data())); + const SInt32 numFormats = item.m_numFormats - item.m_numDeletedFormats; + const SInt32* formats = reinterpret_cast(item.m_size + + static_cast(data.data())); // get the available formats typedef std::map MotifFormatMap; @@ -748,18 +750,20 @@ XWindowsClipboard::motifFillCache() } // check that the format is okay - const MotifClipFormat* motifFormat = - reinterpret_cast(data.data()); - if (data.size() < sizeof(MotifClipFormat) || - motifFormat->m_id != kMotifClipFormat || - motifFormat->m_length < 0 || - motifFormat->m_type == None || - motifFormat->m_deleted != 0) { + MotifClipFormat motifFormat; + if (data.size() < sizeof(motifFormat)) { + continue; + } + std::memcpy (&motifFormat, data.data(), sizeof(motifFormat)); + if (motifFormat.m_id != kMotifClipFormat || + motifFormat.m_length < 0 || + motifFormat.m_type == None || + motifFormat.m_deleted != 0) { continue; } // save it - motifFormats.insert(std::make_pair(motifFormat->m_type, data)); + motifFormats.insert(std::make_pair(motifFormat.m_type, data)); } //const UInt32 numMotifFormats = motifFormats.size(); @@ -782,15 +786,14 @@ XWindowsClipboard::motifFillCache() } // get format - const MotifClipFormat* motifFormat = - reinterpret_cast( - index2->second.data()); - const Atom target = motifFormat->m_type; + MotifClipFormat motifFormat; + std::memcpy (&motifFormat, index2->second.data(), sizeof(motifFormat)); + const Atom target = motifFormat.m_type; // get the data (finally) Atom actualTarget; String targetData; - if (!motifGetSelection(motifFormat, &actualTarget, &targetData)) { + if (!motifGetSelection(&motifFormat, &actualTarget, &targetData)) { LOG((CLOG_DEBUG1 " no data for target %s", XWindowsUtil::atomToString(m_display, target).c_str())); continue; } diff --git a/src/lib/platform/XWindowsKeyState.cpp b/src/lib/platform/XWindowsKeyState.cpp index 6f82d4dfb..f97ef531a 100644 --- a/src/lib/platform/XWindowsKeyState.cpp +++ b/src/lib/platform/XWindowsKeyState.cpp @@ -785,7 +785,7 @@ void XWindowsKeyState::remapKeyModifiers(KeyID id, SInt32 group, synergy::KeyMap::KeyItem& item, void* vself) { - XWindowsKeyState* self = reinterpret_cast(vself); + XWindowsKeyState* self = static_cast(vself); item.m_required = self->mapModifiersFromX(XkbBuildCoreState(item.m_required, group)); item.m_sensitive = diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp index b16e2e516..6a0d72bfc 100644 --- a/src/lib/platform/XWindowsScreen.cpp +++ b/src/lib/platform/XWindowsScreen.cpp @@ -160,15 +160,12 @@ XWindowsScreen::XWindowsScreen( // primary/secondary screen only initialization if (m_isPrimary) { - // start watching for events on other windows - selectEvents(m_root); +#ifdef HAVE_XI2 m_xi2detected = detectXI2(); - if (m_xi2detected) { -#ifdef HAVE_XI2 selectXIRawMotion(); -#endif } else +#endif { // start watching for events on other windows selectEvents(m_root); @@ -745,7 +742,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) LOG((CLOG_WARN "failed to register hotkey %s (id=%04x mask=%04x)", synergy::KeyMap::formatKey(key, mask).c_str(), key, mask)); return 0; } - + LOG((CLOG_DEBUG "registered hotkey %s (id=%04x mask=%04x) as id=%d", synergy::KeyMap::formatKey(key, mask).c_str(), key, mask, id)); return id; } @@ -827,7 +824,7 @@ void XWindowsScreen::fakeMouseButton(ButtonID button, bool press) { const unsigned int xButton = mapButtonToX(button); - if (xButton != 0) { + if (xButton > 0 && xButton < 11) { XTestFakeButtonEvent(m_display, xButton, press ? True : False, CurrentTime); XFlush(m_display); @@ -977,22 +974,6 @@ XWindowsScreen::saveShape() m_w = WidthOfScreen(DefaultScreenOfDisplay(m_display)); m_h = HeightOfScreen(DefaultScreenOfDisplay(m_display)); -#if HAVE_X11_EXTENSIONS_XRANDR_H - if (m_xrandr){ - int numSizes; - XRRScreenSize* xrrs; - Rotation rotation; - xrrs = XRRSizes(m_display, DefaultScreen(m_display), &numSizes); - XRRRotations(m_display, DefaultScreen(m_display), &rotation); - if (xrrs != NULL) { - if (rotation & (RR_Rotate_90|RR_Rotate_270) ){ - m_w = xrrs->height; - m_h = xrrs->width; - } - } - } -#endif - // get center of default screen m_xCenter = m_x + (m_w >> 1); m_yCenter = m_y + (m_h >> 1); @@ -1179,7 +1160,7 @@ XWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg) void XWindowsScreen::handleSystemEvent(const Event& event, void*) { - XEvent* xevent = reinterpret_cast(event.getData()); + XEvent* xevent = static_cast(event.getData()); assert(xevent != NULL); // update key state @@ -1300,7 +1281,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) // handle the event ourself switch (xevent->type) { case CreateNotify: - if (m_isPrimary) { + if (m_isPrimary && !m_xi2detected) { // select events on new window selectEvents(xevent->xcreatewindow.window); } @@ -1442,6 +1423,8 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) XMoveWindow(m_display, m_window, m_x, m_y); XResizeWindow(m_display, m_window, m_w, m_h); } + + sendEvent(m_events->forIScreen().shapeChanged()); } } #endif diff --git a/src/lib/platform/XWindowsUtil.cpp b/src/lib/platform/XWindowsUtil.cpp index 6103cced8..10b35096a 100644 --- a/src/lib/platform/XWindowsUtil.cpp +++ b/src/lib/platform/XWindowsUtil.cpp @@ -1386,7 +1386,7 @@ XWindowsUtil::setWindowProperty(Display* display, Window window, Atom type, SInt32 format) { const UInt32 length = 4 * XMaxRequestSize(display); - const unsigned char* data = reinterpret_cast(vdata); + const unsigned char* data = static_cast(vdata); UInt32 datumSize = static_cast(format / 8); // format 32 on 64bit systems is 8 bytes not 4. if (format == 32) { @@ -1784,5 +1784,5 @@ void XWindowsUtil::ErrorLock::saveHandler(Display*, XErrorEvent* e, void* flag) { LOG((CLOG_DEBUG1 "flagging X error: %d", e->error_code)); - *reinterpret_cast(flag) = true; + *static_cast(flag) = true; } diff --git a/src/lib/plugin/CMakeLists.txt b/src/lib/plugin/CMakeLists.txt deleted file mode 100644 index 237da9896..000000000 --- a/src/lib/plugin/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# synergy -- mouse and keyboard sharing utility -# Copyright (C) 2012-2016 Symless Ltd. -# Copyright (C) 2012 Nick Bolton -# -# 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 LICENSE 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) - add_subdirectory(winmmjoy) -endif() - -if (APPLE) - # 10.7 should be supported, but gives is a _NXArgv linker error - if (OSX_TARGET_MINOR GREATER 7) - add_subdirectory(ns) - endif() -else() - add_subdirectory(ns) -endif() diff --git a/src/lib/plugin/ns/CMakeLists.txt b/src/lib/plugin/ns/CMakeLists.txt deleted file mode 100644 index 80b567412..000000000 --- a/src/lib/plugin/ns/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ -# synergy -- mouse and keyboard sharing utility -# Copyright (C) 2015-2016 Symless Ltd. -# -# 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 LICENSE 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 . - -file(GLOB headers "*.h") -file(GLOB sources "*.cpp") - -if (SYNERGY_ADD_HEADERS) - list(APPEND sources ${headers}) -endif() - -if (WIN32) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(OPENSSL_PLAT_DIR openssl-win64) - else() - set(OPENSSL_PLAT_DIR openssl-win32) - endif() - set(OPENSSL_INCLUDE ../../../../ext/${OPENSSL_PLAT_DIR}/inc32) -endif() - -if (APPLE) - set(OPENSSL_PLAT_DIR openssl-osx) - set(OPENSSL_INCLUDE ../../../../ext/${OPENSSL_PLAT_DIR}/include) -endif() - -include_directories( - ../../../lib/ - ../../../.. - ${OPENSSL_INCLUDE} -) - -add_library(ns SHARED ${sources}) - -if (WIN32) - set(OPENSSL_LIBS - ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/out32dll/libeay32.lib - ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/out32dll/ssleay32.lib - ) -endif() - -if (UNIX) - if (APPLE) - set(OPENSSL_LIBS - ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/libssl.a - ${CMAKE_SOURCE_DIR}/ext/${OPENSSL_PLAT_DIR}/libcrypto.a - ) - else() - set(OPENSSL_LIBS ssl crypto) - endif() -endif() - -target_link_libraries(ns - arch base client common io mt net ipc platform server synergy ${libs} ${OPENSSL_LIBS}) - -if (WIN32) - add_custom_command( - TARGET ns - POST_BUILD - COMMAND xcopy /Y /Q - ..\\..\\..\\..\\..\\lib\\${CMAKE_CFG_INTDIR}\\ns.* - ..\\..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\ - ) - add_custom_command( - TARGET ns - POST_BUILD - COMMAND xcopy /Y /Q - ..\\..\\..\\..\\..\\ext\\${OPENSSL_PLAT_DIR}\\out32dll\\libeay32.* - ..\\..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR} - ) - add_custom_command( - TARGET ns - POST_BUILD - COMMAND xcopy /Y /Q - ..\\..\\..\\..\\..\\ext\\${OPENSSL_PLAT_DIR}\\out32dll\\ssleay32.* - ..\\..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR} - ) -endif() - -if (UNIX) - if (APPLE) - add_custom_command( - TARGET ns - POST_BUILD - COMMAND - mkdir -p - ${CMAKE_SOURCE_DIR}/bin/${CMAKE_CFG_INTDIR}/plugins - && - cp - ${CMAKE_SOURCE_DIR}/lib/${CMAKE_CFG_INTDIR}/libns.* - ${CMAKE_SOURCE_DIR}/bin/${CMAKE_CFG_INTDIR}/plugins/ - ) - else() - if (CMAKE_BUILD_TYPE STREQUAL Debug) - add_custom_command( - TARGET ns - POST_BUILD - COMMAND mkdir -p - ${CMAKE_SOURCE_DIR}/bin/debug/plugins - && - cp - ${CMAKE_SOURCE_DIR}/lib/debug/libns.* - ${CMAKE_SOURCE_DIR}/bin/debug/plugins/ - ) - else() - add_custom_command( - TARGET ns - POST_BUILD - COMMAND mkdir -p - ${CMAKE_SOURCE_DIR}/bin/plugins - && - cp - ${CMAKE_SOURCE_DIR}/lib/libns.* - ${CMAKE_SOURCE_DIR}/bin/plugins/ - ) - endif() - endif() -endif() diff --git a/src/lib/plugin/ns/ns.cpp b/src/lib/plugin/ns/ns.cpp deleted file mode 100644 index 17ba322ff..000000000 --- a/src/lib/plugin/ns/ns.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd - * - * 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 LICENSE 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 "ns.h" - -#include "SecureSocket.h" -#include "SecureListenSocket.h" -#include "arch/Arch.h" -#include "common/PluginVersion.h" -#include "base/Log.h" - -#include -#include -#include -#include - -SecureSocket* g_secureSocket = NULL; -SecureListenSocket* g_secureListenSocket = NULL; -Arch* g_arch = NULL; -Log* g_log = NULL; - -std::string -helperGetLibsUsed(void) -{ - std::stringstream libs(ARCH->getLibsUsed()); - std::string msg; - std::string pid; - std::getline(libs,pid); - - while( std::getline(libs,msg) ) { - LOG(( CLOG_DEBUG "libs:%s",msg.c_str())); - } - return pid; -} - -extern "C" { -void -init(void* log, void* arch) -{ - if (g_log == NULL) { - g_log = new Log(reinterpret_cast(log)); - } - - if (g_arch == NULL) { - Arch::setInstance(reinterpret_cast(arch)); - } - - LOG(( CLOG_DEBUG "library use: %s", helperGetLibsUsed().c_str())); -} - -int -initEvent(void (*sendEvent)(const char*, void*)) -{ - return 0; -} - -void* -invoke(const char* command, void** args) -{ - IEventQueue* arg1 = NULL; - SocketMultiplexer* arg2 = NULL; - if (args != NULL) { - arg1 = reinterpret_cast(args[0]); - arg2 = reinterpret_cast(args[1]); - } - - if (strcmp(command, "getSocket") == 0) { - if (g_secureSocket != NULL) { - delete g_secureSocket; - } - g_secureSocket = new SecureSocket(arg1, arg2); - g_secureSocket->initSsl(false); - return g_secureSocket; - } - else if (strcmp(command, "getListenSocket") == 0) { - if (g_secureListenSocket != NULL) { - delete g_secureListenSocket; - } - g_secureListenSocket = new SecureListenSocket(arg1, arg2); - return g_secureListenSocket; - } - else if (strcmp(command, "deleteSocket") == 0) { - if (g_secureSocket != NULL) { - delete g_secureSocket; - g_secureSocket = NULL; - } - } - else if (strcmp(command, "deleteListenSocket") == 0) { - if (g_secureListenSocket != NULL) { - delete g_secureListenSocket; - g_secureListenSocket = NULL; - } - } - else if (strcmp(command, "version") == 0) { - return (void*)getExpectedPluginVersion(s_pluginNames[kSecureSocket]); - } - - return NULL; -} - -void -cleanup() -{ - if (g_secureSocket != NULL) { - delete g_secureSocket; - } - - if (g_secureListenSocket != NULL) { - delete g_secureListenSocket; - } -} - -} diff --git a/src/lib/plugin/ns/ns.h b/src/lib/plugin/ns/ns.h deleted file mode 100644 index 39999110b..000000000 --- a/src/lib/plugin/ns/ns.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd - * - * 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 LICENSE 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 - -#if defined _WIN32 -#define WIN32_LEAN_AND_MEAN -#include - -#if defined(ns_EXPORTS) -#define NS_API __declspec(dllexport) -#else -#define NS_API __declspec(dllimport) -#endif - -#else -#define NS_API -#endif - -extern "C" { - -NS_API void init(void* log, void* arch); -NS_API int initEvent(void (*sendEvent)(const char*, void*)); -NS_API void* invoke(const char* command, void** args); -NS_API void cleanup(); - -} diff --git a/src/lib/plugin/winmmjoy/winmmjoy.cpp b/src/lib/plugin/winmmjoy/winmmjoy.cpp deleted file mode 100644 index d6306e82d..000000000 --- a/src/lib/plugin/winmmjoy/winmmjoy.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 "winmmjoy.h" - -#include -#include -#include - -#pragma comment(lib, "winmm.lib") - -std::stringstream _logStream; -#define LOG(s) \ - _logStream.str(""); \ - _logStream << "winmmjoy: " << s << std::endl; \ - s_log(_logStream.str().c_str()) - -static bool s_running = true; -static void (*s_sendEvent)(const char*, void*) = NULL; -static void (*s_log)(const char*) = NULL; - -extern "C" { - -void -init(void* log, void* arch) -{ -} - -int -initEvent(void (*sendEvent)(const char*, void*)) -{ - s_sendEvent = sendEvent; - CreateThread(NULL, 0, mainLoop, NULL, 0, NULL); - return 0; -} - -void -cleanup() -{ - s_running = false; -} - -} - -DWORD WINAPI -mainLoop(void* data) -{ - // TODO: use a different message - e.g. DPLG%s (data - plugin) - const char* buttonsEvent = "IPrimaryScreen::getGameDeviceButtonsEvent"; - const char* sticksEvent = "IPrimaryScreen::getGameDeviceSticksEvent"; - const char* triggersEvent = "IPrimaryScreen::getGameDeviceTriggersEvent"; - - JOYINFOEX joyInfo; - ZeroMemory(&joyInfo, sizeof(joyInfo)); - joyInfo.dwSize = sizeof(joyInfo); - joyInfo.dwFlags = JOY_RETURNALL; - - // note: synergy data is often 16-bit, where winmm is 32-bit. - UINT index = JOYSTICKID1; - DWORD buttons, buttonsLast = 0; - DWORD xPos, xPosLast = 0; - DWORD yPos, yPosLast = 0; - - while (s_running) { - - if (joyGetPosEx(index, &joyInfo) != JOYERR_NOERROR) { - Sleep(1000); - continue; - } - - buttons = joyInfo.dwButtons; - xPos = joyInfo.dwXpos; - yPos = joyInfo.dwYpos; - - if (buttons != buttonsLast) { - s_sendEvent(buttonsEvent, - new CGameDeviceButtonInfo(index, (GameDeviceButton)joyInfo.dwButtons)); - } - - if (xPos != xPosLast || yPos != yPosLast) { - s_sendEvent(sticksEvent, - new CGameDeviceStickInfo(index, (short)xPos, (short)yPos, 0, 0)); - } - - buttonsLast = buttons; - xPosLast = xPos; - yPosLast = yPos; - Sleep(1); - } - return 0; -} diff --git a/src/lib/plugin/winmmjoy/winmmjoy.h b/src/lib/plugin/winmmjoy/winmmjoy.h deleted file mode 100644 index 712bd6d99..000000000 --- a/src/lib/plugin/winmmjoy/winmmjoy.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2012 Nick Bolton - * - * 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 LICENSE 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 - -#define WIN32_LEAN_AND_MEAN -#include - -#if defined(winmmjoy_EXPORTS) -#define WINMMJOY_API __declspec(dllexport) -#else -#define WINMMJOY_API __declspec(dllimport) -#endif - -extern "C" { - -WINMMJOY_API void init(void* log, void* arch); -WINMMJOY_API int initEvent(void (*sendEvent)(const char*, void*)); -WINMMJOY_API void cleanup(); - -} - -DWORD WINAPI mainLoop(void* data); - -typedef unsigned char GameDeviceID; -typedef unsigned short GameDeviceButton; - -class CGameDeviceButtonInfo { -public: - CGameDeviceButtonInfo(GameDeviceID id, GameDeviceButton buttons) : - m_id(id), m_buttons(buttons) { } -public: - GameDeviceID m_id; - GameDeviceButton m_buttons; -}; - -class CGameDeviceStickInfo { -public: - CGameDeviceStickInfo(GameDeviceID id, short x1, short y1, short x2, short y2) : - m_id(id), m_x1(x1), m_x2(x2), m_y1(y1), m_y2(y2) { } -public: - GameDeviceID m_id; - short m_x1; - short m_x2; - short m_y1; - short m_y2; -}; - -class CGameDeviceTriggerInfo { -public: - CGameDeviceTriggerInfo(GameDeviceID id, unsigned char t1, unsigned char t2) : - m_id(id), m_t1(t1), m_t2(t2) { } -public: - GameDeviceID m_id; - unsigned char m_t1; - unsigned char m_t2; -}; diff --git a/src/lib/server/CMakeLists.txt b/src/lib/server/CMakeLists.txt index 2c34af078..3cb582ec0 100644 --- a/src/lib/server/CMakeLists.txt +++ b/src/lib/server/CMakeLists.txt @@ -35,6 +35,8 @@ endif() add_library(server STATIC ${sources}) +target_link_libraries(server shared) + if (UNIX) target_link_libraries(server synergy) endif() diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index cf64bc307..a8bef7cfa 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -25,7 +25,6 @@ #include "net/IListenSocket.h" #include "net/ISocketFactory.h" #include "net/XSocket.h" -#include "common/PluginVersion.h" #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" @@ -41,19 +40,11 @@ ClientListener::ClientListener(const NetworkAddress& address, m_socketFactory(socketFactory), m_server(NULL), m_events(events), - m_useSecureNetwork(false) + m_useSecureNetwork(enableCrypto) { assert(m_socketFactory != NULL); try { - // create listen socket - if (enableCrypto) { - m_useSecureNetwork = ARCH->plugin().exists(s_pluginNames[kSecureSocket]); - if (m_useSecureNetwork == false) { - LOG((CLOG_NOTE "crypto disabled because of ns plugin not available")); - } - } - m_listen = m_socketFactory->createListen(m_useSecureNetwork); // setup event handler @@ -115,12 +106,6 @@ ClientListener::setServer(Server* server) m_server = server; } -void -ClientListener::deleteSocket(void* socket) -{ - m_listen->deleteSocket(socket); -} - ClientProxy* ClientListener::getNextClient() { @@ -164,8 +149,7 @@ ClientListener::handleClientAccepted(const Event&, void* vsocket) IDataSocket* socket = static_cast(vsocket); // filter socket messages, including a packetizing filter - bool adopt = !m_useSecureNetwork; - synergy::IStream* stream = new PacketStreamFilter(m_events, socket, adopt); + synergy::IStream* stream = new PacketStreamFilter(m_events, socket, true); assert(m_server != NULL); // create proxy for unknown client @@ -188,7 +172,7 @@ void ClientListener::handleUnknownClient(const Event&, void* vclient) { ClientProxyUnknown* unknownClient = - reinterpret_cast(vclient); + static_cast(vclient); // we should have the client in our new client list assert(m_newClients.count(unknownClient) == 1); @@ -223,16 +207,12 @@ ClientListener::handleUnknownClient(const Event&, void* vclient) } delete unknownClient; - - if (m_useSecureNetwork && !handshakeOk) { - deleteSocket(socket); - } } void ClientListener::handleClientDisconnected(const Event&, void* vclient) { - ClientProxy* client = reinterpret_cast(vclient); + ClientProxy* client = static_cast(vclient); // find client in waiting clients queue for (WaitingClients::iterator i = m_waitingClients.begin(), @@ -250,13 +230,5 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient) void ClientListener::cleanupListenSocket() { - if (!m_useSecureNetwork) { - delete m_listen; - } - else { - ARCH->plugin().invoke( - s_pluginNames[kSecureSocket], - "deleteListenSocket", - NULL); - } + delete m_listen; } diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h index 7674386ce..545e163a3 100644 --- a/src/lib/server/ClientListener.h +++ b/src/lib/server/ClientListener.h @@ -48,8 +48,6 @@ class ClientListener { //@} - void deleteSocket(void* socket); - //! @name accessors //@{ diff --git a/src/lib/server/Config.cpp b/src/lib/server/Config.cpp index dac8f58ea..e50cf1d2e 100644 --- a/src/lib/server/Config.cpp +++ b/src/lib/server/Config.cpp @@ -2096,11 +2096,11 @@ ConfigReadContext::parseInterval(const ArgList& args) const } char* end; - long startValue = strtol(args[0].c_str(), &end, 10); + double startValue = strtod(args[0].c_str(), &end); if (end[0] != '\0') { throw XConfigRead(*this, "invalid interval \"%{1}\"", concatArgs(args)); } - long endValue = strtol(args[1].c_str(), &end, 10); + double endValue = strtod(args[1].c_str(), &end); if (end[0] != '\0') { throw XConfigRead(*this, "invalid interval \"%{1}\"", concatArgs(args)); } diff --git a/src/lib/server/InputFilter.cpp b/src/lib/server/InputFilter.cpp index f03786a7b..0ab2fcaa6 100644 --- a/src/lib/server/InputFilter.cpp +++ b/src/lib/server/InputFilter.cpp @@ -121,7 +121,7 @@ InputFilter::KeystrokeCondition::match(const Event& event) // check if it's our hotkey IPrimaryScreen::HotKeyInfo* kinfo = - reinterpret_cast(event.getData()); + static_cast(event.getData()); if (kinfo->m_id != m_id) { return kNoMatch; } @@ -217,7 +217,7 @@ InputFilter::MouseButtonCondition::match(const Event& event) // check if it's the right button and modifiers. ignore modifiers // that cannot be combined with a mouse button. IPlatformScreen::ButtonInfo* minfo = - reinterpret_cast(event.getData()); + static_cast(event.getData()); if (minfo->m_button != m_button || (minfo->m_mask & ~s_ignoreMask) != m_mask) { return kNoMatch; @@ -256,7 +256,7 @@ InputFilter::ScreenConnectedCondition::match(const Event& event) { if (event.getType() == m_events->forServer().connected()) { Server::ScreenConnectedInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); if (m_screen == info->m_screen || m_screen.empty()) { return kActivate; } @@ -357,7 +357,7 @@ InputFilter::SwitchToScreenAction::perform(const Event& event) String screen = m_screen; if (screen.empty() && event.getType() == m_events->forServer().connected()) { Server::ScreenConnectedInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); screen = info->m_screen; } diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index b0ff56fc6..fd90f5f3a 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -2,11 +2,11 @@ * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * 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 LICENSE 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 @@ -33,7 +33,6 @@ #include "synergy/KeyState.h" #include "synergy/Screen.h" #include "synergy/PacketStreamFilter.h" -#include "synergy/DpiHelper.h" #include "net/TCPSocket.h" #include "net/IDataSocket.h" #include "net/IListenSocket.h" @@ -45,11 +44,13 @@ #include "base/Log.h" #include "base/TMethodEventJob.h" #include "common/stdexcept.h" +#include "shared/SerialKey.h" #include #include #include #include +#include // // Server @@ -60,7 +61,7 @@ Server::Server( PrimaryClient* primaryClient, synergy::Screen* screen, IEventQueue* events, - bool enableDragDrop) : + ServerArgs const& args) : m_mock(false), m_primaryClient(primaryClient), m_active(primaryClient), @@ -91,10 +92,10 @@ Server::Server( m_sendFileThread(NULL), m_writeToDropDirThread(NULL), m_ignoreFileTransfer(false), - m_enableDragDrop(enableDragDrop), m_enableClipboard(true), m_sendDragInfoThread(NULL), - m_waitDragInfoThread(true) + m_waitDragInfoThread(true), + m_args(args) { // must have a primary client and it must have a canonical name assert(m_primaryClient != NULL); @@ -184,7 +185,7 @@ Server::Server( new TMethodEventJob(this, &Server::handleFakeInputEndEvent)); - if (m_enableDragDrop) { + if (m_args.m_enableDragDrop) { m_events->adoptHandler(m_events->forFile().fileChunkSending(), this, new TMethodEventJob(this, @@ -451,6 +452,13 @@ Server::switchScreen(BaseClientProxy* dst, SInt32 x, SInt32 y, bool forScreensaver) { assert(dst != NULL); + + // if trial is expired, exit the process + if (m_args.m_serial.isExpired(std::time(0))) { + LOG((CLOG_ERR "trial has expired, aborting server")); + exit(kExitSuccess); + } + #ifndef NDEBUG { SInt32 dx, dy, dw, dh; @@ -534,7 +542,7 @@ Server::jumpToScreen(BaseClientProxy* newScreen) // get the last cursor position on the target screen SInt32 x, y; newScreen->getJumpCursorPos(x, y); - + switchScreen(newScreen, x, y, false); } @@ -884,14 +892,14 @@ Server::isSwitchOkay(BaseClientProxy* newScreen, if (!preventSwitch && ( (this->m_switchNeedsShift && ((mods & KeyModifierShift) != KeyModifierShift)) || - (this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) || + (this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) || (this->m_switchNeedsAlt && ((mods & KeyModifierAlt) != KeyModifierAlt)) )) { LOG((CLOG_DEBUG1 "need modifiers to switch")); preventSwitch = true; stopSwitch(); - } - + } + return !preventSwitch; } @@ -1171,7 +1179,7 @@ Server::processOptions() } else if (id == kOptionClipboardSharing) { m_enableClipboard = (value != 0); - + if (m_enableClipboard == false) { LOG((CLOG_NOTE "clipboard sharing is disabled")); } @@ -1187,7 +1195,7 @@ void Server::handleShapeChanged(const Event&, void* vclient) { // ignore events from unknown clients - BaseClientProxy* client = reinterpret_cast(vclient); + BaseClientProxy* client = static_cast(vclient); if (m_clientSet.count(client) == 0) { return; } @@ -1224,12 +1232,12 @@ Server::handleClipboardGrabbed(const Event& event, void* vclient) } // ignore events from unknown clients - BaseClientProxy* grabber = reinterpret_cast(vclient); + BaseClientProxy* grabber = static_cast(vclient); if (m_clientSet.count(grabber) == 0) { return; } const IScreen::ClipboardInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); // ignore grab if sequence number is old. always allow primary // screen to grab. @@ -1270,12 +1278,12 @@ void Server::handleClipboardChanged(const Event& event, void* vclient) { // ignore events from unknown clients - BaseClientProxy* sender = reinterpret_cast(vclient); + BaseClientProxy* sender = static_cast(vclient); if (m_clientSet.count(sender) == 0) { return; } const IScreen::ClipboardInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onClipboardChanged(sender, info->m_id, info->m_sequenceNumber); } @@ -1283,7 +1291,7 @@ void Server::handleKeyDownEvent(const Event& event, void*) { IPlatformScreen::KeyInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onKeyDown(info->m_key, info->m_mask, info->m_button, info->m_screens); } @@ -1291,7 +1299,7 @@ void Server::handleKeyUpEvent(const Event& event, void*) { IPlatformScreen::KeyInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onKeyUp(info->m_key, info->m_mask, info->m_button, info->m_screens); } @@ -1299,7 +1307,7 @@ void Server::handleKeyRepeatEvent(const Event& event, void*) { IPlatformScreen::KeyInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onKeyRepeat(info->m_key, info->m_mask, info->m_count, info->m_button); } @@ -1307,7 +1315,7 @@ void Server::handleButtonDownEvent(const Event& event, void*) { IPlatformScreen::ButtonInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onMouseDown(info->m_button); } @@ -1315,7 +1323,7 @@ void Server::handleButtonUpEvent(const Event& event, void*) { IPlatformScreen::ButtonInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onMouseUp(info->m_button); } @@ -1323,7 +1331,7 @@ void Server::handleMotionPrimaryEvent(const Event& event, void*) { IPlatformScreen::MotionInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onMouseMovePrimary(info->m_x, info->m_y); } @@ -1331,7 +1339,7 @@ void Server::handleMotionSecondaryEvent(const Event& event, void*) { IPlatformScreen::MotionInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onMouseMoveSecondary(info->m_x, info->m_y); } @@ -1339,7 +1347,7 @@ void Server::handleWheelEvent(const Event& event, void*) { IPlatformScreen::WheelInfo* info = - reinterpret_cast(event.getData()); + static_cast(event.getData()); onMouseWheel(info->m_xDelta, info->m_yDelta); } @@ -1374,34 +1382,29 @@ Server::handleClientDisconnected(const Event&, void* vclient) { // client has disconnected. it might be an old client or an // active client. we don't care so just handle it both ways. - BaseClientProxy* client = reinterpret_cast(vclient); + BaseClientProxy* client = static_cast(vclient); removeActiveClient(client); removeOldClient(client); - PacketStreamFilter* streamFileter = dynamic_cast(client->getStream()); - TCPSocket* socket = dynamic_cast(streamFileter->getStream()); delete client; - m_clientListener->deleteSocket(socket); } void Server::handleClientCloseTimeout(const Event&, void* vclient) { // client took too long to disconnect. just dump it. - BaseClientProxy* client = reinterpret_cast(vclient); + BaseClientProxy* client = static_cast(vclient); LOG((CLOG_NOTE "forced disconnection of client \"%s\"", getName(client).c_str())); removeOldClient(client); - PacketStreamFilter* streamFileter = dynamic_cast(client->getStream()); - TCPSocket* socket = dynamic_cast(streamFileter->getStream()); + delete client; - m_clientListener->deleteSocket(socket); } void Server::handleSwitchToScreenEvent(const Event& event, void*) { - SwitchToScreenInfo* info = - reinterpret_cast(event.getData()); + SwitchToScreenInfo* info = + static_cast(event.getData()); ClientList::const_iterator index = m_clients.find(info->m_screen); if (index == m_clients.end()) { @@ -1415,8 +1418,8 @@ Server::handleSwitchToScreenEvent(const Event& event, void*) void Server::handleSwitchInDirectionEvent(const Event& event, void*) { - SwitchInDirectionInfo* info = - reinterpret_cast(event.getData()); + SwitchInDirectionInfo* info = + static_cast(event.getData()); // jump to screen in chosen direction from center of this screen SInt32 x = m_x, y = m_y; @@ -1705,8 +1708,8 @@ Server::onMouseUp(ButtonID id) m_ignoreFileTransfer = false; return; } - - if (m_enableDragDrop) { + + if (m_args.m_enableDragDrop) { if (!m_screen->isOnScreen()) { String& file = m_screen->getDraggingFilename(); if (!file.empty()) { @@ -1763,61 +1766,75 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y) } // see if we should change screens - EDirection dir; + // when the cursor is in a corner, there may be a screen either + // horizontally or vertically. check both directions. + EDirection dirh = kNoDirection, dirv = kNoDirection; + SInt32 xh = x, yv = y; if (x < ax + zoneSize) { - x -= zoneSize; - dir = kLeft; + xh -= zoneSize; + dirh = kLeft; } else if (x >= ax + aw - zoneSize) { - x += zoneSize; - dir = kRight; + xh += zoneSize; + dirh = kRight; } - else if (y < ay + zoneSize) { - y -= zoneSize; - dir = kTop; + if (y < ay + zoneSize) { + yv -= zoneSize; + dirv = kTop; } else if (y >= ay + ah - zoneSize) { - y += zoneSize; - dir = kBottom; + yv += zoneSize; + dirv = kBottom; } - else { + if (dirh == kNoDirection && dirv == kNoDirection) { // still on local screen noSwitch(x, y); return false; } - // get jump destination - BaseClientProxy* newScreen = mapToNeighbor(m_active, dir, x, y); + // check both horizontally and vertically + EDirection dirs[] = {dirh, dirv}; + SInt32 xs[] = {xh, x}, ys[] = {y, yv}; + for (int i = 0; i < 2; ++i) { + EDirection dir = dirs[i]; + if (dir == kNoDirection) { + continue; + } + x = xs[i], y = ys[i]; + + // get jump destination + BaseClientProxy* newScreen = mapToNeighbor(m_active, dir, x, y); + + // should we switch or not? + if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { + if (m_args.m_enableDragDrop + && m_screen->isDraggingStarted() + && m_active != newScreen + && m_waitDragInfoThread) { + if (m_sendDragInfoThread == NULL) { + m_sendDragInfoThread = new Thread( + new TMethodJob( + this, + &Server::sendDragInfoThread, newScreen)); + } - // should we switch or not? - if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { - if (m_enableDragDrop - && m_screen->isDraggingStarted() - && m_active != newScreen - && m_waitDragInfoThread) { - if (m_sendDragInfoThread == NULL) { - m_sendDragInfoThread = new Thread( - new TMethodJob( - this, - &Server::sendDragInfoThread, newScreen)); + return false; } - return false; + // switch screen + switchScreen(newScreen, x, y, false); + m_waitDragInfoThread = true; + return true; } - - // switch screen - switchScreen(newScreen, x, y, false); - m_waitDragInfoThread = true; - return true; } - + return false; } void Server::sendDragInfoThread(void* arg) { - BaseClientProxy* newScreen = reinterpret_cast(arg); + BaseClientProxy* newScreen = static_cast(arg); m_dragFileList.clear(); String& dragFileList = m_screen->getDraggingFilename(); @@ -1826,7 +1843,7 @@ Server::sendDragInfoThread(void* arg) di.setFilename(dragFileList); m_dragFileList.push_back(di); } - + #if defined(__APPLE__) // on mac it seems that after faking a LMB up, system would signal back // to synergy a mouse up event, which doesn't happen on windows. as a @@ -1849,7 +1866,7 @@ Server::sendDragInfo(BaseClientProxy* newScreen) { String infoString; UInt32 fileCount = DragInformation::setupDragInfo(m_dragFileList, infoString); - + if (fileCount > 0) { char* info = NULL; size_t size = infoString.size(); @@ -2000,14 +2017,6 @@ Server::onMouseMoveSecondary(SInt32 dx, SInt32 dy) SInt32 newX = m_x; SInt32 newY = m_y; - if (DpiHelper::s_dpiScaled) { - // only scale if it's going back to server - if (newScreen->isPrimary()) { - newX = (SInt32)(newX / DpiHelper::getDpi()); - newY = (SInt32)(newY / DpiHelper::getDpi()); - } - } - // switch screens switchScreen(newScreen, newX, newY, false); } @@ -2053,13 +2062,13 @@ Server::onMouseWheel(SInt32 xDelta, SInt32 yDelta) void Server::onFileChunkSending(const void* data) { - FileChunk* chunk = reinterpret_cast(const_cast(data)); + FileChunk* chunk = static_cast(const_cast(data)); LOG((CLOG_DEBUG1 "sending file chunk")); assert(m_active != NULL); // relay - m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize); + m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize); } void @@ -2368,18 +2377,18 @@ Server::sendFileToClient(const char* filename) if (m_sendFileThread != NULL) { StreamChunker::interruptFile(); } - + m_sendFileThread = new Thread( new TMethodJob( this, &Server::sendFileThread, - reinterpret_cast(const_cast(filename)))); + static_cast(const_cast(filename)))); } void Server::sendFileThread(void* data) { try { - char* filename = reinterpret_cast(data); + char* filename = static_cast(data); LOG((CLOG_DEBUG "sending file to client, filename=%s", filename)); StreamChunker::sendFile(filename, m_events, this); } @@ -2393,7 +2402,7 @@ Server::sendFileThread(void* data) void Server::dragInfoReceived(UInt32 fileNum, String content) { - if (!m_enableDragDrop) { + if (!m_args.m_enableDragDrop) { LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info.")); return; } diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h index 7681487a5..d1e48bd59 100644 --- a/src/lib/server/Server.h +++ b/src/lib/server/Server.h @@ -25,6 +25,7 @@ #include "synergy/mouse_types.h" #include "synergy/INode.h" #include "synergy/DragInformation.h" +#include "synergy/ServerArgs.h" #include "base/Event.h" #include "base/Stopwatch.h" #include "base/EventTypes.h" @@ -106,7 +107,7 @@ class Server : public INode { ownership of \p primaryClient. */ Server(Config& config, PrimaryClient* primaryClient, - synergy::Screen* screen, IEventQueue* events, bool enableDragDrop); + synergy::Screen* screen, IEventQueue* events, ServerArgs const& args); ~Server(); #ifdef TEST_ENV @@ -472,11 +473,11 @@ class Server : public INode { Thread* m_writeToDropDirThread; String m_dragFileExt; bool m_ignoreFileTransfer; - bool m_enableDragDrop; bool m_enableClipboard; Thread* m_sendDragInfoThread; bool m_waitDragInfoThread; ClientListener* m_clientListener; + ServerArgs m_args; }; diff --git a/src/lib/plugin/winmmjoy/CMakeLists.txt b/src/lib/shared/CMakeLists.txt similarity index 71% rename from src/lib/plugin/winmmjoy/CMakeLists.txt rename to src/lib/shared/CMakeLists.txt index b07915bfc..891f4aa78 100644 --- a/src/lib/plugin/winmmjoy/CMakeLists.txt +++ b/src/lib/shared/CMakeLists.txt @@ -1,6 +1,5 @@ # synergy -- mouse and keyboard sharing utility -# Copyright (C) 2012-2016 Symless Ltd. -# Copyright (C) 2012 Nick Bolton +# Copyright (C) 2016 Symless Ltd. # # This package is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -21,12 +20,13 @@ if (SYNERGY_ADD_HEADERS) list(APPEND sources ${headers}) endif() -add_library(winmmjoy SHARED ${sources}) +add_library(shared STATIC ${sources}) -add_custom_command( - TARGET winmmjoy - POST_BUILD - COMMAND xcopy /Y /Q - ..\\..\\..\\..\\..\\lib\\${CMAKE_CFG_INTDIR}\\winmmjoy.* - ..\\..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\ +include_directories( + ../ + ../../../ext + ../../../ext/gtest-1.6.0/include ) + +target_link_libraries(shared arch base) + diff --git a/src/gui/src/EditionType.h b/src/lib/shared/EditionType.h similarity index 86% rename from src/gui/src/EditionType.h rename to src/lib/shared/EditionType.h index d294cda53..66f30aa95 100644 --- a/src/gui/src/EditionType.h +++ b/src/lib/shared/EditionType.h @@ -18,11 +18,13 @@ #ifndef EDITIONTYPE_H #define EDITIONTYPE_H -enum qEditionType { - Basic, - Pro, - Trial, - Unknown +/* Do not reorder these! */ + +enum Edition { + kBasic, + kPro, + Trial_DO_NOT_USE_OR_THERE_WILL_BE_PAIN, + kUnregistered }; #endif // EDITIONTYPE_H diff --git a/src/lib/shared/SerialKey.cpp b/src/lib/shared/SerialKey.cpp new file mode 100644 index 000000000..60a039cbe --- /dev/null +++ b/src/lib/shared/SerialKey.cpp @@ -0,0 +1,264 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2016 Symless Ltd. + * + * 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 LICENSE 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 "SerialKey.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +SerialKey::SerialKey(Edition edition): + m_userLimit(1), + m_warnTime(ULLONG_MAX), + m_expireTime(ULLONG_MAX), + m_edition(edition), + m_trial(false) +{ +} + +SerialKey::SerialKey(std::string serial) : + m_userLimit(1), + m_warnTime(0), + m_expireTime(0), + m_edition(kBasic), + m_trial(true) +{ + string plainText = decode(serial); + bool valid = false; + if (!plainText.empty()) { + valid = parse(plainText); + } + if (!valid) { + throw std::runtime_error ("Invalid serial key"); + } +} + +bool +SerialKey::isExpiring(time_t currentTime) const +{ + bool result = false; + + if (m_trial) { + if (m_warnTime <= currentTime && currentTime < m_expireTime) { + result = true; + } + } + + return result; +} + +bool +SerialKey::isExpired(time_t currentTime) const +{ + bool result = false; + + if (m_trial) { + if (m_expireTime <= currentTime) { + result = true; + } + } + + return result; +} + +bool +SerialKey::isTrial() const +{ + return m_trial; +} + +Edition +SerialKey::edition() const +{ + return m_edition; +} + +std::string +SerialKey::editionString() const +{ + switch (edition()) { + case kBasic: + return "basic"; + case kPro: + return "pro"; + default: { + std::ostringstream oss; + oss << static_cast(edition()); + return oss.str(); + } + } +} + +static std::string +hexEncode (std::string const& str) { + std::ostringstream oss; + for (size_t i = 0; i < str.size(); ++i) { + int c = str[i]; + oss << std::setfill('0') << std::hex << std::setw(2) + << std::uppercase; + oss << c; + } + return oss.str(); +} + +std::string +SerialKey::toString() const +{ + std::ostringstream oss; + oss << "{"; + if (isTrial()) { + oss << "v2;trial;"; + } else { + oss << "v1;"; + } + oss << editionString() << ";"; + oss << m_name << ";"; + oss << m_userLimit << ";"; + oss << m_email << ";"; + oss << m_company << ";"; + oss << (isTrial() ? m_warnTime : 0) << ";"; + oss << (isTrial() ? m_expireTime : 0); + oss << "}"; + return hexEncode(oss.str()); +} + +time_t +SerialKey::daysLeft(time_t currentTime) const +{ + unsigned long long timeLeft = 0; + unsigned long long const day = 60 * 60 * 24; + + if (currentTime < m_expireTime) { + timeLeft = m_expireTime - currentTime; + } + + unsigned long long daysLeft = 0; + daysLeft = timeLeft % day != 0 ? 1 : 0; + + return timeLeft / day + daysLeft; +} + +std::string +SerialKey::email() const +{ + return m_email; +} + +std::string +SerialKey::decode(const std::string& serial) +{ + static const char* const lut = "0123456789ABCDEF"; + string output; + size_t len = serial.length(); + if (len & 1) { + return output; + } + + output.reserve(len / 2); + for (size_t i = 0; i < len; i += 2) { + + char a = serial[i]; + char b = serial[i + 1]; + + const char* p = std::lower_bound(lut, lut + 16, a); + const char* q = std::lower_bound(lut, lut + 16, b); + + if (*q != b || *p != a) { + return output; + } + + output.push_back(static_cast(((p - lut) << 4) | (q - lut))); + } + + return output; +} + +bool +SerialKey::parse(std::string plainSerial) +{ + string parityStart = plainSerial.substr(0, 1); + string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1); + + bool valid = false; + + // check for parity chars { and }, record parity result, then remove them. + if (parityStart == "{" && parityEnd == "}") { + plainSerial = plainSerial.substr(1, plainSerial.length() - 2); + + // tokenize serialised subscription. + vector parts; + std::string::size_type pos = 0; + bool look = true; + while (look) { + std::string::size_type start = pos; + pos = plainSerial.find(";", pos); + if (pos == string::npos) { + pos = plainSerial.length(); + look = false; + } + parts.push_back(plainSerial.substr(start, pos - start)); + pos += 1; + } + + if ((parts.size() == 8) + && (parts.at(0).find("v1") != string::npos)) { + // e.g.: {v1;basic;Bob;1;email;company name;1398297600;1398384000} + m_edition = parseEdition(parts.at(1)); + m_name = parts.at(2); + m_trial = false; + sscanf(parts.at(3).c_str(), "%d", &m_userLimit); + m_email = parts.at(4); + m_company = parts.at(5); + sscanf(parts.at(6).c_str(), "%lld", &m_warnTime); + sscanf(parts.at(7).c_str(), "%lld", &m_expireTime); + valid = true; + } + else if ((parts.size() == 9) + && (parts.at(0).find("v2") != string::npos)) { + // e.g.: {v2;trial;basic;Bob;1;email;company name;1398297600;1398384000} + m_trial = parts.at(1) == "trial" ? true : false; + m_edition = parseEdition(parts.at(2)); + m_name = parts.at(3); + sscanf(parts.at(4).c_str(), "%d", &m_userLimit); + m_email = parts.at(5); + m_company = parts.at(6); + sscanf(parts.at(7).c_str(), "%lld", &m_warnTime); + sscanf(parts.at(8).c_str(), "%lld", &m_expireTime); + valid = true; + } + } + + return valid; +} + +Edition +SerialKey::parseEdition(std::string const& editionStr) +{ + Edition e = kBasic; + if (editionStr == "pro") { + e = kPro; + } + + return e; +} diff --git a/src/lib/shared/SerialKey.h b/src/lib/shared/SerialKey.h new file mode 100644 index 000000000..dd9b71606 --- /dev/null +++ b/src/lib/shared/SerialKey.h @@ -0,0 +1,84 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2016 Symless Ltd. + * + * 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 LICENSE 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 +#include +#include "EditionType.h" + +#ifdef TEST_ENV +#include "gtest/gtest_prod.h" +#endif + +class SerialKey { + friend bool operator== (SerialKey const&, SerialKey const&); +public: + explicit SerialKey(Edition edition = kUnregistered); + explicit SerialKey(std::string serial); + + bool isExpiring(time_t currentTime) const; + bool isExpired(time_t currentTime) const; + bool isTrial() const; + time_t daysLeft(time_t currentTime) const; + std::string email() const; + Edition edition() const; + std::string toString() const; + + static std::string decode(const std::string& serial); + static Edition parseEdition(const std::string& editionStr); + +private: + bool parse(std::string plainSerial); + std::string editionString() const; + +#ifdef TEST_ENV +private: + FRIEND_TEST(SerialKeyTests, parse_noParty_invalid); + FRIEND_TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid); + FRIEND_TEST(SerialKeyTests, parse_validV1Serial_valid); + FRIEND_TEST(SerialKeyTests, parse_validV2Serial_valid); +#endif + +private: + std::string m_name; + std::string m_email; + std::string m_company; + unsigned m_userLimit; + unsigned long long m_warnTime; + unsigned long long m_expireTime; + Edition m_edition; + bool m_trial; +}; + + +inline bool +operator== (SerialKey const& lhs, SerialKey const& rhs) { + return (lhs.m_name == rhs.m_name) && + (lhs.m_email == rhs.m_email) && + (lhs.m_company == rhs.m_company) && + (lhs.m_userLimit == rhs.m_userLimit) && + (lhs.m_warnTime == rhs.m_warnTime) && + (lhs.m_expireTime == rhs.m_expireTime) && + (lhs.m_edition == rhs.m_edition) && + (lhs.m_trial == rhs.m_trial); +} + +inline bool +operator!= (SerialKey const& lhs, SerialKey const& rhs) { + return !(lhs == rhs); +} diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp index 431a91b73..83cecdf88 100644 --- a/src/lib/synergy/ArgParser.cpp +++ b/src/lib/synergy/ArgParser.cpp @@ -1,11 +1,11 @@ /* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2014-2016 Symless Ltd. - * + * * 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 LICENSE 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 @@ -23,7 +23,6 @@ #include "synergy/ClientArgs.h" #include "synergy/ToolArgs.h" #include "synergy/ArgsBase.h" -#include "synergy/DpiHelper.h" #include "base/Log.h" #include "base/String.h" @@ -58,17 +57,8 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv) // save configuration file path args.m_configFile = argv[++i]; } - else if (isArg(i, argc, argv, "", "--res-w", 1)) { - DpiHelper::s_resolutionWidth = synergy::string::stringToSizeType(argv[++i]); - } - else if (isArg(i, argc, argv, "", "--res-h", 1)) { - DpiHelper::s_resolutionHeight = synergy::string::stringToSizeType(argv[++i]); - } - else if (isArg(i, argc, argv, "", "--prm-wc", 1)) { - DpiHelper::s_primaryWidthCenter = synergy::string::stringToSizeType(argv[++i]); - } - else if (isArg(i, argc, argv, "", "--prm-hc", 1)) { - DpiHelper::s_primaryHeightCenter = synergy::string::stringToSizeType(argv[++i]); + else if (isArg(i, argc, argv, "", "--serial-key", 1)) { + args.m_serial = SerialKey(argv[++i]); } else { LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname)); @@ -107,7 +97,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv) // ignore -- included for backwards compatibility } else if (isArg(i, argc, argv, NULL, "--yscroll", 1)) { - // define scroll + // define scroll args.m_yscroll = atoi(argv[++i]); } else { @@ -189,18 +179,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv) args.m_loginAuthenticate = true; return true; } - else if (isArg(i, argc, argv, NULL, "--get-plugin-list", 0)) { - args.m_getPluginList = true; - return true; - } else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) { args.m_getInstalledDir = true; return true; } - else if (isArg(i, argc, argv, NULL, "--get-plugin-dir", 0)) { - args.m_getPluginDir = true; - return true; - } else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) { args.m_getProfileDir = true; return true; @@ -209,26 +191,14 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv) args.m_getArch = true; return true; } - else if (isArg(i, argc, argv, NULL, "--subscription-serial", 1)) { - args.m_subscriptionSerial = argv[++i]; - if (args.m_subscriptionSerial.empty()) { - LOG((CLOG_CRIT "subscription error: serial was not provided")); - return false; - } - return true; - } - else if (isArg(i, argc, argv, NULL, "--get-subscription-filename", 0)) { - args.m_getSubscriptionFilename = true; - return true; - } - else if (isArg(i, argc, argv, NULL, "--check-subscription", 0)) { - args.m_checkSubscription = true; - return true; - } else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) { args.m_notifyActivation = true; return true; } + else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) { + args.m_notifyUpdate = true; + return true; + } else { return false; } @@ -292,10 +262,10 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i) argsBase().m_enableIpc = true; } else if (isArg(i, argc, argv, NULL, "--server")) { - // HACK: stop error happening when using portable (synergyp) + // HACK: stop error happening when using portable (synergyp) } else if (isArg(i, argc, argv, NULL, "--client")) { - // HACK: stop error happening when using portable (synergyp) + // HACK: stop error happening when using portable (synergyp) } else if (isArg(i, argc, argv, NULL, "--enable-drag-drop")) { bool useDragDrop = true; @@ -349,6 +319,26 @@ ArgParser::parseDeprecatedArgs(int argc, const char* const* argv, int& i) i++; return true; } + else if (isArg(i, argc, argv, NULL, "--res-w")) { + LOG((CLOG_NOTE "--res-w is deprecated")); + i++; + return true; + } + else if (isArg(i, argc, argv, NULL, "--res-h")) { + LOG((CLOG_NOTE "--res-h is deprecated")); + i++; + return true; + } + else if (isArg(i, argc, argv, NULL, "--prm-wc")) { + LOG((CLOG_NOTE "--prm-wc is deprecated")); + i++; + return true; + } + else if (isArg(i, argc, argv, NULL, "--prm-hc")) { + LOG((CLOG_NOTE "--prm-hc is deprecated")); + i++; + return true; + } return false; } @@ -399,7 +389,7 @@ ArgParser::splitCommandString(String& command, std::vector& argv) else if (space > rightDoubleQuote){ searchDoubleQuotes(command, leftDoubleQuote, rightDoubleQuote, rightDoubleQuote + 1); } - + if (!ignoreThisSpace) { String subString = command.substr(startPos, space - startPos); @@ -465,7 +455,7 @@ ArgParser::getArgv(std::vector& argsArray) // them to the inner array. So caller only need to use // delete[] to delete the outer array const char** argv = new const char*[argc]; - + for (size_t i = 0; i < argc; i++) { argv[i] = argsArray[i].c_str(); } @@ -497,7 +487,7 @@ ArgParser::assembleCommand(std::vector& argsArray, String ignoreArg, in if (!result.empty()) { // remove the tail space - result = result.substr(0, result.size() - 1); + result = result.substr(0, result.size() - 1); } return result; @@ -514,13 +504,13 @@ bool ArgParser::checkUnexpectedArgs() { #if SYSAPI_WIN32 - // suggest that user installs as a windows service. when launched as + // suggest that user installs as a windows service. when launched as // service, process should automatically detect that it should run in // daemon mode. if (argsBase().m_daemon) { - LOG((CLOG_ERR + LOG((CLOG_ERR "the --daemon argument is not supported on windows. " - "instead, install %s as a service (--service install)", + "instead, install %s as a service (--service install)", argsBase().m_pname)); return true; } diff --git a/src/lib/synergy/ClientApp.cpp b/src/lib/synergy/ClientApp.cpp index 6adac9b98..10aba5f32 100644 --- a/src/lib/synergy/ClientApp.cpp +++ b/src/lib/synergy/ClientApp.cpp @@ -268,7 +268,7 @@ void ClientApp::handleClientRestart(const Event&, void* vtimer) { // discard old timer - EventQueueTimer* timer = reinterpret_cast(vtimer); + EventQueueTimer* timer = static_cast(vtimer); m_events->deleteTimer(timer); m_events->removeHandler(Event::kTimer, timer); @@ -301,7 +301,7 @@ void ClientApp::handleClientFailed(const Event& e, void*) { Client::FailInfo* info = - reinterpret_cast(e.getData()); + static_cast(e.getData()); updateStatus(String("Failed to connect to server: ") + info->m_what); if (!args().m_restartable || !info->m_retry) { @@ -455,11 +455,6 @@ ClientApp::mainLoop() SocketMultiplexer multiplexer; setSocketMultiplexer(&multiplexer); - // load all available plugins. - ARCH->plugin().load(); - // pass log and arch into plugins. - ARCH->plugin().init(Log::getInstance(), Arch::getInstance()); - // start client, etc appUtil().startNode(); @@ -469,9 +464,6 @@ ClientApp::mainLoop() initIpcClient(); } - // init event for all available plugins. - ARCH->plugin().initEvent(m_clientScreen->getEventTarget(), m_events); - // run event loop. if startClient() failed we're supposed to retry // later. the timer installed by startClient() will take care of // that. @@ -506,9 +498,6 @@ ClientApp::mainLoop() cleanupIpcClient(); } - // unload all plugins. - ARCH->plugin().unload(); - return kExitSuccess; } diff --git a/src/lib/synergy/ClipboardChunk.cpp b/src/lib/synergy/ClipboardChunk.cpp index f7a5673db..292826ee6 100644 --- a/src/lib/synergy/ClipboardChunk.cpp +++ b/src/lib/synergy/ClipboardChunk.cpp @@ -21,6 +21,7 @@ #include "synergy/protocol_types.h" #include "io/IStream.h" #include "base/Log.h" +#include size_t ClipboardChunk::s_expectedSize = 0; @@ -41,8 +42,7 @@ ClipboardChunk::start( char* chunk = start->m_chunk; chunk[0] = id; - UInt32* seq = reinterpret_cast(&chunk[1]); - *seq = sequence; + std::memcpy (&chunk[1], &sequence, 4); chunk[5] = kDataStart; memcpy(&chunk[6], size.c_str(), sizeLength); chunk[sizeLength + CLIPBOARD_CHUNK_META_SIZE - 1] = '\0'; @@ -61,8 +61,7 @@ ClipboardChunk::data( char* chunkData = chunk->m_chunk; chunkData[0] = id; - UInt32* seq = reinterpret_cast(&chunkData[1]); - *seq = sequence; + std::memcpy (&chunkData[1], &sequence, 4); chunkData[5] = kDataChunk; memcpy(&chunkData[6], data.c_str(), dataSize); chunkData[dataSize + CLIPBOARD_CHUNK_META_SIZE - 1] = '\0'; @@ -77,8 +76,7 @@ ClipboardChunk::end(ClipboardID id, UInt32 sequence) char* chunk = end->m_chunk; chunk[0] = id; - UInt32* seq = reinterpret_cast(&chunk[1]); - *seq = sequence; + std::memcpy (&chunk[1], &sequence, 4); chunk[5] = kDataEnd; chunk[CLIPBOARD_CHUNK_META_SIZE - 1] = '\0'; @@ -120,21 +118,21 @@ ClipboardChunk::assemble(synergy::IStream* stream, return kFinish; } - LOG((CLOG_ERR "clipboard transmission failed: unknow error")); + LOG((CLOG_ERR "clipboard transmission failed: unknown error")); return kError; } void ClipboardChunk::send(synergy::IStream* stream, void* data) { - ClipboardChunk* clipboardData = reinterpret_cast(data); + ClipboardChunk* clipboardData = static_cast(data); LOG((CLOG_DEBUG1 "sending clipboard chunk")); char* chunk = clipboardData->m_chunk; ClipboardID id = chunk[0]; - UInt32* seq = reinterpret_cast(&chunk[1]); - UInt32 sequence = *seq; + UInt32 sequence; + std::memcpy (&sequence, &chunk[1], 4); UInt8 mark = chunk[5]; String dataChunk(&chunk[6], clipboardData->m_dataSize); diff --git a/src/lib/synergy/DpiHelper.cpp b/src/lib/synergy/DpiHelper.cpp deleted file mode 100644 index 2f2ffcb70..000000000 --- a/src/lib/synergy/DpiHelper.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "synergy/DpiHelper.h" -#include "base/Log.h" - -#include - -size_t DpiHelper::s_dpi = kDefaultDpi; -bool DpiHelper::s_dpiScaled = false; -size_t DpiHelper::s_resolutionWidth = 0; -size_t DpiHelper::s_resolutionHeight = 0; -size_t DpiHelper::s_primaryWidthCenter = 0; -size_t DpiHelper::s_primaryHeightCenter = 0; - -void DpiHelper::calculateDpi(size_t width, size_t height) -{ - if (s_resolutionWidth == 0 || - s_resolutionHeight == 0 || - s_primaryWidthCenter == 0 || - s_primaryHeightCenter == 0) { - return; - } - - size_t dpiTest1 = s_resolutionWidth * 100 / width; - size_t dpiTest2 = s_resolutionHeight * 100 / height; - - if (dpiTest1 == dpiTest2) { - s_dpi = dpiTest1; - - if (s_dpi != kDefaultDpi) { - s_dpiScaled = true; - - LOG((CLOG_DEBUG "DPI: %d%%", s_dpi)); - LOG((CLOG_DEBUG "physical resolution: %d, %d scaled resolution: %d, %d", - s_resolutionWidth, s_resolutionHeight, width, height)); - } - } -} diff --git a/src/lib/synergy/DpiHelper.h b/src/lib/synergy/DpiHelper.h deleted file mode 100644 index 0488a4652..000000000 --- a/src/lib/synergy/DpiHelper.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "common/common.h" - -class DpiHelper { -public: - enum EDpi { - kDefaultDpi = 100 - }; - - static void calculateDpi(size_t width, size_t height); - static float getDpi() { return (float)(s_dpi / 100.0f); } - -public: - static size_t s_dpi; - static bool s_dpiScaled; - static size_t s_resolutionWidth; - static size_t s_resolutionHeight; - static size_t s_primaryWidthCenter; - static size_t s_primaryHeightCenter; -}; diff --git a/src/lib/synergy/KeyState.cpp b/src/lib/synergy/KeyState.cpp index 3808b9449..bdb8706cf 100644 --- a/src/lib/synergy/KeyState.cpp +++ b/src/lib/synergy/KeyState.cpp @@ -524,7 +524,7 @@ KeyState::addActiveModifierCB(KeyID, SInt32 group, synergy::KeyMap::KeyItem& keyItem, void* vcontext) { AddActiveModifierContext* context = - reinterpret_cast(vcontext); + static_cast(vcontext); if (group == context->m_activeGroup && (keyItem.m_generates & context->m_mask) != 0) { context->m_activeModifiers.insert(std::make_pair( diff --git a/src/lib/synergy/ProtocolUtil.cpp b/src/lib/synergy/ProtocolUtil.cpp index ab361880d..ae796fa9c 100644 --- a/src/lib/synergy/ProtocolUtil.cpp +++ b/src/lib/synergy/ProtocolUtil.cpp @@ -120,27 +120,27 @@ ProtocolUtil::vreadf(synergy::IStream* stream, const char* fmt, va_list args) switch (len) { case 1: // 1 byte integer - *reinterpret_cast(v) = buffer[0]; - LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *reinterpret_cast(v), *reinterpret_cast(v))); + *static_cast(v) = buffer[0]; + LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *static_cast(v), *static_cast(v))); break; case 2: // 2 byte integer - *reinterpret_cast(v) = + *static_cast(v) = static_cast( (static_cast(buffer[0]) << 8) | static_cast(buffer[1])); - LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *reinterpret_cast(v), *reinterpret_cast(v))); + LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *static_cast(v), *static_cast(v))); break; case 4: // 4 byte integer - *reinterpret_cast(v) = + *static_cast(v) = (static_cast(buffer[0]) << 24) | (static_cast(buffer[1]) << 16) | (static_cast(buffer[2]) << 8) | static_cast(buffer[3]); - LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *reinterpret_cast(v), *reinterpret_cast(v))); + LOG((CLOG_DEBUG2 "readf: read %d byte integer: %d (0x%x)", len, *static_cast(v), *static_cast(v))); break; } break; @@ -165,9 +165,9 @@ ProtocolUtil::vreadf(synergy::IStream* stream, const char* fmt, va_list args) // 1 byte integer for (UInt32 i = 0; i < n; ++i) { read(stream, buffer, 1); - reinterpret_cast*>(v)->push_back( + static_cast*>(v)->push_back( buffer[0]); - LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, reinterpret_cast*>(v)->back(), reinterpret_cast*>(v)->back())); + LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, static_cast*>(v)->back(), static_cast*>(v)->back())); } break; @@ -175,11 +175,11 @@ ProtocolUtil::vreadf(synergy::IStream* stream, const char* fmt, va_list args) // 2 byte integer for (UInt32 i = 0; i < n; ++i) { read(stream, buffer, 2); - reinterpret_cast*>(v)->push_back( + static_cast*>(v)->push_back( static_cast( (static_cast(buffer[0]) << 8) | static_cast(buffer[1]))); - LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, reinterpret_cast*>(v)->back(), reinterpret_cast*>(v)->back())); + LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, static_cast*>(v)->back(), static_cast*>(v)->back())); } break; @@ -187,12 +187,12 @@ ProtocolUtil::vreadf(synergy::IStream* stream, const char* fmt, va_list args) // 4 byte integer for (UInt32 i = 0; i < n; ++i) { read(stream, buffer, 4); - reinterpret_cast*>(v)->push_back( + static_cast*>(v)->push_back( (static_cast(buffer[0]) << 24) | (static_cast(buffer[1]) << 16) | (static_cast(buffer[2]) << 8) | static_cast(buffer[3])); - LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, reinterpret_cast*>(v)->back(), reinterpret_cast*>(v)->back())); + LOG((CLOG_DEBUG2 "readf: read %d byte integer[%d]: %d (0x%x)", len, i, static_cast*>(v)->back(), static_cast*>(v)->back())); } break; } @@ -340,7 +340,7 @@ ProtocolUtil::getLength(const char* fmt, va_list args) void ProtocolUtil::writef(void* buffer, const char* fmt, va_list args) { - UInt8* dst = reinterpret_cast(buffer); + UInt8* dst = static_cast(buffer); while (*fmt) { if (*fmt == '%') { @@ -515,7 +515,7 @@ ProtocolUtil::read(synergy::IStream* stream, void* vbuffer, UInt32 count) assert(stream != NULL); assert(vbuffer != NULL); - UInt8* buffer = reinterpret_cast(vbuffer); + UInt8* buffer = static_cast(vbuffer); while (count > 0) { // read more UInt32 n = stream->read(buffer, count); diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp index 0153f9a20..ae1a20772 100644 --- a/src/lib/synergy/ServerApp.cpp +++ b/src/lib/synergy/ServerApp.cpp @@ -259,7 +259,7 @@ ServerApp::forceReconnect(const Event&, void*) void ServerApp::handleClientConnected(const Event&, void* vlistener) { - ClientListener* listener = reinterpret_cast(vlistener); + ClientListener* listener = static_cast(vlistener); ClientProxy* client = listener->getNextClient(); if (client != NULL) { m_server->adoptClient(client); @@ -647,7 +647,7 @@ ServerApp::openClientListener(const NetworkAddress& address) Server* ServerApp::openServer(Config& config, PrimaryClient* primaryClient) { - Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args().m_enableDragDrop); + Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args()); try { m_events->adoptHandler( m_events->forServer().disconnected(), server, @@ -707,11 +707,6 @@ ServerApp::mainLoop() return kExitFailed; } - // load all available plugins. - ARCH->plugin().load(); - // pass log and arch into plugins. - ARCH->plugin().init(Log::getInstance(), Arch::getInstance()); - // start server, etc appUtil().startNode(); @@ -721,9 +716,6 @@ ServerApp::mainLoop() initIpcClient(); } - // init event for all available plugins. - ARCH->plugin().initEvent(m_serverScreen->getEventTarget(), m_events); - // handle hangup signal by reloading the server's configuration ARCH->setSignalHandler(Arch::kHANGUP, &reloadSignalHandler, NULL); m_events->adoptHandler(m_events->forServerApp().reloadConfig(), @@ -780,9 +772,6 @@ ServerApp::mainLoop() cleanupIpcClient(); } - // unload all plugins. - ARCH->plugin().unload(); - return kExitSuccess; } diff --git a/src/lib/synergy/ServerArgs.cpp b/src/lib/synergy/ServerArgs.cpp index f56f6e8d5..52166f2aa 100644 --- a/src/lib/synergy/ServerArgs.cpp +++ b/src/lib/synergy/ServerArgs.cpp @@ -19,6 +19,7 @@ ServerArgs::ServerArgs() : m_configFile(), + m_serial(), m_config(NULL) { } diff --git a/src/lib/synergy/ServerArgs.h b/src/lib/synergy/ServerArgs.h index 54310f8e7..e139d1102 100644 --- a/src/lib/synergy/ServerArgs.h +++ b/src/lib/synergy/ServerArgs.h @@ -1,11 +1,11 @@ /* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2014-2016 Symless Ltd. - * + * * 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 LICENSE 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 @@ -18,6 +18,7 @@ #pragma once #include "synergy/ArgsBase.h" +#include "shared/SerialKey.h" class NetworkAddress; class Config; @@ -28,5 +29,6 @@ class ServerArgs : public ArgsBase { public: String m_configFile; + SerialKey m_serial; Config* m_config; }; diff --git a/src/lib/synergy/StreamChunker.cpp b/src/lib/synergy/StreamChunker.cpp index f53c39bc7..2ad64a032 100644 --- a/src/lib/synergy/StreamChunker.cpp +++ b/src/lib/synergy/StreamChunker.cpp @@ -49,7 +49,7 @@ StreamChunker::sendFile( { s_isChunkingFile = true; - std::fstream file(reinterpret_cast(filename), std::ios::in | std::ios::binary); + std::fstream file(static_cast(filename), std::ios::in | std::ios::binary); if (!file.is_open()) { throw runtime_error("failed to open file"); diff --git a/src/lib/synergy/SubscriptionKey.h b/src/lib/synergy/SubscriptionKey.h deleted file mode 100644 index 28744fed5..000000000 --- a/src/lib/synergy/SubscriptionKey.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "base/String.h" - -struct SubscriptionKey { - String m_name; - String m_type; - String m_email; - String m_company; - int m_userLimit; - int m_warnTime; - int m_expireTime; -}; diff --git a/src/lib/synergy/SubscriptionManager.cpp b/src/lib/synergy/SubscriptionManager.cpp deleted file mode 100644 index 78207dc25..000000000 --- a/src/lib/synergy/SubscriptionManager.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "synergy/SubscriptionManager.h" - -#include "synergy/XSynergy.h" -#include "arch/Arch.h" -#include "base/Log.h" -#include "base/String.h" -#include "common/Version.h" - -#include -#include -#include -#include -#include -//#include - -#if SYSAPI_WIN32 -const char* kFile = "Synergy.subkey"; -#else -const char* kFile = ".synergy.subkey"; -#endif - -// -// SubscriptionManager -// - -SubscriptionManager::SubscriptionManager() : - m_key() -{ -} - -void -SubscriptionManager::checkFile(const String& filename_) -{ - String filename = filename_; - if (filename.empty()) { - filename = getFilename(); - } - - std::ifstream stream(filename.c_str()); - if (!stream.is_open()) { - throw XSubscription(synergy::string::sprintf( - "Could not open, path=%s", filename.c_str())); - } - - String serial; - stream >> serial; - - String plainText = decode(serial); - parsePlainSerial(plainText, m_key); - - LOG((CLOG_DEBUG "subscription is valid")); -} - -void -SubscriptionManager::activate(const String& serial) -{ - String plainText = decode(serial); - parsePlainSerial(plainText, m_key); - - String filename = getFilename(); - std::ofstream stream(filename.c_str()); - if (!stream.is_open()) { - throw XSubscription(synergy::string::sprintf( - "Could not open, file=%s", filename.c_str())); - } - - stream << serial << std::endl; - LOG((CLOG_DEBUG "subscription file created, path=%s", filename.c_str())); -} - -String -SubscriptionManager::decode(const String& input) -{ - static const char* const lut = "0123456789ABCDEF"; - size_t len = input.length(); - if (len & 1) { - throw XSubscription("Invalid serial, wrong length."); - } - - String output; - output.reserve(len / 2); - for (size_t i = 0; i < len; i += 2) { - - char a = input[i]; - char b = input[i + 1]; - - const char* p = std::lower_bound(lut, lut + 16, a); - const char* q = std::lower_bound(lut, lut + 16, b); - - if (*q != b || *p != a) { - throw XSubscription("Invalid serial, unrecognized digit."); - } - - output.push_back(static_cast(((p - lut) << 4) | (q - lut))); - } - - return output; -} - -void -SubscriptionManager::parsePlainSerial(const String& plainText, SubscriptionKey& key) -{ - String serial; - String parityStart = plainText.substr(0, 1); - String parityEnd = plainText.substr(plainText.length() - 1, 1); - - // check for parity chars { and }, record parity result, then remove them. - if (parityStart == "{" && parityEnd == "}") { - serial = plainText.substr(1, plainText.length() - 2); - - // tokenize serialised subscription. - std::vector parts; - std::string::size_type pos = 0; - bool look = true; - while (look) { - std::string::size_type start = pos; - pos = serial.find(";", pos); - if (pos == String::npos) { - pos = plainText.length(); - look = false; - } - parts.push_back(serial.substr(start, pos - start)); - pos += 1; - } - - // e.g.: {v1;trial;Bob;1;email;company name;1398297600;1398384000} - if ((parts.size() == 8) - && (parts.at(0).find("v1") != String::npos)) { - key.m_type = parts.at(1); - key.m_name = parts.at(2); - sscanf(parts.at(3).c_str(), "%d", &key.m_userLimit); - key.m_email = parts.at(4); - key.m_company = parts.at(5); - sscanf(parts.at(6).c_str(), "%d", &key.m_warnTime); - sscanf(parts.at(7).c_str(), "%d", &key.m_expireTime); - - // only limit to trial version - if (key.m_type == "trial") { - if (time(0) > key.m_expireTime) { - throw XSubscription("trial has expired"); - } - else if (time(0) > key.m_warnTime) { - int secLeft = key.m_expireTime - static_cast(time(0)); - const int spd = 60 * 60 * 24; - int dayLeft = secLeft / spd + 1; - LOG((CLOG_NOTE "trial will end in %d %s", - dayLeft, - dayLeft == 1 ? "day" : "days")); - } - } - - const char* userText = (key.m_userLimit == 1) ? "user" : "users"; - LOG((CLOG_INFO "%s subscription valid is for %d %s, registered to %s", - key.m_type.c_str(), - key.m_userLimit, - userText, - key.m_name.c_str())); - - return; - } - } - - throw XSubscription(synergy::string::sprintf("Serial is invalid.")); -} - -String -SubscriptionManager::getFilename() -{ - String path = ARCH->getProfileDirectory(); - path = ARCH->concatPath(path, kFile); - if (path.empty()) { - throw XSubscription("Could not get filename."); - } - - return path; -} - -void -SubscriptionManager::printFilename() -{ - std::cout << getFilename() << std::endl; -} diff --git a/src/lib/synergy/SubscriptionManager.h b/src/lib/synergy/SubscriptionManager.h deleted file mode 100644 index fb52701b1..000000000 --- a/src/lib/synergy/SubscriptionManager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "SubscriptionKey.h" -#include "common/common.h" - -#include "gtest/gtest_prod.h" - -class SubscriptionManager { -public: - SubscriptionManager(); - - //! Check the subscription activation file - void checkFile(const String& filename); - - //! Create a subscription activation file based on a serial - void activate(const String& serial); - - //! Use standard output to return subscription filename to gui - void printFilename(); - -private: - FRIEND_TEST(SubscriptionTests, decode_invalidLength_throwException); - FRIEND_TEST(SubscriptionTests, decode_invalidSerial_outputPlainText); - FRIEND_TEST(SubscriptionTests, decode_unrecognizedDigit_throwException); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_noParity_throwException); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey); - FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey); - -private: - String decode(const String& input); - void parsePlainSerial(const String& plainText, SubscriptionKey& key); - String getFilename(); - - SubscriptionKey m_key; -}; diff --git a/src/lib/synergy/ToolApp.cpp b/src/lib/synergy/ToolApp.cpp index b024bfe94..3dcfd05d8 100644 --- a/src/lib/synergy/ToolApp.cpp +++ b/src/lib/synergy/ToolApp.cpp @@ -1,11 +1,11 @@ /* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2014-2016 Symless Ltd. - * + * * 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 LICENSE 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 @@ -18,7 +18,6 @@ #include "synergy/ToolApp.h" #include "synergy/ArgParser.h" -#include "synergy/SubscriptionManager.h" #include "arch/Arch.h" #include "base/Log.h" #include "base/String.h" @@ -72,50 +71,17 @@ ToolApp::run(int argc, char** argv) else if (m_args.m_loginAuthenticate) { loginAuth(); } - else if (m_args.m_getPluginList) { - getPluginList(); - } else if (m_args.m_getInstalledDir) { std::cout << ARCH->getInstalledDirectory() << std::endl; } - else if (m_args.m_getPluginDir) { - std::cout << ARCH->getPluginDirectory() << std::endl; - } else if (m_args.m_getProfileDir) { std::cout << ARCH->getProfileDirectory() << std::endl; } else if (m_args.m_getArch) { std::cout << ARCH->getPlatformName() << std::endl; } - else if (!m_args.m_subscriptionSerial.empty()) { - try { - SubscriptionManager subscriptionManager; - subscriptionManager.activate(m_args.m_subscriptionSerial); - } - catch (XSubscription& e) { - LOG((CLOG_CRIT "subscription error: %s", e.what())); - return kExitSubscription; - } - } - else if (m_args.m_getSubscriptionFilename) { - try { - SubscriptionManager subscriptionManager; - subscriptionManager.printFilename(); - } - catch (XSubscription& e) { - LOG((CLOG_CRIT "subscription error: %s", e.what())); - return kExitSubscription; - } - } - else if (m_args.m_checkSubscription) { - try { - SubscriptionManager subscriptionManager; - subscriptionManager.checkFile(""); - } - catch (XSubscription& e) { - LOG((CLOG_CRIT "subscription error: %s", e.what())); - return kExitSubscription; - } + else if (m_args.m_notifyUpdate) { + notifyUpdate(); } else if (m_args.m_notifyActivation) { notifyActivation(); @@ -172,24 +138,29 @@ ToolApp::loginAuth() } void -ToolApp::getPluginList() +ToolApp::notifyUpdate() { - String credentials; - std::cin >> credentials; + String data; + std::cin >> data; - size_t separator = credentials.find(':'); - String email = credentials.substr(0, separator); - String password = credentials.substr(separator + 1, credentials.length()); + std::vector parts = synergy::string::splitString(data, ':'); + size_t count = parts.size(); - std::stringstream ss; - ss << JSON_URL << "plugins/"; - ss << "?email=" << ARCH->internet().urlEncode(email); - ss << "&password=" << password; + if (count == 3) { + std::stringstream ss; + ss << JSON_URL << "notify/update"; + ss << "?from=" << parts[0]; + ss << "&to=" << parts[1]; + ss << "&serial=" << parts[2]; - std::cout << ARCH->internet().get(ss.str()) << std::endl; + std::cout << ARCH->internet().get(ss.str()) << std::endl; + } + else { + throw XSynergy("Invalid update data."); + } } -void +void ToolApp::notifyActivation() { String info; diff --git a/src/lib/synergy/ToolApp.h b/src/lib/synergy/ToolApp.h index 8706c79a9..771b298fe 100644 --- a/src/lib/synergy/ToolApp.h +++ b/src/lib/synergy/ToolApp.h @@ -29,8 +29,8 @@ class ToolApp : public MinimalApp private: void loginAuth(); - void getPluginList(); void notifyActivation(); + void notifyUpdate(); private: ToolArgs m_args; diff --git a/src/lib/synergy/ToolArgs.cpp b/src/lib/synergy/ToolArgs.cpp index f5d2524a6..2685c1df5 100644 --- a/src/lib/synergy/ToolArgs.cpp +++ b/src/lib/synergy/ToolArgs.cpp @@ -20,14 +20,10 @@ ToolArgs::ToolArgs() : m_printActiveDesktopName(false), m_loginAuthenticate(false), - m_getPluginList(false), - m_getPluginDir(false), m_getInstalledDir(false), m_getProfileDir(false), m_getArch(false), - m_getSubscriptionFilename(false), - m_checkSubscription(false), m_notifyActivation(false), - m_subscriptionSerial() + m_notifyUpdate(false) { } diff --git a/src/lib/synergy/ToolArgs.h b/src/lib/synergy/ToolArgs.h index 0ebc0a4aa..4619efc1e 100644 --- a/src/lib/synergy/ToolArgs.h +++ b/src/lib/synergy/ToolArgs.h @@ -26,13 +26,9 @@ class ToolArgs { public: bool m_printActiveDesktopName; bool m_loginAuthenticate; - bool m_getPluginList; - bool m_getPluginDir; bool m_getInstalledDir; bool m_getProfileDir; bool m_getArch; - bool m_getSubscriptionFilename; - bool m_checkSubscription; bool m_notifyActivation; - String m_subscriptionSerial; + bool m_notifyUpdate; }; diff --git a/src/lib/synergy/key_types.h b/src/lib/synergy/key_types.h index ea9387b1c..f45cea242 100644 --- a/src/lib/synergy/key_types.h +++ b/src/lib/synergy/key_types.h @@ -110,10 +110,12 @@ static const KeyID kKeyScrollLock = 0xEF14; static const KeyID kKeySysReq = 0xEF15; static const KeyID kKeyEscape = 0xEF1B; static const KeyID kKeyHenkan = 0xEF23; /* Start/Stop Conversion */ -static const KeyID kKeyHangulKana = 0xEF26; /* Hangul, Kana */ +static const KeyID kKeyKana = 0xEF26; /* Kana */ static const KeyID kKeyHiraganaKatakana = 0xEF27; /* Hiragana/Katakana toggle */ static const KeyID kKeyZenkaku = 0xEF2A; /* Zenkaku/Hankaku */ -static const KeyID kKeyHanjaKanzi = 0xEF2A; /* Hanja, Kanzi */ +static const KeyID kKeyKanzi = 0xEF2A; /* Kanzi */ +static const KeyID kKeyHangul = 0xEF31; /* Hangul */ +static const KeyID kKeyHanja = 0xEF34; /* Hanja */ static const KeyID kKeyDelete = 0xEFFF; /* Delete, rubout */ // cursor control diff --git a/src/micro/uSynergy.h b/src/micro/uSynergy.h index 44534d248..3d064d513 100644 --- a/src/micro/uSynergy.h +++ b/src/micro/uSynergy.h @@ -46,7 +46,7 @@ extern "C" { #error "Can't define both USYNERGY_LITTLE_ENDIAN and USYNERGY_BIG_ENDIAN" #elif !defined(USYNERGY_LITTLE_ENDIAN) && !defined(USYNERGY_BIG_ENDIAN) /* Attempt to auto detect */ - #if defined(__LITTLE_ENDIAN__) || defined(LITTLE_ENDIAN) || (_BYTE_ORDER == _LITTLE_ENDIAN) + #if defined(__LITTLE_ENDIAN__) || defined(LITTLE_ENDIAN) #define USYNERGY_LITTLE_ENDIAN #elif defined(__BIG_ENDIAN__) || defined(BIG_ENDIAN) || (_BYTE_ORDER == _BIG_ENDIAN) #define USYNERGY_BIG_ENDIAN diff --git a/src/setup/win32/Product.wxs b/src/setup/win32/Product.wxs index 552f76d1d..3663607a9 100644 --- a/src/setup/win32/Product.wxs +++ b/src/setup/win32/Product.wxs @@ -27,10 +27,24 @@ - + + + + + + + + + = 602)]]> + + + + @@ -70,7 +84,6 @@ - @@ -140,11 +153,5 @@ - - - - - - diff --git a/src/test/integtests/CMakeLists.txt b/src/test/integtests/CMakeLists.txt index bde35c2fa..2f1ca7f39 100644 --- a/src/test/integtests/CMakeLists.txt +++ b/src/test/integtests/CMakeLists.txt @@ -68,4 +68,4 @@ endif() add_executable(integtests ${sources}) target_link_libraries(integtests - arch base client common io ipc mt net platform server synergy gtest gmock ${libs}) + arch base client common io ipc mt net platform server synergy gtest gmock ${libs} ${OPENSSL_LIBS}) diff --git a/src/test/integtests/net/NetworkTests.cpp b/src/test/integtests/net/NetworkTests.cpp index dd7fb6b4a..dbb3dd1e4 100644 --- a/src/test/integtests/net/NetworkTests.cpp +++ b/src/test/integtests/net/NetworkTests.cpp @@ -27,6 +27,7 @@ #include "test/global/TestEventQueue.h" #include "server/Server.h" #include "server/ClientListener.h" +#include "server/ClientProxy.h" #include "client/Client.h" #include "synergy/FileChunk.h" #include "synergy/StreamChunker.h" @@ -128,7 +129,9 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -141,10 +144,10 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forFile().fileRecieveCompleted(), &client, @@ -184,7 +187,9 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -197,10 +202,10 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forFile().fileRecieveCompleted(), &client, @@ -234,7 +239,9 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -246,10 +253,10 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forClientListener().connected(), &listener, @@ -289,7 +296,9 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -301,10 +310,10 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forClientListener().connected(), &listener, @@ -328,7 +337,7 @@ TEST_F(NetworkTests, sendToServer_mockFile) void NetworkTests::sendToClient_mockData_handleClientConnected(const Event&, void* vlistener) { - ClientListener* listener = reinterpret_cast(vlistener); + ClientListener* listener = static_cast(vlistener); Server* server = listener->getServer(); ClientProxy* client = listener->getNextClient(); @@ -336,7 +345,7 @@ NetworkTests::sendToClient_mockData_handleClientConnected(const Event&, void* vl throw runtime_error("client is null"); } - BaseClientProxy* bcp = reinterpret_cast(client); + BaseClientProxy* bcp = client; server->adoptClient(bcp); server->setActive(bcp); @@ -346,7 +355,7 @@ NetworkTests::sendToClient_mockData_handleClientConnected(const Event&, void* vl void NetworkTests::sendToClient_mockData_fileRecieveCompleted(const Event& event, void*) { - Client* client = reinterpret_cast(event.getTarget()); + Client* client = static_cast(event.getTarget()); EXPECT_TRUE(client->isReceivedFileSizeValid()); m_events.raiseQuitEvent(); @@ -355,7 +364,7 @@ NetworkTests::sendToClient_mockData_fileRecieveCompleted(const Event& event, voi void NetworkTests::sendToClient_mockFile_handleClientConnected(const Event&, void* vlistener) { - ClientListener* listener = reinterpret_cast(vlistener); + ClientListener* listener = static_cast(vlistener); Server* server = listener->getServer(); ClientProxy* client = listener->getNextClient(); @@ -363,7 +372,7 @@ NetworkTests::sendToClient_mockFile_handleClientConnected(const Event&, void* vl throw runtime_error("client is null"); } - BaseClientProxy* bcp = reinterpret_cast(client); + BaseClientProxy* bcp = client; server->adoptClient(bcp); server->setActive(bcp); @@ -373,7 +382,7 @@ NetworkTests::sendToClient_mockFile_handleClientConnected(const Event&, void* vl void NetworkTests::sendToClient_mockFile_fileRecieveCompleted(const Event& event, void*) { - Client* client = reinterpret_cast(event.getTarget()); + Client* client = static_cast(event.getTarget()); EXPECT_TRUE(client->isReceivedFileSizeValid()); m_events.raiseQuitEvent(); @@ -382,14 +391,14 @@ NetworkTests::sendToClient_mockFile_fileRecieveCompleted(const Event& event, voi void NetworkTests::sendToServer_mockData_handleClientConnected(const Event&, void* vclient) { - Client* client = reinterpret_cast(vclient); + Client* client = static_cast(vclient); sendMockData(client); } void NetworkTests::sendToServer_mockData_fileRecieveCompleted(const Event& event, void*) { - Server* server = reinterpret_cast(event.getTarget()); + Server* server = static_cast(event.getTarget()); EXPECT_TRUE(server->isReceivedFileSizeValid()); m_events.raiseQuitEvent(); @@ -398,14 +407,14 @@ NetworkTests::sendToServer_mockData_fileRecieveCompleted(const Event& event, voi void NetworkTests::sendToServer_mockFile_handleClientConnected(const Event&, void* vclient) { - Client* client = reinterpret_cast(vclient); + Client* client = static_cast(vclient); client->sendFileToServer(kMockFilename); } void NetworkTests::sendToServer_mockFile_fileRecieveCompleted(const Event& event, void*) { - Server* server = reinterpret_cast(event.getTarget()); + Server* server = static_cast(event.getTarget()); EXPECT_TRUE(server->isReceivedFileSizeValid()); m_events.raiseQuitEvent(); diff --git a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp index c7a4b666c..0affab6e6 100644 --- a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp +++ b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp @@ -121,3 +121,24 @@ TEST_F(MSWindowsKeyStateTests, saveModifiers_noModifiers_savedModifiers0) ASSERT_EQ(0, keyState.getSavedModifiers()); delete desks; } + +TEST_F(MSWindowsKeyStateTests, testKoreanLocale_inputModeKey_resultCorrectKeyID) +{ + NiceMock eventQueue; + MSWindowsDesks* desks = newDesks(&eventQueue); + MockKeyMap keyMap; + MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap); + + keyState.setKeyLayout((HKL)0x00000412u); // for ko-KR local ID + ASSERT_EQ(0xEF31, keyState.getKeyID(0x15u, 0x1f2u)); // VK_HANGUL from Hangul key + ASSERT_EQ(0xEF34, keyState.getKeyID(0x19u, 0x1f1u)); // VK_HANJA from Hanja key + ASSERT_EQ(0xEF31, keyState.getKeyID(0x15u, 0x11du)); // VK_HANGUL from R-Alt key + ASSERT_EQ(0xEF34, keyState.getKeyID(0x19u, 0x138u)); // VK_HANJA from R-Ctrl key + + keyState.setKeyLayout((HKL)0x00000411); // for ja-jp locale ID + ASSERT_EQ(0xEF26, keyState.getKeyID(0x15u, 0x1du)); // VK_KANA + ASSERT_EQ(0xEF2A, keyState.getKeyID(0x19u, 0x38u)); // VK_KANJI + + delete desks; +} + diff --git a/src/test/unittests/CMakeLists.txt b/src/test/unittests/CMakeLists.txt index 4cacdf936..3e49dc3c8 100644 --- a/src/test/unittests/CMakeLists.txt +++ b/src/test/unittests/CMakeLists.txt @@ -68,4 +68,4 @@ endif() add_executable(unittests ${sources}) target_link_libraries(unittests - arch base client server common io net platform server synergy mt ipc gtest gmock ${libs}) + arch base client server common io net platform server synergy mt ipc gtest gmock shared ${libs} ${OPENSSL_LIBS}) diff --git a/src/test/unittests/shared/SerialKeyTests.cpp b/src/test/unittests/shared/SerialKeyTests.cpp new file mode 100644 index 000000000..126d26e8f --- /dev/null +++ b/src/test/unittests/shared/SerialKeyTests.cpp @@ -0,0 +1,147 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2016 Symless Inc. + * + * 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 LICENSE 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 TEST_ENV + +#include "shared/SerialKey.h" + +#include "test/global/gtest.h" + +TEST(SerialKeyTests, decode_empty_returnEmptyString) +{ + std::string plainText = SerialKey::decode(""); + EXPECT_EQ(0, plainText.size()); +} + +TEST(SerialKeyTests, decode_invalidDigit_returnEmptyString) +{ + std::string plainText = SerialKey::decode("MOCKZ"); + EXPECT_EQ(0, plainText.size()); +} + +TEST(SerialKeyTests, decode_validSerial_returnPlainText) +{ + std::string plainText = SerialKey::decode("53796E6572677920726F636B7321"); + EXPECT_EQ("Synergy rocks!", plainText); +} + +TEST(SerialKeyTests, parse_noParty_invalid) +{ + SerialKey serial; + bool r = serial.parse("MOCK"); + EXPECT_FALSE(r); +} + +TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid) +{ + SerialKey serial; + bool r = serial.parse("{Synergy;Rocks}"); + EXPECT_FALSE(r); +} + +TEST(SerialKeyTests, parse_validV1Serial_valid) +{ + SerialKey serial; + bool r = serial.parse("{v1;basic;Bob;1;email;company name;0;86400}"); + EXPECT_EQ(true, r); + EXPECT_EQ(kBasic, serial.edition()); + EXPECT_FALSE(serial.isExpired(0)); + EXPECT_EQ(true, serial.daysLeft(0)); + EXPECT_FALSE(serial.isExpiring(1)); +} + +TEST(SerialKeyTests, parse_validV2Serial_valid) +{ + SerialKey serial; + bool r = serial.parse("{v2;trial;pro;Bob;1;email;company name;0;86400}"); + EXPECT_EQ(true, r); + EXPECT_EQ(kPro, serial.edition()); + EXPECT_FALSE(serial.isExpired(0)); + EXPECT_EQ(true, serial.daysLeft(0)); + EXPECT_EQ(true, serial.isExpiring(1)); + EXPECT_EQ(true, serial.isTrial()); +} + +TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;1;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B313B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpiring(0)); + EXPECT_EQ(kBasic, serial.edition()); +} + +TEST(SerialKeyTests, isExpiring_expiringV2TrialBasicSerial_returnTrue) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isExpiring(1)); +} + +TEST(SerialKeyTests, isExpiring_expiredV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpiring(86401)); +} + +TEST(SerialKeyTests, isExpired_validV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpired(0)); +} + +TEST(SerialKeyTests, isExpired_expiringV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpired(1)); +} + +TEST(SerialKeyTests, isExpired_expiredV2TrialBasicSerial_returnTrue) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isExpired(86401)); +} + +TEST(SerialKeyTests, daysLeft_validExactlyOneDayV2TrialBasicSerial_returnOne) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(1, serial.daysLeft(0)); +} + +TEST(SerialKeyTests, daysLeft_validWithinOneDayV2TrialBasicSerial_returnOne) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(1, serial.daysLeft(1)); +} + +TEST(SerialKeyTests, daysLeft_expiredV2TrialBasicSerial_returnZero) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(0, serial.daysLeft(86401)); +} diff --git a/src/test/unittests/synergy/ClipboardChunkTests.cpp b/src/test/unittests/synergy/ClipboardChunkTests.cpp index 2460778a7..e1c3336e0 100644 --- a/src/test/unittests/synergy/ClipboardChunkTests.cpp +++ b/src/test/unittests/synergy/ClipboardChunkTests.cpp @@ -26,9 +26,11 @@ TEST(ClipboardChunkTests, start_formatStartChunk) UInt32 sequence = 0; String mockDataSize("10"); ClipboardChunk* chunk = ClipboardChunk::start(id, sequence, mockDataSize); + UInt32 temp_m_chunk; + memcpy(&temp_m_chunk, &(chunk->m_chunk[1]), 4); EXPECT_EQ(id, chunk->m_chunk[0]); - EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]); + EXPECT_EQ(sequence, temp_m_chunk); EXPECT_EQ(kDataStart, chunk->m_chunk[5]); EXPECT_EQ('1', chunk->m_chunk[6]); EXPECT_EQ('0', chunk->m_chunk[7]); @@ -43,9 +45,11 @@ TEST(ClipboardChunkTests, data_formatDataChunk) UInt32 sequence = 1; String mockData("mock data"); ClipboardChunk* chunk = ClipboardChunk::data(id, sequence, mockData); + UInt32 temp_m_chunk; + memcpy(&temp_m_chunk, &(chunk->m_chunk[1]), 4); EXPECT_EQ(id, chunk->m_chunk[0]); - EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]); + EXPECT_EQ(sequence, temp_m_chunk); EXPECT_EQ(kDataChunk, chunk->m_chunk[5]); EXPECT_EQ('m', chunk->m_chunk[6]); EXPECT_EQ('o', chunk->m_chunk[7]); @@ -66,9 +70,11 @@ TEST(ClipboardChunkTests, end_formatDataChunk) ClipboardID id = 1; UInt32 sequence = 1; ClipboardChunk* chunk = ClipboardChunk::end(id, sequence); + UInt32 temp_m_chunk; + memcpy(&temp_m_chunk, &(chunk->m_chunk[1]), 4); EXPECT_EQ(id, chunk->m_chunk[0]); - EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]); + EXPECT_EQ(sequence, temp_m_chunk); EXPECT_EQ(kDataEnd, chunk->m_chunk[5]); EXPECT_EQ('\0', chunk->m_chunk[6]); diff --git a/src/test/unittests/synergy/DpiHelperTests.cpp b/src/test/unittests/synergy/DpiHelperTests.cpp deleted file mode 100644 index 9dee828ed..000000000 --- a/src/test/unittests/synergy/DpiHelperTests.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "synergy/DpiHelper.h" - -#include "test/global/gtest.h" - -void resetStaticVariables() -{ - DpiHelper::s_resolutionWidth = 0; - DpiHelper::s_resolutionHeight = 0; - DpiHelper::s_primaryWidthCenter = 0; - DpiHelper::s_primaryHeightCenter = 0; - DpiHelper::s_dpi = DpiHelper::kDefaultDpi; - DpiHelper::s_dpiScaled = false; -} - -TEST(DpiHelperTests, calculateDpi_samePhysicalAndVirtualResolutions_defaultDpi) -{ - resetStaticVariables(); - - DpiHelper::s_resolutionWidth = 1920; - DpiHelper::s_resolutionHeight = 1080; - DpiHelper::s_primaryWidthCenter = 960; - DpiHelper::s_primaryHeightCenter = 540; - - DpiHelper::calculateDpi(1920, 1080); - - EXPECT_FALSE(DpiHelper::s_dpiScaled); - EXPECT_EQ(DpiHelper::kDefaultDpi, DpiHelper::s_dpi); -} - -TEST(DpiHelperTests, calculateDpi_differentPhysicalAndVirtualResolutions_scaledDpi) -{ - resetStaticVariables(); - - DpiHelper::s_resolutionWidth = 1920; - DpiHelper::s_resolutionHeight = 1080; - DpiHelper::s_primaryWidthCenter = 960; - DpiHelper::s_primaryHeightCenter = 540; - - DpiHelper::calculateDpi(960, 540); - - EXPECT_TRUE(DpiHelper::s_dpiScaled); - EXPECT_EQ(200, DpiHelper::s_dpi); -} - -TEST(DpiHelperTests, calculateDpi_defaultStaticValues_defaultDpi) -{ - resetStaticVariables(); - - DpiHelper::calculateDpi(1920, 1080); - - EXPECT_FALSE(DpiHelper::s_dpiScaled); - EXPECT_EQ(DpiHelper::kDefaultDpi, DpiHelper::s_dpi); -} diff --git a/src/test/unittests/synergy/ServerArgsParsingTests.cpp b/src/test/unittests/synergy/ServerArgsParsingTests.cpp index 5ae18b94b..f931f7e5d 100644 --- a/src/test/unittests/synergy/ServerArgsParsingTests.cpp +++ b/src/test/unittests/synergy/ServerArgsParsingTests.cpp @@ -1,11 +1,11 @@ /* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2014-2016 Symless Ltd. - * + * * 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 LICENSE 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 diff --git a/src/test/unittests/synergy/SubscriptionTests.cpp b/src/test/unittests/synergy/SubscriptionTests.cpp deleted file mode 100644 index eeda3e7be..000000000 --- a/src/test/unittests/synergy/SubscriptionTests.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2015 Synergy Seamless Inc. - * - * 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 LICENSE 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 "synergy/SubscriptionManager.h" -#include "synergy/XSynergy.h" - -#include "test/global/gtest.h" - -TEST(SubscriptionTests, decode_invalidLength_throwException) -{ - SubscriptionManager subscriptionManager; - String serial("ABC"); - - EXPECT_THROW(subscriptionManager.decode(serial), XSubscription); -} - -TEST(SubscriptionTests, decode_unrecognizedDigit_throwException) -{ - SubscriptionManager subscriptionManager; - String serial("MOCK"); - - EXPECT_THROW(subscriptionManager.decode(serial), XSubscription); -} - -TEST(SubscriptionTests, parsePlainSerial_noParity_throwException) -{ - SubscriptionManager subscriptionManager; - String painText("MOCK"); - SubscriptionKey key; - - EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription); -} - -TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException) -{ - SubscriptionManager subscriptionManager; - String painText("{MOCK}"); - SubscriptionKey key; - - EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription); -} - -TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey) -{ - // valid until 2 March 2049 - SubscriptionManager subscriptionManager; - String painText("{v1;trial;Bob;1;a@a.a;mock company;2147483647;2147483647}"); - SubscriptionKey key; - subscriptionManager.parsePlainSerial(painText, key); - - EXPECT_EQ("trial", key.m_type); - EXPECT_EQ("Bob", key.m_name); - EXPECT_EQ(1, key.m_userLimit); - EXPECT_EQ("a@a.a", key.m_email); - EXPECT_EQ("mock company", key.m_company); - EXPECT_EQ(2147483647, key.m_warnTime); - EXPECT_EQ(2147483647, key.m_expireTime); -} - -TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey) -{ - // valid until 2 March 2049 - SubscriptionManager subscriptionManager; - String painText("{v1;trial;Bob;1;a@a.a;;2147483647;2147483647}"); - SubscriptionKey key; - subscriptionManager.parsePlainSerial(painText, key); - - EXPECT_EQ("trial", key.m_type); - EXPECT_EQ("Bob", key.m_name); - EXPECT_EQ(1, key.m_userLimit); - EXPECT_EQ("a@a.a", key.m_email); - EXPECT_EQ("", key.m_company); - EXPECT_EQ(2147483647, key.m_warnTime); - EXPECT_EQ(2147483647, key.m_expireTime); -} - -TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException) -{ - SubscriptionManager subscriptionManager; - String painText("{v1;trial;Bob;1;1398297600;1398384000}"); - SubscriptionKey key; - - EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription); -} - -TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey) -{ - SubscriptionManager subscriptionManager; - String painText("{v1;basic;Bob;1;a@a.a;mock company;1398297600;1398384000}"); - SubscriptionKey key; - subscriptionManager.parsePlainSerial(painText, key); - - EXPECT_EQ("basic", key.m_type); - EXPECT_EQ("Bob", key.m_name); - EXPECT_EQ(1, key.m_userLimit); - EXPECT_EQ("a@a.a", key.m_email); - EXPECT_EQ("mock company", key.m_company); - EXPECT_EQ(1398297600, key.m_warnTime); - EXPECT_EQ(1398384000, key.m_expireTime); -}