aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/client/Client.h
blob: 7ac515dcb6abddf303de093258daa948ddd28886 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*
 * barrier -- mouse and keyboard sharing utility
 * Copyright (C) 2012-2016 Symless Ltd.
 * Copyright (C) 2002 Chris Schoeneman
 * 
 * This package is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * found in the file LICENSE that should have accompanied this file.
 * 
 * This package is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "barrier/IClient.h"

#include "barrier/Clipboard.h"
#include "barrier/DragInformation.h"
#include "barrier/INode.h"
#include "barrier/ClientArgs.h"
#include "net/NetworkAddress.h"
#include "base/EventTypes.h"
#include "mt/CondVar.h"

class EventQueueTimer;
namespace barrier { class Screen; }
class ServerProxy;
class IDataSocket;
class ISocketFactory;
namespace barrier { class IStream; }
class IEventQueue;
class Thread;
class TCPSocket;

//! Barrier client
/*!
This class implements the top-level client algorithms for barrier.
*/
class Client : public IClient, public INode {
public:
    class FailInfo {
    public:
        FailInfo(const char* what) : m_retry(false), m_what(what) { }
        bool            m_retry;
        String            m_what;
    };

public:
    /*!
    This client will attempt to connect to the server using \p name
    as its name and \p address as the server's address and \p factory
    to create the socket.  \p screen is    the local screen.
    */
    Client(IEventQueue* events, const String& name,
           const NetworkAddress& address, ISocketFactory* socketFactory,
           barrier::Screen* screen, ClientArgs const& args);

    ~Client();

    //! @name manipulators
    //@{

    //! Connect to server
    /*!
    Starts an attempt to connect to the server.  This is ignored if
    the client is trying to connect or is already connected.
    */
    void                connect();

    //! Disconnect
    /*!
    Disconnects from the server with an optional error message.
    */
    void                disconnect(const char* msg);

    //! Notify of handshake complete
    /*!
    Notifies the client that the connection handshake has completed.
    */
    virtual void        handshakeComplete();

    //! Received drag information
    void                dragInfoReceived(UInt32 fileNum, String data);

    //! Create a new thread and use it to send file to Server
    void                sendFileToServer(const char* filename);
    
    //! Send dragging file information back to server
    void                sendDragInfo(UInt32 fileCount, String& info, size_t size);

    
    //@}
    //! @name accessors
    //@{

    //! Test if connected
    /*!
    Returns true iff the client is successfully connected to the server.
    */
    bool                isConnected() const;

    //! Test if connecting
    /*!
    Returns true iff the client is currently attempting to connect to
    the server.
    */
    bool                isConnecting() const;

    //! Get address of server
    /*!
    Returns the address of the server the client is connected (or wants
    to connect) to.
    */
    NetworkAddress        getServerAddress() const;
    
    //! Return true if recieved file size is valid
    bool                isReceivedFileSizeValid();

    //! Return expected file size
    size_t&                getExpectedFileSize() { return m_expectedFileSize; }

    //! Return received file data
    String&                getReceivedFileData() { return m_receivedFileData; }

    //! Return drag file list
    DragFileList        getDragFileList() { return m_dragFileList; }

    //@}

    // IScreen overrides
    virtual void*        getEventTarget() const;
    virtual bool        getClipboard(ClipboardID id, IClipboard*) const;
    virtual void        getShape(SInt32& x, SInt32& y,
                            SInt32& width, SInt32& height) const;
    virtual void        getCursorPos(SInt32& x, SInt32& y) const;

    // IClient overrides
    virtual void        enter(SInt32 xAbs, SInt32 yAbs,
                            UInt32 seqNum, KeyModifierMask mask,
                            bool forScreensaver);
    virtual bool        leave();
    virtual void        setClipboard(ClipboardID, const IClipboard*);
    virtual void        grabClipboard(ClipboardID);
    virtual void        setClipboardDirty(ClipboardID, bool);
    virtual void        keyDown(KeyID, KeyModifierMask, KeyButton);
    virtual void        keyRepeat(KeyID, KeyModifierMask,
                            SInt32 count, KeyButton);
    virtual void        keyUp(KeyID, KeyModifierMask, KeyButton);
    virtual void        mouseDown(ButtonID);
    virtual void        mouseUp(ButtonID);
    virtual void        mouseMove(SInt32 xAbs, SInt32 yAbs);
    virtual void        mouseRelativeMove(SInt32 xRel, SInt32 yRel);
    virtual void        mouseWheel(SInt32 xDelta, SInt32 yDelta);
    virtual void        screensaver(bool activate);
    virtual void        resetOptions();
    virtual void        setOptions(const OptionsList& options);
    virtual String        getName() const;

private:
    void                sendClipboard(ClipboardID);
    void                sendEvent(Event::Type, void*);
    void                sendConnectionFailedEvent(const char* msg);
    void                sendFileChunk(const void* data);
    void                sendFileThread(void*);
    void                writeToDropDirThread(void*);
    void                setupConnecting();
    void                setupConnection();
    void                setupScreen();
    void                setupTimer();
    void                cleanupConnecting();
    void                cleanupConnection();
    void                cleanupScreen();
    void                cleanupTimer();
    void                cleanupStream();
    void                handleConnected(const Event&, void*);
    void                handleConnectionFailed(const Event&, void*);
    void                handleConnectTimeout(const Event&, void*);
    void                handleOutputError(const Event&, void*);
    void                handleDisconnected(const Event&, void*);
    void                handleShapeChanged(const Event&, void*);
    void                handleClipboardGrabbed(const Event&, void*);
    void                handleHello(const Event&, void*);
    void                handleSuspend(const Event& event, void*);
    void                handleResume(const Event& event, void*);
    void                handleFileChunkSending(const Event&, void*);
    void                handleFileRecieveCompleted(const Event&, void*);
    void                handleStopRetry(const Event&, void*);
    void                onFileRecieveCompleted();
    void                sendClipboardThread(void*);

public:
    bool                m_mock;

private:
    String                m_name;
    NetworkAddress        m_serverAddress;
    ISocketFactory*        m_socketFactory;
    barrier::Screen*    m_screen;
    barrier::IStream*    m_stream;
    EventQueueTimer*    m_timer;
    ServerProxy*        m_server;
    bool                m_ready;
    bool                m_active;
    bool                m_suspended;
    bool                m_connectOnResume;
    bool                m_ownClipboard[kClipboardEnd];
    bool                m_sentClipboard[kClipboardEnd];
    IClipboard::Time    m_timeClipboard[kClipboardEnd];
    String                m_dataClipboard[kClipboardEnd];
    IEventQueue*        m_events;
    std::size_t            m_expectedFileSize;
    String                m_receivedFileData;
    DragFileList        m_dragFileList;
    String                m_dragFileExt;
    Thread*                m_sendFileThread;
    Thread*                m_writeToDropDirThread;
    TCPSocket*            m_socket;
    bool                m_useSecureNetwork;
    ClientArgs            m_args;
    bool                m_enableClipboard;
};