diff --git a/cmd/synergyc/synergyc.cpp b/cmd/synergyc/synergyc.cpp
index f1707e90..bd415e6a 100644
--- a/cmd/synergyc/synergyc.cpp
+++ b/cmd/synergyc/synergyc.cpp
@@ -27,6 +27,6 @@
int
main(int argc, char** argv)
{
- CClientApp app;
- return app.run(argc, argv, createTaskBarReceiver);
+ CClientApp app(createTaskBarReceiver);
+ return app.run(argc, argv);
}
diff --git a/cmd/synergys/synergys.cpp b/cmd/synergys/synergys.cpp
index bee31152..6272cdae 100644
--- a/cmd/synergys/synergys.cpp
+++ b/cmd/synergys/synergys.cpp
@@ -27,6 +27,6 @@
int
main(int argc, char** argv)
{
- CServerApp app;
- return app.run(argc, argv, createTaskBarReceiver);
+ CServerApp app(createTaskBarReceiver);
+ return app.run(argc, argv);
}
diff --git a/gui/qsynergy.pro b/gui/qsynergy.pro
index f67e03af..442b33e8 100644
--- a/gui/qsynergy.pro
+++ b/gui/qsynergy.pro
@@ -1,87 +1,83 @@
QT += network
-
TEMPLATE = app
TARGET = qsynergy
-DEPENDPATH += . res
-INCLUDEPATH += . src
-
-FORMS += \
- res/MainWindowBase.ui \
- res/AboutDialogBase.ui \
- res/ServerConfigDialogBase.ui \
- res/ScreenSettingsDialogBase.ui \
- res/ActionDialogBase.ui \
- res/HotkeyDialogBase.ui \
- res/SettingsDialogBase.ui \
- res/LogDialogBase.ui
-SOURCES += \
- src/main.cpp \
- src/MainWindow.cpp \
- src/AboutDialog.cpp \
- src/ServerConfig.cpp \
- src/ServerConfigDialog.cpp \
- src/ScreenSetupView.cpp \
- src/Screen.cpp \
- src/ScreenSetupModel.cpp \
- src/NewScreenWidget.cpp \
- src/TrashScreenWidget.cpp \
- src/ScreenSettingsDialog.cpp \
- src/BaseConfig.cpp \
- src/HotkeyDialog.cpp \
- src/ActionDialog.cpp \
- src/Hotkey.cpp \
- src/Action.cpp \
- src/KeySequence.cpp \
- src/KeySequenceWidget.cpp \
- src/LogDialog.cpp \
- src/SettingsDialog.cpp \
- src/AppConfig.cpp \
- src/QSynergyApplication.cpp
-HEADERS += \
- src/MainWindow.h \
- src/AboutDialog.h \
- src/ServerConfig.h \
- src/ServerConfigDialog.h \
- src/ScreenSetupView.h \
- src/Screen.h \
- src/ScreenSetupModel.h \
- src/NewScreenWidget.h \
- src/TrashScreenWidget.h \
- src/ScreenSettingsDialog.h \
- src/BaseConfig.h \
- src/HotkeyDialog.h \
- src/ActionDialog.h \
- src/Hotkey.h \
- src/Action.h \
- src/KeySequence.h \
- src/KeySequenceWidget.h \
- src/LogDialog.h \
- src/SettingsDialog.h \
- src/AppConfig.h \
- src/QSynergyApplication.h
+DEPENDPATH += . \
+ res
+INCLUDEPATH += . \
+ src
+FORMS += res/MainWindowBase.ui \
+ res/AboutDialogBase.ui \
+ res/ServerConfigDialogBase.ui \
+ res/ScreenSettingsDialogBase.ui \
+ res/ActionDialogBase.ui \
+ res/HotkeyDialogBase.ui \
+ res/SettingsDialogBase.ui \
+ res/LogDialogBase.ui \
+ res/WindowsServicesBase.ui
+SOURCES += src/main.cpp \
+ src/MainWindow.cpp \
+ src/AboutDialog.cpp \
+ src/ServerConfig.cpp \
+ src/ServerConfigDialog.cpp \
+ src/ScreenSetupView.cpp \
+ src/Screen.cpp \
+ src/ScreenSetupModel.cpp \
+ src/NewScreenWidget.cpp \
+ src/TrashScreenWidget.cpp \
+ src/ScreenSettingsDialog.cpp \
+ src/BaseConfig.cpp \
+ src/HotkeyDialog.cpp \
+ src/ActionDialog.cpp \
+ src/Hotkey.cpp \
+ src/Action.cpp \
+ src/KeySequence.cpp \
+ src/KeySequenceWidget.cpp \
+ src/LogDialog.cpp \
+ src/SettingsDialog.cpp \
+ src/AppConfig.cpp \
+ src/QSynergyApplication.cpp \
+ src/WindowsServices.cpp
+HEADERS += src/MainWindow.h \
+ src/AboutDialog.h \
+ src/ServerConfig.h \
+ src/ServerConfigDialog.h \
+ src/ScreenSetupView.h \
+ src/Screen.h \
+ src/ScreenSetupModel.h \
+ src/NewScreenWidget.h \
+ src/TrashScreenWidget.h \
+ src/ScreenSettingsDialog.h \
+ src/BaseConfig.h \
+ src/HotkeyDialog.h \
+ src/ActionDialog.h \
+ src/Hotkey.h \
+ src/Action.h \
+ src/KeySequence.h \
+ src/KeySequenceWidget.h \
+ src/LogDialog.h \
+ src/SettingsDialog.h \
+ src/AppConfig.h \
+ src/QSynergyApplication.h \
+ src/WindowsServices.h
RESOURCES += res/QSynergy.qrc
RC_FILE = res/win/QSynergy.rc
-
-macx {
- QMAKE_INFO_PLIST = res/mac/QSynergy.plist
- QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4
- TARGET = QSynergy
- QSYNERGY_ICON.files = res/mac/QSynergy.icns
- QSYNERGY_ICON.path = Contents/Resources
- QMAKE_BUNDLE_DATA += QSYNERGY_ICON
+macx {
+ QMAKE_INFO_PLIST = res/mac/QSynergy.plist
+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4
+ TARGET = QSynergy
+ QSYNERGY_ICON.files = res/mac/QSynergy.icns
+ QSYNERGY_ICON.path = Contents/Resources
+ QMAKE_BUNDLE_DATA += QSYNERGY_ICON
}
-
-debug {
- OBJECTS_DIR = tmp/debug
- MOC_DIR = tmp/debug
- RCC_DIR = tmp/debug
+debug {
+ OBJECTS_DIR = tmp/debug
+ MOC_DIR = tmp/debug
+ RCC_DIR = tmp/debug
}
-
-release {
- OBJECTS_DIR = tmp/release
- MOC_DIR = tmp/release
- RCC_DIR = tmp/release
+release {
+ OBJECTS_DIR = tmp/release
+ MOC_DIR = tmp/release
+ RCC_DIR = tmp/release
}
-
Debug:DESTDIR = ../bin/Debug
Release:DESTDIR = ../bin/Release
diff --git a/gui/res/MainWindowBase.ui b/gui/res/MainWindowBase.ui
index ac52f236..ac78cb57 100644
--- a/gui/res/MainWindowBase.ui
+++ b/gui/res/MainWindowBase.ui
@@ -7,7 +7,7 @@
0
0
400
- 247
+ 260
@@ -19,13 +19,13 @@
400
- 247
+ 260
400
- 247
+ 260
@@ -33,7 +33,7 @@
- -
+
-
&Start
@@ -133,19 +133,6 @@
- -
-
-
- Qt::Vertical
-
-
-
- 0
- 0
-
-
-
-
-
@@ -177,14 +164,14 @@
- -
+
-
Ready
- -
+
-
Qt::Horizontal
@@ -201,7 +188,7 @@
- &About QSynergy...
+ &About Synergy+...
@@ -209,7 +196,7 @@
&Quit
- Quit QSynergy.
+ Quit
Ctrl+Q
@@ -217,10 +204,10 @@
- &Start Synergy
+ &Start
- Run synergy program.
+ Run
Ctrl+S
@@ -231,10 +218,10 @@
false
- S&top Synergy
+ S&top
- Stop Synergy program.
+ Stop
Ctrl+T
@@ -274,7 +261,7 @@
Settings
- Edit settings for QSynergy and synergy itself
+ Edit settings
@@ -282,7 +269,12 @@
Log output
- Open a window with synergy's output
+ Open a window with output
+
+
+
+
+ Services
diff --git a/gui/res/SettingsDialogBase.ui b/gui/res/SettingsDialogBase.ui
index 53cdb2f3..a093f02a 100644
--- a/gui/res/SettingsDialogBase.ui
+++ b/gui/res/SettingsDialogBase.ui
@@ -7,7 +7,7 @@
0
0
372
- 350
+ 412
@@ -15,7 +15,7 @@
-
-
+
&Advanced
@@ -81,7 +81,7 @@
-
-
+
&Start
@@ -89,62 +89,13 @@
-
- A&utomatically start synergy when QSynergy starts
+ A&utomatically start server or client when GUI starts
- -
-
-
- &Logging level:
-
-
- m_pComboLogLevel
-
-
-
- -
-
-
-
-
- Error
-
-
- -
-
- Warning
-
-
- -
-
- Note
-
-
- -
-
- Info
-
-
- -
-
- Debug
-
-
- -
-
- Debug1
-
-
- -
-
- Debug2
-
-
-
-
-
@@ -156,11 +107,25 @@
-
-
+
&Programs
+
-
+
+
-
+
+
+ Auto detect program paths
+
+
+ true
+
+
+
+
+
-
@@ -175,12 +140,19 @@
-
-
+
+
+ false
+
+
-
+
+ false
+
- &Browse...
+ Browse...
@@ -201,25 +173,103 @@
-
-
-
- -
-
-
- Bro&wse...
+
+
+ false
- -
-
+
-
+
+
+ false
+
+
+ Browse...
+
+
+
+
+
+
+ -
+
+
+ Logging
+
+
+
-
+
+
+ &Logging level:
+
+
+ m_pComboLogLevel
+
+
+
+ -
+
+
+ Log to file:
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+ Browse...
+
+
+
+ -
+
-
-
-
- Auto detect program paths
-
-
+
+ Error
+
-
+ -
+
+ Warning
+
+
+ -
+
+ Note
+
+
+ -
+
+ Info
+
+
+ -
+
+ Debug
+
+
+ -
+
+ Debug1
+
+
+ -
+
+ Debug2
+
+
+
@@ -237,6 +287,9 @@
m_pLineEditInterface
m_pCheckBoxAutoConnect
m_pComboLogLevel
+ m_pCheckBoxLogToFile
+ m_pLineEditLogFilename
+ m_pButtonBrowseLog
buttonBox
diff --git a/gui/res/WindowsServicesBase.ui b/gui/res/WindowsServicesBase.ui
new file mode 100644
index 00000000..72440427
--- /dev/null
+++ b/gui/res/WindowsServicesBase.ui
@@ -0,0 +1,161 @@
+
+
+ WindowsServicesBase
+
+
+
+ 0
+ 0
+ 264
+ 200
+
+
+
+ Windows Services
+
+
+ -
+
+
+ Server
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Uninstall
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Install
+
+
+
+
+
+
+ -
+
+
+ Client
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Uninstall
+
+
+
+ -
+
+
+ Install
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+ -
+
+
+ To start and stop a service, use the Windows services snap-in.
+
+
+ true
+
+
+
+
+
+
+ buttonBox
+
+
+
+
+ buttonBox
+ accepted()
+ WindowsServicesBase
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ WindowsServicesBase
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/gui/src/AppConfig.cpp b/gui/src/AppConfig.cpp
index ea1b850e..2ef35e0b 100644
--- a/gui/src/AppConfig.cpp
+++ b/gui/src/AppConfig.cpp
@@ -7,12 +7,24 @@
const char AppConfig::m_SynergysName[] = "synergys.exe";
const char AppConfig::m_SynergycName[] = "synergyc.exe";
const char AppConfig::m_SynergyProgramDir[] = "bin/";
+const char AppConfig::m_SynergyLogDir[] = "log/";
#else
const char AppConfig::m_SynergysName[] = "synergys";
const char AppConfig::m_SynergycName[] = "synergyc";
const char AppConfig::m_SynergyProgramDir[] = "/usr/bin/";
+const char AppConfig::m_SynergyLogDir[] = "/var/log/";
#endif
+static const char* logLevelNames[] =
+{
+ "ERROR",
+ "WARNING",
+ "NOTE",
+ "INFO",
+ "DEBUG",
+ "DEBUG1",
+ "DEBUG2"
+};
AppConfig::AppConfig(QSettings* settings) :
m_pSettings(settings),
@@ -34,6 +46,33 @@ AppConfig::~AppConfig()
saveSettings();
}
+QString AppConfig::synergyLogDir()
+{
+#if defined(Q_OS_WIN)
+ // on windows, we want to log to program files
+ return QString(QDir::currentPath() + "/log/");
+#else
+ // on unix, we'll log to the standard log dir
+ return "/var/log/";
+#endif
+}
+
+void AppConfig::persistLogDir()
+{
+ QDir dir = synergyLogDir();
+
+ // persist the log directory
+ if (!dir.exists())
+ {
+ dir.mkpath(dir.path());
+ }
+}
+
+QString AppConfig::logLevelText() const
+{
+ return logLevelNames[logLevel()];
+}
+
void AppConfig::loadSettings()
{
m_AutoConnect = settings().value("autoConnectChecked", false).toBool();
@@ -42,8 +81,10 @@ void AppConfig::loadSettings()
m_ScreenName = settings().value("screenName", QHostInfo::localHostName()).toString();
m_Port = settings().value("port", 24800).toInt();
m_Interface = settings().value("interface").toString();
- m_LogLevel = settings().value("logLevelIndex", 0).toInt();
+ m_LogLevel = settings().value("logLevel", 2).toInt();
m_AutoDetectPaths = settings().value("autoDetectPaths", true).toBool();
+ m_LogToFile = settings().value("logToFile", true).toBool();
+ m_LogFilename = settings().value("logFilename", synergyLogDir() + "synergy.log").toString();
}
void AppConfig::saveSettings()
@@ -54,7 +95,30 @@ void AppConfig::saveSettings()
settings().setValue("screenName", m_ScreenName);
settings().setValue("port", m_Port);
settings().setValue("interface", m_Interface);
- settings().setValue("logLevelIndex", m_LogLevel);
+ settings().setValue("logLevel", m_LogLevel);
settings().setValue("autoDetectPaths", m_AutoDetectPaths);
+ settings().setValue("logToFile", m_LogToFile);
+ settings().setValue("logFilename", m_LogFilename);
}
+bool AppConfig::detectPath(const QString& name, QString& path)
+{
+ // look in current working dir and default dir
+ QStringList searchDirs;
+ searchDirs.append("./");
+ searchDirs.append(synergyProgramDir());
+
+ // use the first valid path we find
+ for (int i = 0; i < searchDirs.length(); i++)
+ {
+ QFile f(searchDirs[i] + name);
+ if (f.exists())
+ {
+ path = f.fileName();
+ return true;
+ }
+ }
+
+ // nothing found!
+ return false;
+}
diff --git a/gui/src/AppConfig.h b/gui/src/AppConfig.h
index 591ba55d..572f8fa0 100644
--- a/gui/src/AppConfig.h
+++ b/gui/src/AppConfig.h
@@ -25,10 +25,17 @@ class AppConfig
const QString& interface() const { return m_Interface; }
int logLevel() const { return m_LogLevel; }
bool autoDetectPaths() const { return m_AutoDetectPaths; }
+ bool logToFile() const { return m_LogToFile; }
+ const QString& logFilename() const { return m_LogFilename; }
+ QString logLevelText() const;
QString synergysName() const { return m_SynergysName; }
QString synergycName() const { return m_SynergycName; }
QString synergyProgramDir() const { return m_SynergyProgramDir; }
+ QString synergyLogDir();
+
+ bool detectPath(const QString& name, QString& path);
+ void persistLogDir();
protected:
QSettings& settings() { return *m_pSettings; }
@@ -40,6 +47,8 @@ class AppConfig
void setInterface(const QString& s) { m_Interface = s; }
void setLogLevel(int i) { m_LogLevel = i; }
void setAutoDetectPaths(bool b) { m_AutoDetectPaths = b; }
+ void setLogToFile(bool b) { m_LogToFile = b; }
+ void setLogFilename(const QString& s) { m_LogFilename = s; }
void loadSettings();
void saveSettings();
@@ -54,10 +63,13 @@ class AppConfig
QString m_Interface;
int m_LogLevel;
bool m_AutoDetectPaths;
+ bool m_LogToFile;
+ QString m_LogFilename;
static const char m_SynergysName[];
static const char m_SynergycName[];
static const char m_SynergyProgramDir[];
+ static const char m_SynergyLogDir[];
};
#endif
diff --git a/gui/src/LogDialog.h b/gui/src/LogDialog.h
index 52d8b21f..c6a83db1 100644
--- a/gui/src/LogDialog.h
+++ b/gui/src/LogDialog.h
@@ -17,6 +17,7 @@ class LogDialog : public QDialog, public Ui::LogDialogBase
public:
void append(const QString& s);
+ void clear() { m_pLogOutput->clear(); }
public slots:
void readSynergyOutput();
diff --git a/gui/src/MainWindow.cpp b/gui/src/MainWindow.cpp
index b485b60e..c62ca99e 100644
--- a/gui/src/MainWindow.cpp
+++ b/gui/src/MainWindow.cpp
@@ -3,6 +3,7 @@
#include "ServerConfigDialog.h"
#include "SettingsDialog.h"
#include "LogDialog.h"
+#include "WindowsServices.h"
#include
#include
@@ -22,18 +23,6 @@ static const char* synergyIconFiles[] =
":/res/icons/16x16/synergy-connected.png"
};
-static const char* logLevelNames[] =
-{
- "ERROR",
- "WARNING",
- "NOTE",
- "INFO",
- "DEBUG",
- "DEBUG1",
- "DEBUG2"
-};
-
-
MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent),
MainWindowBase(),
@@ -121,6 +110,9 @@ void MainWindow::createMenuBar()
pMenuFile->addSeparator();
pMenuFile->addAction(m_pActionQuit);
pMenuEdit->addAction(m_pActionSettings);
+#if defined(Q_OS_WIN)
+ pMenuEdit->addAction(m_pActionServices);
+#endif
pMenuView->addAction(m_pActionLogOutput);
pMenuWindow->addAction(m_pActionMinimize);
pMenuWindow->addAction(m_pActionRestore);
@@ -131,13 +123,6 @@ void MainWindow::createMenuBar()
void MainWindow::loadSettings()
{
- // gui
- QRect rect = settings().value("windowGeometry", geometry()).toRect();
- move(rect.x(), rect.y());
- resize(rect.width(), rect.height());
-
- // program settings
-
// the next two must come BEFORE loading groupServerChecked and groupClientChecked or
// disabling and/or enabling the right widgets won't automatically work
m_pRadioExternalConfig->setChecked(settings().value("externalConfig", false).toBool());
@@ -163,13 +148,6 @@ void MainWindow::initConnections()
void MainWindow::saveSettings()
{
- // gui
- settings().setValue("windowGeometry", geometry());
-
-#if !defined(Q_OS_MAC)
- settings().setValue("windowVisible", isVisible());
-#endif
-
// program settings
settings().setValue("groupServerChecked", m_pGroupServer->isChecked());
settings().setValue("externalConfig", m_pRadioExternalConfig->isChecked());
@@ -205,7 +183,7 @@ void MainWindow::startSynergy()
QString app;
QStringList args;
- args << "-f" << "--debug" << logLevelNames[appConfig().logLevel()];
+ args << "-f" << "--debug" << appConfig().logLevelText();
if (!appConfig().screenName().isEmpty())
args << "--name" << appConfig().screenName();
@@ -236,39 +214,9 @@ void MainWindow::startSynergy()
setSynergyState(synergyConnected);
}
-bool MainWindow::detectPath(const QString& name, QString& path)
-{
- // look in current working dir and default dir
- QStringList searchDirs;
- searchDirs.append("./");
- searchDirs.append(appConfig().synergyProgramDir());
-
- // use the first valid path we find
- for (int i = 0; i < searchDirs.length(); i++)
- {
- QFile f(searchDirs[i] + name);
- if (f.exists())
- {
- path = f.fileName();
- return true;
- }
- }
-
- // nothing found!
- return false;
-}
-
bool MainWindow::clientArgs(QStringList& args, QString& app)
{
- if (appConfig().autoDetectPaths())
- {
- // actually returns bool, but ignore for now
- detectPath(appConfig().synergycName(), app);
- }
- else
- {
- app = appConfig().synergyc();
- }
+ app = appPath(appConfig().synergycName(), appConfig().synergyc());
if (!QFile::exists(app))
{
@@ -289,22 +237,75 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
return false;
}
+ if (appConfig().logToFile())
+ {
+ appConfig().persistLogDir();
+ args << "--log" << appConfig().logFilename();
+ }
+
args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port());
return true;
}
-bool MainWindow::serverArgs(QStringList& args, QString& app)
+QString MainWindow::configFilename()
{
- if (appConfig().autoDetectPaths())
+ QString filename;
+ if (m_pRadioInternalConfig->isChecked())
{
- // actually returns bool, but ignore for now
- detectPath(appConfig().synergysName(), app);
+ // TODO: no need to use a temporary file, since we need it to
+ // be permenant (since it'll be used for Windows services, etc).
+ m_pTempConfigFile = new QTemporaryFile();
+ if (!m_pTempConfigFile->open())
+ {
+ QMessageBox::critical(this, tr("Cannot write configuration file"), tr("The temporary configuration file required to start synergy can not be written."));
+ return false;
+ }
+
+ serverConfig().save(*m_pTempConfigFile);
+ filename = m_pTempConfigFile->fileName();
+
+ m_pTempConfigFile->close();
}
else
{
- app = appConfig().synergys();
+ if (!QFile::exists(m_pLineEditConfigFile->text()))
+ {
+ if (QMessageBox::warning(this, tr("Configuration filename invalid"),
+ tr("You have not filled in a valid configuration file for the synergy server. "
+ "Do you want to browse for the configuration file now?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes
+ || !on_m_pButtonBrowseConfigFile_clicked())
+ return false;
+ }
+
+ filename = m_pLineEditConfigFile->text();
}
+ return filename;
+}
+
+QString MainWindow::address()
+{
+ return (!appConfig().interface().isEmpty() ? appConfig().interface() : "") + ":" + QString::number(appConfig().port());
+}
+
+QString MainWindow::appPath(const QString& name, const QString& defaultPath)
+{
+ QString app;
+ if (appConfig().autoDetectPaths())
+ {
+ // actually returns bool, but ignore for now
+ appConfig().detectPath(name, app);
+ }
+ else
+ {
+ app = defaultPath;
+ }
+ return app;
+}
+
+bool MainWindow::serverArgs(QStringList& args, QString& app)
+{
+ app = appPath(appConfig().synergysName(), appConfig().synergys());
if (!QFile::exists(app))
{
@@ -319,36 +320,13 @@ bool MainWindow::serverArgs(QStringList& args, QString& app)
appConfig().setSynergys(app);
}
- if (m_pRadioInternalConfig->isChecked())
+ if (appConfig().logToFile())
{
- m_pTempConfigFile = new QTemporaryFile();
- if (!m_pTempConfigFile->open())
- {
- QMessageBox::critical(this, tr("Cannot write configuration file"), tr("The temporary configuration file required to start synergy can not be written."));
- return false;
- }
-
- serverConfig().save(*m_pTempConfigFile);
- args << "-c" << m_pTempConfigFile->fileName();
-
- m_pTempConfigFile->close();
- // the file will be removed from disk when the object is deleted; this happens in stopSynergy()
- }
- else
- {
- if (!QFile::exists(m_pLineEditConfigFile->text()))
- {
- if (QMessageBox::warning(this, tr("Configuration filename invalid"),
- tr("You have not filled in a valid configuration file for the synergy server. "
- "Do you want to browse for the configuration file now?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes
- || !on_m_pButtonBrowseConfigFile_clicked())
- return false;
- }
-
- args << "-c" << m_pLineEditConfigFile->text();
+ appConfig().persistLogDir();
+ args << "--log" << appConfig().logFilename();
}
- args << "--address" << (!appConfig().interface().isEmpty() ? appConfig().interface() : "") + ":" + QString::number(appConfig().port());
+ args << "-c" << configFilename() << "--address" << address();
return true;
}
@@ -365,7 +343,9 @@ void MainWindow::stopSynergy()
setSynergyState(synergyDisconnected);
}
- delete m_pTempConfigFile;
+ // HACK: deleting the object deletes the physical file, which is
+ // bad, since it could be in use by the Windows service!
+ //delete m_pTempConfigFile;
m_pTempConfigFile = NULL;
}
@@ -460,6 +440,12 @@ void MainWindow::on_m_pActionSettings_triggered()
dlg.exec();
}
+void MainWindow::on_m_pActionServices_triggered()
+{
+ WindowsServices dlg(this, appConfig());
+ dlg.exec();
+}
+
void MainWindow::on_m_pActionLogOutput_triggered()
{
Q_ASSERT(m_pLogDialog);
diff --git a/gui/src/MainWindow.h b/gui/src/MainWindow.h
index 0e107e3e..023b8b42 100644
--- a/gui/src/MainWindow.h
+++ b/gui/src/MainWindow.h
@@ -54,6 +54,10 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void setVisible(bool visible);
int synergyType() const { return m_pGroupClient->isChecked() ? synergyClient : synergyServer; }
int synergyState() const { return m_SynergyState; }
+ QString hostname() const { return m_pLineEditHostname->text(); }
+ QString configFilename();
+ QString address();
+ QString appPath(const QString& name, const QString& defaultPath);
protected slots:
void on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); }
@@ -63,6 +67,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
bool on_m_pActionSave_triggered();
void on_m_pActionAbout_triggered();
void on_m_pActionSettings_triggered();
+ void on_m_pActionServices_triggered();
void on_m_pActionLogOutput_triggered();
void synergyFinished(int exitCode, QProcess::ExitStatus);
void iconActivated(QSystemTrayIcon::ActivationReason reason);
@@ -87,7 +92,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
bool clientArgs(QStringList& args, QString& app);
bool serverArgs(QStringList& args, QString& app);
void setStatus(const QString& status);
- bool detectPath(const QString& name, QString& path);
private:
QSettings m_Settings;
diff --git a/gui/src/SettingsDialog.cpp b/gui/src/SettingsDialog.cpp
index b64f3067..eaa27e9f 100644
--- a/gui/src/SettingsDialog.cpp
+++ b/gui/src/SettingsDialog.cpp
@@ -20,6 +20,8 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
m_pLineEditInterface->setText(appConfig().interface());
m_pComboLogLevel->setCurrentIndex(appConfig().logLevel());
m_pCheckBoxAutoDetectPaths->setChecked(appConfig().autoDetectPaths());
+ m_pCheckBoxLogToFile->setChecked(appConfig().logToFile());
+ m_pLineEditLogFilename->setText(appConfig().logFilename());
}
QString SettingsDialog::browseForSynergyc(QWidget* parent, const QString& programDir, const QString& synergycName)
@@ -76,7 +78,29 @@ void SettingsDialog::accept()
appConfig().setInterface(m_pLineEditInterface->text());
appConfig().setLogLevel(m_pComboLogLevel->currentIndex());
appConfig().setAutoDetectPaths(m_pCheckBoxAutoDetectPaths->isChecked());
+ appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked());
+ appConfig().setLogFilename(m_pLineEditLogFilename->text());
QDialog::accept();
}
+void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i)
+{
+ bool checked = i == 2;
+
+ m_pLineEditLogFilename->setEnabled(checked);
+ m_pButtonBrowseLog->setEnabled(checked);
+}
+
+void SettingsDialog::on_m_pButtonBrowseLog_clicked()
+{
+ QString fileName = QFileDialog::getSaveFileName(
+ this, tr("Save log file to..."),
+ m_pLineEditLogFilename->text(),
+ "Logs (*.log *.txt)");
+
+ if (!fileName.isEmpty())
+ {
+ m_pLineEditLogFilename->setText(fileName);
+ }
+}
diff --git a/gui/src/SettingsDialog.h b/gui/src/SettingsDialog.h
index 75ba6e1e..5ecb515a 100644
--- a/gui/src/SettingsDialog.h
+++ b/gui/src/SettingsDialog.h
@@ -13,22 +13,22 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
public:
SettingsDialog(QWidget* parent, AppConfig& config);
-
- public:
static QString browseForSynergyc(QWidget* parent, const QString& programDir, const QString& synergycName);
static QString browseForSynergys(QWidget* parent, const QString& programDir, const QString& synergysName);
- protected slots:
- bool on_m_pButtonBrowseSynergys_clicked();
- bool on_m_pButtonBrowseSynergyc_clicked();
- void on_m_pCheckBoxAutoDetectPaths_stateChanged(int i);
-
protected:
void accept();
AppConfig& appConfig() { return m_AppConfig; }
private:
AppConfig& m_AppConfig;
+
+ private slots:
+ void on_m_pCheckBoxLogToFile_stateChanged(int );
+ bool on_m_pButtonBrowseSynergys_clicked();
+ bool on_m_pButtonBrowseSynergyc_clicked();
+ void on_m_pCheckBoxAutoDetectPaths_stateChanged(int i);
+ void on_m_pButtonBrowseLog_clicked();
};
#endif
diff --git a/gui/src/WindowsServices.cpp b/gui/src/WindowsServices.cpp
new file mode 100644
index 00000000..2d807e64
--- /dev/null
+++ b/gui/src/WindowsServices.cpp
@@ -0,0 +1,130 @@
+#include "WindowsServices.h"
+#include "AppConfig.h"
+#include "MainWindow.h"
+#include "LogDialog.h"
+
+#include
+#include
+#include
+#include
+
+WindowsServices::WindowsServices(QWidget* parent, AppConfig& appConfig) :
+ QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
+ Ui::WindowsServicesBase(),
+ m_appConfig(appConfig),
+ m_log(new LogDialog(this, process()))
+{
+ setupUi(this);
+}
+
+void WindowsServices::runProc(const QString& app, const QStringList& args, QPushButton* button)
+{
+ // disable until we know we've finished
+ button->setEnabled(false);
+
+ // clear contents so user doesn't get confused by previous messages
+ m_log->clear();
+
+ // deleted at end of function
+ QProcess proc(this);
+ m_process = &proc;
+
+ // send output to log window
+ connect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput()));
+ connect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput()));
+
+ m_process->start(app, args);
+ m_log->show();
+
+ // service management should be instant
+ m_process->waitForFinished();
+
+ if (m_process->exitCode() == 0)
+ {
+ QMessageBox::information(m_log, "Service manager", "Completed successfully.");
+ }
+ else
+ {
+ QMessageBox::critical(
+ m_log, "Service manager error",
+ QString("Unable to install or uninstall service. Error code: " +
+ QString::number(m_process->exitCode())));
+ }
+
+ disconnect(m_process, SIGNAL(readyReadStandardOutput()), m_log, SLOT(readSynergyOutput()));
+ disconnect(m_process, SIGNAL(readyReadStandardError()), m_log, SLOT(readSynergyOutput()));
+
+ button->setEnabled(true);
+}
+
+void WindowsServices::on_m_pInstallServer_clicked()
+{
+ QString app = mainWindow()->appPath(
+ appConfig().synergysName(), appConfig().synergys());
+
+ QStringList args;
+ args <<
+ "--service" << "install" <<
+ "--relaunch" <<
+ "--debug" << appConfig().logLevelText() <<
+ "-c" << mainWindow()->configFilename() <<
+ "--address" << mainWindow()->address();
+
+ if (appConfig().logToFile())
+ {
+ appConfig().persistLogDir();
+ args << "--log" << appConfig().logFilename();
+ }
+
+ runProc(app, args, m_pInstallServer);
+}
+
+void WindowsServices::on_m_pUninstallServer_clicked()
+{
+ QString app = mainWindow()->appPath(
+ appConfig().synergysName(), appConfig().synergys());
+
+ QStringList args;
+ args << "--service" << "uninstall";
+ runProc(app, args, m_pInstallServer);
+}
+
+void WindowsServices::on_m_pInstallClient_clicked()
+{
+ if (mainWindow()->hostname().isEmpty())
+ {
+ QMessageBox::critical(
+ this, "Service manager error", "Hostname was not specified on main screen.");
+ return;
+ }
+
+ QString app = mainWindow()->appPath(
+ appConfig().synergycName(), appConfig().synergyc());
+
+ QStringList args;
+ args <<
+ "--service" << "install" <<
+ "--relaunch" <<
+ "--debug" << appConfig().logLevelText();
+
+ if (appConfig().logToFile())
+ {
+ appConfig().persistLogDir();
+ args << "--log" << appConfig().logFilename();
+ }
+
+ // hostname must come last to be a valid arg
+ args << mainWindow()->hostname();
+
+ runProc(app, args, m_pInstallServer);
+}
+
+void WindowsServices::on_m_pUninstallClient_clicked()
+{
+ QString app = mainWindow()->appPath(
+ appConfig().synergycName(), appConfig().synergyc());
+
+ QStringList args;
+ args << "--service" << "uninstall";
+ runProc(app, args, m_pInstallServer);
+}
diff --git a/gui/src/WindowsServices.h b/gui/src/WindowsServices.h
new file mode 100644
index 00000000..fb00594e
--- /dev/null
+++ b/gui/src/WindowsServices.h
@@ -0,0 +1,41 @@
+#ifndef WINDOWSSERVICES_H
+#define WINDOWSSERVICES_H
+
+#include "ui_WindowsServicesBase.h"
+
+class QWidget;
+class QProcess;
+class QPushButton;
+class QProcess;
+
+class AppConfig;
+class MainWindow;
+class LogDialog;
+
+class WindowsServices : public QDialog, public Ui::WindowsServicesBase
+{
+ Q_OBJECT
+
+ public:
+ WindowsServices(QWidget* parent, AppConfig& appConfig);
+
+ protected:
+ AppConfig &appConfig() const { return m_appConfig; }
+ MainWindow* mainWindow() const { return (MainWindow*)parent(); }
+ QProcess*& process() { return m_process; }
+ void runProc(const QString& app, const QStringList& args, QPushButton* button);
+
+ private:
+ QString m_app;
+ AppConfig &m_appConfig;
+ QProcess* m_process;
+ LogDialog* m_log;
+
+ private slots:
+ void on_m_pUninstallClient_clicked();
+ void on_m_pInstallClient_clicked();
+ void on_m_pUninstallServer_clicked();
+ void on_m_pInstallServer_clicked();
+};
+
+#endif // WINDOWSSERVICES_H
diff --git a/lib/arch/CArch.cpp b/lib/arch/CArch.cpp
index 823d2d7e..b299ffc7 100644
--- a/lib/arch/CArch.cpp
+++ b/lib/arch/CArch.cpp
@@ -666,9 +666,9 @@ CArch::app() const
}
int
-CArch::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver)
+CArch::run(int argc, char** argv)
{
- return m_appUtil->run(argc, argv, createTaskBarReceiver);
+ return m_appUtil->run(argc, argv);
}
void
diff --git a/lib/arch/CArch.h b/lib/arch/CArch.h
index a5822812..f6bb400a 100644
--- a/lib/arch/CArch.h
+++ b/lib/arch/CArch.h
@@ -186,7 +186,7 @@ public:
virtual bool parseArg(const int& argc, const char* const* argv, int& i);
virtual void adoptApp(CApp* app);
virtual CApp& app() const;
- virtual int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver);
+ virtual int run(int argc, char** argv);
virtual void beforeAppExit();
// expose util so we don't need to re-implement all the functions
diff --git a/lib/arch/CArchAppUtilWindows.cpp b/lib/arch/CArchAppUtilWindows.cpp
index 5e01caa2..0a957e56 100644
--- a/lib/arch/CArchAppUtilWindows.cpp
+++ b/lib/arch/CArchAppUtilWindows.cpp
@@ -44,10 +44,13 @@ CArchAppUtilWindows::~CArchAppUtilWindows()
BOOL WINAPI CArchAppUtilWindows::consoleHandler(DWORD CEvent)
{
- // HACK: it would be nice to delete the s_taskBarReceiver object, but
- // this is best done by the CApp destructor; however i don't feel like
- // opening up that can of worms today... i need sleep.
- instance().app().s_taskBarReceiver->cleanup();
+ if (instance().app().m_taskBarReceiver)
+ {
+ // HACK: it would be nice to delete the s_taskBarReceiver object, but
+ // this is best done by the CApp destructor; however i don't feel like
+ // opening up that can of worms today... i need sleep.
+ instance().app().m_taskBarReceiver->cleanup();
+ }
ExitProcess(kExitTerminated);
return TRUE;
@@ -83,8 +86,17 @@ CArchAppUtilWindows::parseArg(const int& argc, const char* const* argv, int& i)
app().argsBase().m_debugServiceWait = true;
}
else if (app().isArg(i, argc, argv, NULL, "--relaunch")) {
+
app().argsBase().m_relaunchMode = true;
}
+ else if (app().isArg(i, argc, argv, NULL, "--exit-pause")) {
+
+ app().argsBase().m_pauseOnExit = true;
+ }
+ else if (app().isArg(i, argc, argv, NULL, "--no-tray")) {
+
+ app().argsBase().m_disableTray = true;
+ }
else {
// option not supported here
return false;
@@ -258,20 +270,17 @@ foregroundStartupStatic(int argc, char** argv)
void
CArchAppUtilWindows::beforeAppExit()
{
- CString name;
- CArchMiscWindows::getParentProcessName(name);
-
- // if the user did not launch from the command prompt (i.e. it was launched
- // by double clicking, or through a debugger), allow user to read any error
- // messages (instead of the window closing automatically).
- if (name != "cmd.exe") {
+ // this can be handy for debugging, since the application is launched in
+ // a new console window, and will normally close on exit (making it so
+ // that we can't see error messages).
+ if (app().argsBase().m_pauseOnExit) {
std::cout << std::endl << "Press any key to exit..." << std::endl;
int c = _getch();
}
}
int
-CArchAppUtilWindows::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver)
+CArchAppUtilWindows::run(int argc, char** argv)
{
// record window instance for tray icon, etc
CArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
@@ -287,7 +296,7 @@ CArchAppUtilWindows::run(int argc, char** argv, CreateTaskBarReceiverFunc create
app().argsBase().m_daemon = false;
}
- return app().runInner(argc, argv, NULL, startup, createTaskBarReceiver);
+ return app().runInner(argc, argv, NULL, startup);
}
CArchAppUtilWindows&
diff --git a/lib/arch/CArchAppUtilWindows.h b/lib/arch/CArchAppUtilWindows.h
index 505a6526..158f718c 100644
--- a/lib/arch/CArchAppUtilWindows.h
+++ b/lib/arch/CArchAppUtilWindows.h
@@ -58,7 +58,7 @@ public:
void debugServiceWait();
- int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver);
+ int run(int argc, char** argv);
void exitApp(int code);
diff --git a/lib/arch/IArchAppUtil.h b/lib/arch/IArchAppUtil.h
index f2c88a65..028e4ce7 100644
--- a/lib/arch/IArchAppUtil.h
+++ b/lib/arch/IArchAppUtil.h
@@ -25,7 +25,7 @@ public:
virtual bool parseArg(const int& argc, const char* const* argv, int& i) = 0;
virtual void adoptApp(CApp* app) = 0;
virtual CApp& app() const = 0;
- virtual int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver) = 0;
+ virtual int run(int argc, char** argv) = 0;
virtual void beforeAppExit() = 0;
virtual void startNode() = 0;
};
diff --git a/lib/platform/CMSWindowsRelauncher.cpp b/lib/platform/CMSWindowsRelauncher.cpp
index 61991b19..8341021e 100644
--- a/lib/platform/CMSWindowsRelauncher.cpp
+++ b/lib/platform/CMSWindowsRelauncher.cpp
@@ -30,7 +30,7 @@ CMSWindowsRelauncher::startAsync()
void
CMSWindowsRelauncher::startThread(void*)
{
- LOG((CLOG_DEBUG "starting relaunch loop"));
+ LOG((CLOG_NOTE "starting relaunch service"));
int ret = relaunchLoop();
// HACK: this actually throws an exception to exit with 0 (nasty)
diff --git a/lib/synergy/CApp.cpp b/lib/synergy/CApp.cpp
index d6b01258..449fe3a6 100644
--- a/lib/synergy/CApp.cpp
+++ b/lib/synergy/CApp.cpp
@@ -30,11 +30,12 @@
CApp* CApp::s_instance = nullptr;
-CApp::CApp(CArgsBase* args) :
+CApp::CApp(CreateTaskBarReceiverFunc createTaskBarReceiver, CArgsBase* args) :
+m_createTaskBarReceiver(createTaskBarReceiver),
m_args(args),
m_bye(&exit),
-s_taskBarReceiver(NULL),
-s_suspended(false)
+m_taskBarReceiver(NULL),
+m_suspended(false)
{
assert(s_instance == nullptr);
s_instance = this;
@@ -50,6 +51,8 @@ CApp::CArgsBase::CArgsBase() :
m_daemon(false), // daemon mode not supported on windows (use --service)
m_debugServiceWait(false),
m_relaunchMode(false),
+m_pauseOnExit(false),
+m_disableTray(false),
#else
m_daemon(true), // backward compatibility for unix (daemon by default)
#endif
@@ -232,7 +235,7 @@ CApp::version()
}
int
-CApp::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver)
+CApp::run(int argc, char** argv)
{
#if SYSAPI_WIN32
// record window instance for tray icon, etc
@@ -251,7 +254,7 @@ CApp::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver
int result = kExitFailed;
try {
- result = ARCH->run(argc, argv, createTaskBarReceiver);
+ result = ARCH->run(argc, argv);
}
catch (XExitApp& e) {
// instead of showing a nasty error, just exit with the error code.
@@ -322,4 +325,16 @@ CApp::initApp(int argc, const char** argv)
// load configuration
loadConfig();
+
+ if (!argsBase().m_disableTray) {
+
+ // create a log buffer so we can show the latest message
+ // as a tray icon tooltip
+ CBufferedLogOutputter* logBuffer = new CBufferedLogOutputter(1000);
+ CLOG->insert(logBuffer, true);
+
+ // make the task bar receiver. the user can control this app
+ // through the task bar.
+ m_taskBarReceiver = m_createTaskBarReceiver(logBuffer);
+ }
}
diff --git a/lib/synergy/CApp.h b/lib/synergy/CApp.h
index d42373c4..0cdec89f 100644
--- a/lib/synergy/CApp.h
+++ b/lib/synergy/CApp.h
@@ -44,10 +44,12 @@ public:
#if SYSAPI_WIN32
bool m_relaunchMode;
bool m_debugServiceWait;
+ bool m_pauseOnExit;
+ bool m_disableTray;
#endif
};
- CApp(CArgsBase* args);
+ CApp(CreateTaskBarReceiverFunc createTaskBarReceiver, CArgsBase* args);
virtual ~CApp();
// Returns args that are common between server and client.
@@ -62,7 +64,7 @@ public:
// Parse command line arguments.
virtual void parseArgs(int argc, const char* const* argv) = 0;
- int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver);
+ int run(int argc, char** argv);
int daemonMainLoop(int, const char**);
@@ -71,7 +73,7 @@ public:
virtual int mainLoop() = 0;
virtual int foregroundStartup(int argc, char** argv) = 0;
virtual int standardStartup(int argc, char** argv) = 0;
- virtual int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup, CreateTaskBarReceiverFunc createTaskBarReceiver) = 0;
+ virtual int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup) = 0;
// Name of the daemon (used for Unix and Windows).
virtual const char* daemonName() const = 0;
@@ -90,8 +92,8 @@ public:
static CApp& instance() { assert(s_instance != nullptr); return *s_instance; }
- bool s_suspended;
- IArchTaskBarReceiver* s_taskBarReceiver;
+ bool m_suspended;
+ IArchTaskBarReceiver* m_taskBarReceiver;
// If --log was specified in args, then add a file logger.
void setupFileLogging();
@@ -118,6 +120,7 @@ private:
CArgsBase* m_args;
static CApp* s_instance;
CFileLogOutputter* m_fileLog;
+ CreateTaskBarReceiverFunc m_createTaskBarReceiver;
};
#define BYE "\nTry `%s --help' for more information."
@@ -166,6 +169,9 @@ private:
" --service manage the windows service, valid options are:\n" \
" install/uninstall/start/stop\n" \
" --relaunch persistently relaunches process in current user \n" \
- " session (useful for vista and upward).\n"
+ " session (useful for vista and upward).\n" \
+ " --exit-pause wait for key press on exit, can be useful for\n" \
+ " reading error messages that occur on exit.\n" \
+ " --no-tray disable the system tray icon.\n"
#endif
diff --git a/lib/synergy/CClientApp.cpp b/lib/synergy/CClientApp.cpp
index 62cc6092..07e432b4 100644
--- a/lib/synergy/CClientApp.cpp
+++ b/lib/synergy/CClientApp.cpp
@@ -49,8 +49,8 @@
#define RETRY_TIME 1.0
-CClientApp::CClientApp() :
-CApp(new CArgs()),
+CClientApp::CClientApp(CreateTaskBarReceiverFunc createTaskBarReceiver) :
+CApp(createTaskBarReceiver, new CArgs()),
s_client(NULL),
s_clientScreen(NULL)
{
@@ -168,6 +168,7 @@ CClientApp::help()
"Usage: %s"
" [--yscroll ]"
WINAPI_ARG
+ HELP_SYS_ARGS
HELP_COMMON_ARGS
" "
"\n\n"
@@ -175,6 +176,7 @@ CClientApp::help()
"\n"
HELP_COMMON_INFO_1
WINAPI_INFO
+ HELP_SYS_INFO
" --yscroll defines the vertical scrolling delta, which is\n"
HELP_COMMON_INFO_2
"\n"
@@ -224,14 +226,17 @@ CClientApp::createScreen()
void
CClientApp::updateStatus()
{
- s_taskBarReceiver->updateStatus(s_client, "");
+ updateStatus("");
}
void
CClientApp::updateStatus(const CString& msg)
{
- s_taskBarReceiver->updateStatus(s_client, msg);
+ if (m_taskBarReceiver)
+ {
+ m_taskBarReceiver->updateStatus(s_client, msg);
+ }
}
@@ -343,7 +348,7 @@ CClientApp::handleClientFailed(const CEvent& e, void*)
}
else {
LOG((CLOG_WARN "failed to connect to server: %s", info->m_what.c_str()));
- if (!s_suspended) {
+ if (!m_suspended) {
scheduleClientRestart(nextRestartTimeout());
}
}
@@ -358,7 +363,7 @@ CClientApp::handleClientDisconnected(const CEvent&, void*)
if (!args().m_restartable) {
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
- else if (!s_suspended) {
+ else if (!m_suspended) {
s_client->connect();
}
updateStatus();
@@ -530,7 +535,7 @@ CClientApp::standardStartup(int argc, char** argv)
}
int
-CClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup, CreateTaskBarReceiverFunc createTaskBarReceiver)
+CClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
{
// general initialization
args().m_serverAddress = new CNetworkAddress;
@@ -541,15 +546,6 @@ CClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFun
CLOG->insert(outputter);
}
- // save log messages
- // use heap memory because CLog deletes outputters on destruction
- CBufferedLogOutputter* logBuffer = new CBufferedLogOutputter(1000);
- CLOG->insert(logBuffer, true);
-
- // make the task bar receiver. the user can control this app
- // through the task bar.
- s_taskBarReceiver = createTaskBarReceiver(logBuffer);
-
int result;
try
{
@@ -558,8 +554,11 @@ CClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFun
}
catch (...)
{
- // done with task bar receiver
- delete s_taskBarReceiver;
+ if (m_taskBarReceiver)
+ {
+ // done with task bar receiver
+ delete m_taskBarReceiver;
+ }
delete args().m_serverAddress;
diff --git a/lib/synergy/CClientApp.h b/lib/synergy/CClientApp.h
index be9b4b89..e7ddccf1 100644
--- a/lib/synergy/CClientApp.h
+++ b/lib/synergy/CClientApp.h
@@ -33,7 +33,7 @@ public:
CNetworkAddress* m_serverAddress;
};
- CClientApp();
+ CClientApp(CreateTaskBarReceiverFunc createTaskBarReceiver);
virtual ~CClientApp();
// Parse client specific command line arguments.
@@ -54,7 +54,7 @@ public:
int foregroundStartup(int argc, char** argv);
int standardStartup(int argc, char** argv);
- int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup, CreateTaskBarReceiverFunc createTaskBarReceiver);
+ int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup);
CScreen* createScreen();
void updateStatus();
void updateStatus(const CString& msg);
diff --git a/lib/synergy/CServerApp.cpp b/lib/synergy/CServerApp.cpp
index b92ff07b..3d481000 100644
--- a/lib/synergy/CServerApp.cpp
+++ b/lib/synergy/CServerApp.cpp
@@ -50,8 +50,8 @@
CEvent::Type CServerApp::s_reloadConfigEvent = CEvent::kUnknown;
-CServerApp::CServerApp() :
-CApp(new CArgs()),
+CServerApp::CServerApp(CreateTaskBarReceiverFunc createTaskBarReceiver) :
+CApp(createTaskBarReceiver, new CArgs()),
s_server(NULL),
s_forceReconnectEvent(CEvent::kUnknown),
s_resetServerEvent(CEvent::kUnknown),
@@ -370,12 +370,15 @@ CServerApp::stopRetryTimer()
void
CServerApp::updateStatus()
{
- s_taskBarReceiver->updateStatus(s_server, "");
+ updateStatus("");
}
void CServerApp::updateStatus( const CString& msg )
{
- s_taskBarReceiver->updateStatus(s_server, msg);
+ if (m_taskBarReceiver)
+ {
+ m_taskBarReceiver->updateStatus(s_server, msg);
+ }
}
void
@@ -657,20 +660,20 @@ CServerApp::handleScreenError(const CEvent&, void*)
void
CServerApp::handleSuspend(const CEvent&, void*)
{
- if (!s_suspended) {
+ if (!m_suspended) {
LOG((CLOG_INFO "suspend"));
stopServer();
- s_suspended = true;
+ m_suspended = true;
}
}
void
CServerApp::handleResume(const CEvent&, void*)
{
- if (s_suspended) {
+ if (m_suspended) {
LOG((CLOG_INFO "resume"));
startServer();
- s_suspended = false;
+ m_suspended = false;
}
}
@@ -796,7 +799,7 @@ void CServerApp::resetServer(const CEvent&, void*)
}
int
-CServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup, CreateTaskBarReceiverFunc createTaskBarReceiver)
+CServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
{
// general initialization
args().m_synergyAddress = new CNetworkAddress;
@@ -808,20 +811,14 @@ CServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFun
CLOG->insert(outputter);
}
- // save log messages
- // use heap memory because CLog deletes outputters on destruction
- CBufferedLogOutputter* logBuffer = new CBufferedLogOutputter(1000);
- CLOG->insert(logBuffer, true);
-
- // make the task bar receiver. the user can control this app
- // through the task bar.
- s_taskBarReceiver = createTaskBarReceiver(logBuffer);
-
// run
int result = startup(argc, argv);
- // done with task bar receiver
- delete s_taskBarReceiver;
+ if (m_taskBarReceiver)
+ {
+ // done with task bar receiver
+ delete m_taskBarReceiver;
+ }
delete args().m_config;
delete args().m_synergyAddress;
diff --git a/lib/synergy/CServerApp.h b/lib/synergy/CServerApp.h
index c2ea50dd..5134423b 100644
--- a/lib/synergy/CServerApp.h
+++ b/lib/synergy/CServerApp.h
@@ -49,7 +49,7 @@ public:
CConfig* m_config;
};
- CServerApp();
+ CServerApp(CreateTaskBarReceiverFunc createTaskBarReceiver);
virtual ~CServerApp();
// Parse server specific command line arguments.
@@ -99,7 +99,7 @@ public:
void handleNoClients(const CEvent&, void*);
bool startServer();
int mainLoop();
- int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup, CreateTaskBarReceiverFunc createTaskBarReceiver);
+ int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup);
int standardStartup(int argc, char** argv);
int foregroundStartup(int argc, char** argv);
void startNode();