diff options
Diffstat (limited to 'src/server/mainwindow/mainwindow.cpp')
-rw-r--r-- | src/server/mainwindow/mainwindow.cpp | 248 |
1 files changed, 169 insertions, 79 deletions
diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index 8762dbf..ec55f75 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -323,7 +323,7 @@ void MainWindow::tellClientCurrentSituation(Client* client) client->startVncClient(c); } } - else if (_mode == Mode::LockedMulticast) + else if (_mode == Mode::LockedUnicast) client->lockScreen(true); } @@ -465,6 +465,8 @@ void MainWindow::mouseReleaseEvent(QMouseEvent* e) */ void MainWindow::reset() { + _mode = Mode::None; + // Unlock all clients for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) if ((*it)->client() != NULL) @@ -602,72 +604,27 @@ void MainWindow::onSessionNameUpdate() } /***************************************************************************//** - * @brief MainWindow::changeProjection + * @brief MainWindow::startVncServerIfNecessary * @param from - * @param mode - * @param to */ -void MainWindow::changeProjection(Client *from, Mode mode, Client *to) +void MainWindow::startVncServerIfNecessary(int from) { - DisableButtons(); - - if (mode == Mode::Broadcast) - { - // Set all clients as watchers - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - { - if ((*it)->client() != NULL && (*it)->client() != getClientFromId(_streamingSource)) - { - // _watchers.insert((*it)->client()->id(), (*it)->client()); - (*it)->client()->setWatcher(true); - } - } - } - else // mode != Mode::Broadcast - { - // If this is the first call in this mode clear the watchers - if ((mode == Mode::LockedMulticast && _mode != Mode::LockedMulticast) - || (mode == Mode::Multicast && _mode != Mode::Multicast)) - { - // _watchers.clear(); - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - { - if ((*it)->client() != NULL) - (*it)->client()->setWatcher(false); - } - } - - // If "to" already watches "from" stop it - // if (_watchers.contains(to->id())) - if (getClientFromId(to->id())->isWatcher()) - { - // _watchers.remove(to->id()); - getClientFromId(to->id())->setWatcher(false); - } - else // list "to" as watcher - { - // _watchers.insert(to->id(), to); - getClientFromId(to->id())->setWatcher(true); - } - } - - // Set the mode - _mode = mode; + Client* os = getClientFromId(_streamingSource); + Client* ns = getClientFromId(from); // if there is a server running which is not "from" stop it. - if (getClientFromId(_streamingSource) != NULL && getClientFromId(_streamingSource) != from) - getClientFromId(_streamingSource)->stopVncServer(); + if (os != NULL && _streamingSource != from) + os->stopVncServer(); // Set new streaming source - _streamingSource = from->id(); + _streamingSource = from; // If streaming source is already active avoid a restart - Client* c = getClientFromId(_streamingSource); - if (c != NULL) { - if (c->isActiveVncServer()) - this->onVncServerStateChange(c); + if (ns != NULL) { + if (ns->isActiveVncServer()) + this->onVncServerStateChange(ns); else // Could not take shortcut, (re)start VNC server on source - c->startVncServer(); + ns->startVncServer(); } } @@ -695,7 +652,29 @@ void MainWindow::onButtonTutorToAll() else if (_clientFrames.size() == 1) QMessageBox::critical(this, tr("Projection"), sStrNoDestAv); else - changeProjection(getTutorFrame()->client(), Mode::Broadcast); + { + DisableButtons(); + + if (_mode != Mode::Broadcast) + { + // Set all clients as watchers + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + if ((*it)->client() != NULL && (*it)->client() != getClientFromId(_streamingSource)) + (*it)->client()->setWatcher(true); + } + } + else // If this mode is already active + { + // Stop reset everything + reset(); + _mode = Mode::None; + return; + } + + _mode = Mode::Broadcast; + startVncServerIfNecessary(getTutorFrame()->client()->id()); + } } /***************************************************************************//** @@ -712,7 +691,29 @@ void MainWindow::onButtonStudentToAll() if (getSelectedFrame()->client() == NULL) QMessageBox::critical(this, tr("Projection"), sStrSourceOffline); else - changeProjection(getSelectedFrame()->client(), Mode::Broadcast); + { + DisableButtons(); + + if (_mode != Mode::Broadcast) + { + // Set all clients as watchers + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + if ((*it)->client() != NULL && (*it)->client() != getClientFromId(_streamingSource)) + (*it)->client()->setWatcher(true); + } + } + else // If this mode is already active + { + // Stop reset everything + reset(); + _mode = Mode::None; + return; + } + + _mode = Mode::Broadcast; + startVncServerIfNecessary(getSelectedFrame()->client()->id()); + } } /***************************************************************************//** @@ -734,7 +735,36 @@ void MainWindow::onButtonTutorToStudent() else if (getTutorFrame()->client() == NULL) QMessageBox::critical(this, tr("Projection"), sStrTutorOffline); else - changeProjection(getTutorFrame()->client(), Mode::Multicast, getSelectedFrame()->client()); + { + DisableButtons(); + + // If this is the first call in this mode clear the watchers + if (_mode != Mode::Multicast) + { + // _watchers.clear(); + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + if ((*it)->client() != NULL) + (*it)->client()->setWatcher(false); + } + } + + // If "to" already watches "from" stop it + // if (_watchers.contains(to->id())) + if (getClientFromId(getSelectedFrame()->client()->id())->isWatcher()) + { + // _watchers.remove(to->id()); + getClientFromId(getSelectedFrame()->client()->id())->setWatcher(false); + } + else // list "to" as watcher + { + // _watchers.insert(to->id(), to); + getClientFromId(getSelectedFrame()->client()->id())->setWatcher(true); + } + + _mode = Mode::Multicast; + startVncServerIfNecessary(getTutorFrame()->client()->id()); + } } /***************************************************************************//** @@ -755,8 +785,33 @@ void MainWindow::onButtonStudentToTutor() QMessageBox::critical(this, tr("Projection"), sStrSourceOffline); else if (getTutorFrame()->client() == NULL) QMessageBox::critical(this, tr("Projection"), sStrTutorOffline); - else - changeProjection(getSelectedFrame()->client(), Mode::Multicast, getTutorFrame()->client()); + else{ + DisableButtons(); + + if (_mode != Mode::Unicast) + { + // If this is the first run in this mode set the tutor as watcher + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + if ((*it)->client() != NULL) + (*it)->client()->setWatcher(getTutorFrame()->client()->id() == (*it)->client()->id()); + _mode = Mode::Unicast; + } + else + { + // If this mode is already active and the current source is selected, stop the streaming. + if (getSelectedFrame()->client()->id() == _streamingSource ) + { + // Stop reset everything + _mode = Mode::None; + reset(); + return; + } + // If another client is selected solely the current streaming source shall be changed. + // This should be handled by startVncServerIfNecessary(...). + } + + startVncServerIfNecessary(getSelectedFrame()->client()->id()); + } } @@ -778,7 +833,33 @@ void MainWindow::onButtonStudentToTutorExclusive() else if (getTutorFrame()->client() == NULL) QMessageBox::critical(this, tr("Projection"), sStrTutorOffline); else - changeProjection(getSelectedFrame()->client(), Mode::LockedMulticast, getTutorFrame()->client()); + { + DisableButtons(); + + if (_mode != Mode::LockedUnicast) + { + // If this is the first run in this mode set the tutor as watcher + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + if ((*it)->client() != NULL) + (*it)->client()->setWatcher(getTutorFrame()->client()->id() == (*it)->client()->id()); + _mode = Mode::LockedUnicast; + } + else + { + // If this mode is already active and the current source is selected, stop the streaming. + if (getSelectedFrame()->client()->id() == _streamingSource ) + { + // Stop reset everything + _mode = Mode::None; + reset(); + return; + } + // If another client is selected solely the current streaming source shall be changed. + // This should be handled by startVncServerIfNecessary(...). + } + + startVncServerIfNecessary(getSelectedFrame()->client()->id()); + } } @@ -1057,7 +1138,7 @@ void MainWindow::onVncServerStateChange(Client* client) else { // Lock others and stop their clients - (*it)->client()->lockScreen(_mode == Mode::LockedMulticast); + (*it)->client()->lockScreen(_mode == Mode::LockedUnicast); (*it)->client()->stopVncClient(); } } @@ -1093,27 +1174,36 @@ void MainWindow::onVncClientStateChange(Client* client) { // VNC Client stopped -> remove from watchers if (!client->isActiveVncClient()){ - // _watchers.remove(client->id()); if (getClientFromId(client->id()) != NULL) getClientFromId(client->id())->setWatcher(false); - // If noboody is watching the multicast stop VNC server - // if (_watchers.isEmpty() && _mode != Mode::Broadcast) - // _streamingSource->stopVncServer(); - bool noWatchers = true; - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + /* + * If noboody is watching the multicast stop VNC server + * If the past connection of this client is not the current + * _streamingSource then the manager has to have stopped it + * already. This is necessary for the race condition when a server + * is stopped and another started at the same time, since the new + * server would be killed if all client disconnect before any of + * the new connect. + */ + if (client->projectionSource() == _streamingSource) { - if ((*it)->client() != NULL) + bool noWatchers = true; + for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); + it != _clientFrames.end(); ++it) { - if ((*it)->client()->isWatcher()) - noWatchers = false; + if ((*it)->client() != NULL) + { + if ((*it)->client()->isWatcher()) + noWatchers = false; + } + } + if (noWatchers && _mode != Mode::Broadcast) + { + Client* c = getClientFromId(_streamingSource); + if (c != NULL) + c->stopVncServer(); } - } - if (noWatchers && _mode != Mode::Broadcast) - { - Client* c = getClientFromId(_streamingSource); - if (c != NULL) - c->stopVncServer(); } } } |