mirror of
https://github.com/debauchee/barrier.git
synced 2024-12-26 20:53:22 +03:00
1cbdaee31b
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.
252 lines
6.5 KiB
C++
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
|