added enable crypto argument to synergys/c #4313

This commit is contained in:
XinyuHou 2015-02-12 15:50:08 +00:00
parent bbcca144f5
commit c4c0fc8a08
24 changed files with 106 additions and 66 deletions

View File

@ -56,7 +56,8 @@ AppConfig::AppConfig(QSettings* settings) :
m_ProcessMode(DEFAULT_PROCESS_MODE), m_ProcessMode(DEFAULT_PROCESS_MODE),
m_AutoConfig(true), m_AutoConfig(true),
m_ElevateMode(false), m_ElevateMode(false),
m_AutoConfigPrompted(false) m_AutoConfigPrompted(false),
m_CryptoEnabled(false)
{ {
Q_ASSERT(m_pSettings); Q_ASSERT(m_pSettings);
@ -128,6 +129,7 @@ void AppConfig::loadSettings()
m_Edition = settings().value("edition", Unknown).toInt(); m_Edition = settings().value("edition", Unknown).toInt();
m_ActivateEmail = settings().value("activateEmail", "").toString(); m_ActivateEmail = settings().value("activateEmail", "").toString();
m_UserToken = settings().value("userToken", "").toString(); m_UserToken = settings().value("userToken", "").toString();
m_CryptoEnabled = settings().value("cryptoEnabled", false).toBool();
} }
void AppConfig::saveSettings() void AppConfig::saveSettings()
@ -147,6 +149,7 @@ void AppConfig::saveSettings()
settings().setValue("edition", m_Edition); settings().setValue("edition", m_Edition);
settings().setValue("activateEmail", m_ActivateEmail); settings().setValue("activateEmail", m_ActivateEmail);
settings().setValue("userToken", m_UserToken); settings().setValue("userToken", m_UserToken);
settings().setValue("cryptoEnabled", m_CryptoEnabled);
} }
void AppConfig::setAutoConfig(bool autoConfig) void AppConfig::setAutoConfig(bool autoConfig)

View File

@ -85,6 +85,9 @@ class AppConfig
void persistLogDir(); void persistLogDir();
bool elevateMode(); bool elevateMode();
void setCryptoEnabled(bool e) { m_CryptoEnabled = e; }
bool getCryptoEnabled() { return m_CryptoEnabled; }
protected: protected:
QSettings& settings() { return *m_pSettings; } QSettings& settings() { return *m_pSettings; }
void setScreenName(const QString& s) { m_ScreenName = s; } void setScreenName(const QString& s) { m_ScreenName = s; }
@ -119,6 +122,7 @@ class AppConfig
int m_Edition; int m_Edition;
QString m_ActivateEmail; QString m_ActivateEmail;
QString m_UserToken; QString m_UserToken;
bool m_CryptoEnabled;
static const char m_SynergysName[]; static const char m_SynergysName[];
static const char m_SynergycName[]; static const char m_SynergycName[];

View File

@ -127,6 +127,8 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_SuppressAutoConfigWarning = false; m_SuppressAutoConfigWarning = false;
m_pComboServerList->hide(); m_pComboServerList->hide();
updateEdition();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -442,6 +444,10 @@ void MainWindow::startSynergy()
#endif #endif
if (m_AppConfig.getCryptoEnabled()) {
args << "--enable-crypto";
}
if ((synergyType() == synergyClient && !clientArgs(args, app)) if ((synergyType() == synergyClient && !clientArgs(args, app))
|| (synergyType() == synergyServer && !serverArgs(args, app))) || (synergyType() == synergyServer && !serverArgs(args, app)))
{ {
@ -814,15 +820,8 @@ void MainWindow::changeEvent(QEvent* event)
retranslateUi(this); retranslateUi(this);
retranslateMenuBar(); retranslateMenuBar();
QString mac = getFirstMacAddress(); updateEdition();
QString hashSrc = m_AppConfig.activateEmail() + mac;
QString hashResult = hash(hashSrc);
if (hashResult == m_AppConfig.userToken()) {
setEdition(m_AppConfig.edition());
}
else {
setEdition(Unknown);
}
break; break;
} }
default: default:
@ -1149,6 +1148,19 @@ void MainWindow::promptAutoConfig()
m_AppConfig.setAutoConfigPrompted(true); m_AppConfig.setAutoConfigPrompted(true);
} }
void MainWindow::updateEdition()
{
QString mac = getFirstMacAddress();
QString hashSrc = m_AppConfig.activateEmail() + mac;
QString hashResult = hash(hashSrc);
if (hashResult == m_AppConfig.userToken()) {
setEdition(m_AppConfig.edition());
}
else {
setEdition(Unknown);
}
}
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString ) void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
{ {
if (m_pComboServerList->count() != 0) { if (m_pComboServerList->count() != 0) {

View File

@ -160,6 +160,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
bool isBonjourRunning(); bool isBonjourRunning();
void downloadBonjour(); void downloadBonjour();
void promptAutoConfig(); void promptAutoConfig();
void updateEdition();
private: private:
QSettings& m_Settings; QSettings& m_Settings;

View File

@ -7,11 +7,12 @@
#include <QMovie> #include <QMovie>
#include <QThread> #include <QThread>
PluginWizardPage::PluginWizardPage(QWidget *parent) : PluginWizardPage::PluginWizardPage(AppConfig& appConfig, QWidget *parent) :
QWizardPage(parent), QWizardPage(parent),
m_Finished(false), m_Finished(false),
m_pWebClient(NULL), m_pWebClient(NULL),
m_pPluginManager(NULL) m_pPluginManager(NULL),
m_AppConfig(appConfig)
{ {
setupUi(this); setupUi(this);
@ -79,6 +80,10 @@ void PluginWizardPage::finished()
{ {
updateStatus(tr("Plugins are ready.")); updateStatus(tr("Plugins are ready."));
stopSpinning(); stopSpinning();
// ideally this should check if ns plugin is ready
m_AppConfig.setCryptoEnabled(true);
m_Finished = true; m_Finished = true;
emit completeChanged(); emit completeChanged();
} }

View File

@ -1,6 +1,8 @@
#ifndef PLUGINWIZARDPAGE_H #ifndef PLUGINWIZARDPAGE_H
#define PLUGINWIZARDPAGE_H #define PLUGINWIZARDPAGE_H
#include "AppConfig.h"
#include "ui_PluginWizardPageBase.h" #include "ui_PluginWizardPageBase.h"
#include <QWizardPage> #include <QWizardPage>
@ -12,7 +14,7 @@ class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage {
Q_OBJECT Q_OBJECT
public: public:
PluginWizardPage(QWidget *parent = 0); PluginWizardPage(AppConfig& appConfig, QWidget *parent = 0);
~PluginWizardPage(); ~PluginWizardPage();
void setFinished(bool b) { m_Finished = b; } void setFinished(bool b) { m_Finished = b; }
@ -44,5 +46,6 @@ private:
WebClient* m_pWebClient; WebClient* m_pWebClient;
PluginManager* m_pPluginManager; PluginManager* m_pPluginManager;
QThread* m_pPluginManagerThread; QThread* m_pPluginManagerThread;
AppConfig& m_AppConfig;
}; };
#endif // PLUGINWIZARDPAGE_H #endif // PLUGINWIZARDPAGE_H

View File

@ -53,6 +53,8 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
// elevate checkbox is only useful on ms windows. // elevate checkbox is only useful on ms windows.
m_pCheckBoxElevateMode->hide(); m_pCheckBoxElevateMode->hide();
#endif #endif
m_pCheckBoxEnableCrypto->setChecked(m_AppConfig.getCryptoEnabled());
} }
void SettingsDialog::accept() void SettingsDialog::accept()
@ -120,10 +122,6 @@ void SettingsDialog::on_m_pButtonBrowseLog_clicked()
} }
} }
void SettingsDialog::on_m_pCheckBoxEnableCrypto_stateChanged(int )
{
}
void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index) void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index)
{ {
QString ietfCode = m_pComboLanguage->itemData(index).toString(); QString ietfCode = m_pComboLanguage->itemData(index).toString();
@ -147,3 +145,8 @@ void SettingsDialog::on_m_pCheckBoxElevateMode_toggled(bool checked)
} }
} }
} }
void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked)
{
m_AppConfig.setCryptoEnabled(checked);
}

View File

@ -47,8 +47,8 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
bool m_SuppressElevateWarning; bool m_SuppressElevateWarning;
private slots: private slots:
void on_m_pCheckBoxEnableCrypto_toggled(bool checked);
void on_m_pCheckBoxElevateMode_toggled(bool checked); void on_m_pCheckBoxElevateMode_toggled(bool checked);
void on_m_pCheckBoxEnableCrypto_stateChanged(int );
void on_m_pComboLanguage_currentIndexChanged(int index); void on_m_pComboLanguage_currentIndexChanged(int index);
void on_m_pCheckBoxLogToFile_stateChanged(int ); void on_m_pCheckBoxLogToFile_stateChanged(int );
void on_m_pButtonBrowseLog_clicked(); void on_m_pButtonBrowseLog_clicked();

View File

@ -30,7 +30,7 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_Edition(Unknown) m_Edition(Unknown)
{ {
setupUi(this); setupUi(this);
m_pPluginPage = new PluginWizardPage(); m_pPluginPage = new PluginWizardPage(mainWindow.appConfig());
addPage(m_pPluginPage); addPage(m_pPluginPage);
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)

View File

@ -18,8 +18,6 @@
#pragma once #pragma once
#define PLUGINS_DIR "plugins"
#include "common/IInterface.h" #include "common/IInterface.h"
#include "common/stdmap.h" #include "common/stdmap.h"
#include "base/String.h" #include "base/String.h"

View File

@ -173,12 +173,7 @@ ArchPluginUnix::invoke(
String String
ArchPluginUnix::getPluginsDir() ArchPluginUnix::getPluginsDir()
{ {
#if WINAPI_XWINDOWS return ARCH->getPluginDirectory();
return "/usr/lib/synergy/plugin";
#else
// TODO: pluging should be in bundle in the final release
return "/Users/xinyu/Projects/synergy/bin/plugins";
#endif
} }
void void

View File

@ -163,24 +163,6 @@ ArchPluginWindows::invoke(
} }
} }
String
ArchPluginWindows::getModuleDir()
{
TCHAR c_modulePath[MAX_PATH];
if (GetModuleFileName(NULL, c_modulePath, MAX_PATH) == 0) {
throw XArch(new XArchEvalWindows);
}
String modulePath(c_modulePath);
size_t lastSlash = modulePath.find_last_of("\\");
if (lastSlash != String::npos) {
return modulePath.substr(0, lastSlash);
}
throw XArch("could not get module path.");
}
void void
ArchPluginWindows::getFilenames(const String& pattern, std::vector<String>& filenames) ArchPluginWindows::getFilenames(const String& pattern, std::vector<String>& filenames)
{ {
@ -201,7 +183,7 @@ ArchPluginWindows::getFilenames(const String& pattern, std::vector<String>& file
String ArchPluginWindows::getPluginsDir() String ArchPluginWindows::getPluginsDir()
{ {
return getModuleDir().append("\\").append(PLUGINS_DIR); return ARCH->getPluginDirectory();
} }
void void

View File

@ -44,7 +44,6 @@ public:
void** args); void** args);
private: private:
String getModuleDir();
void getFilenames(const String& pattern, std::vector<String>& filenames); void getFilenames(const String& pattern, std::vector<String>& filenames);
String getPluginsDir(); String getPluginsDir();

View File

@ -60,7 +60,8 @@ Client::Client(
const String& name, const NetworkAddress& address, const String& name, const NetworkAddress& address,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
synergy::Screen* screen, synergy::Screen* screen,
bool enableDragDrop) : bool enableDragDrop,
bool enableCrypto) :
m_mock(false), m_mock(false),
m_name(name), m_name(name),
m_serverAddress(address), m_serverAddress(address),
@ -103,6 +104,13 @@ Client::Client(
new TMethodEventJob<Client>(this, new TMethodEventJob<Client>(this,
&Client::handleFileRecieveCompleted)); &Client::handleFileRecieveCompleted));
} }
if (enableCrypto) {
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
if (m_useSecureNetwork == false) {
LOG((CLOG_NOTE "crypto disabled because of ns plugin not available"));
}
}
} }
Client::~Client() Client::~Client()
@ -152,7 +160,6 @@ Client::connect()
} }
// create the socket // create the socket
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork); IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork);
m_socket = dynamic_cast<TCPSocket*>(socket); m_socket = dynamic_cast<TCPSocket*>(socket);

View File

@ -59,7 +59,8 @@ public:
const String& name, const NetworkAddress& address, const String& name, const NetworkAddress& address,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
synergy::Screen* screen, synergy::Screen* screen,
bool enableDragDrop); bool enableDragDrop,
bool enableCrypto);
~Client(); ~Client();
#ifdef TEST_ENV #ifdef TEST_ENV

View File

@ -23,6 +23,8 @@
#include "net/TSocketMultiplexerMethodJob.h" #include "net/TSocketMultiplexerMethodJob.h"
#include "arch/XArch.h" #include "arch/XArch.h"
static const char s_certificateFilename[] = { "Synergy.pem" };
// //
// SecureListenSocket // SecureListenSocket
// //
@ -57,7 +59,15 @@ SecureListenSocket::accept()
socket->initSsl(true); socket->initSsl(true);
// TODO: customized certificate path // TODO: customized certificate path
socket->loadCertificates("C:\\Temp\\synergy.pem"); String certificateFilename = ARCH->getProfileDirectory();
#if SYSAPI_WIN32
certificateFilename.append("\\");
#elif SYSAPI_UNIX
certificateFilename.append("/");
#endif
certificateFilename.append(s_certificateFilename);
socket->loadCertificates(certificateFilename.c_str());
socket->secureAccept(); socket->secureAccept();
if (socket != NULL) { if (socket != NULL) {

View File

@ -41,16 +41,24 @@ static const char s_networkSecurity[] = { "libns" };
ClientListener::ClientListener(const NetworkAddress& address, ClientListener::ClientListener(const NetworkAddress& address,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
IEventQueue* events) : IEventQueue* events,
bool enableCrypto) :
m_socketFactory(socketFactory), m_socketFactory(socketFactory),
m_server(NULL), m_server(NULL),
m_events(events) m_events(events),
m_useSecureNetwork(false)
{ {
assert(m_socketFactory != NULL); assert(m_socketFactory != NULL);
try { try {
// create listen socket // create listen socket
if (enableCrypto) {
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity); m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
if (m_useSecureNetwork == false) {
LOG((CLOG_NOTE "crypto disabled because of ns plugin not available"));
}
}
m_listen = m_socketFactory->createListen(m_useSecureNetwork); m_listen = m_socketFactory->createListen(m_useSecureNetwork);
// bind listen address // bind listen address

View File

@ -37,7 +37,8 @@ public:
// The factories are adopted. // The factories are adopted.
ClientListener(const NetworkAddress&, ClientListener(const NetworkAddress&,
ISocketFactory*, ISocketFactory*,
IEventQueue* events); IEventQueue* events,
bool enableCrypto);
~ClientListener(); ~ClientListener();
//! @name manipulators //! @name manipulators

View File

@ -276,6 +276,9 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
argsBase().m_enableDragDrop = true; argsBase().m_enableDragDrop = true;
} }
} }
else if (isArg(i, argc, argv, NULL, "--enable-crypto")) {
argsBase().m_enableCrypto = true;
}
else { else {
// option not supported here // option not supported here
return false; return false;

View File

@ -41,7 +41,8 @@ m_disableTray(false),
m_enableIpc(false), m_enableIpc(false),
m_enableDragDrop(false), m_enableDragDrop(false),
m_shouldExit(false), m_shouldExit(false),
m_synergyAddress() m_synergyAddress(),
m_enableCrypto(false)
{ {
} }

View File

@ -46,4 +46,5 @@ public:
#endif #endif
bool m_shouldExit; bool m_shouldExit;
String m_synergyAddress; String m_synergyAddress;
bool m_enableCrypto;
}; };

View File

@ -342,7 +342,8 @@ ClientApp::openClient(const String& name, const NetworkAddress& address,
address, address,
new TCPSocketFactory(m_events, getSocketMultiplexer()), new TCPSocketFactory(m_events, getSocketMultiplexer()),
screen, screen,
args().m_enableDragDrop); args().m_enableDragDrop,
args().m_enableCrypto);
try { try {
m_events->adoptHandler( m_events->adoptHandler(

View File

@ -632,7 +632,9 @@ ServerApp::openClientListener(const NetworkAddress& address)
{ {
ClientListener* listen = new ClientListener( ClientListener* listen = new ClientListener(
address, address,
new TCPSocketFactory(m_events, getSocketMultiplexer()), m_events); new TCPSocketFactory(m_events, getSocketMultiplexer()),
m_events,
args().m_enableCrypto);
m_events->adoptHandler( m_events->adoptHandler(
m_events->forClientListener().connected(), listen, m_events->forClientListener().connected(), listen,

View File

@ -114,7 +114,7 @@ TEST_F(NetworkTests, sendToClient_mockData)
// server // server
SocketMultiplexer serverSocketMultiplexer; SocketMultiplexer serverSocketMultiplexer;
TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer);
ClientListener listener(serverAddress, serverSocketFactory, &m_events); ClientListener listener(serverAddress, serverSocketFactory, &m_events, false);
NiceMock<MockScreen> serverScreen; NiceMock<MockScreen> serverScreen;
NiceMock<MockPrimaryClient> primaryClient; NiceMock<MockPrimaryClient> primaryClient;
NiceMock<MockConfig> serverConfig; NiceMock<MockConfig> serverConfig;
@ -140,7 +140,7 @@ TEST_F(NetworkTests, sendToClient_mockData)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true); Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true, false);
m_events.adoptHandler( m_events.adoptHandler(
m_events.forIScreen().fileRecieveCompleted(), &client, m_events.forIScreen().fileRecieveCompleted(), &client,
@ -166,7 +166,7 @@ TEST_F(NetworkTests, sendToClient_mockFile)
// server // server
SocketMultiplexer serverSocketMultiplexer; SocketMultiplexer serverSocketMultiplexer;
TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer);
ClientListener listener(serverAddress, serverSocketFactory, &m_events); ClientListener listener(serverAddress, serverSocketFactory, &m_events, false);
NiceMock<MockScreen> serverScreen; NiceMock<MockScreen> serverScreen;
NiceMock<MockPrimaryClient> primaryClient; NiceMock<MockPrimaryClient> primaryClient;
NiceMock<MockConfig> serverConfig; NiceMock<MockConfig> serverConfig;
@ -192,7 +192,7 @@ TEST_F(NetworkTests, sendToClient_mockFile)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true); Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true, false);
m_events.adoptHandler( m_events.adoptHandler(
m_events.forIScreen().fileRecieveCompleted(), &client, m_events.forIScreen().fileRecieveCompleted(), &client,
@ -217,7 +217,7 @@ TEST_F(NetworkTests, sendToServer_mockData)
// server // server
SocketMultiplexer serverSocketMultiplexer; SocketMultiplexer serverSocketMultiplexer;
TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer);
ClientListener listener(serverAddress, serverSocketFactory, &m_events); ClientListener listener(serverAddress, serverSocketFactory, &m_events, false);
NiceMock<MockScreen> serverScreen; NiceMock<MockScreen> serverScreen;
NiceMock<MockPrimaryClient> primaryClient; NiceMock<MockPrimaryClient> primaryClient;
NiceMock<MockConfig> serverConfig; NiceMock<MockConfig> serverConfig;
@ -238,7 +238,7 @@ TEST_F(NetworkTests, sendToServer_mockData)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true); Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true, false);
m_events.adoptHandler( m_events.adoptHandler(
m_events.forClientListener().connected(), &listener, m_events.forClientListener().connected(), &listener,
@ -269,7 +269,7 @@ TEST_F(NetworkTests, sendToServer_mockFile)
// server // server
SocketMultiplexer serverSocketMultiplexer; SocketMultiplexer serverSocketMultiplexer;
TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer);
ClientListener listener(serverAddress, serverSocketFactory, &m_events); ClientListener listener(serverAddress, serverSocketFactory, &m_events, false);
NiceMock<MockScreen> serverScreen; NiceMock<MockScreen> serverScreen;
NiceMock<MockPrimaryClient> primaryClient; NiceMock<MockPrimaryClient> primaryClient;
NiceMock<MockConfig> serverConfig; NiceMock<MockConfig> serverConfig;
@ -290,7 +290,7 @@ TEST_F(NetworkTests, sendToServer_mockFile)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true); Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, true, false);
m_events.adoptHandler( m_events.adoptHandler(
m_events.forClientListener().connected(), &listener, m_events.forClientListener().connected(), &listener,