diff options
author | Simon Rettberg | 2018-07-20 15:41:45 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-07-20 15:41:45 +0200 |
commit | e354df7172efbe25e94f1c6ae5516912dad1d114 (patch) | |
tree | dab58ddbeb78743ebad07669d932d475ac5ba5df | |
parent | [client] Don't activateWindow VNC viewer on open in multiscreen mode (diff) | |
download | pvs2-e354df7172efbe25e94f1c6ae5516912dad1d114.tar.gz pvs2-e354df7172efbe25e94f1c6ae5516912dad1d114.tar.xz pvs2-e354df7172efbe25e94f1c6ae5516912dad1d114.zip |
[server] Resize thumbs server side on mismatch
The server requests the appropriate size thumbnail from the client so no
bandwidth will be wasted. However, due to privacy concerns, the client
might actually send a thumb that's smaller than requested, resulting in
a tiny thumbnail on the server with huge gray borders. The server will
now scale up the image in those cases.
We'd actually also scale the image down now if it were too large, but
this doesn't happen under normal circumstances.
-rw-r--r-- | src/server/connectionframe/connectionframe.cpp | 41 | ||||
-rw-r--r-- | src/server/connectionframe/connectionframe.h | 8 | ||||
-rw-r--r-- | src/server/mainwindow/mainwindow.cpp | 3 | ||||
-rw-r--r-- | src/server/net/client.cpp | 17 | ||||
-rw-r--r-- | src/server/net/client.h | 4 |
5 files changed, 40 insertions, 33 deletions
diff --git a/src/server/connectionframe/connectionframe.cpp b/src/server/connectionframe/connectionframe.cpp index fb2c96a..875e031 100644 --- a/src/server/connectionframe/connectionframe.cpp +++ b/src/server/connectionframe/connectionframe.cpp @@ -17,9 +17,9 @@ #include "connectionframe.h" #include "../mainwindow/mainwindow.h" #include "../net/client.h" -#include <QPixmap> #include <QImage> #include <cassert> +#include <cmath> static QString style_student( "QLabel{ background-color: #FFF; border-radius: 2px; color: black;} \ @@ -173,7 +173,7 @@ void ConnectionFrame::assignClient(Client* client) { assert(_client == NULL); connect( client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()) ); - connect( client, SIGNAL(thumbUpdated(Client*, const QPixmap&, const QByteArray&)), this, SLOT(onThumbUpdated(Client*, const QPixmap&, const QByteArray&)) ); + connect( client, SIGNAL(thumbUpdated(Client*, const QImage&)), this, SLOT(onThumbUpdated(Client*, const QImage&)) ); connect( client, SIGNAL(vncServerStateChange(Client*)), this, SLOT(updateAppearance())); connect( client, SIGNAL(vncClientStateChange(Client*)), this, SLOT(updateAppearance())); connect( client, SIGNAL(stateChanged()), this, SLOT(updateAppearance())); @@ -192,11 +192,15 @@ void ConnectionFrame::assignClient(Client* client) */ void ConnectionFrame::showDefaultThumb() { - const int width = this->width() - 6; - const int height = this->height() - 8 - _lblHostName->height() - _lblUserName->height(); - _remoteScreen = term->pixmap(width, height, QIcon::Normal, QIcon::On); - this->repaint(); - //_imgScreen->setPixmap(_remoteScreen); + _remoteScreen = term->pixmap(_desiredThumbSize, QIcon::Normal, QIcon::On).toImage(); + this->update(); +} + +void ConnectionFrame::calcDesiredThumbSize(const QSize &frameSize) +{ + const int width = frameSize.width() - 10; + const int height = frameSize.height() - 12 - _lblHostName->height() - (_lblUserName->isHidden() ? 0 : _lblUserName->height()); + _desiredThumbSize = QSize(width, height); } void ConnectionFrame::updateLabels() @@ -210,6 +214,7 @@ void ConnectionFrame::updateLabels() _lblUserName->setText(_client->name()); _lblUserName->show(); } + calcDesiredThumbSize(this->size()); } /** @@ -226,7 +231,6 @@ void ConnectionFrame::mouseReleaseEvent(QMouseEvent* event) if ((this->pos() - _previousPosition).manhattanLength() > _startDragDistance ) { emit frameMoved(this); } else { - qDebug("Clicked"); move(_previousPosition); emit clicked(this); } @@ -308,8 +312,16 @@ void ConnectionFrame::paintEvent(QPaintEvent *event) return; } + if (!_desiredThumbSize.isEmpty()) { + if (abs(100 - ((_remoteScreen.width() * 100) / _desiredThumbSize.width())) > 5 + && abs(100 - ((_remoteScreen.height() * 100) / _desiredThumbSize.height())) > 5) { + qDebug() << "Rescale thumb" << _remoteScreen.size() << "to" << _desiredThumbSize; + _remoteScreen = _remoteScreen.scaled(_desiredThumbSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + } + QPainter painter(this); - painter.drawPixmap((this->width() - _remoteScreen.width()) / 2, 4, _remoteScreen); + painter.drawImage((this->width() - _remoteScreen.width()) / 2, 4, _remoteScreen); event->accept(); } @@ -324,9 +336,7 @@ void ConnectionFrame::timerEvent(QTimerEvent* /* event */ ) ++_timerCounter; if (_client->isActiveVncServer() && _timerCounter % 5 != 0) return; - const int width = this->width() - 8; - const int height = this->height() - 9 - _lblHostName->height() - _lblUserName->height(); - _client->requestThumb(width, height); + _client->requestThumb(_desiredThumbSize); } /** @@ -417,9 +427,9 @@ void ConnectionFrame::onClientDisconnected() _timerId = 0; } _client = NULL; - showDefaultThumb(); updateLabels(); updateAppearance(); + showDefaultThumb(); } /** @@ -427,11 +437,10 @@ void ConnectionFrame::onClientDisconnected() * @param client * @param thumb */ -void ConnectionFrame::onThumbUpdated(Client* client, const QPixmap& thumb, const QByteArray&) +void ConnectionFrame::onThumbUpdated(Client* client, const QImage& thumb) { assert(client == _client); _remoteScreen = thumb; - //_imgScreen->setPixmap(_remoteScreen); - this->repaint(); + this->update(); } diff --git a/src/server/connectionframe/connectionframe.h b/src/server/connectionframe/connectionframe.h index 4558406..898d97a 100644 --- a/src/server/connectionframe/connectionframe.h +++ b/src/server/connectionframe/connectionframe.h @@ -27,11 +27,12 @@ private: QLabel *_icoCam, *_icoEye, *_icoLock; QList<QLabel*> _icons; - QPixmap _remoteScreen; + QImage _remoteScreen; QPoint _clickPoint; QPoint _previousPosition; QPoint _gridPosition; + QSize _desiredThumbSize; Client *_client; @@ -43,6 +44,7 @@ private: static const int _startDragDistance = 40; void showDefaultThumb(); + void calcDesiredThumbSize(const QSize &frameSize); QLabel* addIcon(const QIcon* icon); MainWindow *_mainWindow; @@ -59,7 +61,6 @@ public: void setGridPosition(const QPoint& pos); void updateGeometry(); - const QPixmap& getFramePixmap() const { return _remoteScreen; } void assignClient(Client *client); void setSelection(bool selected); inline bool isSelected() { return _isSelected; } @@ -73,6 +74,7 @@ public: void setTutor(bool b); protected: + void resizeEvent(QResizeEvent* event) { calcDesiredThumbSize(event->size()); } void mouseDoubleClickEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* e); void enterEvent(QEvent* event); @@ -89,7 +91,7 @@ signals: private slots: void onClientDisconnected(); - void onThumbUpdated(Client* client, const QPixmap& thumb, const QByteArray& rawImage); + void onThumbUpdated(Client* client, const QImage& thumb); void updateAppearance(); void updateLabels(); }; diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index 523c61c..5daade4 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -642,9 +642,6 @@ void MainWindow::onFrameClicked(ConnectionFrame* frame) getSelectedFrame()->setSelection(false); } frame->setSelection(true); - qDebug() << "ID of frame: " << frame->computerId(); - qDebug() << "ID of selectedFrame: " << getSelectedFrame()->computerId(); - qDebug() << "position of selectedFrame: " << getSelectedFrame()->getGridPosition(); unlockContextButtons(); } diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp index 0dd8783..c11cb63 100644 --- a/src/server/net/client.cpp +++ b/src/server/net/client.cpp @@ -104,7 +104,7 @@ void Client::removeAttentionInternal() } /******************************************************************************/ -void Client::requestThumb(const int width, const int height) +void Client::requestThumb(const QSize& size) { if (_socket->state() != QAbstractSocket::ConnectedState) { qDebug("requestThumb called in bad state"); @@ -112,8 +112,8 @@ void Client::requestThumb(const int width, const int height) } NetworkMessage msgTmb; msgTmb.setField(_ID, _THUMB); - msgTmb.setField(_X, QString::number(width)); - msgTmb.setField(_Y, QString::number(height)); + msgTmb.setField(_X, QString::number(size.width())); + msgTmb.setField(_Y, QString::number(size.height())); msgTmb.writeMessage(_socket); } @@ -154,16 +154,15 @@ void Client::handleMsg() if (_authed == 2) { // Following messages are only valid of the client is already authenticated if (id == _THUMB) { - QPixmap pixmap; - const QByteArray& rawImage = _fromClient.getFieldBytes("IMG"); + QImage image; + _rawRemoteScreen = _fromClient.getFieldBytes("IMG"); /* size 0 means the client is in exam-mode and therefore doesn't send any thumbnail */ - if (rawImage.size() > 0) { - if (!pixmap.loadFromData(rawImage)) { + if (_rawRemoteScreen.size() > 0) { + if (!image.loadFromData(_rawRemoteScreen)) { qDebug("Could not decode thumbnail image from client."); return; } - _rawRemoteScreen = QByteArray(rawImage); - emit thumbUpdated(this, pixmap, rawImage); + emit thumbUpdated(this, image); } } else if (id == _VNCSERVER) { // Client tells about startup of vnc server diff --git a/src/server/net/client.h b/src/server/net/client.h index 885d4fc..32237bf 100644 --- a/src/server/net/client.h +++ b/src/server/net/client.h @@ -54,7 +54,7 @@ public: void startVncClient(Client const * const to ); void stopVncClient(); void lockScreen(bool); - void requestThumb(const int width, const int height); + void requestThumb(const QSize& size); private: @@ -93,7 +93,7 @@ protected: signals: void authenticating(Client* client, ClientLogin* request); void authenticated(Client* client); - void thumbUpdated(Client* client, const QPixmap& thumb, const QByteArray& rawImage); + void thumbUpdated(Client* client, const QImage& thumb); void vncServerStateChange(Client* client); void vncClientStateChange(Client* client); void stateChanged(); |