summaryrefslogtreecommitdiffstats
path: root/src/server/mainwindow/mainwindow.cpp
diff options
context:
space:
mode:
authorManuel Schneider2014-07-22 14:35:30 +0200
committerManuel Schneider2014-07-22 14:35:30 +0200
commit4d522589c0ab04ae2be76d53788597626e57e71f (patch)
tree8f4352ca4d3ca259f4111a44955b8a0adc0c026a /src/server/mainwindow/mainwindow.cpp
parentNew bug detected (diff)
downloadpvs2-4d522589c0ab04ae2be76d53788597626e57e71f.tar.gz
pvs2-4d522589c0ab04ae2be76d53788597626e57e71f.tar.xz
pvs2-4d522589c0ab04ae2be76d53788597626e57e71f.zip
Bugfix: One click source change now fully supported
Since the async nature of this protocol introduces race conditions when changing the source of the projection, the possiblity that two servers exist at a moment is still there. Even though we thought we do not support multiple sources. This is the reason why _desiredProjectionSource is needed after all.
Diffstat (limited to 'src/server/mainwindow/mainwindow.cpp')
-rw-r--r--src/server/mainwindow/mainwindow.cpp130
1 files changed, 55 insertions, 75 deletions
diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp
index d7cab75..ab94535 100644
--- a/src/server/mainwindow/mainwindow.cpp
+++ b/src/server/mainwindow/mainwindow.cpp
@@ -316,8 +316,7 @@ void MainWindow::tellClientCurrentSituation(Client* client)
client->lockScreen(true);
if (_mode == Mode::Broadcast){
- // _watchers.insert(client->id(), client);
- client->setWatcher(true);
+ client->setDesiredProjectionSource(_streamingSource);
Client* c = getClientFromId(_streamingSource);
if (c != NULL) {
client->startVncClient(c);
@@ -660,8 +659,10 @@ void MainWindow::onButtonTutorToAll()
// 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);
+ if ((*it)->client() != NULL && (*it)->client() != getClientFromId(_streamingSource)){
+ (*it)->client()->setDesiredProjectionSource(getTutorFrame()->client()->id());
+ }
+
}
}
else // If this mode is already active
@@ -702,25 +703,21 @@ void MainWindow::onButtonTutorToStudent()
// 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);
+ (*it)->client()->setDesiredProjectionSource(NO_SOURCE);
}
}
// If "to" already watches "from" stop it
- // if (_watchers.contains(to->id()))
- if (getClientFromId(getSelectedFrame()->client()->id())->isWatcher())
+ if (getSelectedFrame()->client()->isWatcher())
{
- // _watchers.remove(to->id());
- getClientFromId(getSelectedFrame()->client()->id())->setWatcher(false);
+ getSelectedFrame()->client()->setDesiredProjectionSource(NO_SOURCE);
}
else // list "to" as watcher
{
- // _watchers.insert(to->id(), to);
- getClientFromId(getSelectedFrame()->client()->id())->setWatcher(true);
+ getSelectedFrame()->client()->setDesiredProjectionSource(getTutorFrame()->client()->id());
}
_mode = Mode::Multicast;
@@ -746,31 +743,25 @@ void MainWindow::onButtonStudentToTutor()
QMessageBox::critical(this, tr("Projection"), sStrSourceOffline);
else if (getTutorFrame()->client() == NULL)
QMessageBox::critical(this, tr("Projection"), sStrTutorOffline);
- 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
+ else
+ {
+ // If this is not the first run in this mode and the current source is selected, stop the streaming.
+ if (_mode == Mode::Unicast && getSelectedFrame()->client()->id() == _streamingSource)
{
- // 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(...).
+ // Stop reset everything
+ _mode = Mode::None;
+ reset();
+ return;
}
+ // Unset all clients desired sources. Except the tutors desired source, this has to be the selecteds frame
+ for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
+ if ((*it)->client() != NULL){
+ (*it)->client()->setDesiredProjectionSource(getTutorFrame()->client()->id() == (*it)->client()->id() ? getSelectedFrame()->client()->id():NO_SOURCE);
+ qDebug() << "ID" <<(*it)->client()->id() << "ds" << (*it)->client()->desiredProjectionSource() <<"ps"<< (*it)->client()->projectionSource();
+}
+ DisableButtons();
+ _mode = Mode::Unicast;
startVncServerIfNecessary(getSelectedFrame()->client()->id());
}
}
@@ -802,7 +793,8 @@ void MainWindow::onButtonStudentToTutorExclusive()
// 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());
+ // Unset all but tutors desired projection, which is student
+ (*it)->client()->setDesiredProjectionSource(getTutorFrame()->client()->id() == (*it)->client()->id() ? getSelectedFrame()->client()->id():NO_SOURCE);
_mode = Mode::LockedUnicast;
}
else
@@ -1062,46 +1054,34 @@ void MainWindow::onVncServerStateChange(Client* client)
if (client->isActiveVncServer())
{
- if (_mode == Mode::Broadcast)
- {
- for (QList<ConnectionFrame*>::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 // !Mode::Broadcast --> Mode::LockedMC || Mode::MC
+// if (_mode == Mode::Broadcast)
+// {
+// for (QList<ConnectionFrame*>::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
{
+ // apply the desired projection sources
for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
{
// Ignore offline clients
if ( (*it)->client() != NULL)
{
- // if (_watchers.contains((*it)->client()->id()))
- if ((*it)->client()->isWatcher())
- {
- // Unlock destination and connect VNCclient
- (*it)->client()->lockScreen(false);
+ qDebug() << "ID" <<(*it)->client()->id() << "ds" << (*it)->client()->desiredProjectionSource() <<"ps"<< (*it)->client()->projectionSource();
+ if ( (*it)->client()->desiredProjectionSource() == client->id() )
(*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(_mode == Mode::LockedUnicast);
- (*it)->client()->stopVncClient();
- }
+
+ (*it)->client()->lockScreen((*it)->client()->desiredProjectionSource() == NO_SOURCE && _mode == Mode::LockedUnicast);
}
}
}
@@ -1109,15 +1089,16 @@ void MainWindow::onVncServerStateChange(Client* client)
else
{
// VNC server stopped on some client or failed to start - reset local pending projection information
- // foreach (Client *c, _watchers) {
- // c->stopVncClient();
- // }
for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
{
if ((*it)->client() != NULL)
{
- if ((*it)->client()->isWatcher())
+ if ((*it)->client()->desiredProjectionSource() == client->id()) {
+ (*it)->client()->setDesiredProjectionSource(NO_SOURCE);
(*it)->client()->stopVncClient();
+ if (_mode == Mode::LockedUnicast)
+ (*it)->client()->lockScreen(true);
+ }
}
}
}
@@ -1135,11 +1116,10 @@ void MainWindow::onVncClientStateChange(Client* client)
{
// VNC Client stopped -> remove from watchers
if (!client->isActiveVncClient()){
- if (getClientFromId(client->id()) != NULL)
- getClientFromId(client->id())->setWatcher(false);
+ // client->setDesiredProjectionSource(NO_SOURCE);
/*
- * If noboody is watching the multicast stop VNC server
+ * If nobody 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