1 /*
2  * synergy -- mouse and keyboard sharing utility
3  * Copyright (C) 2012-2016 Symless Ltd.
4  * Copyright (C) 2002 Chris Schoeneman
5  *
6  * This package is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * found in the file LICENSE that should have accompanied this file.
9  *
10  * This package is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "synergy/IClient.h"
22 
23 #include "synergy/Clipboard.h"
24 #include "synergy/DragInformation.h"
25 #include "synergy/INode.h"
26 #include "synergy/ClientArgs.h"
27 #include "net/NetworkAddress.h"
28 #include "base/EventTypes.h"
29 #include "mt/CondVar.h"
30 
31 class EventQueueTimer;
32 namespace synergy { class Screen; }
33 class ServerProxy;
34 class IDataSocket;
35 class ISocketFactory;
36 namespace synergy { class IStream; }
37 class IEventQueue;
38 class Thread;
39 class TCPSocket;
40 
41 //! Synergy client
42 /*!
43 This class implements the top-level client algorithms for synergy.
44 */
45 class Client : public IClient, public INode {
46 public:
47     class FailInfo {
48     public:
FailInfo(const char * what)49         FailInfo(const char* what) : m_retry(false), m_what(what) { }
50         bool            m_retry;
51         String            m_what;
52     };
53 
54 public:
55     /*!
56     This client will attempt to connect to the server using \p name
57     as its name and \p address as the server's address and \p factory
58     to create the socket.  \p screen is    the local screen.
59     */
60     Client(IEventQueue* events, const String& name,
61            const NetworkAddress& address, ISocketFactory* socketFactory,
62            synergy::Screen* screen, lib::synergy::ClientArgs const& args);
63     Client(Client const &) =delete;
64     Client(Client &&) =delete;
65     ~Client();
66 
67     Client& operator=(Client const &) =delete;
68     Client& operator=(Client &&) =delete;
69 
70     //! @name manipulators
71     //@{
72 
73     //! Connect to server
74     /*!
75     Starts an attempt to connect to the server.  This is ignored if
76     the client is trying to connect or is already connected.
77     */
78     void                connect(size_t addressIndex = 0);
79 
80     //! Disconnect
81     /*!
82     Disconnects from the server with an optional error message.
83     */
84     void                disconnect(const char* msg);
85 
86     //! Refuse connection
87     /*!
88     Disconnects from the server with an optional error message.
89     Unlike disconnect this function doesn't try to use other ip addresses
90     */
91     void                refuseConnection(const char* msg);
92 
93     //! Notify of handshake complete
94     /*!
95     Notifies the client that the connection handshake has completed.
96     */
97     virtual void        handshakeComplete();
98 
99     //! Received drag information
100     void                dragInfoReceived(UInt32 fileNum, String data);
101 
102     //! Create a new thread and use it to send file to Server
103     void                sendFileToServer(const char* filename);
104 
105     //! Send dragging file information back to server
106     void                sendDragInfo(UInt32 fileCount, String& info, size_t size);
107 
108 
109     //@}
110     //! @name accessors
111     //@{
112 
113     //! Test if connected
114     /*!
115     Returns true iff the client is successfully connected to the server.
116     */
117     bool                isConnected() const;
118 
119     //! Test if connecting
120     /*!
121     Returns true iff the client is currently attempting to connect to
122     the server.
123     */
124     bool                isConnecting() const;
125 
126     //! Get address of server
127     /*!
128     Returns the address of the server the client is connected (or wants
129     to connect) to.
130     */
131     NetworkAddress        getServerAddress() const;
132 
133     //! Return true if received file size is valid
134     bool                isReceivedFileSizeValid();
135 
136     //! Return expected file size
getExpectedFileSize()137     size_t&                getExpectedFileSize() { return m_expectedFileSize; }
138 
139     //! Return received file data
getReceivedFileData()140     String&                getReceivedFileData() { return m_receivedFileData; }
141 
142     //! Return drag file list
getDragFileList()143     DragFileList        getDragFileList() { return m_dragFileList; }
144 
145     //! Return last resolved adresses count
getLastResolvedAddressesCount()146     size_t              getLastResolvedAddressesCount() const { return m_resolvedAddressesCount; }
147 
148     //@}
149 
150     // IScreen overrides
151     virtual void*        getEventTarget() const;
152     virtual bool        getClipboard(ClipboardID id, IClipboard*) const;
153     virtual void        getShape(SInt32& x, SInt32& y,
154                             SInt32& width, SInt32& height) const;
155     virtual void        getCursorPos(SInt32& x, SInt32& y) const;
156 
157     // IClient overrides
158     virtual void        enter(SInt32 xAbs, SInt32 yAbs,
159                             UInt32 seqNum, KeyModifierMask mask,
160                             bool forScreensaver);
161     virtual bool        leave();
162     virtual void        setClipboard(ClipboardID, const IClipboard*);
163     virtual void        grabClipboard(ClipboardID);
164     virtual void        setClipboardDirty(ClipboardID, bool);
165     virtual void        keyDown(KeyID, KeyModifierMask, KeyButton);
166     virtual void        keyRepeat(KeyID, KeyModifierMask,
167                             SInt32 count, KeyButton);
168     virtual void        keyUp(KeyID, KeyModifierMask, KeyButton);
169     virtual void        mouseDown(ButtonID);
170     virtual void        mouseUp(ButtonID);
171     virtual void        mouseMove(SInt32 xAbs, SInt32 yAbs);
172     virtual void        mouseRelativeMove(SInt32 xRel, SInt32 yRel);
173     virtual void        mouseWheel(SInt32 xDelta, SInt32 yDelta);
174     virtual void        screensaver(bool activate);
175     virtual void        resetOptions();
176     virtual void        setOptions(const OptionsList& options);
177     virtual String        getName() const;
178 
179 private:
180     void                sendClipboard(ClipboardID);
181     void                sendEvent(Event::Type, void*);
182     void                sendConnectionFailedEvent(const char* msg);
183     void                sendFileChunk(const void* data);
184     void                sendFileThread(void*);
185     void                writeToDropDirThread(void*);
186     void                setupConnecting();
187     void                setupConnection();
188     void                setupScreen();
189     void                setupTimer();
190     void                cleanup();
191     void                cleanupConnecting();
192     void                cleanupConnection();
193     void                cleanupScreen();
194     void                cleanupTimer();
195     void                cleanupStream();
196     void                handleConnected(const Event&, void*);
197     void                handleConnectionFailed(const Event&, void*);
198     void                handleConnectTimeout(const Event&, void*);
199     void                handleOutputError(const Event&, void*);
200     void                handleDisconnected(const Event&, void*);
201     void                handleShapeChanged(const Event&, void*);
202     void                handleClipboardGrabbed(const Event&, void*);
203     void                handleHello(const Event&, void*);
204     void                handleSuspend(const Event& event, void*);
205     void                handleResume(const Event& event, void*);
206     void                handleFileChunkSending(const Event&, void*);
207     void                handleFileRecieveCompleted(const Event&, void*);
208     void                handleStopRetry(const Event&, void*);
209     void                onFileRecieveCompleted();
210     void                sendClipboardThread(void*);
211 
212 public:
213     bool                m_mock;
214 
215 private:
216     String              m_name;
217     NetworkAddress      m_serverAddress;
218     ISocketFactory*     m_socketFactory;
219     synergy::Screen*    m_screen;
220     synergy::IStream*   m_stream;
221     EventQueueTimer*    m_timer;
222     ServerProxy*        m_server;
223     bool                m_ready;
224     bool                m_active;
225     bool                m_suspended;
226     bool                m_connectOnResume;
227     bool                m_ownClipboard[kClipboardEnd];
228     bool                m_sentClipboard[kClipboardEnd];
229     IClipboard::Time    m_timeClipboard[kClipboardEnd];
230     String              m_dataClipboard[kClipboardEnd];
231     IEventQueue*        m_events;
232     std::size_t         m_expectedFileSize;
233     String              m_receivedFileData;
234     DragFileList        m_dragFileList;
235     String              m_dragFileExt;
236     Thread*             m_sendFileThread;
237     Thread*             m_writeToDropDirThread;
238     TCPSocket*          m_socket;
239     bool                m_useSecureNetwork;
240     bool                m_enableClipboard;
241     size_t              m_maximumClipboardSize;
242     lib::synergy::ClientArgs          m_args;
243     size_t              m_resolvedAddressesCount = 0;
244 };
245