barrier/server/CServer.h
crs 1cbdaee31b added better handling of X server disconnecting unexpectedly.
the apps still exit but they do it in a mostly controlled
manner.  in particular, the server threads except the one
processing primary screen events will terminate gracefully.
this will be important should the server ever allow HTTP
clients to rewrite the configuration file.

note that X makes it effectively impossible to continue once
the X server disconnects.  even if it didn't it would be
difficult for synergy to recover.  users will have to add
synergy to the X display manager's startup script if they
expect the server to be restarted.  alternatively, we could
add code to fork synergy at startup;  the child would do
the normal work while the parent would simply wait for the
child to exit and restart it.
2002-06-03 13:45:30 +00:00

252 lines
6.5 KiB
C++

#ifndef CSERVER_H
#define CSERVER_H
#include "ClipboardTypes.h"
#include "KeyTypes.h"
#include "MouseTypes.h"
#include "CConfig.h"
#include "CClipboard.h"
#include "CCondVar.h"
#include "CMutex.h"
#include "CString.h"
#include "CThread.h"
#include "XBase.h"
#include "stdlist.h"
#include "stdmap.h"
class CThread;
class IServerProtocol;
class ISocketFactory;
class ISecurityFactory;
class IPrimaryScreen;
class CHTTPServer;
class CServer {
public:
CServer();
~CServer();
// manipulators
// start the server. does not return until quit() is called.
void run();
// tell server to exit gracefully
void quit();
// tell the server to shutdown. this is called in an emergency
// when we need to tell the server that we cannot continue. the
// server will attempt to clean up.
void shutdown();
// update screen map. returns true iff the new configuration was
// accepted.
bool setConfig(const CConfig&);
// handle events on server's screen. onMouseMovePrimary() returns
// true iff the mouse enters a jump zone and jumps.
void onKeyDown(KeyID, KeyModifierMask);
void onKeyUp(KeyID, KeyModifierMask);
void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
void onMouseDown(ButtonID);
void onMouseUp(ButtonID);
bool onMouseMovePrimary(SInt32 x, SInt32 y);
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
void onMouseWheel(SInt32 delta);
void grabClipboard(ClipboardID);
// handle updates from primary
void setInfo(SInt32 wScreen, SInt32 hScreen,
SInt32 zoneSize,
SInt32 xMouse, SInt32 yMouse);
// handle messages from clients
void setInfo(const CString& clientName,
SInt32 wScreen, SInt32 hScreen,
SInt32 zoneSize,
SInt32 xMouse, SInt32 yMouse);
void grabClipboard(ClipboardID,
UInt32 seqNum, const CString& clientName);
void setClipboard(ClipboardID,
UInt32 seqNum, const CString& data);
// accessors
// returns true if the mouse should be locked to the current screen
bool isLockedToScreen() const;
// get the current screen map
void getConfig(CConfig*) const;
// get the primary screen's name
CString getPrimaryScreenName() const;
// get the sides of the primary screen that have neighbors
UInt32 getActivePrimarySides() const;
protected:
bool onCommandKey(KeyID, KeyModifierMask, bool down);
private:
class CCleanupNote {
public:
CCleanupNote(CServer*);
~CCleanupNote();
private:
CServer* m_server;
};
class CConnectionNote {
public:
CConnectionNote(CServer*, const CString&, IServerProtocol*);
~CConnectionNote();
private:
bool m_pending;
CServer* m_server;
CString m_name;
};
class CScreenInfo {
public:
CScreenInfo(const CString& name, IServerProtocol*);
~CScreenInfo();
public:
// the thread handling this screen's connection. used when
// forcing a screen to disconnect.
CThread m_thread;
CString m_name;
IServerProtocol* m_protocol;
bool m_ready;
SInt32 m_width, m_height;
SInt32 m_zoneSize;
bool m_gotClipboard[kClipboardEnd];
};
// handle mouse motion
bool onMouseMovePrimaryNoLock(SInt32 x, SInt32 y);
void onMouseMoveSecondaryNoLock(SInt32 dx, SInt32 dy);
// update screen info
void setInfoNoLock(const CString& screenName,
SInt32 wScreen, SInt32 hScreen,
SInt32 zoneSize,
SInt32 xMouse, SInt32 yMouse);
// grab the clipboard
void grabClipboardNoLock(ClipboardID,
UInt32 seqNum, const CString& clientName);
// returns true iff mouse should be locked to the current screen
bool isLockedToScreenNoLock() const;
// change the active screen
void switchScreen(CScreenInfo*, SInt32 x, SInt32 y);
// lookup neighboring screen
CScreenInfo* getNeighbor(CScreenInfo*, CConfig::EDirection) const;
// 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
// cross multiple screens.
CScreenInfo* getNeighbor(CScreenInfo*,
CConfig::EDirection,
SInt32& x, SInt32& y) const;
// adjust coordinates to account for resolution differences. the
// position is converted to a resolution independent form then
// converted back to screen coordinates on the destination screen.
void mapPosition(CScreenInfo* src,
CConfig::EDirection srcSide,
CScreenInfo* dst,
SInt32& x, SInt32& y) const;
// open/close the primary screen
void openPrimaryScreen();
void closePrimaryScreen();
// clear gotClipboard flags in all screens
void clearGotClipboard(ClipboardID);
// send clipboard to the active screen if it doesn't already have it
void sendClipboard(ClipboardID);
// update the clipboard if owned by the primary screen
void updatePrimaryClipboard(ClipboardID);
// cancel running threads
void cleanupThreads(double timeout = -1.0);
// thread method to accept incoming client connections
void acceptClients(void*);
// thread method to do startup handshake with client
void handshakeClient(void*);
// thread method to accept incoming HTTP connections
void acceptHTTPClients(void*);
// thread method to process HTTP requests
void processHTTPRequest(void*);
// thread cleanup list maintenance
friend class CCleanupNote;
void addCleanupThread(const CThread& thread);
void removeCleanupThread(const CThread& thread);
// connection list maintenance
friend class CConnectionNote;
CScreenInfo* addConnection(const CString& name, IServerProtocol*);
void removeConnection(const CString& name);
private:
typedef std::list<CThread*> CThreadList;
typedef std::map<CString, CScreenInfo*> CScreenList;
class CClipboardInfo {
public:
CClipboardInfo();
public:
CClipboard m_clipboard;
CString m_clipboardData;
CString m_clipboardOwner;
UInt32 m_clipboardSeqNum;
bool m_clipboardReady;
};
CMutex m_mutex;
double m_bindTimeout;
ISocketFactory* m_socketFactory;
ISecurityFactory* m_securityFactory;
CThreadList m_cleanupList;
CCondVar<SInt32> m_cleanupSize;
IPrimaryScreen* m_primary;
CScreenList m_screens;
CScreenInfo* m_active;
CScreenInfo* m_primaryInfo;
// the sequence number of enter messages
UInt32 m_seqNum;
// current mouse position (in absolute secondary screen coordinates)
SInt32 m_x, m_y;
CConfig m_config;
CClipboardInfo m_clipboards[kClipboardEnd];
// HTTP request processing stuff
CHTTPServer* m_httpServer;
CCondVar<SInt32> m_httpAvailable;
static const SInt32 s_httpMaxSimultaneousRequests;
};
#endif