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

source code of qtbase/src/plugins/platforms/vnc/qvnc_p.h