1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the plugins 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 http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QSCREENVNC_P_H 43 #define QSCREENVNC_P_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists for the convenience 50 // of the QLibrary class. This header file may change from version to version 51 // without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 56 #include "qscreenvnc_qws.h" 57 58 #ifndef QT_NO_QWS_VNC 59 60 #include <QtCore/qvarlengtharray.h> 61 #include <QtCore/qsharedmemory.h> 62 #include <QtNetwork/qtcpsocket.h> 63 #include <QtNetwork/qtcpserver.h> 64 65 QT_BEGIN_NAMESPACE 66 67 class QVNCServer; 68 69 #ifndef QT_NO_QWS_CURSOR 70 class QVNCCursor : public QProxyScreenCursor 71 { 72 public: 73 QVNCCursor(QVNCScreen *s); 74 ~QVNCCursor(); 75 76 void hide(); 77 void show(); 78 void set(const QImage &image, int hotx, int hoty); 79 void move(int x, int y); 80 81 private: 82 void setDirty(const QRect &r) const; 83 QVNCScreen *screen; 84 }; 85 86 class QVNCClientCursor : public QProxyScreenCursor 87 { 88 public: 89 QVNCClientCursor(QVNCServer *s); 90 ~QVNCClientCursor(); 91 92 void set(const QImage &image, int hotx, int hoty); 93 void write() const; 94 95 private: 96 QVNCServer *server; 97 }; 98 #endif // QT_NO_QWS_CURSOR 99 100 #define MAP_TILE_SIZE 16 101 #define MAP_WIDTH 1280 / MAP_TILE_SIZE 102 #define MAP_HEIGHT 1024 / MAP_TILE_SIZE 103 104 class QVNCDirtyMap 105 { 106 public: 107 QVNCDirtyMap(QScreen *screen); 108 virtual ~QVNCDirtyMap(); 109 110 void reset(); 111 bool dirty(int x, int y) const; 112 virtual void setDirty(int x, int y, bool force = false) = 0; 113 void setClean(int x, int y); 114 115 int bytesPerPixel; 116 117 int numDirty; 118 int mapWidth; 119 int mapHeight; 120 121 protected: 122 uchar *map; 123 QScreen *screen; 124 uchar *buffer; 125 int bufferWidth; 126 int bufferHeight; 127 int bufferStride; 128 int numTiles; 129 }; 130 131 template <class T> 132 class QVNCDirtyMapOptimized : public QVNCDirtyMap 133 { 134 public: QVNCDirtyMapOptimized(QScreen * screen)135 QVNCDirtyMapOptimized(QScreen *screen) : QVNCDirtyMap(screen) {} ~QVNCDirtyMapOptimized()136 ~QVNCDirtyMapOptimized() {} 137 138 void setDirty(int x, int y, bool force = false); 139 }; 140 141 class QRfbRect 142 { 143 public: QRfbRect()144 QRfbRect() {} QRfbRect(quint16 _x,quint16 _y,quint16 _w,quint16 _h)145 QRfbRect(quint16 _x, quint16 _y, quint16 _w, quint16 _h) { 146 x = _x; y = _y; w = _w; h = _h; 147 } 148 149 void read(QTcpSocket *s); 150 void write(QTcpSocket *s) const; 151 152 quint16 x; 153 quint16 y; 154 quint16 w; 155 quint16 h; 156 }; 157 158 class QRfbPixelFormat 159 { 160 public: size()161 static int size() { return 16; } 162 163 void read(QTcpSocket *s); 164 void write(QTcpSocket *s); 165 166 int bitsPerPixel; 167 int depth; 168 bool bigEndian; 169 bool trueColor; 170 int redBits; 171 int greenBits; 172 int blueBits; 173 int redShift; 174 int greenShift; 175 int blueShift; 176 }; 177 178 class QRfbServerInit 179 { 180 public: QRfbServerInit()181 QRfbServerInit() { name = 0; } ~QRfbServerInit()182 ~QRfbServerInit() { delete[] name; } 183 size()184 int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); } 185 void setName(const char *n); 186 187 void read(QTcpSocket *s); 188 void write(QTcpSocket *s); 189 190 quint16 width; 191 quint16 height; 192 QRfbPixelFormat format; 193 char *name; 194 }; 195 196 class QRfbSetEncodings 197 { 198 public: 199 bool read(QTcpSocket *s); 200 201 quint16 count; 202 }; 203 204 class QRfbFrameBufferUpdateRequest 205 { 206 public: 207 bool read(QTcpSocket *s); 208 209 char incremental; 210 QRfbRect rect; 211 }; 212 213 class QRfbKeyEvent 214 { 215 public: 216 bool read(QTcpSocket *s); 217 218 char down; 219 int keycode; 220 int unicode; 221 }; 222 223 class QRfbPointerEvent 224 { 225 public: 226 bool read(QTcpSocket *s); 227 228 uint buttons; 229 quint16 x; 230 quint16 y; 231 }; 232 233 class QRfbClientCutText 234 { 235 public: 236 bool read(QTcpSocket *s); 237 238 quint32 length; 239 }; 240 241 class QVNCScreenPrivate : public QObject 242 { 243 public: 244 QVNCScreenPrivate(QVNCScreen *parent); 245 ~QVNCScreenPrivate(); 246 247 void setDirty(const QRect &rect, bool force = false); 248 void configure(); 249 250 qreal dpiX; 251 qreal dpiY; 252 bool doOnScreenSurface; 253 QVNCDirtyMap *dirty; 254 int refreshRate; 255 QVNCServer *vncServer; 256 257 #if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY) 258 QSharedMemory shm; 259 #endif 260 261 QVNCScreen *q_ptr; 262 263 bool noDisablePainting; 264 }; 265 266 class QRfbEncoder 267 { 268 public: QRfbEncoder(QVNCServer * s)269 QRfbEncoder(QVNCServer *s) : server(s) {} ~QRfbEncoder()270 virtual ~QRfbEncoder() {} 271 272 virtual void write() = 0; 273 274 protected: 275 QVNCServer *server; 276 }; 277 278 class QRfbRawEncoder : public QRfbEncoder 279 { 280 public: QRfbRawEncoder(QVNCServer * s)281 QRfbRawEncoder(QVNCServer *s) : QRfbEncoder(s) {} 282 283 void write(); 284 285 private: 286 QByteArray buffer; 287 }; 288 289 template <class SRC> class QRfbHextileEncoder; 290 291 template <class SRC> 292 class QRfbSingleColorHextile 293 { 294 public: QRfbSingleColorHextile(QRfbHextileEncoder<SRC> * e)295 QRfbSingleColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 296 bool read(const uchar *data, int width, int height, int stride); 297 void write(QTcpSocket *socket) const; 298 299 private: 300 QRfbHextileEncoder<SRC> *encoder; 301 }; 302 303 template <class SRC> 304 class QRfbDualColorHextile 305 { 306 public: QRfbDualColorHextile(QRfbHextileEncoder<SRC> * e)307 QRfbDualColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 308 bool read(const uchar *data, int width, int height, int stride); 309 void write(QTcpSocket *socket) const; 310 311 private: 312 struct Rect { 313 quint8 xy; 314 quint8 wh; 315 } Q_PACKED rects[8 * 16]; 316 317 quint8 numRects; 318 QRfbHextileEncoder<SRC> *encoder; 319 320 private: lastx()321 inline int lastx() const { return rectx(numRects); } lasty()322 inline int lasty() const { return recty(numRects); } rectx(int r)323 inline int rectx(int r) const { return rects[r].xy >> 4; } recty(int r)324 inline int recty(int r) const { return rects[r].xy & 0x0f; } width(int r)325 inline int width(int r) const { return (rects[r].wh >> 4) + 1; } height(int r)326 inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; } 327 setX(int r,int x)328 inline void setX(int r, int x) { 329 rects[r].xy = (x << 4) | (rects[r].xy & 0x0f); 330 } setY(int r,int y)331 inline void setY(int r, int y) { 332 rects[r].xy = (rects[r].xy & 0xf0) | y; 333 } setWidth(int r,int width)334 inline void setWidth(int r, int width) { 335 rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f); 336 } setHeight(int r,int height)337 inline void setHeight(int r, int height) { 338 rects[r].wh = (rects[r].wh & 0xf0) | (height - 1); 339 } 340 setWidth(int width)341 inline void setWidth(int width) { setWidth(numRects, width); } setHeight(int height)342 inline void setHeight(int height) { setHeight(numRects, height); } setX(int x)343 inline void setX(int x) { setX(numRects, x); } setY(int y)344 inline void setY(int y) { setY(numRects, y); } 345 void next(); 346 }; 347 348 template <class SRC> 349 class QRfbMultiColorHextile 350 { 351 public: QRfbMultiColorHextile(QRfbHextileEncoder<SRC> * e)352 QRfbMultiColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {} 353 bool read(const uchar *data, int width, int height, int stride); 354 void write(QTcpSocket *socket) const; 355 356 private: rect(int r)357 inline quint8* rect(int r) { 358 return rects.data() + r * (bpp + 2); 359 } rect(int r)360 inline const quint8* rect(int r) const { 361 return rects.constData() + r * (bpp + 2); 362 } setX(int r,int x)363 inline void setX(int r, int x) { 364 quint8 *ptr = rect(r) + bpp; 365 *ptr = (x << 4) | (*ptr & 0x0f); 366 } setY(int r,int y)367 inline void setY(int r, int y) { 368 quint8 *ptr = rect(r) + bpp; 369 *ptr = (*ptr & 0xf0) | y; 370 } 371 void setColor(SRC color); rectx(int r)372 inline int rectx(int r) const { 373 const quint8 *ptr = rect(r) + bpp; 374 return *ptr >> 4; 375 } recty(int r)376 inline int recty(int r) const { 377 const quint8 *ptr = rect(r) + bpp; 378 return *ptr & 0x0f; 379 } setWidth(int r,int width)380 inline void setWidth(int r, int width) { 381 quint8 *ptr = rect(r) + bpp + 1; 382 *ptr = ((width - 1) << 4) | (*ptr & 0x0f); 383 } setHeight(int r,int height)384 inline void setHeight(int r, int height) { 385 quint8 *ptr = rect(r) + bpp + 1; 386 *ptr = (*ptr & 0xf0) | (height - 1); 387 } 388 389 bool beginRect(); 390 void endRect(); 391 392 static const int maxRectsSize = 16 * 16; 393 QVarLengthArray<quint8, maxRectsSize> rects; 394 395 quint8 bpp; 396 quint8 numRects; 397 QRfbHextileEncoder<SRC> *encoder; 398 }; 399 400 template <class SRC> 401 class QRfbHextileEncoder : public QRfbEncoder 402 { 403 public: 404 QRfbHextileEncoder(QVNCServer *s); 405 void write(); 406 407 private: 408 enum SubEncoding { 409 Raw = 1, 410 BackgroundSpecified = 2, 411 ForegroundSpecified = 4, 412 AnySubrects = 8, 413 SubrectsColoured = 16 414 }; 415 416 QByteArray buffer; 417 QRfbSingleColorHextile<SRC> singleColorHextile; 418 QRfbDualColorHextile<SRC> dualColorHextile; 419 QRfbMultiColorHextile<SRC> multiColorHextile; 420 421 SRC bg; 422 SRC fg; 423 bool newBg; 424 bool newFg; 425 426 friend class QRfbSingleColorHextile<SRC>; 427 friend class QRfbDualColorHextile<SRC>; 428 friend class QRfbMultiColorHextile<SRC>; 429 }; 430 431 class QVNCServer : public QObject 432 { 433 Q_OBJECT 434 public: 435 QVNCServer(QVNCScreen *screen); 436 QVNCServer(QVNCScreen *screen, int id); 437 ~QVNCServer(); 438 439 void setDirty(); setDirtyCursor()440 void setDirtyCursor() { dirtyCursor = true; setDirty(); } isConnected()441 inline bool isConnected() const { return state == Connected; } setRefreshRate(int rate)442 inline void setRefreshRate(int rate) { refreshRate = rate; } 443 444 enum ClientMsg { SetPixelFormat = 0, 445 FixColourMapEntries = 1, 446 SetEncodings = 2, 447 FramebufferUpdateRequest = 3, 448 KeyEvent = 4, 449 PointerEvent = 5, 450 ClientCutText = 6 }; 451 452 enum ServerMsg { FramebufferUpdate = 0, 453 SetColourMapEntries = 1 }; 454 455 void convertPixels(char *dst, const char *src, int count) const; 456 clientBytesPerPixel()457 inline int clientBytesPerPixel() const { 458 return pixelFormat.bitsPerPixel / 8; 459 } 460 screen()461 inline QVNCScreen* screen() const { return qvnc_screen; } dirtyMap()462 inline QVNCDirtyMap* dirtyMap() const { return qvnc_screen->d_ptr->dirty; } clientSocket()463 inline QTcpSocket* clientSocket() const { return client; } 464 QImage screenImage() const; doPixelConversion()465 inline bool doPixelConversion() const { return needConversion; } 466 #ifndef QT_NO_QWS_CURSOR hasClientCursor()467 inline bool hasClientCursor() const { return qvnc_cursor != 0; } 468 #endif 469 470 private: 471 void setPixelFormat(); 472 void setEncodings(); 473 void frameBufferUpdateRequest(); 474 void pointerEvent(); 475 void keyEvent(); 476 void clientCutText(); 477 bool pixelConversionNeeded() const; 478 479 private slots: 480 void newConnection(); 481 void readClient(); 482 void checkUpdate(); 483 void discardClient(); 484 485 private: 486 void init(uint port); 487 enum ClientState { Unconnected, Protocol, Init, Connected }; 488 QTimer *timer; 489 QTcpServer *serverSocket; 490 QTcpSocket *client; 491 ClientState state; 492 quint8 msgType; 493 bool handleMsg; 494 QRfbPixelFormat pixelFormat; 495 Qt::KeyboardModifiers keymod; 496 int encodingsPending; 497 int cutTextPending; 498 uint supportCopyRect : 1; 499 uint supportRRE : 1; 500 uint supportCoRRE : 1; 501 uint supportHextile : 1; 502 uint supportZRLE : 1; 503 uint supportCursor : 1; 504 uint supportDesktopSize : 1; 505 bool wantUpdate; 506 bool sameEndian; 507 bool needConversion; 508 #if Q_BYTE_ORDER == Q_BIG_ENDIAN 509 bool swapBytes; 510 #endif 511 bool dirtyCursor; 512 int refreshRate; 513 QVNCScreen *qvnc_screen; 514 #ifndef QT_NO_QWS_CURSOR 515 QVNCClientCursor *qvnc_cursor; 516 #endif 517 518 QRfbEncoder *encoder; 519 }; 520 521 522 QT_END_NAMESPACE 523 #endif // QT_NO_QWS_VNC 524 #endif // QSCREENVNC_P_H 525