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/CMakeLists.txt b/CMakeLists.txt index 45c8d9d6a..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 5) +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() diff --git a/ChangeLog b/ChangeLog index 477426ca4..dbb3b088c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +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 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 9c28ab75f..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 "); @@ -438,7 +449,7 @@ def configureCore(self, target="", extraArgs=""): if generator.cmakeName.find('Unix Makefiles') == -1: sdkDir = self.getMacSdkDir() cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir - cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macSdk + cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macDeploy cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1) cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2) @@ -498,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: @@ -656,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") @@ -1843,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'): @@ -1898,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/dpiaware.manifest b/res/dpiaware.manifest deleted file mode 100644 index 743e3369b..000000000 --- a/res/dpiaware.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - true - - - - diff --git a/src/cmd/synergyc/CMakeLists.txt b/src/cmd/synergyc/CMakeLists.txt index 653cf374f..22bbe2573 100644 --- a/src/cmd/synergyc/CMakeLists.txt +++ b/src/cmd/synergyc/CMakeLists.txt @@ -60,15 +60,6 @@ add_executable(synergyc ${sources}) target_link_libraries(synergyc arch base client common io mt net ipc platform server synergy ${libs} ${OPENSSL_LIBS}) -if (WIN32) - ADD_CUSTOM_COMMAND( - TARGET synergyc - POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_SOURCE_DIR}\\res\\dpiaware.manifest\" -inputresource:\"$\"\;\#1 -outputresource:\"$\"\;\#1 - COMMENT "Adding display aware manifest..." - ) -endif() - if (CONF_CPACK) install(TARGETS synergyc diff --git a/src/cmd/synergyd/CMakeLists.txt b/src/cmd/synergyd/CMakeLists.txt index c8b578a90..a63bee676 100644 --- a/src/cmd/synergyd/CMakeLists.txt +++ b/src/cmd/synergyd/CMakeLists.txt @@ -37,15 +37,6 @@ endif() target_link_libraries(synergyd arch base common io ipc mt net platform synergy shared ${libs} ${OPENSSL_LIBS}) -if (WIN32) - ADD_CUSTOM_COMMAND( - TARGET synergyd - POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_SOURCE_DIR}\\res\\dpiaware.manifest\" -inputresource:\"$\"\;\#1 -outputresource:\"$\"\;\#1 - COMMENT "Adding display aware manifest..." - ) -endif() - if (CONF_CPACK) install(TARGETS synergyd diff --git a/src/cmd/synergys/CMakeLists.txt b/src/cmd/synergys/CMakeLists.txt index 023574b16..2474bcc67 100644 --- a/src/cmd/synergys/CMakeLists.txt +++ b/src/cmd/synergys/CMakeLists.txt @@ -60,15 +60,6 @@ add_executable(synergys ${sources}) target_link_libraries(synergys arch base client common io mt net ipc platform server synergy ${libs} ${OPENSSL_LIBS}) -if (WIN32) - ADD_CUSTOM_COMMAND( - TARGET synergys - POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_SOURCE_DIR}\\res\\dpiaware.manifest\" -inputresource:\"$\"\;\#1 -outputresource:\"$\"\;\#1 - COMMENT "Adding display aware manifest..." - ) -endif() - if (CONF_CPACK) install(TARGETS synergys diff --git a/src/gui/res/SettingsDialogBase.ui b/src/gui/res/SettingsDialogBase.ui index dca1bdadd..f604cf7a2 100644 --- a/src/gui/res/SettingsDialogBase.ui +++ b/src/gui/res/SettingsDialogBase.ui @@ -330,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/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/ActivationDialog.cpp b/src/gui/src/ActivationDialog.cpp index 253ec3ee0..6035dfa88 100644 --- a/src/gui/src/ActivationDialog.cpp +++ b/src/gui/src/ActivationDialog.cpp @@ -71,7 +71,8 @@ void ActivationDialog::accept() std::pair result; try { - QString serialKey = ui->m_pTextEditSerialKey->toPlainText().trimmed(); + SerialKey serialKey (ui->m_pTextEditSerialKey->toPlainText(). + trimmed().toStdString()); result = m_LicenseManager->setSerialKey(serialKey); } catch (std::exception& e) { diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 06f9f43da..e6d15e63d 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -161,7 +161,7 @@ void AppConfig::loadSettings() m_ActivateEmail = settings().value("activateEmail", "").toString(); 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(); diff --git a/src/gui/src/LicenseManager.cpp b/src/gui/src/LicenseManager.cpp index 221fd16d8..6f761135e 100644 --- a/src/gui/src/LicenseManager.cpp +++ b/src/gui/src/LicenseManager.cpp @@ -29,11 +29,10 @@ LicenseManager::LicenseManager(AppConfig* appConfig) : } std::pair -LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired) +LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) { std::pair ret (true, ""); time_t currentTime = ::time(0); - SerialKey serialKey (serialKeyString.toStdString()); if (!acceptExpired && serialKey.isExpired(currentTime)) { ret.first = false; @@ -44,7 +43,8 @@ LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired) if (serialKey != m_serialKey) { using std::swap; swap (serialKey, m_serialKey); - m_AppConfig->setSerialKey(serialKeyString); + m_AppConfig->setSerialKey(QString::fromStdString + (m_serialKey.toString())); emit serialKeyChanged(m_serialKey); if (serialKey.isTrial()) { @@ -114,7 +114,13 @@ LicenseManager::serialKey() const void LicenseManager::refresh() { if (!m_AppConfig->serialKey().isEmpty()) { - setSerialKey(m_AppConfig->serialKey(), true); + 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); diff --git a/src/gui/src/LicenseManager.h b/src/gui/src/LicenseManager.h index 2dc89cd8d..7ece4e23c 100644 --- a/src/gui/src/LicenseManager.h +++ b/src/gui/src/LicenseManager.h @@ -30,7 +30,8 @@ class LicenseManager: public QObject public: LicenseManager(AppConfig* appConfig); - std::pair setSerialKey(QString serialKey, bool acceptExpired = false); + std::pair setSerialKey(SerialKey serialKey, + bool acceptExpired = false); void refresh(); Edition activeEdition() const; QString activeEditionName() const; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index f32ebdc8a..e13328c0f 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -808,25 +808,6 @@ bool MainWindow::serverArgs(QStringList& args, QString& app) args << "--serial-key" << appConfig().serialKey(); } -#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 return true; } diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index d36db7557..cf4d0c1ee 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -119,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); @@ -159,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/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/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/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/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 74abfcd75..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" @@ -105,7 +104,6 @@ MSWindowsScreen::MSWindowsScreen( m_xCenter(0), m_yCenter(0), m_multimon(false), m_xCursor(0), m_yCursor(0), - m_xFractionalMove(0.0f), m_yFractionalMove(0.0f), m_sequenceNumber(0), m_mark(0), m_markReceived(0), @@ -146,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"); @@ -348,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); @@ -576,21 +569,6 @@ void MSWindowsScreen::saveMousePosition(SInt32 x, SInt32 y) { LOG((CLOG_DEBUG5 "saved mouse position for next delta: %+d,%+d", x,y)); } -void MSWindowsScreen::accumulateFractionalMove(float x, float y, SInt32& intX, SInt32& intY) -{ - // Accumulate together the move into the running total - m_xFractionalMove += x; - m_yFractionalMove += y; - - // Return the integer part - intX = (SInt32)m_xFractionalMove; - intY = (SInt32)m_yFractionalMove; - - // And keep only the fractional part - m_xFractionalMove -= intX; - m_yFractionalMove -= intY; -} - UInt32 MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) { @@ -1369,20 +1347,10 @@ MSWindowsScreen::onMouseButton(WPARAM wParam, LPARAM lParam) bool MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) { - SInt32 originalMX = mx; - SInt32 originalMY = my; - float scaledMX = (float)mx; - float scaledMY = (float)my; - - if (DpiHelper::s_dpiScaled) { - scaledMX /= DpiHelper::getDpi(); - scaledMY /= DpiHelper::getDpi(); - } - // compute motion delta (relative to the last known // mouse position) - float x = scaledMX - m_xCursor; - float y = scaledMY - m_yCursor; + SInt32 x = mx - m_xCursor; + SInt32 y = my - m_yCursor; LOG((CLOG_DEBUG3 "mouse move - motion delta: %+d=(%+d - %+d),%+d=(%+d - %+d)", @@ -1395,14 +1363,14 @@ MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) } // save position to compute delta of next motion - saveMousePosition((SInt32)scaledMX, (SInt32)scaledMY); + saveMousePosition(mx, my); if (m_isOnScreen) { // 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; @@ -1415,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 @@ -1424,18 +1391,16 @@ 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)); } else { // send motion - SInt32 ix, iy; - accumulateFractionalMove(x, y, ix, iy); - sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(ix, iy)); + sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(x, y)); } } @@ -1623,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 4d947be7f..b1ae0f944 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -216,10 +216,6 @@ class MSWindowsScreen : public PlatformScreen { // save last position of mouse to compute next delta movement void saveMousePosition(SInt32 x, SInt32 y); - // accumulates together a series of fractional pixel moves, each time - // taking away and returning just the integer part of the running total. - void accumulateFractionalMove(float x, float y, SInt32& intX, SInt32& intY); - // check if it is a modifier key repeating message bool isModifierRepeat(KeyModifierMask oldState, KeyModifierMask state, WPARAM wParam) const; @@ -270,9 +266,6 @@ class MSWindowsScreen : public PlatformScreen { // last mouse position SInt32 m_xCursor, m_yCursor; - // accumulated fractional pixel moves - float m_xFractionalMove, m_yFractionalMove; - // last clipboard UInt32 m_sequenceNumber; 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.mm b/src/lib/platform/OSXScreen.mm index 2c2e66d6b..992144e44 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -496,7 +496,23 @@ // 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); diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp index c70324705..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); @@ -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); } 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/Server.cpp b/src/lib/server/Server.cpp index ec730bcd4..fd90f5f3a 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -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" @@ -1767,52 +1766,66 @@ 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_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)); + 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; @@ -2004,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); } diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp index 6693ebf00..83cecdf88 100644 --- a/src/lib/synergy/ArgParser.cpp +++ b/src/lib/synergy/ArgParser.cpp @@ -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,18 +57,6 @@ 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]); } @@ -332,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; } diff --git a/src/lib/synergy/ClipboardChunk.cpp b/src/lib/synergy/ClipboardChunk.cpp index 25c0e2d86..292826ee6 100644 --- a/src/lib/synergy/ClipboardChunk.cpp +++ b/src/lib/synergy/ClipboardChunk.cpp @@ -118,7 +118,7 @@ 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; } 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/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 03a309e81..3663607a9 100644 --- a/src/setup/win32/Product.wxs +++ b/src/setup/win32/Product.wxs @@ -28,8 +28,23 @@ + + + + + + + + + = 602)]]> + + + + 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/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); -}