issue #65 - Auto config feature using Zeroconf/Bonjour
merging zeroconf into trunk
This commit is contained in:
parent
1a5ebb7922
commit
8cad7551e6
|
@ -1,3 +1,7 @@
|
|||
1.6.0
|
||||
=====
|
||||
Feature #65 - Auto config feature using Zeroconf/Bonjour
|
||||
|
||||
1.5.1
|
||||
=====
|
||||
Bug #3307 - Configuration file paths containing spaces don't work
|
||||
|
|
Binary file not shown.
|
@ -41,7 +41,12 @@ SOURCES += src/main.cpp \
|
|||
src/Ipc.cpp \
|
||||
src/SynergyLocale.cpp \
|
||||
src/QUtility.cpp \
|
||||
src/PremiumAuth.cpp
|
||||
src/PremiumAuth.cpp \
|
||||
src/ZeroconfServer.cpp \
|
||||
src/ZeroconfThread.cpp \
|
||||
src/ZeroconfRegister.cpp \
|
||||
src/ZeroconfBrowser.cpp \
|
||||
src/ZeroconfService.cpp
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/AboutDialog.h \
|
||||
src/ServerConfig.h \
|
||||
|
@ -69,7 +74,13 @@ HEADERS += src/MainWindow.h \
|
|||
src/Ipc.h \
|
||||
src/SynergyLocale.h \
|
||||
src/QUtility.h \
|
||||
src/PremiumAuth.h
|
||||
src/PremiumAuth.h \
|
||||
src/ZeroconfServer.h \
|
||||
src/ZeroconfThread.h \
|
||||
src/ZeroconfRegister.h \
|
||||
src/ZeroconfRecord.h \
|
||||
src/ZeroconfBrowser.h \
|
||||
src/ZeroconfService.h
|
||||
RESOURCES += res/Synergy.qrc
|
||||
RC_FILE = res/win/Synergy.rc
|
||||
macx {
|
||||
|
@ -82,6 +93,9 @@ macx {
|
|||
QMAKE_BUNDLE_DATA += QSYNERGY_ICON
|
||||
LIBS += $$MACX_LIBS
|
||||
}
|
||||
unix:!macx {
|
||||
LIBS += -ldns_sd
|
||||
}
|
||||
debug {
|
||||
OBJECTS_DIR = tmp/debug
|
||||
MOC_DIR = tmp/debug
|
||||
|
@ -95,5 +109,7 @@ release {
|
|||
win32 {
|
||||
Debug:DESTDIR = ../../bin/Debug
|
||||
Release:DESTDIR = ../../bin/Release
|
||||
LIBS += -L"../../ext/bonjour/x64" -ldnssd
|
||||
INCLUDEPATH += "$(BONJOUR_SDK_HOME)/Include"
|
||||
}
|
||||
else:DESTDIR = ../../bin
|
||||
|
|
|
@ -252,7 +252,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>&Client (use another computer's keyboard and mouse):</string>
|
||||
<string>&Client (use another computer's mouse and keyboard):</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioButtonPremiumLogin">
|
||||
<property name="text">
|
||||
<string>Yes, I have Synergy Premium</string>
|
||||
<string>I donated to Synergy and have a premium login...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -289,33 +289,10 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioButtonPremiumRegister">
|
||||
<property name="text">
|
||||
<string>Tell me more...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioButtonPremiumLater">
|
||||
<property name="text">
|
||||
<string>Not interested</string>
|
||||
<string>No, I have not donated to Synergy, skip this step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -360,7 +337,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Server (new setup)</string>
|
||||
<string>&Server (share this computer's mouse and keyboard)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -373,7 +350,11 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>This is the first computer you are configuring. Your keyboard and mouse are connected to this computer. This will allow you to move your mouse over to another computer's screen. There can only be one server in your setup.</string>
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">My main mouse and keyboard are connected to this computer. This will allow you to move your mouse over to another computer's screen. There can only be one server in your setup.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -405,7 +386,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Client (add to setup)</string>
|
||||
<string>&Client (use another computer's mouse and keyboard)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -418,7 +399,11 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You have already set up a server. This is a computer you wish to control using the server's keyboard and mouse. There can be many clients in your setup.</string>
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You have already set up a server. This computer will be controlled using the server's mouse and keyboard. There can be many clients in your setup.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -443,225 +428,15 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWizardPage" name="m_pCryptoPage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Encryption</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Network traffic can be easily monitored on public networks (e.g. schools and corporate networks) or WiFi networks. Using encryption can reduce the risk that sensitive information (e.g. passwords) will be revealed to others.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableCrypto">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable encryption</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabel_27">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>A longer password will provide stronger encryption. It is a good idea to use 20 characters or more.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="m_pLabel_23">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Password:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pLineEditCryptoPassword1</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="m_pLineEditCryptoPassword1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="m_pLabel_24">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Confirm:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pLineEditCryptoPassword2</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="m_pLineEditCryptoPassword2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>m_pComboLanguage</tabstop>
|
||||
<tabstop>m_pRadioButtonPremiumLogin</tabstop>
|
||||
<tabstop>m_pLineEditPremiumEmail</tabstop>
|
||||
<tabstop>m_pLineEditPremiumPassword</tabstop>
|
||||
<tabstop>m_pRadioButtonPremiumRegister</tabstop>
|
||||
<tabstop>m_pRadioButtonPremiumLater</tabstop>
|
||||
<tabstop>m_pServerRadioButton</tabstop>
|
||||
<tabstop>m_pClientRadioButton</tabstop>
|
||||
<tabstop>m_pLineEditCryptoPassword1</tabstop>
|
||||
<tabstop>m_pLineEditCryptoPassword2</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "ServerConfigDialog.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "SetupWizard.h"
|
||||
#include "ZeroconfService.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
|
@ -64,7 +65,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
|||
m_AppConfig(appConfig),
|
||||
m_pSynergy(NULL),
|
||||
m_SynergyState(synergyDisconnected),
|
||||
m_ServerConfig(&m_Settings, 5, 3),
|
||||
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig.screenName()),
|
||||
m_pTempConfigFile(NULL),
|
||||
m_pTrayIcon(NULL),
|
||||
m_pTrayIconMenu(NULL),
|
||||
|
@ -75,7 +76,8 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
|||
m_pMenuFile(NULL),
|
||||
m_pMenuEdit(NULL),
|
||||
m_pMenuWindow(NULL),
|
||||
m_pMenuHelp(NULL)
|
||||
m_pMenuHelp(NULL),
|
||||
m_pZeroconfService(NULL)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
|
@ -107,16 +109,20 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
|||
resize(700, 530);
|
||||
setMinimumSize(size());
|
||||
#endif
|
||||
|
||||
updateZeroconfService();
|
||||
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
if (appConfig().processMode() == Desktop)
|
||||
{
|
||||
if (appConfig().processMode() == Desktop) {
|
||||
stopDesktop();
|
||||
}
|
||||
|
||||
saveSettings();
|
||||
|
||||
delete m_pZeroconfService;
|
||||
}
|
||||
|
||||
void MainWindow::open()
|
||||
|
@ -382,8 +388,8 @@ void MainWindow::startSynergy()
|
|||
|
||||
args << "-f" << "--no-tray" << "--debug" << appConfig().logLevelText();
|
||||
|
||||
if (!appConfig().screenName().isEmpty())
|
||||
args << "--name" << appConfig().screenName();
|
||||
|
||||
args << "--name" << getScreenName();
|
||||
|
||||
if (appConfig().cryptoEnabled())
|
||||
{
|
||||
|
@ -553,7 +559,8 @@ QString MainWindow::configFilename()
|
|||
|
||||
QString MainWindow::address()
|
||||
{
|
||||
return (!appConfig().interface().isEmpty() ? appConfig().interface() : "") + ":" + QString::number(appConfig().port());
|
||||
QString i = appConfig().interface();
|
||||
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
||||
}
|
||||
|
||||
QString MainWindow::appPath(const QString& name)
|
||||
|
@ -796,6 +803,29 @@ void MainWindow::updatePremiumInfo()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateZeroconfService()
|
||||
{
|
||||
if (!m_AppConfig.wizardShouldRun()) {
|
||||
if (m_pZeroconfService) {
|
||||
delete m_pZeroconfService;
|
||||
}
|
||||
|
||||
m_pZeroconfService = new ZeroconfService(this);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
||||
{
|
||||
m_pGroupServer->setChecked(!on);
|
||||
updateZeroconfService();
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pGroupServer_toggled(bool on)
|
||||
{
|
||||
m_pGroupClient->setChecked(!on);
|
||||
updateZeroconfService();
|
||||
}
|
||||
|
||||
bool MainWindow::on_m_pButtonBrowseConfigFile_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Browse for a synergys config file"), QString(), synergyConfigFilter);
|
||||
|
@ -841,12 +871,37 @@ void MainWindow::on_m_pActionSettings_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pButtonConfigureServer_clicked()
|
||||
void MainWindow::autoAddScreen(const QString name)
|
||||
{
|
||||
int r = m_ServerConfig.autoAddScreen(name);
|
||||
if (r != kAutoAddScreenOk) {
|
||||
switch (r) {
|
||||
case kAutoAddScreenNoServer:
|
||||
showConfigureServer(
|
||||
tr("Please add the server (%1) to the grid.")
|
||||
.arg(appConfig().screenName()));
|
||||
break;
|
||||
|
||||
case kAutoAddScreenNoSpace:
|
||||
showConfigureServer(
|
||||
tr("Please add the client (%1) to the grid.").arg(name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::showConfigureServer(const QString& message)
|
||||
{
|
||||
ServerConfigDialog dlg(this, serverConfig(), appConfig().screenName());
|
||||
dlg.message(message);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pButtonConfigureServer_clicked()
|
||||
{
|
||||
showConfigureServer();
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pActionWizard_triggered()
|
||||
{
|
||||
SetupWizard wizard(*this, false);
|
||||
|
|
|
@ -49,6 +49,7 @@ class QTemporaryFile;
|
|||
class LogDialog;
|
||||
class QSynergyApplication;
|
||||
class SetupWizard;
|
||||
class ZeroconfService;
|
||||
|
||||
class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
{
|
||||
|
@ -91,6 +92,13 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void open();
|
||||
void clearLog();
|
||||
VersionChecker& versionChecker() { return m_VersionChecker; }
|
||||
QString getScreenName();
|
||||
void startSynergy();
|
||||
ServerConfig& serverConfig() { return m_ServerConfig; }
|
||||
void showConfigureServer(const QString& message);
|
||||
void showConfigureServer() { showConfigureServer(""); }
|
||||
void autoAddScreen(const QString name);
|
||||
void updateZeroconfService();
|
||||
|
||||
public slots:
|
||||
void appendLogRaw(const QString& text);
|
||||
|
@ -98,8 +106,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void appendLogError(const QString& text);
|
||||
|
||||
protected slots:
|
||||
void on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); }
|
||||
void on_m_pGroupServer_toggled(bool on) { m_pGroupClient->setChecked(!on); }
|
||||
void on_m_pGroupClient_toggled(bool on);
|
||||
void on_m_pGroupServer_toggled(bool on);
|
||||
bool on_m_pButtonBrowseConfigFile_clicked();
|
||||
void on_m_pButtonConfigureServer_clicked();
|
||||
bool on_m_pActionSave_triggered();
|
||||
|
@ -109,7 +117,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void on_m_pElevateCheckBox_toggled(bool checked);
|
||||
void synergyFinished(int exitCode, QProcess::ExitStatus);
|
||||
void trayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void startSynergy();
|
||||
void stopSynergy();
|
||||
void logOutput();
|
||||
void logError();
|
||||
|
@ -120,7 +127,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
AppConfig& appConfig() { return m_AppConfig; }
|
||||
QProcess*& synergyProcess() { return m_pSynergy; }
|
||||
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
|
||||
ServerConfig& serverConfig() { return m_ServerConfig; }
|
||||
void initConnections();
|
||||
void createMenuBar();
|
||||
void createStatusBar();
|
||||
|
@ -137,7 +143,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void onModeChanged(bool startDesktop, bool applyService);
|
||||
void updateStateFromLogLine(const QString& line);
|
||||
QString getIPAddresses();
|
||||
QString getScreenName();
|
||||
void stopService();
|
||||
void stopDesktop();
|
||||
void changeEvent(QEvent* event);
|
||||
|
@ -163,6 +168,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
QMenu* m_pMenuEdit;
|
||||
QMenu* m_pMenuWindow;
|
||||
QMenu* m_pMenuHelp;
|
||||
ZeroconfService* m_pZeroconfService;
|
||||
|
||||
private slots:
|
||||
void on_m_pButtonApply_clicked();
|
||||
|
|
|
@ -64,12 +64,12 @@ class Screen : public BaseConfig
|
|||
QTextStream& writeAliasesSection(QTextStream& outStream) const;
|
||||
|
||||
bool swapped() const { return m_Swapped; }
|
||||
QString& name() { return m_Name; }
|
||||
void setName(const QString& name) { m_Name = name; }
|
||||
|
||||
protected:
|
||||
void init();
|
||||
void setName(const QString& name) { m_Name = name; }
|
||||
QPixmap* pixmap() { return &m_Pixmap; }
|
||||
QString& name() { return m_Name; }
|
||||
|
||||
void setPixmap(const QPixmap& pixmap) { m_Pixmap = pixmap; }
|
||||
QStringList& aliases() { return m_Aliases; }
|
||||
|
|
|
@ -28,18 +28,21 @@ static const struct
|
|||
const char* name;
|
||||
} neighbourDirs[] =
|
||||
{
|
||||
{ 0, -1, "up" },
|
||||
{ 1, 0, "right" },
|
||||
{ 0, 1, "down" },
|
||||
{ -1, 0, "left" },
|
||||
{ 0, -1, "up" },
|
||||
{ 0, 1, "down" },
|
||||
|
||||
};
|
||||
|
||||
const int serverDefaultIndex = 7;
|
||||
|
||||
ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows) :
|
||||
ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows , QString serverName) :
|
||||
m_pSettings(settings),
|
||||
m_Screens(),
|
||||
m_NumColumns(numColumns),
|
||||
m_NumRows(numRows)
|
||||
m_NumRows(numRows),
|
||||
m_ServerName(serverName)
|
||||
{
|
||||
Q_ASSERT(m_pSettings);
|
||||
|
||||
|
@ -263,3 +266,62 @@ int ServerConfig::numScreens() const
|
|||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int ServerConfig::autoAddScreen(const QString name)
|
||||
{
|
||||
int serverIndex = -1;
|
||||
int targetIndex = -1;
|
||||
if (!findScreenName(m_ServerName, serverIndex)) {
|
||||
if (!tryFixNoServer(m_ServerName, serverIndex)) {
|
||||
return kAutoAddScreenNoServer;
|
||||
}
|
||||
}
|
||||
if (findScreenName(name, targetIndex)) {
|
||||
// already exists.
|
||||
return kAutoAddScreenOk;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
for (unsigned int i = 0; i < sizeof(neighbourDirs) / sizeof(neighbourDirs[0]); i++) {
|
||||
int idx = adjacentScreenIndex(serverIndex, neighbourDirs[i].x, neighbourDirs[i].y);
|
||||
if (idx != -1 && screens()[idx].isNull()) {
|
||||
m_Screens[idx].setName(name);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
return kAutoAddScreenNoSpace;
|
||||
}
|
||||
|
||||
saveSettings();
|
||||
return kAutoAddScreenOk;
|
||||
}
|
||||
|
||||
bool ServerConfig::findScreenName(const QString& name, int& index)
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = 0; i < screens().size(); i++) {
|
||||
QString test = screens()[i].name();
|
||||
if (!screens()[i].isNull() &&
|
||||
screens()[i].name().compare(name) == 0) {
|
||||
index = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool ServerConfig::tryFixNoServer(const QString& name, int& index)
|
||||
{
|
||||
bool fixed = false;
|
||||
if (screens()[serverDefaultIndex].isNull()) {
|
||||
m_Screens[serverDefaultIndex].setName(name);
|
||||
index = serverDefaultIndex;
|
||||
fixed = true;
|
||||
}
|
||||
|
||||
return fixed;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class ServerConfig : public BaseConfig
|
|||
friend QTextStream& operator<<(QTextStream& outStream, const ServerConfig& config);
|
||||
|
||||
public:
|
||||
ServerConfig(QSettings* settings, int numColumns, int numRows);
|
||||
ServerConfig(QSettings* settings, int numColumns, int numRows, QString serverName);
|
||||
~ServerConfig();
|
||||
|
||||
public:
|
||||
|
@ -64,6 +64,7 @@ class ServerConfig : public BaseConfig
|
|||
bool save(const QString& fileName) const;
|
||||
void save(QFile& file) const;
|
||||
int numScreens() const;
|
||||
int autoAddScreen(const QString name);
|
||||
|
||||
protected:
|
||||
QSettings& settings() { return *m_pSettings; }
|
||||
|
@ -89,6 +90,10 @@ class ServerConfig : public BaseConfig
|
|||
void init();
|
||||
int adjacentScreenIndex(int idx, int deltaColumn, int deltaRow) const;
|
||||
|
||||
private:
|
||||
bool findScreenName(const QString& name, int& index);
|
||||
bool tryFixNoServer(const QString& name, int& index);
|
||||
|
||||
private:
|
||||
QSettings* m_pSettings;
|
||||
ScreenList m_Screens;
|
||||
|
@ -106,9 +111,16 @@ class ServerConfig : public BaseConfig
|
|||
int m_SwitchCornerSize;
|
||||
QList<bool> m_SwitchCorners;
|
||||
HotkeyList m_Hotkeys;
|
||||
QString m_ServerName;
|
||||
};
|
||||
|
||||
QTextStream& operator<<(QTextStream& outStream, const ServerConfig& config);
|
||||
|
||||
enum {
|
||||
kAutoAddScreenOk,
|
||||
kAutoAddScreenNoServer,
|
||||
kAutoAddScreenNoSpace
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -23,13 +23,15 @@
|
|||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QMessageBox>
|
||||
|
||||
ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, const QString& defaultScreenName) :
|
||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
Ui::ServerConfigDialogBase(),
|
||||
m_OrigServerConfig(config),
|
||||
m_ServerConfig(config),
|
||||
m_ScreenSetupModel(serverConfig().screens(), serverConfig().numColumns(), serverConfig().numRows())
|
||||
m_ScreenSetupModel(serverConfig().screens(), serverConfig().numColumns(), serverConfig().numRows()),
|
||||
m_Message("")
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
|
@ -61,6 +63,17 @@ ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, co
|
|||
model().screen(serverConfig().numColumns() / 2, serverConfig().numRows() / 2) = Screen(defaultScreenName);
|
||||
}
|
||||
|
||||
void ServerConfigDialog::showEvent(QShowEvent* event)
|
||||
{
|
||||
QDialog::show();
|
||||
|
||||
if (!m_Message.isEmpty())
|
||||
{
|
||||
// TODO: ideally this massage box should pop up after the dialog is shown
|
||||
QMessageBox::information(this, tr("Configure server"), m_Message);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::accept()
|
||||
{
|
||||
serverConfig().haveHeartbeat(m_pCheckBoxHeartbeat->isChecked());
|
||||
|
|
|
@ -36,6 +36,8 @@ class ServerConfigDialog : public QDialog, public Ui::ServerConfigDialogBase
|
|||
|
||||
public slots:
|
||||
void accept();
|
||||
void showEvent(QShowEvent* event);
|
||||
void message(const QString& message) { m_Message = message; }
|
||||
|
||||
protected slots:
|
||||
void on_m_pButtonNewHotkey_clicked();
|
||||
|
@ -57,6 +59,7 @@ class ServerConfigDialog : public QDialog, public Ui::ServerConfigDialogBase
|
|||
ServerConfig& m_OrigServerConfig;
|
||||
ServerConfig m_ServerConfig;
|
||||
ScreenSetupModel m_ScreenSetupModel;
|
||||
QString m_Message;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -105,13 +105,6 @@ bool SetupWizard::validateCurrentPage()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (m_pRadioButtonPremiumRegister->isChecked())
|
||||
{
|
||||
const QUrl url(QString(PREMIUM_REGISTER_URL));
|
||||
QDesktopServices::openUrl(url);
|
||||
m_pRadioButtonPremiumLogin->setChecked(true);
|
||||
return false;
|
||||
}
|
||||
else if (m_pRadioButtonPremiumLater->isChecked())
|
||||
{
|
||||
return true;
|
||||
|
@ -122,25 +115,6 @@ bool SetupWizard::validateCurrentPage()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (currentPage() == m_pCryptoPage)
|
||||
{
|
||||
if (m_pCheckBoxEnableCrypto->isChecked())
|
||||
{
|
||||
if (m_pLineEditCryptoPassword1->text().isEmpty())
|
||||
{
|
||||
message.setText(tr("Encryption password required."));
|
||||
message.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_pLineEditCryptoPassword1->text() != m_pLineEditCryptoPassword2->text())
|
||||
{
|
||||
message.setText(tr("Encryption password and confirmation do not match."));
|
||||
message.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -169,8 +143,6 @@ void SetupWizard::accept()
|
|||
{
|
||||
AppConfig& appConfig = m_MainWindow.appConfig();
|
||||
|
||||
appConfig.setCryptoEnabled(m_pCheckBoxEnableCrypto->isChecked());
|
||||
appConfig.setCryptoPass(m_pLineEditCryptoPassword1->text());
|
||||
appConfig.setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
|
||||
appConfig.setPremiumEmail(m_pLineEditPremiumEmail->text());
|
||||
|
||||
|
@ -205,6 +177,7 @@ void SetupWizard::accept()
|
|||
|
||||
if (m_StartMain)
|
||||
{
|
||||
m_MainWindow.updateZeroconfService();
|
||||
m_MainWindow.open();
|
||||
}
|
||||
|
||||
|
@ -225,14 +198,6 @@ void SetupWizard::reject()
|
|||
|
||||
void SetupWizard::on_m_pCheckBoxEnableCrypto_stateChanged(int )
|
||||
{
|
||||
bool enabled = m_pCheckBoxEnableCrypto->isChecked();
|
||||
m_pLineEditCryptoPassword1->setEnabled(enabled);
|
||||
m_pLineEditCryptoPassword2->setEnabled(enabled);
|
||||
if (!enabled)
|
||||
{
|
||||
m_pLineEditCryptoPassword1->clear();
|
||||
m_pLineEditCryptoPassword2->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SetupWizard::on_m_pComboLanguage_currentIndexChanged(int index)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfBrowser.h"
|
||||
|
||||
#include <QtCore/QSocketNotifier>
|
||||
|
||||
ZeroconfBrowser::ZeroconfBrowser(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_DnsServiceRef(0),
|
||||
m_pSocket(0)
|
||||
{
|
||||
}
|
||||
|
||||
ZeroconfBrowser::~ZeroconfBrowser()
|
||||
{
|
||||
if (m_DnsServiceRef) {
|
||||
DNSServiceRefDeallocate(m_DnsServiceRef);
|
||||
m_DnsServiceRef = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfBrowser::browseForType(const QString& type)
|
||||
{
|
||||
DNSServiceErrorType err = DNSServiceBrowse(&m_DnsServiceRef, 0, 0,
|
||||
type.toUtf8().constData(), 0, browseReply, this);
|
||||
|
||||
if (err != kDNSServiceErr_NoError) {
|
||||
emit error(err);
|
||||
}
|
||||
else {
|
||||
int sockFD = DNSServiceRefSockFD(m_DnsServiceRef);
|
||||
if (sockFD == -1) {
|
||||
emit error(kDNSServiceErr_Invalid);
|
||||
}
|
||||
else {
|
||||
m_pSocket = new QSocketNotifier(sockFD, QSocketNotifier::Read, this);
|
||||
connect(m_pSocket, SIGNAL(activated(int)), this,
|
||||
SLOT(socketReadyRead()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfBrowser::socketReadyRead()
|
||||
{
|
||||
DNSServiceErrorType err = DNSServiceProcessResult(m_DnsServiceRef);
|
||||
if (err != kDNSServiceErr_NoError) {
|
||||
emit error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfBrowser::browseReply(DNSServiceRef, DNSServiceFlags flags,
|
||||
quint32, DNSServiceErrorType errorCode, const char* serviceName,
|
||||
const char* regType, const char* replyDomain, void* context)
|
||||
{
|
||||
ZeroconfBrowser* browser = static_cast<ZeroconfBrowser*>(context);
|
||||
if (errorCode != kDNSServiceErr_NoError) {
|
||||
emit browser->error(errorCode);
|
||||
}
|
||||
else {
|
||||
ZeroconfRecord record(serviceName, regType, replyDomain);
|
||||
if (flags & kDNSServiceFlagsAdd) {
|
||||
if (!browser->m_Records.contains(record)) {
|
||||
browser->m_Records.append(record);
|
||||
}
|
||||
}
|
||||
else {
|
||||
browser->m_Records.removeAll(record);
|
||||
}
|
||||
if (!(flags & kDNSServiceFlagsMoreComing)) {
|
||||
emit browser->currentRecordsChanged(browser->m_Records);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfRecord.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#define _MSL_STDINT_H
|
||||
#include <stdint.h>
|
||||
#include <dns_sd.h>
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
class ZeroconfBrowser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZeroconfBrowser(QObject* parent = 0);
|
||||
~ZeroconfBrowser();
|
||||
void browseForType(const QString& type);
|
||||
inline QList<ZeroconfRecord> currentRecords() const { return m_Records; }
|
||||
inline QString serviceType() const { return m_BrowsingType; }
|
||||
|
||||
signals:
|
||||
void currentRecordsChanged(const QList<ZeroconfRecord>& list);
|
||||
void error(DNSServiceErrorType err);
|
||||
|
||||
private slots:
|
||||
void socketReadyRead();
|
||||
|
||||
private:
|
||||
static void DNSSD_API browseReply(DNSServiceRef, DNSServiceFlags flags,
|
||||
quint32, DNSServiceErrorType errorCode, const char* serviceName,
|
||||
const char* regType, const char* replyDomain, void* context);
|
||||
|
||||
private:
|
||||
DNSServiceRef m_DnsServiceRef;
|
||||
QSocketNotifier* m_pSocket;
|
||||
QList<ZeroconfRecord> m_Records;
|
||||
QString m_BrowsingType;
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 <QtCore/QMetaType>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class ZeroconfRecord
|
||||
{
|
||||
public:
|
||||
ZeroconfRecord() {}
|
||||
ZeroconfRecord(const QString& name, const QString& regType,
|
||||
const QString& domain)
|
||||
: serviceName(name), registeredType(regType), replyDomain(domain)
|
||||
{}
|
||||
ZeroconfRecord(const char* name, const char* regType, const char* domain)
|
||||
{
|
||||
serviceName = QString::fromUtf8(name);
|
||||
registeredType = QString::fromUtf8(regType);
|
||||
replyDomain = QString::fromUtf8(domain);
|
||||
}
|
||||
|
||||
bool operator==(const ZeroconfRecord& other) const {
|
||||
return serviceName == other.serviceName
|
||||
&& registeredType == other.registeredType
|
||||
&& replyDomain == other.replyDomain;
|
||||
}
|
||||
|
||||
public:
|
||||
QString serviceName;
|
||||
QString registeredType;
|
||||
QString replyDomain;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ZeroconfRecord)
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfRegister.h"
|
||||
|
||||
#include <QtCore/QSocketNotifier>
|
||||
|
||||
ZeroconfRegister::ZeroconfRegister(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_DnsServiceRef(0),
|
||||
m_pSocket(0)
|
||||
{
|
||||
}
|
||||
|
||||
ZeroconfRegister::~ZeroconfRegister()
|
||||
{
|
||||
if (m_DnsServiceRef) {
|
||||
DNSServiceRefDeallocate(m_DnsServiceRef);
|
||||
m_DnsServiceRef = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfRegister::registerService(const ZeroconfRecord& record,
|
||||
quint16 servicePort)
|
||||
{
|
||||
if (m_DnsServiceRef) {
|
||||
qWarning("Warning: Already registered a service for this object");
|
||||
return;
|
||||
}
|
||||
|
||||
quint16 bigEndianPort = servicePort;
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
{
|
||||
bigEndianPort = 0 | ((servicePort & 0x00ff) << 8) | ((servicePort & 0xff00) >> 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
DNSServiceErrorType err = DNSServiceRegister(&m_DnsServiceRef, 0, 0,
|
||||
record.serviceName.toUtf8().constData(),
|
||||
record.registeredType.toUtf8().constData(),
|
||||
record.replyDomain.isEmpty() ? 0 : record.replyDomain.toUtf8().constData(),
|
||||
0, bigEndianPort, 0, 0, registerService, this);
|
||||
|
||||
if (err != kDNSServiceErr_NoError) {
|
||||
emit error(err);
|
||||
}
|
||||
else {
|
||||
int sockfd = DNSServiceRefSockFD(m_DnsServiceRef);
|
||||
if (sockfd == -1) {
|
||||
emit error(kDNSServiceErr_Invalid);
|
||||
}
|
||||
else {
|
||||
m_pSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
|
||||
connect(m_pSocket, SIGNAL(activated(int)), this, SLOT(socketReadyRead()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfRegister::socketReadyRead()
|
||||
{
|
||||
DNSServiceErrorType err = DNSServiceProcessResult(m_DnsServiceRef);
|
||||
if (err != kDNSServiceErr_NoError) {
|
||||
emit error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfRegister::registerService(DNSServiceRef, DNSServiceFlags,
|
||||
DNSServiceErrorType errorCode, const char* name, const char* regtype,
|
||||
const char* domain, void* data)
|
||||
{
|
||||
ZeroconfRegister* serviceRegister = static_cast<ZeroconfRegister*>(data);
|
||||
if (errorCode != kDNSServiceErr_NoError) {
|
||||
emit serviceRegister->error(errorCode);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 <QtCore/QObject>
|
||||
|
||||
#include "ZeroconfRecord.h"
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
// Bonjour flags
|
||||
#define _MSL_STDINT_H
|
||||
#include <stdint.h>
|
||||
#if defined(Q_OS_WIN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <dns_sd.h>
|
||||
|
||||
class ZeroconfRegister : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZeroconfRegister(QObject* parent = 0);
|
||||
~ZeroconfRegister();
|
||||
|
||||
void registerService(const ZeroconfRecord& record, quint16 servicePort);
|
||||
inline ZeroconfRecord registeredRecord() const { return finalRecord; }
|
||||
|
||||
signals:
|
||||
void error(DNSServiceErrorType error);
|
||||
void serviceRegistered(const ZeroconfRecord& record);
|
||||
|
||||
private slots:
|
||||
void socketReadyRead();
|
||||
|
||||
private:
|
||||
static void DNSSD_API registerService(DNSServiceRef sdRef,
|
||||
DNSServiceFlags, DNSServiceErrorType errorCode, const char* name,
|
||||
const char* regtype, const char* domain, void* context);
|
||||
|
||||
private:
|
||||
DNSServiceRef m_DnsServiceRef;
|
||||
QSocketNotifier* m_pSocket;
|
||||
ZeroconfRecord finalRecord;
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfServer.h"
|
||||
#include "ZeroconfThread.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
ZeroconfServer::ZeroconfServer(QObject* parent) :
|
||||
QTcpServer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ZeroconfServer::incomingConnection(int socketDescriptor)
|
||||
{
|
||||
ZeroconfThread* thread = new ZeroconfThread(socketDescriptor, this);
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
thread->start();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 <QStringList>
|
||||
#include <QTcpServer>
|
||||
|
||||
class ZeroconfRegister;
|
||||
|
||||
class ZeroconfServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZeroconfServer(QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
void incomingConnection(int socketDescriptor);
|
||||
|
||||
private:
|
||||
QStringList fortunes;
|
||||
};
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfService.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "ZeroconfRegister.h"
|
||||
#include "ZeroconfBrowser.h"
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QMessageBox>
|
||||
#define _MSL_STDINT_H
|
||||
#include <stdint.h>
|
||||
#include <dns_sd.h>
|
||||
|
||||
const char* ZeroconfService:: m_ServerServiceName = "_synergyServerZeroconf._tcp";
|
||||
const char* ZeroconfService:: m_ClientServiceName = "_synergyClientZeroconf._tcp";
|
||||
|
||||
ZeroconfService::ZeroconfService(MainWindow* mainWindow) :
|
||||
m_pMainWindow(mainWindow),
|
||||
m_pZeroconfBrowser(0),
|
||||
m_pZeroconfRegister(0),
|
||||
m_ServiceRegistered(false)
|
||||
{
|
||||
if (m_pMainWindow->synergyType() == MainWindow::synergyServer) {
|
||||
if (registerService(true)) {
|
||||
m_pZeroconfBrowser = new ZeroconfBrowser(this);
|
||||
connect(m_pZeroconfBrowser, SIGNAL(
|
||||
currentRecordsChanged(const QList<ZeroconfRecord>&)),
|
||||
this, SLOT(clientDetected(const QList<ZeroconfRecord>&)));
|
||||
m_pZeroconfBrowser->browseForType(
|
||||
QLatin1String(m_ClientServiceName));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_pZeroconfBrowser = new ZeroconfBrowser(this);
|
||||
connect(m_pZeroconfBrowser, SIGNAL(
|
||||
currentRecordsChanged(const QList<ZeroconfRecord>&)),
|
||||
this, SLOT(serverDetected(const QList<ZeroconfRecord>&)));
|
||||
m_pZeroconfBrowser->browseForType(
|
||||
QLatin1String(m_ServerServiceName));
|
||||
}
|
||||
|
||||
connect(m_pZeroconfBrowser, SIGNAL(error(DNSServiceErrorType)),
|
||||
this, SLOT(errorHandle(int32_t)));
|
||||
}
|
||||
|
||||
ZeroconfService::~ZeroconfService()
|
||||
{
|
||||
if (m_pZeroconfBrowser) {
|
||||
delete m_pZeroconfBrowser;
|
||||
}
|
||||
if (m_pZeroconfRegister) {
|
||||
delete m_pZeroconfRegister;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfService::serverDetected(const QList<ZeroconfRecord>& list)
|
||||
{
|
||||
foreach (ZeroconfRecord record, list) {
|
||||
registerService(false);
|
||||
m_pMainWindow->m_pLineEditHostname->setText(record.serviceName);
|
||||
m_pMainWindow->appendLogNote(tr("zeroconf server detected: %1").arg(
|
||||
record.serviceName));
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
m_pMainWindow->startSynergy();
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfService::clientDetected(const QList<ZeroconfRecord>& list)
|
||||
{
|
||||
foreach (ZeroconfRecord record, list) {
|
||||
m_pMainWindow->appendLogNote(tr("zeroconf client detected: %1").arg(
|
||||
record.serviceName));
|
||||
m_pMainWindow->autoAddScreen(record.serviceName);
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
m_pMainWindow->startSynergy();
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroconfService::errorHandle(int32_t errorCode)
|
||||
{
|
||||
QMessageBox::critical(0, tr("Zero configuration service"),
|
||||
tr("Error code: %1.").arg(errorCode));
|
||||
}
|
||||
|
||||
QString ZeroconfService::getLocalIPAddresses()
|
||||
{
|
||||
foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) {
|
||||
if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress(QHostAddress::LocalHost))
|
||||
return address.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ZeroconfService::registerService(bool server)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (!m_ServiceRegistered) {
|
||||
if (!m_zeroconfServer.listen()) {
|
||||
QMessageBox::critical(0, tr("Zero configuration service"),
|
||||
tr("Unable to start the zeroconf: %1.")
|
||||
.arg(m_zeroconfServer.errorString()));
|
||||
result = false;
|
||||
}
|
||||
else {
|
||||
m_pZeroconfRegister = new ZeroconfRegister(this);
|
||||
if (server) {
|
||||
m_pZeroconfRegister->registerService(
|
||||
ZeroconfRecord(tr("%1").arg(getLocalIPAddresses()),
|
||||
QLatin1String(m_ServerServiceName), QString()),
|
||||
m_zeroconfServer.serverPort());
|
||||
}
|
||||
else {
|
||||
m_pZeroconfRegister->registerService(
|
||||
ZeroconfRecord(tr("%1").arg(m_pMainWindow->getScreenName()),
|
||||
QLatin1String(m_ClientServiceName), QString()),
|
||||
m_zeroconfServer.serverPort());
|
||||
}
|
||||
|
||||
m_ServiceRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfServer.h"
|
||||
#include "ZeroconfRecord.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class ZeroconfRegister;
|
||||
class ZeroconfBrowser;
|
||||
class MainWindow;
|
||||
|
||||
class ZeroconfService : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZeroconfService(MainWindow* mainWindow);
|
||||
~ZeroconfService();
|
||||
|
||||
private slots:
|
||||
void serverDetected(const QList<ZeroconfRecord>& list);
|
||||
void clientDetected(const QList<ZeroconfRecord>& list);
|
||||
void errorHandle(int32_t errorCode);
|
||||
|
||||
private:
|
||||
QString getLocalIPAddresses();
|
||||
bool registerService(bool server);
|
||||
|
||||
private:
|
||||
MainWindow* m_pMainWindow;
|
||||
ZeroconfServer m_zeroconfServer;
|
||||
ZeroconfBrowser* m_pZeroconfBrowser;
|
||||
ZeroconfRegister* m_pZeroconfRegister;
|
||||
bool m_ServiceRegistered;
|
||||
|
||||
static const char* m_ServerServiceName;
|
||||
static const char* m_ClientServiceName;
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 "ZeroconfThread.h"
|
||||
|
||||
#include <QtNetwork>
|
||||
|
||||
ZeroconfThread::ZeroconfThread(int socketDescriptor, QObject* parent) :
|
||||
QThread(parent),
|
||||
m_SocketDescriptor(socketDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void ZeroconfThread::run()
|
||||
{
|
||||
QTcpSocket tcpSocket;
|
||||
if (!tcpSocket.setSocketDescriptor(m_SocketDescriptor)) {
|
||||
emit error(tcpSocket.error());
|
||||
return;
|
||||
}
|
||||
|
||||
tcpSocket.disconnectFromHost();
|
||||
tcpSocket.waitForDisconnected();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* 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 COPYING 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 <QThread>
|
||||
#include <QTcpSocket>
|
||||
|
||||
class ZeroconfThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZeroconfThread(int socketDescriptor, QObject* parent);
|
||||
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void error(QTcpSocket::SocketError socketError);
|
||||
|
||||
private:
|
||||
int m_SocketDescriptor;
|
||||
QString m_Text;
|
||||
};
|
Loading…
Reference in New Issue