1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtGui module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QVNC_P_H 41 #define QVNC_P_H 42 43 #include "qvncscreen.h" 44 45 #include <QtCore/QLoggingCategory> 46 #include <QtCore/qbytearray.h> 47 #include <QtCore/qvarlengtharray.h> 48 #include <qpa/qplatformcursor.h> 49 50 QT_BEGIN_NAMESPACE 51 52 Q_DECLARE_LOGGING_CATEGORY(lcVnc) 53 54 class QTcpSocket; 55 class QTcpServer; 56 57 class QVncScreen; 58 class QVncServer; 59 class QVncClientCursor; 60 class QVncClient; 61 62 // This fits with the VNC hextile messages 63 #define MAP_TILE_SIZE 16 64 65 class QVncDirtyMap 66 { 67 public: 68 QVncDirtyMap(QVncScreen *screen); 69 virtual ~QVncDirtyMap(); 70 71 void reset(); 72 bool dirty(int x, int y) const; 73 virtual void setDirty(int x, int y, bool force = false) = 0; 74 void setClean(int x, int y); 75 76 QVncScreen *screen; 77 int bytesPerPixel; 78 int numDirty; 79 int mapWidth; 80 int mapHeight; 81 82 protected: 83 uchar *map; 84 uchar *buffer; 85 int bufferWidth; 86 int bufferHeight; 87 int bufferStride; 88 int numTiles; 89 }; 90 91 template <class T> 92 class QVncDirtyMapOptimized : public QVncDirtyMap 93 { 94 public: QVncDirtyMapOptimized(QVncScreen * screen)95 QVncDirtyMapOptimized(QVncScreen *screen) : QVncDirtyMap(screen) {} ~QVncDirtyMapOptimized()96 ~QVncDirtyMapOptimized() {} 97 98 void setDirty(int x, int y, bool force = false) override; 99 }; 100 101 102 class QRfbRect 103 { 104 public: QRfbRect()105 QRfbRect() {} QRfbRect(quint16 _x,quint16 _y,quint16 _w,quint16 _h)106 QRfbRect(quint16 _x, quint16 _y, quint16 _w, quint16 _h) { 107 x = _x; y = _y; w = _w; h = _h; 108 } 109 110 void read(QTcpSocket *s); 111 void write(QTcpSocket *s) const; 112 113 quint16 x; 114 quint16 y; 115 quint16 w; 116 quint16 h; 117 }; 118 119 class QRfbPixelFormat 120 { 121 public: size()122 static int size() { return 16; } 123 124 void read(QTcpSocket *s); 125 void write(QTcpSocket *s); 126 127 int bitsPerPixel; 128 int depth; 129 bool bigEndian; 130 bool trueColor; 131 int redBits; 132 int greenBits; 133 int blueBits; 134 int redShift; 135 int greenShift; 136 int blueShift; 137 }; 138 139 class QRfbServerInit 140 { 141 public: QRfbServerInit()142 QRfbServerInit() { name = nullptr; } ~QRfbServerInit()143 ~QRfbServerInit() { delete[] name; } 144 size()145 int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); } 146 void setName(const char *n); 147 148 void read(QTcpSocket *s); 149 void write(QTcpSocket *s); 150 151 quint16 width; 152 quint16 height; 153 QRfbPixelFormat format; 154 char *name; 155 }; 156 157 class QRfbSetEncodings 158 { 159 public: 160 bool read(QTcpSocket *s); 161 162 quint16 count; 163 }; 164 165 class QRfbFrameBufferUpdateRequest 166 { 167 public: 168 bool read(QTcpSocket *s); 169 170 char incremental; 171 QRfbRect rect; 172 }; 173 174 class QRfbKeyEvent 175 { 176 public: 177 bool read(QTcpSocket *s); 178 179 char down; 180 int keycode; 181 int unicode; 182 }; 183 184 class QRfbPointerEvent 185 { 186 public: 187 bool read(QTcpSocket *s); 188 189 Qt::MouseButtons buttons; 190 quint16 x; 191 quint16 y; 192 }; 193 194 class QRfbClientCutText 195 { 196 public: 197 bool read(QTcpSocket *s); 198 199 quint32 length; 200 }; 201 202 class QRfbEncoder 203 { 204 public: QRfbEncoder(QVncClient * s)205 QRfbEncoder(QVncClient *s) : client(s) {} ~QRfbEncoder()206 virtual ~QRfbEncoder() {} 207 208 virtual void write() = 0; 209 210 protected: 211 QVncClient *client; 212 }; 213 214 class QRfbRawEncoder : public QRfbEncoder 215 { 216 public: QRfbRawEncoder(QVncClient * s)217 QRfbRawEncoder(QVncClient *s) : QRfbEncoder(s) {} 218 219 void write() override; 220 221 private: 222 QByteArray buffer; 223 }; 224 225 template <class SRC> class QRfbHextileEncoder; 226 227 template <class SRC> 228 class QRfbSingleColorHextile 229 { 230 public: QRfbSingleColorHextile(QRfbHextileEncoder<SRC> * e)231 QRfbSingleColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 232 bool read(const uchar *data, int width, int height, int stride); 233 void write(QTcpSocket *socket) const; 234 235 private: 236 QRfbHextileEncoder<SRC> *encoder; 237 }; 238 239 template <class SRC> 240 class QRfbDualColorHextile 241 { 242 public: QRfbDualColorHextile(QRfbHextileEncoder<SRC> * e)243 QRfbDualColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 244 bool read(const uchar *data, int width, int height, int stride); 245 void write(QTcpSocket *socket) const; 246 247 private: 248 struct Rect { 249 quint8 xy; 250 quint8 wh; 251 } Q_PACKED rects[8 * 16]; 252 253 quint8 numRects; 254 QRfbHextileEncoder<SRC> *encoder; 255 256 private: lastx()257 inline int lastx() const { return rectx(numRects); } lasty()258 inline int lasty() const { return recty(numRects); } rectx(int r)259 inline int rectx(int r) const { return rects[r].xy >> 4; } recty(int r)260 inline int recty(int r) const { return rects[r].xy & 0x0f; } width(int r)261 inline int width(int r) const { return (rects[r].wh >> 4) + 1; } height(int r)262 inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; } 263 setX(int r,int x)264 inline void setX(int r, int x) { 265 rects[r].xy = (x << 4) | (rects[r].xy & 0x0f); 266 } setY(int r,int y)267 inline void setY(int r, int y) { 268 rects[r].xy = (rects[r].xy & 0xf0) | y; 269 } setWidth(int r,int width)270 inline void setWidth(int r, int width) { 271 rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f); 272 } setHeight(int r,int height)273 inline void setHeight(int r, int height) { 274 rects[r].wh = (rects[r].wh & 0xf0) | (height - 1); 275 } 276 setWidth(int width)277 inline void setWidth(int width) { setWidth(numRects, width); } setHeight(int height)278 inline void setHeight(int height) { setHeight(numRects, height); } setX(int x)279 inline void setX(int x) { setX(numRects, x); } setY(int y)280 inline void setY(int y) { setY(numRects, y); } 281 void next(); 282 }; 283 284 template <class SRC> 285 class QRfbMultiColorHextile 286 { 287 public: QRfbMultiColorHextile(QRfbHextileEncoder<SRC> * e)288 QRfbMultiColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 289 bool read(const uchar *data, int width, int height, int stride); 290 void write(QTcpSocket *socket) const; 291 292 private: rect(int r)293 inline quint8* rect(int r) { 294 return rects.data() + r * (bpp + 2); 295 } rect(int r)296 inline const quint8* rect(int r) const { 297 return rects.constData() + r * (bpp + 2); 298 } setX(int r,int x)299 inline void setX(int r, int x) { 300 quint8 *ptr = rect(r) + bpp; 301 *ptr = (x << 4) | (*ptr & 0x0f); 302 } setY(int r,int y)303 inline void setY(int r, int y) { 304 quint8 *ptr = rect(r) + bpp; 305 *ptr = (*ptr & 0xf0) | y; 306 } 307 void setColor(SRC color); rectx(int r)308 inline int rectx(int r) const { 309 const quint8 *ptr = rect(r) + bpp; 310 return *ptr >> 4; 311 } recty(int r)312 inline int recty(int r) const { 313 const quint8 *ptr = rect(r) + bpp; 314 return *ptr & 0x0f; 315 } setWidth(int r,int width)316 inline void setWidth(int r, int width) { 317 quint8 *ptr = rect(r) + bpp + 1; 318 *ptr = ((width - 1) << 4) | (*ptr & 0x0f); 319 } setHeight(int r,int height)320 inline void setHeight(int r, int height) { 321 quint8 *ptr = rect(r) + bpp + 1; 322 *ptr = (*ptr & 0xf0) | (height - 1); 323 } 324 325 bool beginRect(); 326 void endRect(); 327 328 static const int maxRectsSize = 16 * 16; 329 QVarLengthArray<quint8, maxRectsSize> rects; 330 331 quint8 bpp; 332 quint8 numRects; 333 QRfbHextileEncoder<SRC> *encoder; 334 }; 335 336 template <class SRC> 337 class QRfbHextileEncoder : public QRfbEncoder 338 { 339 public: 340 QRfbHextileEncoder(QVncServer *s); 341 void write(); 342 343 private: 344 enum SubEncoding { 345 Raw = 1, 346 BackgroundSpecified = 2, 347 ForegroundSpecified = 4, 348 AnySubrects = 8, 349 SubrectsColoured = 16 350 }; 351 352 QByteArray buffer; 353 QRfbSingleColorHextile<SRC> singleColorHextile; 354 QRfbDualColorHextile<SRC> dualColorHextile; 355 QRfbMultiColorHextile<SRC> multiColorHextile; 356 357 SRC bg; 358 SRC fg; 359 bool newBg; 360 bool newFg; 361 362 friend class QRfbSingleColorHextile<SRC>; 363 friend class QRfbDualColorHextile<SRC>; 364 friend class QRfbMultiColorHextile<SRC>; 365 }; 366 367 #if QT_CONFIG(cursor) 368 class QVncClientCursor : public QPlatformCursor 369 { 370 public: 371 QVncClientCursor(); 372 ~QVncClientCursor(); 373 374 void write(QVncClient *client) const; 375 376 void changeCursor(QCursor *widgetCursor, QWindow *window) override; 377 378 void addClient(QVncClient *client); 379 uint removeClient(QVncClient *client); 380 381 QImage cursor; 382 QPoint hotspot; 383 QVector<QVncClient *> clients; 384 }; 385 #endif // QT_CONFIG(cursor) 386 387 class QVncServer : public QObject 388 { 389 Q_OBJECT 390 public: 391 QVncServer(QVncScreen *screen, quint16 port = 5900); 392 ~QVncServer(); 393 394 enum ServerMsg { FramebufferUpdate = 0, 395 SetColourMapEntries = 1 }; 396 397 void setDirty(); 398 399 screen()400 inline QVncScreen* screen() const { return qvnc_screen; } dirtyMap()401 inline QVncDirtyMap* dirtyMap() const { return qvnc_screen->dirty; } 402 QImage screenImage() const; 403 void discardClient(QVncClient *client); 404 405 private slots: 406 void newConnection(); 407 void init(); 408 409 private: 410 QTcpServer *serverSocket; 411 QVector<QVncClient*> clients; 412 QVncScreen *qvnc_screen; 413 quint16 m_port; 414 }; 415 416 QT_END_NAMESPACE 417 418 #endif 419