summaryrefslogtreecommitdiffstats
path: root/src/client/vnc/vncthread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/vnc/vncthread.cpp')
-rw-r--r--src/client/vnc/vncthread.cpp111
1 files changed, 9 insertions, 102 deletions
diff --git a/src/client/vnc/vncthread.cpp b/src/client/vnc/vncthread.cpp
index dcc61d0..1dbe005 100644
--- a/src/client/vnc/vncthread.cpp
+++ b/src/client/vnc/vncthread.cpp
@@ -22,20 +22,6 @@
#include <netinet/tcp.h>
/**
- * Calc greatest common divisor.
- *
- * @param a one number
- * @param b another number
- * @return greatest common divisor of a and b
- */
-static int gcd(int a, int b)
-{
- if (b == 0)
- return a;
- return gcd(b, a % b);
-}
-
-/**
* Initialize this VNC client connection worker thread.
*
* @param host The IP address of the VNC server we're going to connect to
@@ -44,9 +30,8 @@ static int gcd(int a, int b)
* @param quality The desired quality level for the VNC stream
*/
VncThread::VncThread(QString host, int port, QString passwd, int quality) :
- QThread(), _frameBuffer(NULL), _run(true), _started(false)
+ QThread(), _run(true), _started(false)
{
- _srcStepX = _srcStepY = _dstStepX = _dstStepY = 0;
_host = host;
_port = port;
_passwd = passwd;
@@ -60,57 +45,18 @@ VncThread::~VncThread()
{
qDebug("VNC worker destructor called.");
Q_ASSERT(_run == false);
- if (_frameBuffer != NULL)
- delete[] _frameBuffer;
if (_client != NULL) {
if (_client->sock != -1)
::close(_client->sock);
_client->sock = -1;
- _client->frameBuffer = NULL;
rfbClientCleanup(_client);
}
}
-/**
- * When using image scaling, calc matching pixel borders for both
- * resolutions to prevent artifacts through bilinear scaling.
- * If you simply round to the nearest number when scaling, you would
- * slightly stretch or shrink the image area, which leads to strange
- * sub-pixel-movements of parts of the image when being updated.
- * The values calculated here are used to determine a larger area around
- * the area that should actually be updated, that will not cause any
- * artifacts when scaling down/up.
- */
-void VncThread::calcScaling()
-{
- if (_localSize.isEmpty())
- return;
- if (_clientSize.isEmpty())
- return;
- const int gcdX = gcd(_localSize.width(), _clientSize.width());
- const int gcdY = gcd(_localSize.height(), _clientSize.height());
- _srcStepX = _clientSize.width() / gcdX;
- _srcStepY = _clientSize.height() / gcdY;
- _dstStepX = _localSize.width() / gcdX;
- _dstStepY = _localSize.height() / gcdY;
- qDebug() << "Scaling updated to " << _clientSize << " -> " << _localSize;
- emit imageUpdated(0, 0, _localSize.width(), _localSize.height());
-}
-
////////////////////////////////////////////////////////////////////////////////
// Public
/**
- * Tell the client that the size of the viewer window has changed.
- *
- * @param size The new size of the viewer window
- */
-void VncThread::setTargetBuffer(QSharedPointer<QImage> &buffer)
-{
- _imgScaled = buffer;
-}
-
-/**
* Worker thread's mainloop, connecting to the VNC server and handling the
* connection. The vnc client library is written in a blocking manner, so we
* just do everything in our own thread and just hand over the image updates to
@@ -207,41 +153,6 @@ const QString VncThread::getDesktopName() const
*/
void VncThread::processImageUpdate(int x, int y, int w, int h)
{
- QSharedPointer<QImage> buffer = _imgScaled;
- QPainter painter(buffer.data());
- if (buffer->size() != _localSize) {
- _localSize = buffer->size();
- this->calcScaling();
- x = 0;
- y = 0;
- w = _img.width();
- h = _img.height();
- }
- if (_srcStepX > 1 || _srcStepY > 1) {
- // Scaling is required as vnc server and client are using different resolutions
- // Calc section offsets first
- const int startX = x / _srcStepX;
- const int startY = y / _srcStepY;
- const int endX = (x + w - 1) / _srcStepX + 1;
- const int endY = (y + h - 1) / _srcStepY + 1;
- // Now pixel offsets for source
- const int srcX = startX * _srcStepX;
- const int srcY = startY * _srcStepY;
- const int srcW = endX * _srcStepX - srcX;
- const int srcH = endY * _srcStepY - srcY;
- // Pixel offsets for destination
- x = startX * _dstStepX;
- y = startY * _dstStepY;
- w = endX * _dstStepX - x;
- h = endY * _dstStepY - y;
- // Rescale
- QImage scaled(
- _img.copy(srcX, srcY, srcW, srcH).scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- painter.drawImage(x, y, scaled, 0, 0, w, h);
- } else {
- // Same resolution, nothing to do
- painter.drawImage(x, y, _img, x, y, w, h);
- }
emit imageUpdated(x, y, w, h);
}
@@ -275,16 +186,18 @@ char* VncThread::passwdHandler(rfbClient *client)
rfbBool VncThread::frameBufferHandler(rfbClient *client)
{
VncThread *t = (VncThread*)rfbClientGetClientData(client, 0);
- const int width = client->width, height = client->height, depth = 32; // client->format.bitsPerPixel;
+ const int width = client->width, height = client->height, depth = 32;
const int size = width * height * (depth / 8);
qDebug("[%s] Remote desktop: %ix%ix%i", t->metaObject()->className(), width, height, depth);
- if (t->_frameBuffer != NULL)
- delete[] t->_frameBuffer;
-
- t->_frameBuffer = new uint8_t[size];
- client->frameBuffer = t->_frameBuffer;
+ t->_img = QSharedPointer<QImage>(new QImage(width, height, QImage::Format_RGB32));
+ if (size > t->_img->byteCount()) {
+ qDebug() << "Fatal: Created image too small:" << t->_img->byteCount() << "<" << size;
+ ::exit(1);
+ }
+ client->frameBuffer = t->_img->bits();
memset(client->frameBuffer, '\0', size);
+ client->format.trueColour = 1;
client->format.bitsPerPixel = depth;
client->format.redShift = 16;
client->format.greenShift = 8;
@@ -320,12 +233,6 @@ rfbBool VncThread::frameBufferHandler(rfbClient *client)
}
SetFormatAndEncodings(client);
- t->_clientSize = QSize(width, height);
-
- t->_img = QImage(client->frameBuffer, client->width, client->height, QImage::Format_RGB32);
-
- t->calcScaling();
-
SendFramebufferUpdateRequest(client, 0, 0, width, height, false);
if (!t->_started) {