diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c8d9d6a..3492a0c68 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 6) set(VERSION_STAGE stable) set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV}") diff --git a/ChangeLog b/ChangeLog index 477426ca4..eb209c696 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +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 @@ class InternalCommands: ' 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 @@ class InternalCommands: # 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 @@ class InternalCommands: 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 @@ class InternalCommands: 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 @@ class InternalCommands: 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 @@ class InternalCommands: 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 @@ class InternalCommands: 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 @@ class InternalCommands: # 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 @@ class CommandHandler: 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/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..335dd821b 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 + (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..f7be9fbf7 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -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/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 @@ private: // HACK // 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 @@ private: // 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; - } + postHIDVirtualKey(virtualKey, keyDown); - // 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; - } - - // 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 @@ private: 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/server/Server.cpp b/src/lib/server/Server.cpp index ec730bcd4..c980d03b3 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" @@ -2004,14 +2003,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/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/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); -}