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