2001-10-06 14:13:28 +00:00
|
|
|
#ifndef CSERVER_H
|
|
|
|
#define CSERVER_H
|
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
#include "IServer.h"
|
2002-07-13 22:00:38 +00:00
|
|
|
#include "IPrimaryScreenReceiver.h"
|
2002-06-10 22:06:45 +00:00
|
|
|
#include "CConfig.h"
|
|
|
|
#include "CClipboard.h"
|
2002-06-02 11:49:46 +00:00
|
|
|
#include "CCondVar.h"
|
2001-10-06 14:13:28 +00:00
|
|
|
#include "CMutex.h"
|
2002-05-31 18:09:43 +00:00
|
|
|
#include "CThread.h"
|
2002-06-01 19:26:11 +00:00
|
|
|
#include "stdlist.h"
|
|
|
|
#include "stdmap.h"
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
class CClientProxy;
|
|
|
|
class CHTTPServer;
|
|
|
|
class CPrimaryClient;
|
|
|
|
class IClient;
|
|
|
|
class IDataSocket;
|
2001-10-06 14:13:28 +00:00
|
|
|
class IServerProtocol;
|
|
|
|
class ISocketFactory;
|
|
|
|
class ISecurityFactory;
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Synergy server
|
|
|
|
/*!
|
|
|
|
This class implements the top-level server algorithms for synergy.
|
|
|
|
*/
|
2002-07-13 22:00:38 +00:00
|
|
|
class CServer : public IServer, public IPrimaryScreenReceiver {
|
2002-04-29 14:40:01 +00:00
|
|
|
public:
|
2002-07-30 14:59:36 +00:00
|
|
|
/*!
|
|
|
|
The server will look itself up in the configuration using \c serverName
|
|
|
|
as its name.
|
|
|
|
*/
|
2002-06-09 17:59:32 +00:00
|
|
|
CServer(const CString& serverName);
|
2001-10-06 14:13:28 +00:00
|
|
|
~CServer();
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! @name manipulators
|
|
|
|
//@{
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Open server
|
|
|
|
/*!
|
|
|
|
Open the server and return true iff successful.
|
|
|
|
*/
|
2002-06-21 17:55:47 +00:00
|
|
|
bool open();
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Server main loop
|
|
|
|
/*!
|
|
|
|
Run server's event loop and return when quit() is called.
|
|
|
|
This must be called between a successful open() and close().
|
|
|
|
|
|
|
|
(cancellation point)
|
|
|
|
*/
|
2001-10-06 14:13:28 +00:00
|
|
|
void run();
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Exit event loop
|
|
|
|
/*!
|
|
|
|
Force run() to return. This call can return before
|
|
|
|
run() does (i.e. asynchronously). This may only be
|
|
|
|
called between a successful open() and close().
|
|
|
|
*/
|
2001-11-19 00:33:36 +00:00
|
|
|
void quit();
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Close server
|
|
|
|
/*!
|
|
|
|
Close the server.
|
|
|
|
*/
|
2002-07-13 22:00:38 +00:00
|
|
|
void close();
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Set configuration
|
|
|
|
/*!
|
|
|
|
Change the server's configuration. Returns true iff the new
|
|
|
|
configuration was accepted (it must include the server's name).
|
|
|
|
This will disconnect any clients no longer in the configuration.
|
|
|
|
*/
|
2002-05-31 18:09:43 +00:00
|
|
|
bool setConfig(const CConfig&);
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//@}
|
|
|
|
//! @name accessors
|
|
|
|
//@{
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Get configuration
|
|
|
|
/*!
|
|
|
|
Returns the current configuration.
|
|
|
|
*/
|
2002-05-31 14:43:23 +00:00
|
|
|
void getConfig(CConfig*) const;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Get name
|
|
|
|
/*!
|
|
|
|
Returns the server's name passed to the c'tor
|
|
|
|
*/
|
2002-05-30 16:13:16 +00:00
|
|
|
CString getPrimaryScreenName() const;
|
|
|
|
|
2002-07-30 14:59:36 +00:00
|
|
|
//@}
|
|
|
|
|
2002-07-13 22:00:38 +00:00
|
|
|
// IServer overrides
|
2002-07-16 16:52:26 +00:00
|
|
|
virtual void onError();
|
2002-07-13 22:00:38 +00:00
|
|
|
virtual void onInfoChanged(const CString&, const CClientInfo&);
|
|
|
|
virtual bool onGrabClipboard(const CString&, ClipboardID, UInt32);
|
|
|
|
virtual void onClipboardChanged(ClipboardID, UInt32, const CString&);
|
|
|
|
|
2002-07-10 21:22:28 +00:00
|
|
|
// IPrimaryScreenReceiver overrides
|
2002-07-13 22:00:38 +00:00
|
|
|
virtual void onScreensaver(bool activated);
|
2002-07-09 21:22:31 +00:00
|
|
|
virtual void onKeyDown(KeyID, KeyModifierMask);
|
|
|
|
virtual void onKeyUp(KeyID, KeyModifierMask);
|
|
|
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
|
|
|
virtual void onMouseDown(ButtonID);
|
|
|
|
virtual void onMouseUp(ButtonID);
|
|
|
|
virtual bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
|
|
|
virtual void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
|
|
|
virtual void onMouseWheel(SInt32 delta);
|
2002-07-10 21:22:28 +00:00
|
|
|
|
2002-04-29 14:40:01 +00:00
|
|
|
protected:
|
2002-07-30 14:59:36 +00:00
|
|
|
//! Handle special keys
|
|
|
|
/*!
|
|
|
|
Handles keys with special meaning.
|
|
|
|
*/
|
2001-10-06 14:13:28 +00:00
|
|
|
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
|
|
|
|
2002-04-29 14:40:01 +00:00
|
|
|
private:
|
2002-07-09 21:22:31 +00:00
|
|
|
typedef std::list<CThread> CThreadList;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-07-11 13:13:37 +00:00
|
|
|
// get the sides of the primary screen that have neighbors
|
|
|
|
UInt32 getActivePrimarySides() const;
|
|
|
|
|
2002-06-01 10:52:02 +00:00
|
|
|
// handle mouse motion
|
|
|
|
bool onMouseMovePrimaryNoLock(SInt32 x, SInt32 y);
|
|
|
|
void onMouseMoveSecondaryNoLock(SInt32 dx, SInt32 dy);
|
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
// set the clipboard
|
|
|
|
void onClipboardChangedNoLock(ClipboardID,
|
|
|
|
UInt32 seqNum, const CString& data);
|
|
|
|
|
2002-06-01 10:52:02 +00:00
|
|
|
// returns true iff mouse should be locked to the current screen
|
|
|
|
bool isLockedToScreenNoLock() const;
|
|
|
|
|
2001-10-06 14:13:28 +00:00
|
|
|
// change the active screen
|
2002-07-09 21:22:31 +00:00
|
|
|
void switchScreen(IClient*,
|
2002-06-23 23:24:22 +00:00
|
|
|
SInt32 x, SInt32 y, bool forScreenSaver);
|
2001-10-06 14:13:28 +00:00
|
|
|
|
|
|
|
// lookup neighboring screen
|
2002-07-15 15:01:36 +00:00
|
|
|
IClient* getNeighbor(IClient*, EDirection) const;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
|
|
|
// lookup neighboring screen. given a position relative to the
|
|
|
|
// source screen, find the screen we should move onto and where.
|
|
|
|
// if the position is sufficiently far from the source then we
|
2002-06-19 17:03:29 +00:00
|
|
|
// cross multiple screens. if there is no suitable screen then
|
|
|
|
// return NULL and x,y are not modified.
|
2002-07-15 15:01:36 +00:00
|
|
|
IClient* getNeighbor(IClient*, EDirection,
|
2002-06-10 22:06:45 +00:00
|
|
|
SInt32& x, SInt32& y) const;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
|
|
|
// open/close the primary screen
|
|
|
|
void openPrimaryScreen();
|
2001-10-14 16:58:01 +00:00
|
|
|
void closePrimaryScreen();
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-04-29 13:31:44 +00:00
|
|
|
// update the clipboard if owned by the primary screen
|
|
|
|
void updatePrimaryClipboard(ClipboardID);
|
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
// close all clients that are *not* in config, not including the
|
|
|
|
// primary client.
|
|
|
|
void closeClients(const CConfig& config);
|
|
|
|
|
2002-06-21 15:18:01 +00:00
|
|
|
// start a thread, adding it to the list of threads
|
2002-07-18 17:00:48 +00:00
|
|
|
CThread startThread(IJob* adopted);
|
2002-06-21 15:18:01 +00:00
|
|
|
|
|
|
|
// cancel running threads, waiting at most timeout seconds for
|
|
|
|
// them to finish.
|
|
|
|
void stopThreads(double timeout = -1.0);
|
|
|
|
|
|
|
|
// reap threads, clearing finished threads from the thread list.
|
|
|
|
// doReapThreads does the work on the given thread list.
|
|
|
|
void reapThreads();
|
|
|
|
void doReapThreads(CThreadList&);
|
2001-10-06 14:13:28 +00:00
|
|
|
|
|
|
|
// thread method to accept incoming client connections
|
|
|
|
void acceptClients(void*);
|
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
// thread method to do client interaction
|
|
|
|
void runClient(void*);
|
|
|
|
CClientProxy* handshakeClient(IDataSocket*);
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-05-30 16:13:16 +00:00
|
|
|
// thread method to accept incoming HTTP connections
|
|
|
|
void acceptHTTPClients(void*);
|
|
|
|
|
|
|
|
// thread method to process HTTP requests
|
|
|
|
void processHTTPRequest(void*);
|
|
|
|
|
2001-10-06 14:13:28 +00:00
|
|
|
// connection list maintenance
|
2002-07-09 21:22:31 +00:00
|
|
|
void addConnection(IClient*);
|
2001-10-06 14:13:28 +00:00
|
|
|
void removeConnection(const CString& name);
|
|
|
|
|
2002-04-29 14:40:01 +00:00
|
|
|
private:
|
2002-04-29 13:31:44 +00:00
|
|
|
class CClipboardInfo {
|
2002-04-27 14:19:53 +00:00
|
|
|
public:
|
2002-04-29 13:31:44 +00:00
|
|
|
CClipboardInfo();
|
2002-04-27 14:19:53 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
CClipboard m_clipboard;
|
|
|
|
CString m_clipboardData;
|
|
|
|
CString m_clipboardOwner;
|
|
|
|
UInt32 m_clipboardSeqNum;
|
|
|
|
};
|
2001-10-06 14:13:28 +00:00
|
|
|
|
|
|
|
CMutex m_mutex;
|
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// the name of the primary screen
|
2002-06-09 17:59:32 +00:00
|
|
|
CString m_name;
|
|
|
|
|
2002-07-09 21:22:31 +00:00
|
|
|
// how long to wait to bind our socket until we give up
|
2001-10-06 14:13:28 +00:00
|
|
|
double m_bindTimeout;
|
|
|
|
|
|
|
|
ISocketFactory* m_socketFactory;
|
|
|
|
ISecurityFactory* m_securityFactory;
|
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// running threads
|
2002-06-21 15:18:01 +00:00
|
|
|
CThreadList m_threads;
|
2002-07-18 17:00:48 +00:00
|
|
|
CThread* m_acceptClientThread;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// the screens
|
2002-07-09 21:22:31 +00:00
|
|
|
typedef std::map<CString, IClient*> CClientList;
|
|
|
|
typedef std::map<CString, CThread> CClientThreadList;
|
|
|
|
|
|
|
|
// all clients indexed by name
|
|
|
|
CClientList m_clients;
|
|
|
|
|
|
|
|
// run thread of all secondary screen clients. does not include the
|
|
|
|
// primary screen's run thread.
|
|
|
|
CClientThreadList m_clientThreads;
|
|
|
|
|
|
|
|
// the primary screen client
|
|
|
|
CPrimaryClient* m_primaryClient;
|
|
|
|
|
|
|
|
// the client with focus
|
|
|
|
IClient* m_active;
|
2001-10-06 14:13:28 +00:00
|
|
|
|
2002-04-29 13:31:44 +00:00
|
|
|
// the sequence number of enter messages
|
|
|
|
UInt32 m_seqNum;
|
|
|
|
|
2002-05-24 17:54:28 +00:00
|
|
|
// current mouse position (in absolute secondary screen coordinates)
|
2001-10-06 14:13:28 +00:00
|
|
|
SInt32 m_x, m_y;
|
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// current configuration
|
2002-05-31 14:43:23 +00:00
|
|
|
CConfig m_config;
|
2001-11-25 18:32:41 +00:00
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// clipboard cache
|
2002-04-29 13:31:44 +00:00
|
|
|
CClipboardInfo m_clipboards[kClipboardEnd];
|
2002-05-30 16:13:16 +00:00
|
|
|
|
2002-06-22 19:20:21 +00:00
|
|
|
// state saved when screen saver activates
|
2002-07-09 21:22:31 +00:00
|
|
|
IClient* m_activeSaver;
|
2002-06-22 19:20:21 +00:00
|
|
|
SInt32 m_xSaver, m_ySaver;
|
|
|
|
|
2002-06-02 11:49:46 +00:00
|
|
|
// HTTP request processing stuff
|
2002-05-30 16:13:16 +00:00
|
|
|
CHTTPServer* m_httpServer;
|
2002-06-02 11:49:46 +00:00
|
|
|
CCondVar<SInt32> m_httpAvailable;
|
|
|
|
static const SInt32 s_httpMaxSimultaneousRequests;
|
2001-10-06 14:13:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|