From 8cad7551e6fdf1041d70ace02b3e9e04adc4ec87 Mon Sep 17 00:00:00 2001 From: jerry Date: Thu, 21 Aug 2014 17:32:40 +0000 Subject: [PATCH] issue #65 - Auto config feature using Zeroconf/Bonjour merging zeroconf into trunk --- ChangeLog | 4 + ext/bonjour/x64/libdnssd.a | Bin 0 -> 23056 bytes src/gui/gui.pro | 20 ++- src/gui/res/MainWindowBase.ui | 2 +- src/gui/res/SetupWizardBase.ui | 253 ++--------------------------- src/gui/src/MainWindow.cpp | 79 +++++++-- src/gui/src/MainWindow.h | 16 +- src/gui/src/Screen.h | 4 +- src/gui/src/ServerConfig.cpp | 70 +++++++- src/gui/src/ServerConfig.h | 14 +- src/gui/src/ServerConfigDialog.cpp | 15 +- src/gui/src/ServerConfigDialog.h | 3 + src/gui/src/SetupWizard.cpp | 37 +---- src/gui/src/ZeroconfBrowser.cpp | 88 ++++++++++ src/gui/src/ZeroconfBrowser.h | 57 +++++++ src/gui/src/ZeroconfRecord.h | 50 ++++++ src/gui/src/ZeroconfRegister.cpp | 89 ++++++++++ src/gui/src/ZeroconfRegister.h | 61 +++++++ src/gui/src/ZeroconfServer.cpp | 33 ++++ src/gui/src/ZeroconfServer.h | 37 +++++ src/gui/src/ZeroconfService.cpp | 145 +++++++++++++++++ src/gui/src/ZeroconfService.h | 55 +++++++ src/gui/src/ZeroconfThread.cpp | 38 +++++ src/gui/src/ZeroconfThread.h | 38 +++++ 24 files changed, 905 insertions(+), 303 deletions(-) create mode 100644 ext/bonjour/x64/libdnssd.a create mode 100644 src/gui/src/ZeroconfBrowser.cpp create mode 100644 src/gui/src/ZeroconfBrowser.h create mode 100644 src/gui/src/ZeroconfRecord.h create mode 100644 src/gui/src/ZeroconfRegister.cpp create mode 100644 src/gui/src/ZeroconfRegister.h create mode 100644 src/gui/src/ZeroconfServer.cpp create mode 100644 src/gui/src/ZeroconfServer.h create mode 100644 src/gui/src/ZeroconfService.cpp create mode 100644 src/gui/src/ZeroconfService.h create mode 100644 src/gui/src/ZeroconfThread.cpp create mode 100644 src/gui/src/ZeroconfThread.h diff --git a/ChangeLog b/ChangeLog index d29fd8b6..85ec662c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/ext/bonjour/x64/libdnssd.a b/ext/bonjour/x64/libdnssd.a new file mode 100644 index 0000000000000000000000000000000000000000..0e31ab582867f3a04e18c7b9b01724da8a28f143 GIT binary patch literal 23056 zcmeI4&6C_l6~N!l+F55Y`7n;{I0=lMqzDBpv-7nRaJk0z#$e(&&U#5)DT?uUM!P%l zthCH%j7?D~SBe7%4mon>#EAnZ4jlLsa^Mf(@8CdquUk?-sk^l;15T-|u4;{@-)l+T z{nOLy59!>6;cT>barFoFbXadUHhP_2r~P)l-Vh?bt=HFk8(o>>&ME->5MbpG0IMee zj{i%>=l={q@x&)GzVsFV#nbGInbK6nlS@@kgHlP`r3U#!JruP`vUF8L$2Yfa0~8jMtk06yL{lQ2YS( zC~p5z#*elEKH44(rjxs4e?A`%hJ%Se-1lHG*z<;CmJWmM+uK{-D430JdEtk{>B8%; zcTsP$e=xAfk{ny!esJHDnR;5Dj5NvhQ; zlIP0IBmMQJRu4>~v;#jJPW<`1-a})SjCk|Lty|vg{$%9+>|l(ik#O{zNs)3ClxWMF z2h;mrzm;60S;kWdrs!;{XgLa8v^$xH-Ym-9PFgHiMHlw-ata~OvvVsL-MhM}+RY+N zC8wKI-ex%pTr>*&oylxJZV+Q3bscqt4;J3+VU*j{E?K$Cd2<$wy!jj(bukT1<<%5a z-W!*;Zw9mQz2U*Z#NUkoZ6zkgK~bsT?TTkQ@Ma-L*)C5>E{(^tYyM8a?0{XaB=7i( zeQ$<0!e+2fw^6^@h;O??l$2PO`byyY-YA>|zNrdLI_wC6KM!Y%QFwJRo!*e9T$t!w z6(zhp3w|~Cj74W6rH_@B!&yoS<6kaz!?hrJEZd&P>y1XYi%;UtMk{)N-&wuB^b9_d z0nRMp6IkpWU0Msh2cg)vZ|cyvvxeqrXjc)EJ~aNmc6UBML=7I1-h>YLMmyHU2P+)G z>*7HiPwI8zbkaL!*V~Boj^oa8gI+8bkLtDYbczXUJCmsw3I6>h!0yt{@Lrq{rSp2C z!!BozO=`T3(BUxau=-iH>9D$?@-8pYHXWk+6ZLWwML9a6PN?OVm&hg4Lwt17sljR7 z8oZfRB5$t%dEK5)-bJjn6XF7neAVQkM<>Hc{2}t{QHxTm*vO+hhX9~g^T9dAcS|8w9jIxgDKi|{n*6lIy zr<1V0ap^@Z(OH(`6lGcC6vbeiBFaeDAi1Xe6sWM0!L#B&0NsBwC8-vXf?d?d=@e=m zOR~*^*{&nAZP{zD*U2l8wfG1x`!Hs2v$lSc%-&_^&0}_I*3+21Z`Mm1=M1)sE3;=6 zv#b{`+qoFvrXI_|3h3s!7H|2-?s4vHk~c3j!j?QO;G8;`~A%Zgn# z6jW|@UyC?Z>|RL7rIO*WA7hsl+hu^vZh6~|^tPhm(aQ2-J0#vmLhmU|b+x=_QuN9( zNos0((w5co7V{X8UNsb(8AeXatX8+>$Zbcry1&Jz=wTki&)JjqNqP)B?7WP#)Hnip zxd&!F&13krSuf$1+Rc^Q(g7mP?qG|>Bi!Pqq*ittj_kI2+SpjtS5wxu zh_`!Ev8(1agq- zarG0vp~#gJucB?sOD#QdC@4Q6nM}ge8f@ZLQ5(&|t5p_>wdE2kuRTXz+j{@3vb2iV zB3{A?#;aPeQ*JMz*r*t;o+z@6$vP^w?mCCo(R*dp=z^lR$mqh0pjMXfRb^zc$~-dm zEh+#8Wp(@FzueSd3wH+QqPs1qvs3Ikt5(efi^j0^)QXHPyuc`q);E@#UZ-(gMX&3U zPCK)%vuTy(&1JTT<$XTItXg49CwPi1ubl9WRx~QNm&2{nlHYAJ}zQ=`A?=u;uNjqN~{oZkV$QR{QHZ*VfTjmQ_Bm zvcE-q;MEkxsrUR!?LC|q_c`~0X-z{MYH%BOQ$BF2=xmJ+2ic%wW4Ylv`_|U`bCoZl zSS~V~@hoGRy>(h@j=vcptHy%yV*p90!A;y}9J68@Uy|13R(@S)<0_9rw1%x0SHz<@ z#`sOW`iy5Nb5E|IN0BPJ$)nH}tQ5P>%5CUY`1jbPhpqV?%Vr1qd6H{>eRkfwHNOwc zddXrxT02f}wtZ&S>k71SLr>Fwq!Xu6iA`^|tuTsBZ|PJ1GSmF+r~;HlCL0`w8r;QQ zW|2)*&@c3%0&B0Y;W}Ga`52;kB*6dOy2@u5-MGRq{%%C6i7x14uwt_>zbHRhlUuE` z>&#un@BfV7qiKHQua`V!{KmyL_VbY6wA{+C>zrLzU$OQ(G)9Mc7k8p3F8w@7@8T17 z-aPLjH0x>J#iwSy#JeE-Z{l)qSdHH5u%qF(b=yxQQMc9=<^Z0is;-?xNPxFoj;?F)k3?@=ymiN zy^80@;~7_lC*S(R)wP-Li - &Client (use another computer's keyboard and mouse): + &Client (use another computer's mouse and keyboard): true diff --git a/src/gui/res/SetupWizardBase.ui b/src/gui/res/SetupWizardBase.ui index 32407740..b6f25474 100644 --- a/src/gui/res/SetupWizardBase.ui +++ b/src/gui/res/SetupWizardBase.ui @@ -128,7 +128,7 @@ - Yes, I have Synergy Premium + I donated to Synergy and have a premium login... @@ -289,33 +289,10 @@ - - - - Tell me more... - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 5 - - - - - Not interested + No, I have not donated to Synergy, skip this step @@ -360,7 +337,7 @@ - &Server (new setup) + &Server (share this computer's mouse and keyboard) @@ -373,7 +350,11 @@ - 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. + <!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> true @@ -405,7 +386,7 @@ - &Client (add to setup) + &Client (use another computer's mouse and keyboard) @@ -418,7 +399,11 @@ - 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. + <!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> true @@ -443,225 +428,15 @@ - - - - 0 - 0 - - - - Encryption - - - - - - 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. - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - 75 - true - - - - Enable encryption - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - 0 - 0 - - - - A longer password will provide stronger encryption. It is a good idea to use 20 characters or more. - - - true - - - - - - - - - - 100 - 0 - - - - - 75 - true - - - - &Password: - - - 10 - - - m_pLineEditCryptoPassword1 - - - - - - - false - - - - 0 - 0 - - - - - 200 - 0 - - - - - 0 - 0 - - - - - 0 - 0 - - - - QLineEdit::Password - - - - - - - - 100 - 0 - - - - - 75 - true - - - - &Confirm: - - - 10 - - - m_pLineEditCryptoPassword2 - - - - - - - false - - - - 0 - 0 - - - - - 200 - 0 - - - - QLineEdit::Password - - - - - - - - - Qt::Vertical - - - - 20 - 100 - - - - - - m_pComboLanguage m_pRadioButtonPremiumLogin m_pLineEditPremiumEmail m_pLineEditPremiumPassword - m_pRadioButtonPremiumRegister m_pRadioButtonPremiumLater m_pServerRadioButton m_pClientRadioButton - m_pLineEditCryptoPassword1 - m_pLineEditCryptoPassword2 diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 555d62f3..dbb70d8b 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -25,6 +25,7 @@ #include "ServerConfigDialog.h" #include "SettingsDialog.h" #include "SetupWizard.h" +#include "ZeroconfService.h" #include #include @@ -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,13 +388,13 @@ void MainWindow::startSynergy() args << "-f" << "--no-tray" << "--debug" << appConfig().logLevelText(); - if (!appConfig().screenName().isEmpty()) - args << "--name" << appConfig().screenName(); - if (appConfig().cryptoEnabled()) - { - args << "--crypto-pass" << appConfig().cryptoPass(); - } + args << "--name" << getScreenName(); + + if (appConfig().cryptoEnabled()) + { + args << "--crypto-pass" << appConfig().cryptoPass(); + } if (desktopMode) { @@ -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); diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 5ff697fe..0efea0ef 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -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(); diff --git a/src/gui/src/Screen.h b/src/gui/src/Screen.h index c8bf8cfc..855b265b 100644 --- a/src/gui/src/Screen.h +++ b/src/gui/src/Screen.h @@ -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; } diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp index 7823e19f..12819c1a 100644 --- a/src/gui/src/ServerConfig.cpp +++ b/src/gui/src/ServerConfig.cpp @@ -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; +} diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h index d1b5d75d..89a6d7cd 100644 --- a/src/gui/src/ServerConfig.h +++ b/src/gui/src/ServerConfig.h @@ -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 m_SwitchCorners; HotkeyList m_Hotkeys; + QString m_ServerName; }; QTextStream& operator<<(QTextStream& outStream, const ServerConfig& config); +enum { + kAutoAddScreenOk, + kAutoAddScreenNoServer, + kAutoAddScreenNoSpace +}; + #endif diff --git a/src/gui/src/ServerConfigDialog.cpp b/src/gui/src/ServerConfigDialog.cpp index d37d29a5..1ff11ec5 100644 --- a/src/gui/src/ServerConfigDialog.cpp +++ b/src/gui/src/ServerConfigDialog.cpp @@ -23,13 +23,15 @@ #include #include +#include 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()); diff --git a/src/gui/src/ServerConfigDialog.h b/src/gui/src/ServerConfigDialog.h index f27abe87..1752b82a 100644 --- a/src/gui/src/ServerConfigDialog.h +++ b/src/gui/src/ServerConfigDialog.h @@ -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 diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index 3ad12098..924e677a 100644 --- a/src/gui/src/SetupWizard.cpp +++ b/src/gui/src/SetupWizard.cpp @@ -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) diff --git a/src/gui/src/ZeroconfBrowser.cpp b/src/gui/src/ZeroconfBrowser.cpp new file mode 100644 index 00000000..690ec54c --- /dev/null +++ b/src/gui/src/ZeroconfBrowser.cpp @@ -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 . + */ + +#include "ZeroconfBrowser.h" + +#include + +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(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); + } + } +} diff --git a/src/gui/src/ZeroconfBrowser.h b/src/gui/src/ZeroconfBrowser.h new file mode 100644 index 00000000..ce8218eb --- /dev/null +++ b/src/gui/src/ZeroconfBrowser.h @@ -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 . + */ + +#pragma once + +#include "ZeroconfRecord.h" + +#include +#define _MSL_STDINT_H +#include +#include + +class QSocketNotifier; + +class ZeroconfBrowser : public QObject +{ + Q_OBJECT + +public: + ZeroconfBrowser(QObject* parent = 0); + ~ZeroconfBrowser(); + void browseForType(const QString& type); + inline QList currentRecords() const { return m_Records; } + inline QString serviceType() const { return m_BrowsingType; } + +signals: + void currentRecordsChanged(const QList& 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 m_Records; + QString m_BrowsingType; +}; diff --git a/src/gui/src/ZeroconfRecord.h b/src/gui/src/ZeroconfRecord.h new file mode 100644 index 00000000..2e1e739f --- /dev/null +++ b/src/gui/src/ZeroconfRecord.h @@ -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 . + */ + +#pragma once + +#include +#include + +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) diff --git a/src/gui/src/ZeroconfRegister.cpp b/src/gui/src/ZeroconfRegister.cpp new file mode 100644 index 00000000..83408376 --- /dev/null +++ b/src/gui/src/ZeroconfRegister.cpp @@ -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 . + */ + +#include "ZeroconfRegister.h" + +#include + +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(data); + if (errorCode != kDNSServiceErr_NoError) { + emit serviceRegister->error(errorCode); + } +} diff --git a/src/gui/src/ZeroconfRegister.h b/src/gui/src/ZeroconfRegister.h new file mode 100644 index 00000000..726905ec --- /dev/null +++ b/src/gui/src/ZeroconfRegister.h @@ -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 . + */ + +#pragma once + +#include + +#include "ZeroconfRecord.h" + +class QSocketNotifier; + +// Bonjour flags +#define _MSL_STDINT_H +#include +#if defined(Q_OS_WIN) +#define WIN32_LEAN_AND_MEAN +#endif +#include + +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; +}; diff --git a/src/gui/src/ZeroconfServer.cpp b/src/gui/src/ZeroconfServer.cpp new file mode 100644 index 00000000..a7297659 --- /dev/null +++ b/src/gui/src/ZeroconfServer.cpp @@ -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 . + */ + +#include "ZeroconfServer.h" +#include "ZeroconfThread.h" + +#include + +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(); +} diff --git a/src/gui/src/ZeroconfServer.h b/src/gui/src/ZeroconfServer.h new file mode 100644 index 00000000..2b658e48 --- /dev/null +++ b/src/gui/src/ZeroconfServer.h @@ -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 . + */ + +#pragma once + +#include +#include + +class ZeroconfRegister; + +class ZeroconfServer : public QTcpServer +{ + Q_OBJECT + +public: + ZeroconfServer(QObject* parent = 0); + +protected: + void incomingConnection(int socketDescriptor); + +private: + QStringList fortunes; +}; diff --git a/src/gui/src/ZeroconfService.cpp b/src/gui/src/ZeroconfService.cpp new file mode 100644 index 00000000..3660a312 --- /dev/null +++ b/src/gui/src/ZeroconfService.cpp @@ -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 . + */ + +#include "ZeroconfService.h" + +#include "MainWindow.h" +#include "ZeroconfRegister.h" +#include "ZeroconfBrowser.h" + +#include +#include +#define _MSL_STDINT_H +#include +#include + +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&)), + this, SLOT(clientDetected(const QList&))); + m_pZeroconfBrowser->browseForType( + QLatin1String(m_ClientServiceName)); + } + } + else { + m_pZeroconfBrowser = new ZeroconfBrowser(this); + connect(m_pZeroconfBrowser, SIGNAL( + currentRecordsChanged(const QList&)), + this, SLOT(serverDetected(const QList&))); + 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& 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& 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; +} diff --git a/src/gui/src/ZeroconfService.h b/src/gui/src/ZeroconfService.h new file mode 100644 index 00000000..44782a5d --- /dev/null +++ b/src/gui/src/ZeroconfService.h @@ -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 . + */ + +#pragma once + +#include "ZeroconfServer.h" +#include "ZeroconfRecord.h" + +#include + +class ZeroconfRegister; +class ZeroconfBrowser; +class MainWindow; + +class ZeroconfService : public QObject +{ + Q_OBJECT + +public: + ZeroconfService(MainWindow* mainWindow); + ~ZeroconfService(); + +private slots: + void serverDetected(const QList& list); + void clientDetected(const QList& 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; +}; diff --git a/src/gui/src/ZeroconfThread.cpp b/src/gui/src/ZeroconfThread.cpp new file mode 100644 index 00000000..41f37adf --- /dev/null +++ b/src/gui/src/ZeroconfThread.cpp @@ -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 . + */ + +#include "ZeroconfThread.h" + +#include + +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(); +} diff --git a/src/gui/src/ZeroconfThread.h b/src/gui/src/ZeroconfThread.h new file mode 100644 index 00000000..42347ff3 --- /dev/null +++ b/src/gui/src/ZeroconfThread.h @@ -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 . + */ + +#pragma once + +#include +#include + +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; +};