From 6f4fb557610beccb225a6bf3d46c0118b221bd99 Mon Sep 17 00:00:00 2001 From: sr Date: Tue, 5 Feb 2013 17:28:19 +0100 Subject: [SERVER] Implement all four VNC projection modes --- src/server/mainwindow/mainwindow.cpp | 196 +++++++++++++++++++++++++++++++---- 1 file changed, 173 insertions(+), 23 deletions(-) (limited to 'src/server/mainwindow/mainwindow.cpp') diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index bbd6b33..48a1a57 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -61,7 +61,10 @@ MainWindow::MainWindow(QWidget* parent) : // Close button in tool bar connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(onButtonExit())); - connect(ui->action_BroadcastScreen, SIGNAL(triggered()), this, SLOT(onButtonBroadcast())); + connect(ui->action_BroadcastScreen, SIGNAL(triggered()), this, SLOT(onButtonStudentToAll())); + connect(ui->action_TutorToAll, SIGNAL(triggered()), this, SLOT(onButtonTutorToAll())); + connect(ui->action_StudentToTutor, SIGNAL(triggered()), this, SLOT(onButtonStudentToTutor())); + connect(ui->action_TutorToStudent, SIGNAL(triggered()), this, SLOT(onButtonTutorToStudent())); connect(ui->action_Lock, SIGNAL(toggled(bool)), this, SLOT(onButtonLock(bool))); // Clicking the session name label shows the edit field for it connect(_sessionNameLabel, SIGNAL(clicked()), this, SLOT(onSessionNameClick())); @@ -350,45 +353,192 @@ void MainWindow::onButtonChat() */ } -void MainWindow::onButtonBroadcast() +void MainWindow::prepareForProjection(Client * const from, Client * const to) +{ + // Projection source is never allowed to be an active VNC viewer + if (from->isActiveVncClient()) + from->stopVncClient(); + + if (to == NULL) + { + // One to many + from->setProjectionSource(true); + + if (from->isActiveVncServer()) + { + // From is already active, if there is at least one active client, assume it is not + // shutting down, so we can directly tell the new client to connect to it + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + Client *c = (**it).client(); + if (c == NULL || c->id() == from->id()) + continue; + if (c->currentProjectionSource() != from->id()) + continue; + // Yep :-) + this->onVncServerStateChange(from); + return; + } + } + // Could not take shortcut, (re)start VNC server on source + from->startVncServer(); + return; + } + + // One to one is desired, figure out what to do with current client + + if (to->isActiveVncClient()) + to->stopVncClient(); + to->setDesiredProjectionSource(from->id()); + + if (from->isActiveVncServer()) + { + // From is already active, if there is at least one active client, assume it is not + // shutting down, so we can directly tell the new client to connect to it + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + Client *c = (**it).client(); + if (c == NULL || c->id() == from->id()) + continue; + if (c->currentProjectionSource() != from->id()) + continue; + // Yep :-) + this->onVncServerStateChange(from); + return; + } + } + // Could not take shortcut, (re)start VNC server on source + from->startVncServer(); +} + +void MainWindow::onButtonStudentToAll() { const qint64 now = QDateTime::currentMSecsSinceEpoch(); if (now < _buttonBlockTime) return; _buttonBlockTime = now + 3000; - Client *source = NULL; // the desired source (selected frame) - Client *oldSource = NULL; // if there is a client that is already broadcaster, save it here + // + Client *from = NULL; for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { Client *c = (**it).client(); + if (c == NULL) + continue; if ((**it).selected()) - source = c; - if (c != NULL && c->isProjectionSource()) - oldSource = c; + from = c; + else + c->setProjectionSource(false); } - if (source == NULL && oldSource == NULL) - { - QMessageBox::information(this, tr("No Projection Source selected"), tr("You did not select any active client as the connection source.")); + if (from == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No projection source selected.") + ); + else + prepareForProjection(from, NULL); +} + +void MainWindow::onButtonStudentToTutor() +{ + const qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now < _buttonBlockTime) return; + _buttonBlockTime = now + 3000; + // + Client *from = NULL; + Client *to = NULL; + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) + { + Client *c = (**it).client(); + if (c == NULL) + continue; + if ((**it).selected()) + from = c; + else if ((**it).isTutor()) + to = c; } - if (oldSource != NULL) + if (from == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No projection source selected.") + ); + else if (to == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No tutor defined, or tutor is offline.") + ); + else if (to == from) + QMessageBox::critical(this, + tr("Projection"), + tr("Selected projection target is tutor.") + ); + else + prepareForProjection(from, to); +} + +void MainWindow::onButtonTutorToAll() +{ + const qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now < _buttonBlockTime) + return; + _buttonBlockTime = now + 3000; + // + Client *from = NULL; + for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - // Is already broadcast source, disable - oldSource->setProjectionSource(false); - oldSource->stopVncServer(); - if (source == NULL || source->id() == oldSource->id()) - return; + Client *c = (**it).client(); + if (c == NULL) + continue; + if ((**it).isTutor()) + from = c; + else + c->setProjectionSource(false); } - source->setProjectionSource(true); + if (from == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No tutor defined, or tutor is offline.") + ); + else + prepareForProjection(from, NULL); +} + +void MainWindow::onButtonTutorToStudent() +{ + const qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now < _buttonBlockTime) + return; + _buttonBlockTime = now + 3000; + // + Client *from = NULL; + Client *to = NULL; for (QList::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { Client *c = (**it).client(); - if (c == NULL || c->id() == source->id()) + if (c == NULL) continue; - //c->setDesiredProjectionSource(source->id()); - c->setProjectionSource(false); + if ((**it).selected()) + to = c; + else if ((**it).isTutor()) + from = c; } - source->startVncServer(); + if (from == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No projection source selected.") + ); + else if (to == NULL) + QMessageBox::critical(this, + tr("Projection"), + tr("No tutor defined, or tutor is offline.") + ); + else if (to == from) + QMessageBox::critical(this, + tr("Projection"), + tr("Selected projection source is tutor.") + ); + else + prepareForProjection(from, to); } void MainWindow::onButtonLock(bool checked) @@ -518,11 +668,11 @@ void MainWindow::onClientAuthenticated(Client* client) // Move to any free tile placeFrameInFreeSlot(cf); } - // Assign client instance - cf->assignClient(client); // Make first active client tutor if (!anyClient && !hasActiveTutor) cf->setTutor(true); + // Assign client instance + cf->assignClient(client); // ################ NetworkMessage msg; // If clients are currently locked, tell this new client -- cgit v1.2.3-55-g7522