summaryrefslogtreecommitdiffstats
path: root/src/server/mainwindow/mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/mainwindow/mainwindow.cpp')
-rw-r--r--src/server/mainwindow/mainwindow.cpp248
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();
}
}
}