blob: c8f4c24f07a52508b60158b48ca58acabd1ffed4 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossman615d16b2019-05-03 10:53:06 +02002 * Copyright 2009-2019 Pierre Ossman for Cendio AB
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00003 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20//
21// VNCSConnectionST is our derived class of SConnection for VNCServerST - there
22// is one for each connected client. We think of VNCSConnectionST as part of
23// the VNCServerST implementation, so its methods are allowed full access to
24// members of VNCServerST.
25//
26
27#ifndef __RFB_VNCSCONNECTIONST_H__
28#define __RFB_VNCSCONNECTIONST_H__
29
Pierre Ossman16e1dcb2017-05-16 14:33:43 +020030#include <map>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000031
Pierre Ossmanc09e5582015-12-11 20:23:17 +010032#include <rfb/Congestion.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000033#include <rfb/EncodeManager.h>
Pierre Ossman707fa122015-12-11 20:21:20 +010034#include <rfb/SConnection.h>
35#include <rfb/Timer.h>
Pierre Ossman1b478e52011-11-15 12:08:30 +000036
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000037namespace rfb {
Pierre Ossman707fa122015-12-11 20:21:20 +010038 class VNCServerST;
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +010039
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000040 class VNCSConnectionST : public SConnection,
Pierre Ossman1bb8b6c2011-10-25 15:20:05 +000041 public Timer::Callback {
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000042 public:
43 VNCSConnectionST(VNCServerST* server_, network::Socket* s, bool reverse);
44 virtual ~VNCSConnectionST();
45
Pierre Ossman7d64b332018-10-08 15:59:02 +020046 // SConnection methods
47
48 virtual bool accessCheck(AccessRights ar) const;
49 virtual void close(const char* reason);
50
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000051 // Methods called from VNCServerST. None of these methods ever knowingly
52 // throw an exception.
53
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000054 // init() must be called to initialise the protocol. If it fails it
55 // returns false, and close() will have been called.
56 bool init();
57
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000058 // processMessages() processes incoming messages from the client, invoking
59 // various callbacks as a result. It continues to process messages until
60 // reading might block. shutdown() will be called on the connection's
61 // Socket if an error occurs, via the close() call.
62 void processMessages();
63
Pierre Ossmand408ca52016-04-29 14:26:05 +020064 // flushSocket() pushes any unwritten data on to the network.
65 void flushSocket();
66
Pierre Ossmana3ac01e2011-11-07 21:13:54 +000067 // Called when the underlying pixelbuffer is resized or replaced.
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000068 void pixelBufferChange();
Pierre Ossmana3ac01e2011-11-07 21:13:54 +000069
70 // Wrappers to make these methods "safe" for VNCServerST.
71 void writeFramebufferUpdateOrClose();
72 void screenLayoutChangeOrClose(rdr::U16 reason);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000073 void setCursorOrClose();
Pierre Ossmana3ac01e2011-11-07 21:13:54 +000074 void bellOrClose();
Pierre Ossmana3ac01e2011-11-07 21:13:54 +000075 void setDesktopNameOrClose(const char *name);
Pierre Ossmanb45a84f2016-12-12 16:59:15 +010076 void setLEDStateOrClose(unsigned int state);
Pierre Ossmane6aab242018-10-05 16:59:22 +020077 void approveConnectionOrClose(bool accept, const char* reason);
Pierre Ossman615d16b2019-05-03 10:53:06 +020078 void requestClipboardOrClose();
79 void announceClipboardOrClose(bool available);
80 void sendClipboardDataOrClose(const char* data);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000081
Pierre Ossmanf8586822018-10-08 16:03:43 +020082 // The following methods never throw exceptions
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000083
Pierre Ossmanb114cec2011-11-20 15:36:11 +000084 // getComparerState() returns if this client would like the framebuffer
85 // comparer to be enabled.
86 bool getComparerState();
87
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000088 // renderedCursorChange() is called whenever the server-side rendered
89 // cursor changes shape or position. It ensures that the next update will
90 // clean up the old rendered cursor and if necessary draw the new rendered
91 // cursor.
92 void renderedCursorChange();
93
94 // needRenderedCursor() returns true if this client needs the server-side
95 // rendered cursor. This may be because it does not support local cursor
96 // or because the current cursor position has not been set by this client.
97 bool needRenderedCursor();
98
99 network::Socket* getSock() { return sock; }
Pierre Ossman7e1093e2018-10-11 08:08:19 +0200100
101 // Change tracking
102
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000103 void add_changed(const Region& region) { updates.add_changed(region); }
104 void add_copied(const Region& dest, const Point& delta) {
105 updates.add_copied(dest, delta);
106 }
107
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000108 private:
109 // SConnection callbacks
110
Pierre Ossmanf8586822018-10-08 16:03:43 +0200111 // These methods are invoked as callbacks from processMsg()
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000112
113 virtual void authSuccess();
Pierre Ossman88a94ed2019-04-01 14:22:01 +0200114 virtual void authFailure(const char* reason);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000115 virtual void queryConnection(const char* userName);
116 virtual void clientInit(bool shared);
117 virtual void setPixelFormat(const PixelFormat& pf);
118 virtual void pointerEvent(const Point& pos, int buttonMask);
Pierre Ossman5ae28212017-05-16 14:30:38 +0200119 virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000120 virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
Pierre Ossman34bb0612009-03-21 21:16:14 +0000121 virtual void setDesktopSize(int fb_width, int fb_height,
122 const ScreenSet& layout);
Pierre Ossman2c764942011-11-14 15:54:30 +0000123 virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
Pierre Ossman1b478e52011-11-15 12:08:30 +0000124 virtual void enableContinuousUpdates(bool enable,
125 int x, int y, int w, int h);
Pierre Ossman615d16b2019-05-03 10:53:06 +0200126 virtual void handleClipboardRequest();
127 virtual void handleClipboardAnnounce(bool available);
128 virtual void handleClipboardData(const char* data);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000129 virtual void supportsLocalCursor();
Pierre Ossman2c764942011-11-14 15:54:30 +0000130 virtual void supportsFence();
Pierre Ossman1b478e52011-11-15 12:08:30 +0000131 virtual void supportsContinuousUpdates();
Pierre Ossmanb45a84f2016-12-12 16:59:15 +0100132 virtual void supportsLEDState();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000133
Pierre Ossman1bb8b6c2011-10-25 15:20:05 +0000134 // Timer callbacks
135 virtual bool handleTimeout(Timer* t);
136
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000137 // Internal methods
138
Pierre Ossman851e6802017-09-12 16:44:44 +0200139 bool isShiftPressed();
140
Pierre Ossman1b478e52011-11-15 12:08:30 +0000141 // Congestion control
142 void writeRTTPing();
Pierre Ossman1bb8b6c2011-10-25 15:20:05 +0000143 bool isCongested();
144
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000145 // writeFramebufferUpdate() attempts to write a framebuffer update to the
146 // client.
147
148 void writeFramebufferUpdate();
Pierre Ossmancef3cf72016-11-25 10:06:34 +0100149 void writeNoDataUpdate();
150 void writeDataUpdate();
Pierre Ossmanb65feda2018-11-23 17:45:04 +0100151 void writeLosslessRefresh();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000152
Pierre Ossmana3ac01e2011-11-07 21:13:54 +0000153 void screenLayoutChange(rdr::U16 reason);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000154 void setCursor();
Pierre Ossmana3ac01e2011-11-07 21:13:54 +0000155 void setDesktopName(const char *name);
Pierre Ossmanb45a84f2016-12-12 16:59:15 +0100156 void setLEDState(unsigned int state);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000157 void setSocketTimeouts();
158
Pierre Ossman7e1093e2018-10-11 08:08:19 +0200159 private:
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000160 network::Socket* sock;
161 CharArray peerEndpoint;
Pierre Ossman7069bdd2015-02-06 14:41:58 +0100162 bool reverseConnection;
Pierre Ossmana3ac01e2011-11-07 21:13:54 +0000163
164 bool inProcessMessages;
165
Pierre Ossmanb8b1e962012-07-20 10:47:00 +0000166 bool pendingSyncFence, syncFence;
Pierre Ossman2c764942011-11-14 15:54:30 +0000167 rdr::U32 fenceFlags;
168 unsigned fenceDataLen;
169 char *fenceData;
170
Pierre Ossmanc09e5582015-12-11 20:23:17 +0100171 Congestion congestion;
Pierre Ossman1b478e52011-11-15 12:08:30 +0000172 Timer congestionTimer;
Peter Åstrand (astrand)7a368c92018-09-19 12:45:17 +0200173 Timer losslessTimer;
Pierre Ossman1b478e52011-11-15 12:08:30 +0000174
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000175 VNCServerST* server;
176 SimpleUpdateTracker updates;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000177 Region requested;
Pierre Ossman671d2ef2015-06-09 16:09:06 +0200178 bool updateRenderedCursor, removeRenderedCursor;
179 Region damagedCursorRegion;
Pierre Ossman1b478e52011-11-15 12:08:30 +0000180 bool continuousUpdates;
181 Region cuRegion;
Pierre Ossmanc0397262014-03-14 15:59:46 +0100182 EncodeManager encodeManager;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000183
Pierre Ossman16e1dcb2017-05-16 14:33:43 +0200184 std::map<rdr::U32, rdr::U32> pressedKeys;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000185
Pierre Ossman65e08fd2018-10-26 15:54:00 +0200186 Timer idleTimer;
187
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000188 time_t pointerEventTime;
189 Point pointerEventPos;
Pierre Ossman25db44a2017-11-16 16:40:44 +0100190 bool clientHasCursor;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000191
Pierre Ossman88a94ed2019-04-01 14:22:01 +0200192 Timer authFailureTimer;
193 CharArray authFailureMsg;
194
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000195 CharArray closeReason;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000196 };
197}
198#endif