diff options
Diffstat (limited to 'src/client/vnc/vncthread.cpp')
-rw-r--r-- | src/client/vnc/vncthread.cpp | 111 |
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) { |