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
50QT_BEGIN_NAMESPACE
51
52Q_DECLARE_LOGGING_CATEGORY(lcVnc)
53
54class QTcpSocket;
55class QTcpServer;
56
57class QVncScreen;
58class QVncServer;
59class QVncClientCursor;
60class QVncClient;
61
62// This fits with the VNC hextile messages
63#define MAP_TILE_SIZE 16
64
65class QVncDirtyMap
66{
67public:
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
82protected:
83 uchar *map;
84 uchar *buffer;
85 int bufferWidth;
86 int bufferHeight;
87 int bufferStride;
88 int numTiles;
89};
90
91template <class T>
92class QVncDirtyMapOptimized : public QVncDirtyMap
93{
94public:
95 QVncDirtyMapOptimized(QVncScreen *screen) : QVncDirtyMap(screen) {}
96 ~QVncDirtyMapOptimized() {}
97
98 void setDirty(int x, int y, bool force = false) override;
99};
100
101
102class QRfbRect
103{
104public:
105 QRfbRect() {}
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
119class QRfbPixelFormat
120{
121public:
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
139class QRfbServerInit
140{
141public:
142 QRfbServerInit() { name = nullptr; }
143 ~QRfbServerInit() { delete[] name; }
144
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
157class QRfbSetEncodings
158{
159public:
160 bool read(QTcpSocket *s);
161
162 quint16 count;
163};
164
165class QRfbFrameBufferUpdateRequest
166{
167public:
168 bool read(QTcpSocket *s);
169
170 char incremental;
171 QRfbRect rect;
172};
173
174class QRfbKeyEvent
175{
176public:
177 bool read(QTcpSocket *s);
178
179 char down;
180 int keycode;
181 int unicode;
182};
183
184class QRfbPointerEvent
185{
186public:
187 bool read(QTcpSocket *s);
188
189 Qt::MouseButtons buttons;
190 quint16 x;
191 quint16 y;
192};
193
194class QRfbClientCutText
195{
196public:
197 bool read(QTcpSocket *s);
198
199 quint32 length;
200};
201
202class QRfbEncoder
203{
204public:
205 QRfbEncoder(QVncClient *s) : client(s) {}
206 virtual ~QRfbEncoder() {}
207
208 virtual void write() = 0;
209
210protected:
211 QVncClient *client;
212};
213
214class QRfbRawEncoder : public QRfbEncoder
215{
216public:
217 QRfbRawEncoder(QVncClient *s) : QRfbEncoder(s) {}
218
219 void write() override;
220
221private:
222 QByteArray buffer;
223};
224
225template <class SRC> class QRfbHextileEncoder;
226
227template <class SRC>
228class QRfbSingleColorHextile
229{
230public:
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
235private:
236 QRfbHextileEncoder<SRC> *encoder;
237};
238
239template <class SRC>
240class QRfbDualColorHextile
241{
242public:
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
247private:
248 struct Rect {
249 quint8 xy;
250 quint8 wh;
251 } Q_PACKED rects[8 * 16];
252
253 quint8 numRects;
254 QRfbHextileEncoder<SRC> *encoder;
255
256private:
257 inline int lastx() const { return rectx(numRects); }
258 inline int lasty() const { return recty(numRects); }
259 inline int rectx(int r) const { return rects[r].xy >> 4; }
260 inline int recty(int r) const { return rects[r].xy & 0x0f; }
261 inline int width(int r) const { return (rects[r].wh >> 4) + 1; }
262 inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; }
263
264 inline void setX(int r, int x) {
265 rects[r].xy = (x << 4) | (rects[r].xy & 0x0f);
266 }
267 inline void setY(int r, int y) {
268 rects[r].xy = (rects[r].xy & 0xf0) | y;
269 }
270 inline void setWidth(int r, int width) {
271 rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f);
272 }
273 inline void setHeight(int r, int height) {
274 rects[r].wh = (rects[r].wh & 0xf0) | (height - 1);
275 }
276
277 inline void setWidth(int width) { setWidth(numRects, width); }
278 inline void setHeight(int height) { setHeight(numRects, height); }
279 inline void setX(int x) { setX(numRects, x); }
280 inline void setY(int y) { setY(numRects, y); }
281 void next();
282};
283
284template <class SRC>
285class QRfbMultiColorHextile
286{
287public:
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
292private:
293 inline quint8* rect(int r) {
294 return rects.data() + r * (bpp + 2);
295 }
296 inline const quint8* rect(int r) const {
297 return rects.constData() + r * (bpp + 2);
298 }
299 inline void setX(int r, int x) {
300 quint8 *ptr = rect(r) + bpp;
301 *ptr = (x << 4) | (*ptr & 0x0f);
302 }
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);
308 inline int rectx(int r) const {
309 const quint8 *ptr = rect(r) + bpp;
310 return *ptr >> 4;
311 }
312 inline int recty(int r) const {
313 const quint8 *ptr = rect(r) + bpp;
314 return *ptr & 0x0f;
315 }
316 inline void setWidth(int r, int width) {
317 quint8 *ptr = rect(r) + bpp + 1;
318 *ptr = ((width - 1) << 4) | (*ptr & 0x0f);
319 }
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
336template <class SRC>
337class QRfbHextileEncoder : public QRfbEncoder
338{
339public:
340 QRfbHextileEncoder(QVncServer *s);
341 void write();
342
343private:
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)
368class QVncClientCursor : public QPlatformCursor
369{
370public:
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 QList<QVncClient *> clients;
384};
385#endif // QT_CONFIG(cursor)
386
387class QVncServer : public QObject
388{
389 Q_OBJECT
390public:
391 QVncServer(QVncScreen *screen, quint16 port = 5900);
392 ~QVncServer();
393
394 enum ServerMsg { FramebufferUpdate = 0,
395 SetColourMapEntries = 1 };
396
397 void setDirty();
398
399
400 inline QVncScreen* screen() const { return qvnc_screen; }
401 inline QVncDirtyMap* dirtyMap() const { return qvnc_screen->dirty; }
402 QImage screenImage() const;
403 void discardClient(QVncClient *client);
404
405private slots:
406 void newConnection();
407 void init();
408
409private:
410 QTcpServer *serverSocket;
411 QList<QVncClient*> clients;
412 QVncScreen *qvnc_screen;
413 quint16 m_port;
414};
415
416QT_END_NAMESPACE
417
418#endif
419