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