Merge changes from v1.8.6 and v1.8.7

This commit is contained in:
Andrew Nelless 2017-01-20 23:18:03 +00:00
commit c27c094f9c
26 changed files with 232 additions and 363 deletions

View File

@ -27,4 +27,6 @@ Client: Applesoft Windy OS 10
* Is there a way to work around it? No/Yes, you can... * Is there a way to work around it? No/Yes, you can...
* Does this bug prevent you from using Synergy entirely? Yes/No * 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. Put anything else you can think of here.

View File

@ -1,3 +1,16 @@
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 v1.8.5-stable
============= =============
Bug #5680 - Server crashes when disconnecting SSL clients Bug #5680 - Server crashes when disconnecting SSL clients

View File

@ -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) 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/) 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) 3. Copy the binaries to /usr/bin using: sudo cp synergy* /usr/bin
4. Copy the binaries to /usr/bin using: 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 http://support.apple.com/en-us/ht1528
Once the binaries have been copied to /usr/bin, you should follow the configuration guide: Once the binaries have been copied to /usr/bin, you should follow the configuration guide:

View File

@ -41,7 +41,7 @@ class Toolchain:
cmd_opt_dict = { cmd_opt_dict = {
'about' : ['', []], 'about' : ['', []],
'setup' : ['g:', ['generator=']], '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']], 'build' : ['dr', ['debug', 'release']],
'clean' : ['dr', ['debug', 'release']], 'clean' : ['dr', ['debug', 'release']],
'update' : ['', []], 'update' : ['', []],
@ -247,6 +247,9 @@ class InternalCommands:
# by default, unknown # by default, unknown
macSdk = None macSdk = None
# by default, unknown
macDeploy = None
# by default, unknown # by default, unknown
macIdentity = None macIdentity = None
@ -311,7 +314,7 @@ class InternalCommands:
' genlist Shows the list of available platform generators\n' ' genlist Shows the list of available platform generators\n'
' usage Shows the help screen\n' ' usage Shows the help screen\n'
'\n' '\n'
'Example: %s build -g 3' 'Example: %s conf -g 3'
) % (app, app) ) % (app, app)
def configureAll(self, targets, extraArgs=''): def configureAll(self, targets, extraArgs=''):
@ -370,7 +373,7 @@ class InternalCommands:
# ensure latest setup and do not ask config for generator (only fall # ensure latest setup and do not ask config for generator (only fall
# back to prompt if not specified as arg) # back to prompt if not specified as arg)
self.ensure_setup_latest() self.ensure_setup_latest()
if sys.platform == "darwin": if sys.platform == "darwin":
config = self.getConfig() config = self.getConfig()
@ -379,6 +382,11 @@ class InternalCommands:
elif config.has_option("hm", "macSdk"): elif config.has_option("hm", "macSdk"):
self.macSdk = config.get('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: if self.macIdentity:
config.set('hm', 'macIdentity', self.macIdentity) config.set('hm', 'macIdentity', self.macIdentity)
elif config.has_option("hm", "macIdentity"): elif config.has_option("hm", "macIdentity"):
@ -388,7 +396,10 @@ class InternalCommands:
if not self.macSdk: if not self.macSdk:
raise Exception("Arg missing: --mac-sdk <version>"); raise Exception("Arg missing: --mac-sdk <version>");
if not self.macDeploy:
self.macDeploy = self.macSdk
if not self.macIdentity: if not self.macIdentity:
raise Exception("Arg missing: --mac-identity <name>"); raise Exception("Arg missing: --mac-identity <name>");
@ -443,7 +454,7 @@ class InternalCommands:
if generator.cmakeName.find('Unix Makefiles') == -1: if generator.cmakeName.find('Unix Makefiles') == -1:
sdkDir = self.getMacSdkDir() sdkDir = self.getMacSdkDir()
cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir 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_MAJOR=" + macSdkMatch.group(1)
cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2) cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2)
@ -505,8 +516,8 @@ class InternalCommands:
sdkDir = self.getMacSdkDir() sdkDir = self.getMacSdkDir()
shortForm = "macosx" + self.macSdk shortForm = "macosx" + self.macSdk
version = str(major) + "." + str(minor) 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() (qMajor, qMinor, qRev) = self.getQmakeVersion()
if qMajor <= 4: if qMajor <= 4:
@ -662,6 +673,9 @@ class InternalCommands:
if config.has_option("hm", "macSdk"): if config.has_option("hm", "macSdk"):
self.macSdk = config.get("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"): if config.has_option("hm", "macIdentity"):
self.macIdentity = config.get("hm", "macIdentity") self.macIdentity = config.get("hm", "macIdentity")
@ -1846,7 +1860,10 @@ class InternalCommands:
# version is major and minor with no dots (e.g. 106) # version is major and minor with no dots (e.g. 106)
version = str(major) + str(minor) 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): def reset(self):
if os.path.exists('build'): if os.path.exists('build'):
@ -1903,6 +1920,8 @@ class CommandHandler:
self.qtDir = a self.qtDir = a
elif o == '--mac-sdk': elif o == '--mac-sdk':
self.ic.macSdk = a self.ic.macSdk = a
elif o == '--mac-deploy':
self.ic.macDeploy = a
elif o == '--mac-identity': elif o == '--mac-identity':
self.ic.macIdentity = a self.ic.macIdentity = a

View File

@ -330,11 +330,13 @@
<tabstop>m_pLineEditScreenName</tabstop> <tabstop>m_pLineEditScreenName</tabstop>
<tabstop>m_pSpinBoxPort</tabstop> <tabstop>m_pSpinBoxPort</tabstop>
<tabstop>m_pLineEditInterface</tabstop> <tabstop>m_pLineEditInterface</tabstop>
<tabstop>m_pComboElevate</tabstop>
<tabstop>m_pCheckBoxAutoHide</tabstop>
<tabstop>m_pCheckBoxEnableCrypto</tabstop>
<tabstop>m_pComboLogLevel</tabstop> <tabstop>m_pComboLogLevel</tabstop>
<tabstop>m_pCheckBoxLogToFile</tabstop> <tabstop>m_pCheckBoxLogToFile</tabstop>
<tabstop>m_pLineEditLogFilename</tabstop> <tabstop>m_pLineEditLogFilename</tabstop>
<tabstop>m_pButtonBrowseLog</tabstop> <tabstop>m_pButtonBrowseLog</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>

View File

@ -71,7 +71,8 @@ void ActivationDialog::accept()
std::pair<bool, QString> result; std::pair<bool, QString> result;
try { try {
QString serialKey = ui->m_pTextEditSerialKey->toPlainText().trimmed(); SerialKey serialKey (ui->m_pTextEditSerialKey->toPlainText().
trimmed().toStdString());
result = m_LicenseManager->setSerialKey(serialKey); result = m_LicenseManager->setSerialKey(serialKey);
} }
catch (std::exception& e) { catch (std::exception& e) {

View File

@ -161,7 +161,7 @@ void AppConfig::loadSettings()
m_ActivateEmail = settings().value("activateEmail", "").toString(); m_ActivateEmail = settings().value("activateEmail", "").toString();
m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool(); m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool();
m_AutoHide = settings().value("autoHide", false).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_lastVersion = settings().value("lastVersion", "Unknown").toString();
m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt(); m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt();
m_ActivationHasRun = settings().value("activationHasRun", false).toBool(); m_ActivationHasRun = settings().value("activationHasRun", false).toBool();

View File

@ -29,11 +29,10 @@ LicenseManager::LicenseManager(AppConfig* appConfig) :
} }
std::pair<bool, QString> std::pair<bool, QString>
LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired) LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired)
{ {
std::pair<bool, QString> ret (true, ""); std::pair<bool, QString> ret (true, "");
time_t currentTime = ::time(0); time_t currentTime = ::time(0);
SerialKey serialKey (serialKeyString.toStdString());
if (!acceptExpired && serialKey.isExpired(currentTime)) { if (!acceptExpired && serialKey.isExpired(currentTime)) {
ret.first = false; ret.first = false;
@ -44,7 +43,8 @@ LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired)
if (serialKey != m_serialKey) { if (serialKey != m_serialKey) {
using std::swap; using std::swap;
swap (serialKey, m_serialKey); swap (serialKey, m_serialKey);
m_AppConfig->setSerialKey(serialKeyString); m_AppConfig->setSerialKey(QString::fromStdString
(m_serialKey.toString()));
emit serialKeyChanged(m_serialKey); emit serialKeyChanged(m_serialKey);
if (serialKey.isTrial()) { if (serialKey.isTrial()) {
@ -114,7 +114,13 @@ LicenseManager::serialKey() const
void LicenseManager::refresh() void LicenseManager::refresh()
{ {
if (!m_AppConfig->serialKey().isEmpty()) { 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))) { if (m_serialKey.isExpired(::time(0))) {
emit endTrial(true); emit endTrial(true);

View File

@ -30,7 +30,8 @@ class LicenseManager: public QObject
public: public:
LicenseManager(AppConfig* appConfig); LicenseManager(AppConfig* appConfig);
std::pair<bool, QString> setSerialKey(QString serialKey, bool acceptExpired = false); std::pair<bool, QString> setSerialKey(SerialKey serialKey,
bool acceptExpired = false);
void refresh(); void refresh();
Edition activeEdition() const; Edition activeEdition() const;
QString activeEditionName() const; QString activeEditionName() const;

View File

@ -808,25 +808,6 @@ bool MainWindow::serverArgs(QStringList& args, QString& app)
args << "--serial-key" << appConfig().serialKey(); 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; return true;
} }

View File

@ -159,7 +159,8 @@ bool checkMacAssistiveDevices()
QMessageBox::information( QMessageBox::information(
NULL, "Synergy", NULL, "Synergy",
"Please enable access to assistive devices " "Please enable access to assistive devices "
"(System Preferences), then re-open Synergy."); "System Preferences -> Security & Privacy -> "
"Privacy -> Accessibility, then re-open Synergy.");
} }
return result; return result;

View File

@ -117,9 +117,11 @@ ArchDaemonUnix::daemonize(const char* name, DaemonFunc func)
open("/dev/null", O_RDWR); open("/dev/null", O_RDWR);
int dupErr = dup(1); int dupErr = dup(1);
if (dupErr)
if (dupErr < 0) {
// NB: file logging actually isn't working at this point! // NB: file logging actually isn't working at this point!
LOG((CLOG_ERR "dup error: %i", dupErr)); LOG((CLOG_ERR "dup error: %i", dupErr));
}
#ifdef __APPLE__ #ifdef __APPLE__
return execSelfNonDaemonized(); return execSelfNonDaemonized();

View File

@ -76,5 +76,5 @@ ArchSystemUnix::setting(const std::string&, const std::string&) const
std::string std::string
ArchSystemUnix::getLibsUsed(void) const ArchSystemUnix::getLibsUsed(void) const
{ {
return "not implmented.\nuse lsof on shell"; return "not implemented.\nuse lsof on shell";
} }

View File

@ -146,7 +146,7 @@ IpcClientProxy::send(const IpcMessage& message)
switch (message.type()) { switch (message.type()) {
case kIpcLogLine: { case kIpcLogLine: {
const IpcLogLineMessage& llm = static_cast<const IpcLogLineMessage&>(message); const IpcLogLineMessage& llm = static_cast<const IpcLogLineMessage&>(message);
String logLine = llm.logLine(); const String logLine = llm.logLine();
ProtocolUtil::writef(&m_stream, kIpcMsgLogLine, &logLine); ProtocolUtil::writef(&m_stream, kIpcMsgLogLine, &logLine);
break; break;
} }

View File

@ -94,7 +94,7 @@ IpcServerProxy::send(const IpcMessage& message)
case kIpcCommand: { case kIpcCommand: {
const IpcCommandMessage& cm = static_cast<const IpcCommandMessage&>(message); const IpcCommandMessage& cm = static_cast<const IpcCommandMessage&>(message);
String command = cm.command(); const String command = cm.command();
ProtocolUtil::writef(&m_stream, kIpcMsgCommand, &command); ProtocolUtil::writef(&m_stream, kIpcMsgCommand, &command);
break; break;
} }

View File

@ -31,7 +31,6 @@
#include "synergy/App.h" #include "synergy/App.h"
#include "synergy/ArgsBase.h" #include "synergy/ArgsBase.h"
#include "synergy/ClientApp.h" #include "synergy/ClientApp.h"
#include "synergy/DpiHelper.h"
#include "mt/Lock.h" #include "mt/Lock.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/win32/ArchMiscWindows.h" #include "arch/win32/ArchMiscWindows.h"
@ -105,7 +104,6 @@ MSWindowsScreen::MSWindowsScreen(
m_xCenter(0), m_yCenter(0), m_xCenter(0), m_yCenter(0),
m_multimon(false), m_multimon(false),
m_xCursor(0), m_yCursor(0), m_xCursor(0), m_yCursor(0),
m_xFractionalMove(0.0f), m_yFractionalMove(0.0f),
m_sequenceNumber(0), m_sequenceNumber(0),
m_mark(0), m_mark(0),
m_markReceived(0), m_markReceived(0),
@ -146,10 +144,6 @@ MSWindowsScreen::MSWindowsScreen(
stopOnDeskSwitch); stopOnDeskSwitch);
m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events); m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events);
DpiHelper::calculateDpi(
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN));
updateScreenShape(); updateScreenShape();
m_class = createWindowClass(); m_class = createWindowClass();
m_window = createWindow(m_class, "Synergy"); m_window = createWindow(m_class, "Synergy");
@ -348,8 +342,7 @@ MSWindowsScreen::leave()
// warp to center // warp to center
LOG((CLOG_DEBUG1 "warping cursor to center: %+d, %+d", m_xCenter, m_yCenter)); LOG((CLOG_DEBUG1 "warping cursor to center: %+d, %+d", m_xCenter, m_yCenter));
float dpi = DpiHelper::getDpi(); warpCursor(m_xCenter, m_yCenter);
warpCursor(m_xCenter / dpi, m_yCenter / dpi);
// disable special key sequences on win95 family // disable special key sequences on win95 family
enableSpecialKeys(false); 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)); 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 UInt32
MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
{ {
@ -1369,20 +1347,10 @@ MSWindowsScreen::onMouseButton(WPARAM wParam, LPARAM lParam)
bool bool
MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) 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 // compute motion delta (relative to the last known
// mouse position) // mouse position)
float x = scaledMX - m_xCursor; SInt32 x = mx - m_xCursor;
float y = scaledMY - m_yCursor; SInt32 y = my - m_yCursor;
LOG((CLOG_DEBUG3 LOG((CLOG_DEBUG3
"mouse move - motion delta: %+d=(%+d - %+d),%+d=(%+d - %+d)", "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 // save position to compute delta of next motion
saveMousePosition((SInt32)scaledMX, (SInt32)scaledMY); saveMousePosition(mx, my);
if (m_isOnScreen) { if (m_isOnScreen) {
// motion on primary screen // motion on primary screen
sendEvent( sendEvent(
m_events->forIPrimaryScreen().motionOnPrimary(), m_events->forIPrimaryScreen().motionOnPrimary(),
MotionInfo::alloc(originalMX, originalMY)); MotionInfo::alloc(m_xCursor, m_yCursor));
if (m_buttons[kButtonLeft] == true && m_draggingStarted == false) { if (m_buttons[kButtonLeft] == true && m_draggingStarted == false) {
m_draggingStarted = true; 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 // will always try to return to the original entry point on the
// secondary screen. // secondary screen.
LOG((CLOG_DEBUG5 "warping server cursor to center: %+d,%+d", m_xCenter, m_yCenter)); LOG((CLOG_DEBUG5 "warping server cursor to center: %+d,%+d", m_xCenter, m_yCenter));
float dpi = DpiHelper::getDpi(); warpCursorNoFlush(m_xCenter, m_yCenter);
warpCursorNoFlush(m_xCenter / dpi, m_yCenter / dpi);
// examine the motion. if it's about the distance // examine the motion. if it's about the distance
// from the center of the screen to an edge then // 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 // ignore (see warpCursorNoFlush() for a further
// description). // description).
static SInt32 bogusZoneSize = 10; static SInt32 bogusZoneSize = 10;
if (-x + bogusZoneSize > (m_xCenter - m_x) / dpi || if (-x + bogusZoneSize > m_xCenter - m_x ||
x + bogusZoneSize > (m_x + m_w - m_xCenter) / dpi || x + bogusZoneSize > m_x + m_w - m_xCenter ||
-y + bogusZoneSize > (m_yCenter - m_y) / dpi || -y + bogusZoneSize > m_yCenter - m_y ||
y + bogusZoneSize > (m_y + m_h - m_yCenter) / dpi) { y + bogusZoneSize > m_y + m_h - m_yCenter) {
LOG((CLOG_DEBUG "dropped bogus delta motion: %+d,%+d", x, y)); LOG((CLOG_DEBUG "dropped bogus delta motion: %+d,%+d", x, y));
} }
else { else {
// send motion // send motion
SInt32 ix, iy; sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(x, y));
accumulateFractionalMove(x, y, ix, iy);
sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(ix, iy));
} }
} }
@ -1623,26 +1588,13 @@ void
MSWindowsScreen::updateScreenShape() MSWindowsScreen::updateScreenShape()
{ {
// get shape and center // get shape and center
if (DpiHelper::s_dpiScaled) { m_w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
// use the original resolution size for width and height m_h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
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_x = GetSystemMetrics(SM_XVIRTUALSCREEN); m_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
m_y = GetSystemMetrics(SM_YVIRTUALSCREEN); m_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1;
m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1;
// check for multiple monitors // check for multiple monitors
m_multimon = (m_w != GetSystemMetrics(SM_CXSCREEN) || m_multimon = (m_w != GetSystemMetrics(SM_CXSCREEN) ||
m_h != GetSystemMetrics(SM_CYSCREEN)); m_h != GetSystemMetrics(SM_CYSCREEN));

View File

@ -216,10 +216,6 @@ private: // HACK
// save last position of mouse to compute next delta movement // save last position of mouse to compute next delta movement
void saveMousePosition(SInt32 x, SInt32 y); 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 // check if it is a modifier key repeating message
bool isModifierRepeat(KeyModifierMask oldState, bool isModifierRepeat(KeyModifierMask oldState,
KeyModifierMask state, WPARAM wParam) const; KeyModifierMask state, WPARAM wParam) const;
@ -270,9 +266,6 @@ private:
// last mouse position // last mouse position
SInt32 m_xCursor, m_yCursor; SInt32 m_xCursor, m_yCursor;
// accumulated fractional pixel moves
float m_xFractionalMove, m_yFractionalMove;
// last clipboard // last clipboard
UInt32 m_sequenceNumber; UInt32 m_sequenceNumber;

View File

@ -23,6 +23,7 @@
#include "base/Log.h" #include "base/Log.h"
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <IOKit/hidsystem/IOHIDLib.h>
// Note that some virtual keys codes appear more than once. The // Note that some virtual keys codes appear more than once. The
// first instance of a virtual key code maps to the KeyID that we // first instance of a virtual key code maps to the KeyID that we
@ -470,6 +471,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 void
OSXKeyState::fakeKey(const Keystroke& keystroke) OSXKeyState::fakeKey(const Keystroke& keystroke)
{ {
@ -478,76 +578,14 @@ OSXKeyState::fakeKey(const Keystroke& keystroke)
KeyButton button = keystroke.m_data.m_button.m_button; KeyButton button = keystroke.m_data.m_button.m_button;
bool keyDown = keystroke.m_data.m_button.m_press; 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); CGKeyCode virtualKey = mapKeyButtonToVirtualKey(button);
LOG((CLOG_DEBUG1 LOG((CLOG_DEBUG1
" button=0x%04x virtualKey=0x%04x keyDown=%s client=0x%04x", " button=0x%04x virtualKey=0x%04x keyDown=%s",
button, virtualKey, keyDown ? "down" : "up", client)); button, virtualKey, keyDown ? "down" : "up"));
CGEventRef ref = CGEventCreateKeyboardEvent( postHIDVirtualKey(virtualKey, keyDown);
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;
}
// 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; break;
} }

View File

@ -149,6 +149,12 @@ private:
static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton); static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton);
void init(); 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: private:
// OS X uses a physical key if 0 for the 'A' key. synergy reserves // OS X uses a physical key if 0 for the 'A' key. synergy reserves

View File

@ -33,7 +33,6 @@
#include "synergy/KeyState.h" #include "synergy/KeyState.h"
#include "synergy/Screen.h" #include "synergy/Screen.h"
#include "synergy/PacketStreamFilter.h" #include "synergy/PacketStreamFilter.h"
#include "synergy/DpiHelper.h"
#include "net/TCPSocket.h" #include "net/TCPSocket.h"
#include "net/IDataSocket.h" #include "net/IDataSocket.h"
#include "net/IListenSocket.h" #include "net/IListenSocket.h"
@ -2004,14 +2003,6 @@ Server::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
SInt32 newX = m_x; SInt32 newX = m_x;
SInt32 newY = m_y; 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 // switch screens
switchScreen(newScreen, newX, newY, false); switchScreen(newScreen, newX, newY, false);
} }

View File

@ -23,7 +23,6 @@
#include "synergy/ClientArgs.h" #include "synergy/ClientArgs.h"
#include "synergy/ToolArgs.h" #include "synergy/ToolArgs.h"
#include "synergy/ArgsBase.h" #include "synergy/ArgsBase.h"
#include "synergy/DpiHelper.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/String.h" #include "base/String.h"
@ -62,18 +61,6 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
// save configuration file path // save configuration file path
args.m_configFile = argv[++i]; 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)) { else if (isArg(i, argc, argv, "", "--serial-key", 1)) {
args.m_serial = SerialKey(argv[++i]); args.m_serial = SerialKey(argv[++i]);
} }
@ -331,6 +318,26 @@ ArgParser::parseDeprecatedArgs(int argc, const char* const* argv, int& i)
i++; i++;
return true; 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; return false;
} }

View File

@ -118,7 +118,7 @@ ClipboardChunk::assemble(synergy::IStream* stream,
return kFinish; return kFinish;
} }
LOG((CLOG_ERR "clipboard transmission failed: unknow error")); LOG((CLOG_ERR "clipboard transmission failed: unknown error"));
return kError; return kError;
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "synergy/DpiHelper.h"
#include "base/Log.h"
#include <assert.h>
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));
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
};

View File

@ -29,8 +29,23 @@
<ComponentGroupRef Id="OpenSslComponents" /> <ComponentGroupRef Id="OpenSslComponents" />
<ComponentGroupRef Id="ProductQtPluginComponents" /> <ComponentGroupRef Id="ProductQtPluginComponents" />
<MergeRef Id="CRT" /> <MergeRef Id="CRT" />
<ComponentRef Id="RegistryEntries" />
</Feature> </Feature>
<DirectoryRef Id="TARGETDIR">
<Component Id="RegistryEntries" Guid="7CF3564D-1F8E-4D3D-9781-E1EE22D5BD67">
<RegistryKey Root="HKLM"
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="[INSTALLFOLDER]synergys.exe" Value="~ HIGHDPIAWARE WIN7RTM"/>
</RegistryKey>
<Condition>
<![CDATA[Installed OR (VersionNT >= 602)]]>
</Condition>
</Component>
</DirectoryRef>
<Icon Id="synergy.ico" SourceFile="$(var.ResPath)/synergy.ico"/> <Icon Id="synergy.ico" SourceFile="$(var.ResPath)/synergy.ico"/>
<WixVariable Id="WixUILicenseRtf" Value="$(var.ResPath)\License.rtf" /> <WixVariable Id="WixUILicenseRtf" Value="$(var.ResPath)\License.rtf" />

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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);
}