From 273550ed1696a25c135b74992240200db03d97e4 Mon Sep 17 00:00:00 2001 From: Manuel Schneider Date: Tue, 27 May 2014 00:23:19 +0200 Subject: Drop _desiredProjectionSource. Dont send a stopVncClient if it has not been started before. --- src/server/mainwindow/mainwindow.cpp | 122 +++++++++++++++++------------------ src/server/mainwindow/mainwindow.h | 1 + src/server/net/client.cpp | 25 ++++--- src/server/net/client.h | 9 --- 4 files changed, 70 insertions(+), 87 deletions(-) (limited to 'src/server') diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index 97b4528..4c0a497 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -450,13 +450,14 @@ void MainWindow::broadcast(Client *from) _streamingSource->stopVncServer(); _streamingSource = from; - // Server must not listen to itself - _streamingSource->setDesiredProjectionSource(0); + // Server must not listen to anybody + _streamingSource->stopVncClient(); + // Set desired projection source on all clients, if not "from" or oflline for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) if ((*it)->client() != NULL && (*it)->client() != _streamingSource) - (*it)->client()->setDesiredProjectionSource(_streamingSource->id()); + _watchers.insert((*it)->client()->id(), (*it)->client()); if (_streamingSource->isActiveVncServer()) // From is already active @@ -475,6 +476,9 @@ void MainWindow::broadcast(Client *from) */ void MainWindow::multicast(Client *from, Client *to, bool blockOthers) { + if (_broadcast) + _watchers.clear(); + _broadcast = false; _lockOthers = blockOthers; @@ -491,9 +495,9 @@ void MainWindow::multicast(Client *from, Client *to, bool blockOthers) if (to->isActiveVncServer()) to->stopVncServer(); - from->setDesiredProjectionSource(0); + from->stopVncClient(); to->setBroadcastSource(false); - to->setDesiredProjectionSource(from->id()); + _watchers.insert(to->id(), to); if (blockOthers) { // Set lock others @@ -624,7 +628,7 @@ void MainWindow::onButtonStopProjection() Client *c = (**it).client(); if (c == NULL) continue; - c->setDesiredProjectionSource(0); + c->stopVncClient(); c->setBroadcastSource(false); } @@ -840,7 +844,7 @@ void MainWindow::onClientAuthenticated(Client* client) client->lockScreen(true); if (_broadcast){ - client->setDesiredProjectionSource(_streamingSource->id()); + _watchers.insert(client->id(), client); client->startVncClient(_streamingSource); } else if (_lockOthers) client->lockScreen(true); @@ -858,44 +862,51 @@ void MainWindow::onVncServerStateChange(Client* client) return; if (client->isActiveVncServer()) { - // VNC Server started on some client - start projection on all clients interested in that client's screen - for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + if (_broadcast) { - Client *c = (**it).client(); - if (c == NULL || c->id() == client->id()) - continue; // Offline or self - if (c->currentProjectionSource() == client->id()) - continue; // Already watching this client - if (c->desiredProjectionSource() != client->id() && !client->isBroadcastSource()) - continue; // Not interested - c->startVncClient(client); + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + if ((*it)->client() != NULL) + { + // Unlock all online clients + (*it)->client()->lockScreen(false); + + // Start VNCclients on all online clients but source + if ((*it)->client() != client) + (*it)->client()->startVncClient(client); + } + } + } + else // !_broadcast + { + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { + if ( (*it)->client() != NULL) { + if (_watchers.contains((*it)->client()->id())) + { + // Unlock destination and connect VNCclient + (*it)->client()->lockScreen(false); + (*it)->client()->startVncClient(client); + } + else if ((*it)->client()->id() == client->id() ) + { + // Unlock source + (*it)->client()->lockScreen(false); + } + else + { + // Lock others and stop their clients + (*it)->client()->lockScreen(_lockOthers); + (*it)->client()->stopVncClient(); + } + } + } } } else { // VNC server stopped on some client or failed to start - reset local pending projection information - // If at least one other client seemed to be waiting for this client's screen, pop up a message - // on the console - bool wasInterested = client->isBroadcastSource(); - //qDebug() << "On VNC stop:" << client->ip() << "was projection source:" << wasInterested; - client->setBroadcastSource(false); - for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - { - Client *c = (**it).client(); - if (c == NULL) - continue; - if (c->desiredProjectionSource() == client->id()) - { - wasInterested = true; - c->setDesiredProjectionSource(0); - } - } - if (wasInterested && QDateTime::currentMSecsSinceEpoch() < _buttonBlockTime) - { - QMessageBox::information(this, - tr("Projection Error"), - tr("Could not send screen contents of %1 to other clients: VNC Startup failed.").arg(client->name()) - ); + foreach (Client *c, _watchers) { + c->stopVncClient(); } } } @@ -910,32 +921,15 @@ void MainWindow::onVncClientStateChange(Client* client, int lastProjectionSource { if (!isValidClient(client)) // Check here because this slot is connected queued return; - // If last source is not known or not existent, we cannot do anything meaningful here - if (lastProjectionSource == 0) - return; - // Client is not a vnc client anymore. Check if the VNC server it was (supposedly) connected - // to is still running, and kill it if there are no more clients connected to it. - // (client->currentProjectionSource() will still contain the id of the server it was connected to during this event) - // 1. check if vnc server is still running - // 2. check if there are any other clients "using" that server - bool inUse = false; - Client *server = NULL; - for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - { - Client *c = (**it).client(); - if (c == NULL) - continue; - if (c->id() == lastProjectionSource) - server = c; - if (c != client && c->currentProjectionSource() == lastProjectionSource) - { - inUse = true; - break; - } + + // VNC Client stopped -> remove from watchers + if (!client->isActiveVncClient()){ + _watchers.remove(client->id()); + + // If noboody is watching the multicast stop VNC server + if (_watchers.isEmpty() && !_broadcast) + _streamingSource->stopVncServer(); } - // 3. kill server if applicable - if (!inUse && server != NULL) - server->stopVncServer(); } /***************************************************************************//** diff --git a/src/server/mainwindow/mainwindow.h b/src/server/mainwindow/mainwindow.h index fabc11a..4b75241 100644 --- a/src/server/mainwindow/mainwindow.h +++ b/src/server/mainwindow/mainwindow.h @@ -52,6 +52,7 @@ private: bool _broadcast; bool _lockOthers; Client * _streamingSource; + QMap _watchers; QList _clientFrames; ListenServer *_listenServer; diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp index 7eeb3d4..4478e28 100644 --- a/src/server/net/client.cpp +++ b/src/server/net/client.cpp @@ -20,7 +20,6 @@ Client::Client(QSslSocket* socket) : _socket(socket) { assert(socket != NULL); _authed = 0; - _desiredProjectionSource = 0; _isBroadcastSource = false; _currentProjectionSource = 0; _vncPort = 0; @@ -196,16 +195,12 @@ void Client::handleMsg() if (_activeVncClient) { qDebug() << "Client " << _name << " started its VNC client (watching " << projectionSource << ")"; - if (projectionSource == _desiredProjectionSource) - _desiredProjectionSource = 0; emit vncClientStateChange(this, _currentProjectionSource); _currentProjectionSource = projectionSource; } else { qDebug() << "Client " << _name << " stopped its VNC client (watched " << projectionSource << ")"; - if (projectionSource == _desiredProjectionSource) - _desiredProjectionSource = 0; emit vncClientStateChange(this, _currentProjectionSource); _currentProjectionSource = 0; } @@ -311,20 +306,22 @@ void Client::startVncClient(const Client * const to) /******************************************************************************/ void Client::stopVncClient() { - NetworkMessage msg; - msg.setField(_ID, _VNCCLIENT); - sendMessage(msg); + if (_currentProjectionSource != 0) { + NetworkMessage msg; + msg.setField(_ID, _VNCCLIENT); + sendMessage(msg); + } } /******************************************************************************/ void Client::lockScreen(bool lock) { - if (_isTutor) - return; - NetworkMessage msg; - msg.setField(_ID, _LOCK); - msg.setField(_ENABLE, lock ? __TRUE : __FALSE); - sendMessage(msg); + if (!_isTutor){ + NetworkMessage msg; + msg.setField(_ID, _LOCK); + msg.setField(_ENABLE, lock ? __TRUE : __FALSE); + sendMessage(msg); + } } /******************************************************************************/ diff --git a/src/server/net/client.h b/src/server/net/client.h index 198b213..5623717 100644 --- a/src/server/net/client.h +++ b/src/server/net/client.h @@ -44,7 +44,6 @@ public: inline const QString& host() const { return _host; } inline const QString ip() const { return _socket->peerAddress().toString(); } inline const int id() const { return _id; } - inline const int desiredProjectionSource() const { return _desiredProjectionSource; } inline const int currentProjectionSource() const { return _currentProjectionSource; } // To be replaced by states inline const bool isActiveVncClient() const { return _activeVncClient; } @@ -53,15 +52,8 @@ public: // Setters inline void setBroadcastSource(bool enable) { _isBroadcastSource = enable; } - inline void setDesiredProjectionSource(int source) { _desiredProjectionSource = source; } inline void setTutor(bool enable){ _isTutor = enable; } - - //New ones -//b void startVncServer(); - - - //Send message stuff void startVncServer(); void stopVncServer(); @@ -82,7 +74,6 @@ private: NetworkMessage _fromClient; int _timerIdAuthTimeout, _timerPingTimeout; int _id; // this client's unique id - int _desiredProjectionSource; bool _isBroadcastSource; // Tells whether this client is currently the VNC broadcast source. int _currentProjectionSource; QString _vncRwPass, _vncRoPass; -- cgit v1.2.3-55-g7522