refactored client code. it now uses IClient and IServer and

has a CServerProxy, making it's design similar to the server
code.
This commit is contained in:
crs 2002-07-10 20:18:32 +00:00
parent df6748f669
commit 710e1bdd47
15 changed files with 1207 additions and 669 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,18 @@
#ifndef CCLIENT_H #ifndef CCLIENT_H
#define CCLIENT_H #define CCLIENT_H
#include "ClipboardTypes.h" #include "IClient.h"
#include "IClipboard.h" #include "IClipboard.h"
#include "CNetworkAddress.h"
#include "CMutex.h" #include "CMutex.h"
#include "CString.h"
class CNetworkAddress; class CServerProxy;
class IInputStream; class CThread;
class IOutputStream; class IDataSocket;
class ISecondaryScreen; class ISecondaryScreen;
class IServer;
class CClient { class CClient : public IClient {
public: public:
CClient(const CString& clientName); CClient(const CString& clientName);
~CClient(); ~CClient();
@ -24,74 +25,87 @@ public:
// not call this while in run(). // not call this while in run().
void camp(bool on); void camp(bool on);
// open the client's screen // set the server's address that the client should connect to
bool open(); void setAddress(const CNetworkAddress& serverAddress);
// start the client. does not return until quit() is called.
// returns true if the client ever connected to the server
// successfully. may also throw exceptions after successfully
// connecting. a successful open() must preceed this call.
bool run(const CNetworkAddress& serverAddress);
// tell client to exit run() gracefully. this must only be called // tell client to exit run() gracefully. this must only be called
// after a successful open(). // after a successful open().
void quit(); void quit();
// handle events on client's screen // handle events on client's screen
// FIXME -- this should mimic methods on IServer
// FIXME -- maybe create a IScreenReceiver with these methods and
// have CPrimaryClient and CClient inherit from them. IServer
// still needs similar methods with extra parameters, though. so
// CServerProxy
// CPrimaryClient
// CClient
// need IScreenReceiver. these classes effective receive notifications
// from screens. note that there's another class of notifications that
// only the server needs (key, mouyse, screensaver). so maybe we have
// IPrimaryScreenReceiver and ISecondaryScreenReceiver (the latter is
// derived with no extra methods from IScreenReceiver).
void onClipboardChanged(ClipboardID); void onClipboardChanged(ClipboardID);
void onResolutionChanged(); void onResolutionChanged();
// accessors // accessors
// returns true if the server rejected us
bool wasRejected() const;
// IClient overrides
virtual bool open();
virtual void run();
virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask,
bool screenSaver);
virtual bool leave();
virtual void setClipboard(ClipboardID, const CString&);
virtual void grabClipboard(ClipboardID);
virtual void setClipboardDirty(ClipboardID, bool dirty);
virtual void keyDown(KeyID, KeyModifierMask);
virtual void keyRepeat(KeyID, KeyModifierMask, SInt32 count);
virtual void keyUp(KeyID, KeyModifierMask);
virtual void mouseDown(ButtonID);
virtual void mouseUp(ButtonID);
virtual void mouseMove(SInt32 xAbs, SInt32 yAbs);
virtual void mouseWheel(SInt32 delta);
virtual void screenSaver(bool activate);
virtual CString getName() const;
virtual void getShape(SInt32& x, SInt32& y,
SInt32& width, SInt32& height) const;
virtual void getCenter(SInt32& x, SInt32& y) const;
virtual void getMousePos(SInt32& x, SInt32& y) const;
virtual SInt32 getJumpZoneSize() const;
private: private:
void runSession(void*);
// open/close the secondary screen // open/close the secondary screen
void openSecondaryScreen(); void openSecondaryScreen();
void closeSecondaryScreen(); void closeSecondaryScreen();
// if compressing mouse motion then send the last motion now // send the clipboard to the server
void flushCompressedMouse(); void sendClipboard(ClipboardID);
// message handlers // handle server messaging
void onEnter(); void runSession(void*);
void onLeave(); void deleteSession(CThread*);
void onGrabClipboard(); void runServer();
void onScreenSaver(); CServerProxy* handshakeServer(IDataSocket*);
void onQueryInfo();
void onQueryInfoNoLock();
void onInfoAcknowledgment();
void onSetClipboard();
void onKeyDown();
void onKeyRepeat();
void onKeyUp();
void onMouseDown();
void onMouseUp();
void onMouseMove();
void onMouseWheel();
void onErrorIncompatible();
void onErrorBusy();
void onErrorUnknown();
void onErrorBad();
private: private:
CMutex m_mutex; CMutex m_mutex;
CString m_name; CString m_name;
IInputStream* m_input;
IOutputStream* m_output;
ISecondaryScreen* m_screen; ISecondaryScreen* m_screen;
const CNetworkAddress* m_serverAddress; IServer* m_server;
CNetworkAddress m_serverAddress;
bool m_camp; bool m_camp;
bool m_active; bool m_active;
UInt32 m_seqNum; UInt32 m_seqNum;
bool m_ignoreMove; bool m_rejected;
bool m_ownClipboard[kClipboardEnd]; bool m_ownClipboard[kClipboardEnd];
IClipboard::Time m_timeClipboard[kClipboardEnd]; IClipboard::Time m_timeClipboard[kClipboardEnd];
CString m_dataClipboard[kClipboardEnd]; CString m_dataClipboard[kClipboardEnd];
bool m_compressMouse;
SInt32 m_xMouse, m_yMouse;
}; };
#endif #endif

576
client/CServerProxy.cpp Normal file
View File

@ -0,0 +1,576 @@
#include "CServerProxy.h"
#include "CProtocolUtil.h"
#include "IClient.h"
#include "ProtocolTypes.h"
#include "IInputStream.h"
#include "IOutputStream.h"
#include "CLock.h"
#include "CLog.h"
#include "CStopwatch.h"
#include "XBase.h"
#include <memory>
//
// CServerProxy
//
CServerProxy::CServerProxy(IClient* client,
IInputStream* input, IOutputStream* output) :
m_client(client),
m_input(input),
m_output(output)
{
assert(m_client != NULL);
assert(m_input != NULL);
assert(m_output != NULL);
}
CServerProxy::~CServerProxy()
{
delete m_input;
delete m_output;
}
bool
CServerProxy::run()
{
bool failedToConnect = false;
try {
// no compressed mouse motion yet
m_compressMouse = false;
// not ignoring mouse motions
m_ignoreMouse = false;
// handle messages from server
CStopwatch heartbeat;
for (;;) {
// if no input is pending then flush compressed mouse motion
if (getInputStream()->getSize() == 0) {
flushCompressedMouse();
}
// wait for a message
log((CLOG_DEBUG2 "waiting for message"));
UInt8 code[4];
UInt32 n = getInputStream()->read(code, 4, kHeartRate);
// check if server hungup
if (n == 0) {
log((CLOG_NOTE "server disconnected"));
break;
}
// check for time out
if (n == (UInt32)-1 || heartbeat.getTime() > kHeartRate) {
// send heartbeat
CLock lock(&m_mutex);
CProtocolUtil::writef(getOutputStream(), kMsgCNoop);
heartbeat.reset();
if (n == (UInt32)-1) {
// no message to process
continue;
}
}
// verify we got an entire code
if (n != 4) {
// client sent an incomplete message
log((CLOG_ERR "incomplete message from server"));
break;
}
// parse message
log((CLOG_DEBUG2 "msg from server: %c%c%c%c", code[0], code[1], code[2], code[3]));
if (memcmp(code, kMsgDMouseMove, 4) == 0) {
mouseMove();
}
else if (memcmp(code, kMsgDMouseWheel, 4) == 0) {
mouseWheel();
}
else if (memcmp(code, kMsgDKeyDown, 4) == 0) {
keyDown();
}
else if (memcmp(code, kMsgDKeyUp, 4) == 0) {
keyUp();
}
else if (memcmp(code, kMsgDMouseDown, 4) == 0) {
mouseDown();
}
else if (memcmp(code, kMsgDMouseUp, 4) == 0) {
mouseUp();
}
else if (memcmp(code, kMsgDKeyRepeat, 4) == 0) {
keyRepeat();
}
else if (memcmp(code, kMsgCNoop, 4) == 0) {
// accept and discard no-op
}
else if (memcmp(code, kMsgCEnter, 4) == 0) {
enter();
}
else if (memcmp(code, kMsgCLeave, 4) == 0) {
leave();
}
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
grabClipboard();
}
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
screenSaver();
}
else if (memcmp(code, kMsgQInfo, 4) == 0) {
queryInfo();
}
else if (memcmp(code, kMsgCInfoAck, 4) == 0) {
infoAcknowledgment();
}
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
setClipboard();
}
else if (memcmp(code, kMsgCClose, 4) == 0) {
// server wants us to hangup
log((CLOG_DEBUG1 "recv close"));
break;
}
else if (memcmp(code, kMsgEIncompatible, 4) == 0) {
SInt32 major, minor;
CProtocolUtil::readf(getInputStream(),
kMsgEIncompatible + 4, &major, &minor);
log((CLOG_ERR "server has incompatible version %d.%d", major, minor));
failedToConnect = true;
break;
}
else if (memcmp(code, kMsgEBusy, 4) == 0) {
log((CLOG_ERR "server already has a connected client with name \"%s\"", getName().c_str()));
failedToConnect = true;
break;
}
else if (memcmp(code, kMsgEUnknown, 4) == 0) {
log((CLOG_ERR "server refused client with name \"%s\"", getName().c_str()));
failedToConnect = true;
break;
}
else if (memcmp(code, kMsgEBad, 4) == 0) {
log((CLOG_ERR "server disconnected due to a protocol error"));
failedToConnect = true;
break;
}
else {
// unknown message
log((CLOG_ERR "unknown message from server"));
failedToConnect = true;
break;
}
}
}
catch (XBase& e) {
log((CLOG_ERR "error: %s", e.what()));
}
catch (...) {
throw;
}
return !failedToConnect;
}
IClient*
CServerProxy::getClient() const
{
return m_client;
}
CString
CServerProxy::getName() const
{
return m_client->getName();
}
IInputStream*
CServerProxy::getInputStream() const
{
return m_input;
}
IOutputStream*
CServerProxy::getOutputStream() const
{
return m_output;
}
void
CServerProxy::onError()
{
// ignore
}
void
CServerProxy::onInfoChanged(const CString&, const CClientInfo& info)
{
// ignore mouse motion until we receive acknowledgment of our info
// change message.
CLock lock(&m_mutex);
m_ignoreMouse = true;
// send info update
sendInfo(info);
}
bool
CServerProxy::onGrabClipboard(const CString&, ClipboardID id, UInt32 seqNum)
{
log((CLOG_DEBUG1 "sending clipboard %d changed", id));
CLock lock(&m_mutex);
CProtocolUtil::writef(getOutputStream(), kMsgCClipboard, id, seqNum);
}
void
CServerProxy::onClipboardChanged(ClipboardID id,
UInt32 seqNum, const CString& data)
{
log((CLOG_DEBUG1 "sending clipboard %d seqnum=%d, size=%d", id, seqNum, data.size()));
CLock lock(&m_mutex);
CProtocolUtil::writef(getOutputStream(), kMsgDClipboard, id, seqNum, &data);
}
void
CServerProxy::onKeyDown(KeyID, KeyModifierMask)
{
// ignore
}
void
CServerProxy::onKeyUp(KeyID, KeyModifierMask)
{
// ignore
}
void
CServerProxy::onKeyRepeat(KeyID, KeyModifierMask, SInt32)
{
// ignore
}
void
CServerProxy::onMouseDown(ButtonID)
{
// ignore
}
void
CServerProxy::onMouseUp(ButtonID)
{
// ignore
}
bool
CServerProxy::onMouseMovePrimary(SInt32, SInt32)
{
return false;
}
void
CServerProxy::onMouseMoveSecondary(SInt32, SInt32)
{
// ignore
}
void
CServerProxy::onMouseWheel(SInt32)
{
// ignore
}
void
CServerProxy::onScreenSaver(bool)
{
// ignore
}
void
CServerProxy::flushCompressedMouse()
{
bool send = false;
SInt32 x, y;
{
CLock lock(&m_mutex);
if (m_compressMouse) {
m_compressMouse = false;
x = m_xMouse;
y = m_yMouse;
send = true;
}
}
if (send) {
getClient()->mouseMove(x, y);
}
}
void
CServerProxy::sendInfo(const CClientInfo& info)
{
// note -- m_mutex should be locked on entry
log((CLOG_DEBUG1 "sending info shape=%d,%d %dx%d zone=%d pos=%d,%d", info.m_x, info.m_y, info.m_w, info.m_h, info.m_zoneSize, info.m_mx, info.m_my));
CProtocolUtil::writef(getOutputStream(), kMsgDInfo,
info.m_x, info.m_y,
info.m_w, info.m_h,
info.m_zoneSize,
info.m_mx, info.m_my);
}
void
CServerProxy::enter()
{
// parse
SInt16 x, y;
UInt16 mask;
UInt32 seqNum;
CProtocolUtil::readf(getInputStream(),
kMsgCEnter + 4, &x, &y, &seqNum, &mask);
log((CLOG_DEBUG1 "recv enter, %d,%d %d %04x", x, y, seqNum, mask));
// discard old compressed mouse motion, if any
{
CLock lock(&m_mutex);
m_compressMouse = false;
}
// forward
getClient()->enter(x, y, seqNum, static_cast<KeyModifierMask>(mask), false);
}
void
CServerProxy::leave()
{
// parse
log((CLOG_DEBUG1 "recv leave"));
// send last mouse motion
flushCompressedMouse();
// forward
getClient()->leave();
}
void
CServerProxy::setClipboard()
{
// parse
ClipboardID id;
UInt32 seqNum;
CString data;
CProtocolUtil::readf(getInputStream(),
kMsgDClipboard + 4, &id, &seqNum, &data);
log((CLOG_DEBUG "recv clipboard %d size=%d", id, data.size()));
// validate
if (id >= kClipboardEnd) {
return;
}
// forward
getClient()->setClipboard(id, data);
}
void
CServerProxy::grabClipboard()
{
// parse
ClipboardID id;
UInt32 seqNum;
CProtocolUtil::readf(getInputStream(), kMsgCClipboard + 4, &id, &seqNum);
log((CLOG_DEBUG "recv grab clipboard %d", id));
// validate
if (id >= kClipboardEnd) {
return;
}
// forward
getClient()->grabClipboard(id);
}
void
CServerProxy::keyDown()
{
// get mouse up to date
flushCompressedMouse();
// parse
UInt16 id, mask;
CProtocolUtil::readf(getInputStream(), kMsgDKeyDown + 4, &id, &mask);
log((CLOG_DEBUG1 "recv key down id=%d, mask=0x%04x", id, mask));
// forward
getClient()->keyDown(static_cast<KeyID>(id),
static_cast<KeyModifierMask>(mask));
}
void
CServerProxy::keyRepeat()
{
// get mouse up to date
flushCompressedMouse();
// parse
UInt16 id, mask, count;
CProtocolUtil::readf(getInputStream(),
kMsgDKeyRepeat + 4, &id, &mask, &count);
log((CLOG_DEBUG1 "recv key repeat id=%d, mask=0x%04x, count=%d", id, mask, count));
// forward
getClient()->keyRepeat(static_cast<KeyID>(id),
static_cast<KeyModifierMask>(mask),
count);
}
void
CServerProxy::keyUp()
{
// get mouse up to date
flushCompressedMouse();
// parse
UInt16 id, mask;
CProtocolUtil::readf(getInputStream(), kMsgDKeyUp + 4, &id, &mask);
log((CLOG_DEBUG1 "recv key up id=%d, mask=0x%04x", id, mask));
// forward
getClient()->keyUp(static_cast<KeyID>(id),
static_cast<KeyModifierMask>(mask));
}
void
CServerProxy::mouseDown()
{
// get mouse up to date
flushCompressedMouse();
// parse
SInt8 id;
CProtocolUtil::readf(getInputStream(), kMsgDMouseDown + 4, &id);
log((CLOG_DEBUG1 "recv mouse down id=%d", id));
// forward
getClient()->mouseDown(static_cast<ButtonID>(id));
}
void
CServerProxy::mouseUp()
{
// get mouse up to date
flushCompressedMouse();
// parse
SInt8 id;
CProtocolUtil::readf(getInputStream(), kMsgDMouseUp + 4, &id);
log((CLOG_DEBUG1 "recv mouse up id=%d", id));
// forward
getClient()->mouseUp(static_cast<ButtonID>(id));
}
void
CServerProxy::mouseMove()
{
// parse
bool ignore;
SInt16 x, y;
CProtocolUtil::readf(getInputStream(), kMsgDMouseMove + 4, &x, &y);
{
// note if we should ignore the move
CLock lock(&m_mutex);
ignore = m_ignoreMouse;
// compress mouse motion events if more input follows
if (!ignore && !m_compressMouse && getInputStream()->getSize() > 0) {
m_compressMouse = true;
}
// if compressing then ignore the motion but record it
if (m_compressMouse) {
ignore = true;
m_xMouse = x;
m_yMouse = y;
}
}
log((CLOG_DEBUG2 "recv mouse move %d,%d", x, y));
// forward
if (!ignore) {
getClient()->mouseMove(x, y);
}
}
void
CServerProxy::mouseWheel()
{
// get mouse up to date
flushCompressedMouse();
// parse
SInt16 delta;
CProtocolUtil::readf(getInputStream(), kMsgDMouseWheel + 4, &delta);
log((CLOG_DEBUG2 "recv mouse wheel %+d", delta));
// forward
getClient()->mouseWheel(delta);
}
void
CServerProxy::screenSaver()
{
// parse
SInt8 on;
CProtocolUtil::readf(getInputStream(), kMsgCScreenSaver + 4, &on);
log((CLOG_DEBUG1 "recv screen saver on=%d", on));
// forward
getClient()->screenSaver(on != 0);
}
void
CServerProxy::queryInfo()
{
// get current info
CClientInfo info;
getClient()->getShape(info.m_x, info.m_y, info.m_w, info.m_h);
getClient()->getMousePos(info.m_mx, info.m_my);
info.m_zoneSize = getClient()->getJumpZoneSize();
// send it
CLock lock(&m_mutex);
sendInfo(info);
}
void
CServerProxy::infoAcknowledgment()
{
// parse
log((CLOG_DEBUG1 "recv info acknowledgment"));
// now allow mouse motion
CLock lock(&m_mutex);
m_ignoreMouse = false;
}

89
client/CServerProxy.h Normal file
View File

@ -0,0 +1,89 @@
#ifndef CSERVERPROXY_H
#define CSERVERPROXY_H
#include "IServer.h"
#include "CMutex.h"
class IClient;
class IInputStream;
class IOutputStream;
class CServerProxy : public IServer {
public:
CServerProxy(IClient* client,
IInputStream* adoptedInput,
IOutputStream* adoptedOutput);
~CServerProxy();
// manipulators
// handle messages. returns true iff server didn't reject our
// connection.
bool run();
// accessors
// get the client
IClient* getClient() const;
// get the client name
CString getName() const;
// get the input and output streams for the server
IInputStream* getInputStream() const;
IOutputStream* getOutputStream() const;
// IServer overrides
virtual void onError();
virtual void onInfoChanged(const CString& clientName,
const CClientInfo&);
virtual bool onGrabClipboard(const CString& clientName,
ClipboardID, UInt32 seqNum);
virtual void onClipboardChanged(ClipboardID,
UInt32 seqNum, const CString& data);
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);
virtual void onScreenSaver(bool activated);
private:
// if compressing mouse motion then send the last motion now
void flushCompressedMouse();
void sendInfo(const CClientInfo&);
// message handlers
void enter();
void leave();
void setClipboard();
void grabClipboard();
void keyDown();
void keyRepeat();
void keyUp();
void mouseDown();
void mouseUp();
void mouseMove();
void mouseWheel();
void screenSaver();
void queryInfo();
void infoAcknowledgment();
private:
CMutex m_mutex;
IClient* m_client;
IInputStream* m_input;
IOutputStream* m_output;
bool m_compressMouse;
SInt32 m_xMouse, m_yMouse;
bool m_ignoreMouse;
};
#endif

View File

@ -4,11 +4,14 @@ DEPTH = ..
bin_PROGRAMS = synergy bin_PROGRAMS = synergy
synergy_SOURCES = \ synergy_SOURCES = \
CXWindowsSecondaryScreen.cpp \
CClient.cpp \ CClient.cpp \
CServerProxy.cpp \
CXWindowsSecondaryScreen.cpp \
client.cpp \ client.cpp \
CClient.h \ CClient.h \
CServerProxy.h \
CXWindowsSecondaryScreen.h \ CXWindowsSecondaryScreen.h \
ISecondaryScreen.h \
$(NULL) $(NULL)
synergy_LDADD = \ synergy_LDADD = \
$(DEPTH)/platform/libplatform.a \ $(DEPTH)/platform/libplatform.a \

View File

@ -81,6 +81,7 @@ realMain(CMutex* mutex)
// create client // create client
s_client = new CClient(s_name); s_client = new CClient(s_name);
s_client->camp(s_camp); s_client->camp(s_camp);
s_client->setAddress(s_serverAddress);
if (!s_client->open()) { if (!s_client->open()) {
delete s_client; delete s_client;
s_client = NULL; s_client = NULL;
@ -92,13 +93,17 @@ realMain(CMutex* mutex)
mutex->unlock(); mutex->unlock();
} }
locked = false; locked = false;
bool success = s_client->run(s_serverAddress); s_client->run();
locked = true; locked = true;
if (mutex != NULL) { if (mutex != NULL) {
mutex->lock(); mutex->lock();
} }
// get client status
bool success = !s_client->wasRejected();
// clean up // clean up
s_client->close();
delete s_client; delete s_client;
s_client = NULL; s_client = NULL;
CLog::setLock(NULL); CLog::setLock(NULL);
@ -111,6 +116,7 @@ realMain(CMutex* mutex)
if (!locked && mutex != NULL) { if (!locked && mutex != NULL) {
mutex->lock(); mutex->lock();
} }
s_client->close();
delete s_client; delete s_client;
s_client = NULL; s_client = NULL;
CLog::setLock(NULL); CLog::setLock(NULL);

View File

@ -27,7 +27,7 @@ public:
IOutputStream* getOutputStream() const; IOutputStream* getOutputStream() const;
// IClient overrides // IClient overrides
virtual void open() = 0; virtual bool open() = 0;
virtual void run() = 0; virtual void run() = 0;
virtual void close() = 0; virtual void close() = 0;
virtual void enter(SInt32 xAbs, SInt32 yAbs, virtual void enter(SInt32 xAbs, SInt32 yAbs,
@ -49,6 +49,7 @@ public:
virtual void getShape(SInt32& x, SInt32& y, virtual void getShape(SInt32& x, SInt32& y,
SInt32& width, SInt32& height) const = 0; SInt32& width, SInt32& height) const = 0;
virtual void getCenter(SInt32& x, SInt32& y) const = 0; virtual void getCenter(SInt32& x, SInt32& y) const = 0;
virtual void getMousePos(SInt32& x, SInt32& y) const = 0;
virtual SInt32 getJumpZoneSize() const = 0; virtual SInt32 getJumpZoneSize() const = 0;
private: private:

View File

@ -29,7 +29,7 @@ CClientProxy1_0::~CClientProxy1_0()
// do nothing // do nothing
} }
void bool
CClientProxy1_0::open() CClientProxy1_0::open()
{ {
// send request // send request
@ -55,6 +55,8 @@ CClientProxy1_0::open()
// handle reply // handle reply
recvInfo(false); recvInfo(false);
return true;
} }
void void
@ -258,6 +260,12 @@ CClientProxy1_0::getCenter(SInt32& x, SInt32& y) const
y = m_info.m_my; y = m_info.m_my;
} }
void
CClientProxy1_0::getMousePos(SInt32&, SInt32&) const
{
assert(0 && "shouldn't be called");
}
SInt32 SInt32
CClientProxy1_0::getJumpZoneSize() const CClientProxy1_0::getJumpZoneSize() const
{ {

View File

@ -13,7 +13,7 @@ public:
~CClientProxy1_0(); ~CClientProxy1_0();
// IClient overrides // IClient overrides
virtual void open(); virtual bool open();
virtual void run(); virtual void run();
virtual void close(); virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs, virtual void enter(SInt32 xAbs, SInt32 yAbs,
@ -34,6 +34,7 @@ public:
virtual void getShape(SInt32& x, SInt32& y, virtual void getShape(SInt32& x, SInt32& y,
SInt32& width, SInt32& height) const; SInt32& width, SInt32& height) const;
virtual void getCenter(SInt32& x, SInt32& y) const; virtual void getCenter(SInt32& x, SInt32& y) const;
virtual void getMousePos(SInt32& x, SInt32& y) const;
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;
private: private:

View File

@ -149,7 +149,7 @@ CPrimaryClient::onScreenSaver(bool activated)
m_server->onScreenSaver(activated); m_server->onScreenSaver(activated);
} }
void bool
CPrimaryClient::open() CPrimaryClient::open()
{ {
// all clipboards are clean and owned by us // all clipboards are clean and owned by us
@ -160,6 +160,8 @@ CPrimaryClient::open()
// now open the screen // now open the screen
m_screen->open(); m_screen->open();
return true;
} }
void void
@ -296,6 +298,12 @@ CPrimaryClient::getCenter(SInt32& x, SInt32& y) const
y = m_info.m_my; y = m_info.m_my;
} }
void
CPrimaryClient::getMousePos(SInt32&, SInt32&) const
{
assert(0 && "shouldn't be called");
}
SInt32 SInt32
CPrimaryClient::getJumpZoneSize() const CPrimaryClient::getJumpZoneSize() const
{ {

View File

@ -52,7 +52,7 @@ public:
virtual void onScreenSaver(bool activated); virtual void onScreenSaver(bool activated);
// IClient overrides // IClient overrides
virtual void open(); virtual bool open();
virtual void run(); virtual void run();
virtual void close(); virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs, virtual void enter(SInt32 xAbs, SInt32 yAbs,
@ -74,6 +74,7 @@ public:
virtual void getShape(SInt32& x, SInt32& y, virtual void getShape(SInt32& x, SInt32& y,
SInt32& width, SInt32& height) const; SInt32& width, SInt32& height) const;
virtual void getCenter(SInt32& x, SInt32& y) const; virtual void getCenter(SInt32& x, SInt32& y) const;
virtual void getMousePos(SInt32& x, SInt32& y) const;
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;
private: private:

View File

@ -21,14 +21,6 @@
#include "CLog.h" #include "CLog.h"
#include "CStopwatch.h" #include "CStopwatch.h"
#include "TMethodJob.h" #include "TMethodJob.h"
#include <memory>
// hack to work around operator=() bug in STL in g++ prior to v3
#if defined(__GNUC__) && (__GNUC__ < 3)
#define assign(_dst, _src, _type) _dst.reset(_src)
#else
#define assign(_dst, _src, _type) _dst = std::auto_ptr<_type >(_src)
#endif
// //
// CServer // CServer
@ -1106,11 +1098,11 @@ CServer::acceptClients(void*)
{ {
log((CLOG_DEBUG1 "starting to wait for clients")); log((CLOG_DEBUG1 "starting to wait for clients"));
std::auto_ptr<IListenSocket> listen; IListenSocket* listen = NULL;
try { try {
// create socket listener // create socket listener
// listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen()); // listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen());
assign(listen, new CTCPListenSocket, IListenSocket); // FIXME listen = new CTCPListenSocket; // FIXME -- use factory
// bind to the desired port. keep retrying if we can't bind // bind to the desired port. keep retrying if we can't bind
// the address immediately. // the address immediately.
@ -1147,11 +1139,19 @@ CServer::acceptClients(void*)
startThread(new TMethodJob<CServer>( startThread(new TMethodJob<CServer>(
this, &CServer::runClient, socket)); this, &CServer::runClient, socket));
} }
// clean up
delete listen;
} }
catch (XBase& e) { catch (XBase& e) {
log((CLOG_ERR "cannot listen for clients: %s", e.what())); log((CLOG_ERR "cannot listen for clients: %s", e.what()));
delete listen;
quit(); quit();
} }
catch (...) {
delete listen;
throw;
}
} }
void void
@ -1159,12 +1159,20 @@ CServer::runClient(void* vsocket)
{ {
// get the socket pointer from the argument // get the socket pointer from the argument
assert(vsocket != NULL); assert(vsocket != NULL);
std::auto_ptr<IDataSocket> socket(reinterpret_cast<IDataSocket*>(vsocket)); IDataSocket* socket = reinterpret_cast<IDataSocket*>(vsocket);
// create proxy // create proxy
CClientProxy* proxy = handshakeClient(socket.get()); CClientProxy* proxy = NULL;
if (proxy == NULL) { try {
return; proxy = handshakeClient(socket);
if (proxy == NULL) {
delete socket;
return;
}
}
catch (...) {
delete socket;
throw;
} }
// add the connection // add the connection
@ -1181,6 +1189,7 @@ CServer::runClient(void* vsocket)
log((CLOG_WARN "a client with name \"%s\" is already connected", e.getName().c_str())); log((CLOG_WARN "a client with name \"%s\" is already connected", e.getName().c_str()));
CProtocolUtil::writef(proxy->getOutputStream(), kMsgEBusy); CProtocolUtil::writef(proxy->getOutputStream(), kMsgEBusy);
delete proxy; delete proxy;
delete socket;
return; return;
} }
catch (XUnknownClient& e) { catch (XUnknownClient& e) {
@ -1188,10 +1197,12 @@ CServer::runClient(void* vsocket)
log((CLOG_WARN "a client with name \"%s\" is not in the map", e.getName().c_str())); log((CLOG_WARN "a client with name \"%s\" is not in the map", e.getName().c_str()));
CProtocolUtil::writef(proxy->getOutputStream(), kMsgEUnknown); CProtocolUtil::writef(proxy->getOutputStream(), kMsgEUnknown);
delete proxy; delete proxy;
delete socket;
return; return;
} }
catch (...) { catch (...) {
delete proxy; delete proxy;
delete socket;
throw; throw;
} }
@ -1222,11 +1233,13 @@ CServer::runClient(void* vsocket)
catch (...) { catch (...) {
// run() was probably cancelled // run() was probably cancelled
removeConnection(proxy->getName()); removeConnection(proxy->getName());
delete socket;
throw; throw;
} }
// remove the connection // clean up
removeConnection(proxy->getName()); removeConnection(proxy->getName());
delete socket;
} }
CClientProxy* CClientProxy*
@ -1244,13 +1257,14 @@ CServer::handshakeClient(IDataSocket* socket)
/* FIXME -- implement ISecurityFactory /* FIXME -- implement ISecurityFactory
input = m_securityFactory->createInputFilter(input, own); input = m_securityFactory->createInputFilter(input, own);
output = m_securityFactory->createOutputFilter(output, own); output = m_securityFactory->createOutputFilter(output, own);
own = true; own = true;
*/ */
} }
// attach the packetizing filters // attach the packetizing filters
input = new CInputPacketStream(input, own); input = new CInputPacketStream(input, own);
output = new COutputPacketStream(output, own); output = new COutputPacketStream(output, own);
own = true;
CClientProxy* proxy = NULL; CClientProxy* proxy = NULL;
CString name("<unknown>"); CString name("<unknown>");
@ -1344,7 +1358,7 @@ CServer::handshakeClient(IDataSocket* socket)
if (proxy != NULL) { if (proxy != NULL) {
delete proxy; delete proxy;
} }
else { else if (own) {
delete input; delete input;
delete output; delete output;
} }
@ -1355,7 +1369,7 @@ CServer::handshakeClient(IDataSocket* socket)
if (proxy != NULL) { if (proxy != NULL) {
delete proxy; delete proxy;
} }
else { else if (own) {
delete input; delete input;
delete output; delete output;
} }
@ -1368,11 +1382,11 @@ CServer::acceptHTTPClients(void*)
{ {
log((CLOG_DEBUG1 "starting to wait for HTTP clients")); log((CLOG_DEBUG1 "starting to wait for HTTP clients"));
std::auto_ptr<IListenSocket> listen; IListenSocket* listen = NULL;
try { try {
// create socket listener // create socket listener
// listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen()); // listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen());
assign(listen, new CTCPListenSocket, IListenSocket); // FIXME listen = new CTCPListenSocket; // FIXME -- use factory
// bind to the desired port. keep retrying if we can't bind // bind to the desired port. keep retrying if we can't bind
// the address immediately. // the address immediately.
@ -1419,12 +1433,20 @@ CServer::acceptHTTPClients(void*)
startThread(new TMethodJob<CServer>( startThread(new TMethodJob<CServer>(
this, &CServer::processHTTPRequest, socket)); this, &CServer::processHTTPRequest, socket));
} }
// clean up
delete listen;
} }
catch (XBase& e) { catch (XBase& e) {
log((CLOG_ERR "cannot listen for HTTP clients: %s", e.what())); log((CLOG_ERR "cannot listen for HTTP clients: %s", e.what()));
delete listen;
// FIXME -- quit? // FIXME -- quit?
quit(); quit();
} }
catch (...) {
delete listen;
throw;
}
} }
void void

View File

@ -11,8 +11,8 @@ class IClient : public IInterface {
public: public:
// manipulators // manipulators
// open client // open client. return true iff successful.
virtual void open() = 0; virtual bool open() = 0;
// service client // service client
virtual void run() = 0; virtual void run() = 0;
@ -68,6 +68,9 @@ public:
// get the center pixel // get the center pixel
virtual void getCenter(SInt32& x, SInt32& y) const = 0; virtual void getCenter(SInt32& x, SInt32& y) const = 0;
// get the mouse position
virtual void getMousePos(SInt32& x, SInt32& y) const = 0;
// get the size of jump zone // get the size of jump zone
virtual SInt32 getJumpZoneSize() const = 0; virtual SInt32 getJumpZoneSize() const = 0;
}; };

View File

@ -20,7 +20,6 @@ libsynergy_a_SOURCES = \
IClient.h \ IClient.h \
IClipboard.h \ IClipboard.h \
IScreenSaver.h \ IScreenSaver.h \
ISecondaryScreen.h \
IServer.h \ IServer.h \
ISocketFactory.h \ ISocketFactory.h \
KeyTypes.h \ KeyTypes.h \