From 1f1b773a35a1403af02c5f5a359933bfc459457d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 17 Dec 2015 13:29:34 +0100 Subject: Support for client side cursors in the VNC plugin Client side cursors are a major performance optimization, avoiding the need to transmit images to the client just because the cursor has moved. Change-Id: Icdf4ff948571d39d82c86d251bca46390889d02f Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/vnc/qvnc.cpp | 27 +++++++-------------------- src/plugins/platforms/vnc/qvnc_p.h | 7 ------- src/plugins/platforms/vnc/qvncscreen.cpp | 26 +++++++++++++++++++++++++- src/plugins/platforms/vnc/qvncscreen.h | 7 +++++-- 4 files changed, 37 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp index da03d889a6..6b9c55e4db 100644 --- a/src/plugins/platforms/vnc/qvnc.cpp +++ b/src/plugins/platforms/vnc/qvnc.cpp @@ -526,6 +526,9 @@ void QRfbRawEncoder::write() QVncClientCursor::QVncClientCursor(QVncServer *s) : server(s) { + QWindow *w = QGuiApplication::focusWindow(); + QCursor c = w ? w->cursor() : QCursor(Qt::ArrowCursor); + changeCursor(&c, 0); } QVncClientCursor::~QVncClientCursor() @@ -634,9 +637,6 @@ void QVncServer::init() connect(serverSocket, SIGNAL(newConnection()), this, SLOT(newConnection())); -#ifndef QT_NO_QWS_CURSOR - qvnc_cursor = 0; -#endif encoder = 0; } @@ -646,10 +646,6 @@ QVncServer::~QVncServer() encoder = 0; delete client; client = 0; -#ifndef QT_NO_QWS_CURSOR - delete qvnc_cursor; - qvnc_cursor = 0; -#endif } void QVncServer::setDirty() @@ -977,10 +973,8 @@ void QVncServer::setEncodings() break; case Cursor: supportCursor = true; - if (!qvnc_screen->screen()) { - delete qvnc_cursor; - qvnc_cursor = new QVncClientCursor(this); - } + qDebug() << "client side cursor supported."; + qvnc_screen->enableClientCursor(); break; case DesktopSize: supportDesktopSize = true; @@ -1259,10 +1253,7 @@ void QVncServer::checkUpdate() return; if (dirtyCursor) { -#ifndef QT_NO_QWS_CURSOR - Q_ASSERT(qvnc_cursor); - qvnc_cursor->write(); -#endif + qvnc_screen->clientCursor->write(); dirtyCursor = false; wantUpdate = false; return; @@ -1287,11 +1278,7 @@ void QVncServer::discardClient() state = Disconnected; delete encoder; encoder = 0; -#ifndef QT_NO_QWS_CURSOR - delete qvnc_cursor; - qvnc_cursor = 0; -#endif - + qvnc_screen->disableClientCursor(); qvnc_screen->setPowerState(QPlatformScreen::PowerStateOff); } diff --git a/src/plugins/platforms/vnc/qvnc_p.h b/src/plugins/platforms/vnc/qvnc_p.h index f9364656b7..b67c1df838 100644 --- a/src/plugins/platforms/vnc/qvnc_p.h +++ b/src/plugins/platforms/vnc/qvnc_p.h @@ -416,9 +416,6 @@ public: inline QTcpSocket* clientSocket() const { return client; } QImage screenImage() const; inline bool doPixelConversion() const { return needConversion; } -#ifndef QT_NO_QWS_CURSOR - inline bool hasClientCursor() const { return qvnc_cursor != 0; } -#endif private: void setPixelFormat(); @@ -464,10 +461,6 @@ private: bool dirtyCursor; int refreshRate; QVncScreen *qvnc_screen; -#ifndef QT_NO_QWS_CURSOR - QVncClientCursor *qvnc_cursor; -#endif - QRfbEncoder *encoder; }; diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp index 29b5dda77d..b2ed898dcc 100644 --- a/src/plugins/platforms/vnc/qvncscreen.cpp +++ b/src/plugins/platforms/vnc/qvncscreen.cpp @@ -40,6 +40,7 @@ #include "qvncscreen.h" #include "qvnc_p.h" #include +#include #include @@ -55,6 +56,8 @@ QVncScreen::QVncScreen(const QStringList &args) QVncScreen::~QVncScreen() { + if (clientCursor) + delete clientCursor; } bool QVncScreen::initialize() @@ -67,7 +70,7 @@ bool QVncScreen::initialize() QFbScreen::initializeCompositor(); QT_VNC_DEBUG() << "QVncScreen::init" << geometry(); - mCursor = new QFbCursor(this); + disableClientCursor(); switch (depth()) { case 32: @@ -104,6 +107,27 @@ QRegion QVncScreen::doRedraw() return touched; } +void QVncScreen::enableClientCursor() +{ + delete mCursor; + mCursor = 0; + clientCursor = new QVncClientCursor(vncServer); +} + +void QVncScreen::disableClientCursor() +{ + if (vncServer && clientCursor) { + delete clientCursor; + clientCursor = 0; + } + mCursor = new QFbCursor(this); +} + +QPlatformCursor *QVncScreen::cursor() const +{ + return mCursor ? static_cast(mCursor) : static_cast(clientCursor); +} + // grabWindow() grabs "from the screen" not from the backingstores. // In linuxfb's case it will also include the mouse cursor. QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) const diff --git a/src/plugins/platforms/vnc/qvncscreen.h b/src/plugins/platforms/vnc/qvncscreen.h index 5911121169..db2d3ac959 100644 --- a/src/plugins/platforms/vnc/qvncscreen.h +++ b/src/plugins/platforms/vnc/qvncscreen.h @@ -49,6 +49,7 @@ class QFbCursor; class QTcpSocket; class QVncServer; class QVncDirtyMap; +class QVncClientCursor; class QVncScreen : public QFbScreen { @@ -64,7 +65,9 @@ public: QRegion doRedraw() Q_DECL_OVERRIDE; QImage *image() const { return mScreenImage; } -// QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return mCursor; } + void enableClientCursor(); + void disableClientCursor(); + QPlatformCursor *cursor() const Q_DECL_OVERRIDE; void clearDirty() { dirtyRegion = QRegion(); } @@ -76,7 +79,7 @@ public: QRegion dirtyRegion; int refreshRate = 30; QVncServer *vncServer = 0; - + QVncClientCursor *clientCursor = 0; }; QT_END_NAMESPACE -- cgit v1.2.3