1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  * Copyright 2009-2019 Pierre Ossman for Cendio AB
3  *
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 // -=- VNCServerST.h
21 
22 // Single-threaded VNCServer implementation
23 
24 #ifndef __RFB_VNCSERVERST_H__
25 #define __RFB_VNCSERVERST_H__
26 
27 #include <sys/time.h>
28 
29 #include <rfb/SDesktop.h>
30 #include <rfb/VNCServer.h>
31 #include <rfb/Blacklist.h>
32 #include <rfb/Cursor.h>
33 #include <rfb/Timer.h>
34 #include <rfb/ScreenSet.h>
35 
36 namespace rfb {
37 
38   class VNCSConnectionST;
39   class ComparingUpdateTracker;
40   class ListConnInfo;
41   class PixelBuffer;
42   class KeyRemapper;
43 
44   class VNCServerST : public VNCServer,
45                       public Timer::Callback {
46   public:
47     // -=- Constructors
48 
49     //   Create a server exporting the supplied desktop.
50     VNCServerST(const char* name_, SDesktop* desktop_);
51     virtual ~VNCServerST();
52 
53 
54     // Methods overridden from SocketServer
55 
56     // addSocket
57     //   Causes the server to allocate an RFB-protocol management
58     //   structure for the socket & initialise it.
59     virtual void addSocket(network::Socket* sock, bool outgoing=false);
60 
61     // removeSocket
62     //   Clean up any resources associated with the Socket
63     virtual void removeSocket(network::Socket* sock);
64 
65     // getSockets() gets a list of sockets.  This can be used to generate an
66     // fd_set for calling select().
67     virtual void getSockets(std::list<network::Socket*>* sockets);
68 
69     // processSocketReadEvent
70     //   Read more RFB data from the Socket.  If an error occurs during
71     //   processing then shutdown() is called on the Socket, causing
72     //   removeSocket() to be called by the caller at a later time.
73     virtual void processSocketReadEvent(network::Socket* sock);
74 
75     // processSocketWriteEvent
76     //   Flush pending data from the Socket on to the network.
77     virtual void processSocketWriteEvent(network::Socket* sock);
78 
79 
80     // Methods overridden from VNCServer
81 
82     virtual void blockUpdates();
83     virtual void unblockUpdates();
84     virtual void setPixelBuffer(PixelBuffer* pb, const ScreenSet& layout);
85     virtual void setPixelBuffer(PixelBuffer* pb);
86     virtual void setScreenLayout(const ScreenSet& layout);
getPixelBuffer()87     virtual const PixelBuffer* getPixelBuffer() const { return pb; }
88 
89     virtual void requestClipboard();
90     virtual void announceClipboard(bool available);
91     virtual void sendClipboardData(const char* data);
92 
93     virtual void approveConnection(network::Socket* sock, bool accept,
94                                    const char* reason);
closeClients(const char * reason)95     virtual void closeClients(const char* reason) {closeClients(reason, 0);}
96     virtual SConnection* getConnection(network::Socket* sock);
97 
98     virtual void add_changed(const Region &region);
99     virtual void add_copied(const Region &dest, const Point &delta);
100     virtual void setCursor(int width, int height, const Point& hotspot,
101                            const rdr::U8* data);
102     virtual void setCursorPos(const Point& p, bool warped);
103     virtual void setName(const char* name_);
104     virtual void setLEDState(unsigned state);
105 
106     virtual void bell();
107 
108     // VNCServerST-only methods
109 
110     // Methods to get the currently set server state
111 
getScreenLayout()112     const ScreenSet& getScreenLayout() const { return screenLayout; }
getCursor()113     const Cursor* getCursor() const { return cursor; }
getCursorPos()114     const Point& getCursorPos() const { return cursorPos; }
getName()115     const char* getName() const { return name.buf; }
getLEDState()116     unsigned getLEDState() const { return ledState; }
117 
118     // Event handlers
119     void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
120     void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask);
121 
122     void handleClipboardRequest(VNCSConnectionST* client);
123     void handleClipboardAnnounce(VNCSConnectionST* client, bool available);
124     void handleClipboardData(VNCSConnectionST* client, const char* data);
125 
126     unsigned int setDesktopSize(VNCSConnectionST* requester,
127                                 int fb_width, int fb_height,
128                                 const ScreenSet& layout);
129 
130     // closeClients() closes all RFB sessions, except the specified one (if
131     // any), and logs the specified reason for closure.
132     void closeClients(const char* reason, network::Socket* sock);
133 
134     // queryConnection() does some basic checks and then passes on the
135     // request to the desktop.
136     void queryConnection(VNCSConnectionST* client, const char* userName);
137 
138     // clientReady() is called by a VNCSConnectionST instance when the
139     // client has completed the handshake and is ready for normal
140     // communication.
141     void clientReady(VNCSConnectionST* client, bool shared);
142 
143     // Estimated time until the next time new updates will be pushed
144     // to clients
145     int msToNextUpdate();
146 
147     // Part of the framebuffer that has been modified but is not yet
148     // ready to be sent to clients
149     Region getPendingRegion();
150 
151     // getRenderedCursor() returns an up to date version of the server
152     // side rendered cursor buffer
153     const RenderedCursor* getRenderedCursor();
154 
155   protected:
156 
157     // Timer callbacks
158     virtual bool handleTimeout(Timer* t);
159 
160     // - Internal methods
161 
162     void startDesktop();
163     void stopDesktop();
164 
165     // - Check how many of the clients are authenticated.
166     int authClientCount();
167 
168     bool needRenderedCursor();
169     void startFrameClock();
170     void stopFrameClock();
171     void writeUpdate();
172 
173     bool getComparerState();
174 
175   protected:
176     Blacklist blacklist;
177     Blacklist* blHosts;
178 
179     SDesktop* desktop;
180     bool desktopStarted;
181     int blockCounter;
182     PixelBuffer* pb;
183     ScreenSet screenLayout;
184     unsigned int ledState;
185 
186     CharArray name;
187 
188     std::list<VNCSConnectionST*> clients;
189     VNCSConnectionST* pointerClient;
190     VNCSConnectionST* clipboardClient;
191     std::list<VNCSConnectionST*> clipboardRequestors;
192     std::list<network::Socket*> closingSockets;
193 
194     ComparingUpdateTracker* comparer;
195 
196     Point cursorPos;
197     Cursor* cursor;
198     RenderedCursor renderedCursor;
199     bool renderedCursorInvalid;
200 
201     KeyRemapper* keyRemapper;
202 
203     Timer idleTimer;
204     Timer disconnectTimer;
205     Timer connectTimer;
206 
207     Timer frameTimer;
208   };
209 
210 };
211 
212 #endif
213 
214