diff --git a/Make-linux b/Make-linux index c64314b5..e3e656d6 100644 --- a/Make-linux +++ b/Make-linux @@ -13,7 +13,7 @@ RMR = /bin/rm -rf # # compiler options # -GCXXDEFS = -D_POSIX_C_SOURCE=199309 +GCXXDEFS = -D_XOPEN_SOURCE=500 GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include GCXXOPTS = -Wall -W -fexceptions -fno-rtti CXXOPTIMIZER = -g diff --git a/base/Makefile b/base/Makefile index 42128cec..8e262bd4 100644 --- a/base/Makefile +++ b/base/Makefile @@ -13,6 +13,7 @@ LCXXINCS = \ $(NULL) CXXFILES = \ XBase.cpp \ + CLog.cpp \ CFunctionJob.cpp \ CStopwatch.cpp \ $(NULL) diff --git a/synergy/CClient.cpp b/synergy/CClient.cpp index 1a20bc1e..6fb1d215 100644 --- a/synergy/CClient.cpp +++ b/synergy/CClient.cpp @@ -6,7 +6,7 @@ #include "ProtocolTypes.h" #include "CTimerThread.h" #include "XSynergy.h" -#include +#include "CLog.h" #include // @@ -29,6 +29,8 @@ CClient::~CClient() #include "CXWindowsSecondaryScreen.h" void CClient::run(const CNetworkAddress& serverAddress) { + log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str())); + std::auto_ptr socket; std::auto_ptr input; std::auto_ptr output; @@ -37,8 +39,10 @@ void CClient::run(const CNetworkAddress& serverAddress) CTimerThread timer(30.0); // FIXME -- timeout in member // create socket and attempt to connect to server + log((CLOG_DEBUG "connecting to server")); socket.reset(new CTCPSocket()); // FIXME -- use factory socket->connect(serverAddress); + log((CLOG_INFO "connected to server")); // get the input and output streams IInputStream* srcInput = socket->getInputStream(); @@ -59,16 +63,19 @@ void CClient::run(const CNetworkAddress& serverAddress) output.reset(new COutputPacketStream(srcOutput, true)); // wait for hello from server + log((CLOG_DEBUG "wait for hello")); SInt32 major, minor; CProtocolUtil::readf(input.get(), "Synergy%2i%2i", &major, &minor); // check versions + log((CLOG_DEBUG "got hello version %d.%d", major, minor)); if (major < kMajorVersion || (major == kMajorVersion && minor < kMinorVersion)) { throw XIncompatibleClient(major, minor); } // say hello back + log((CLOG_DEBUG "say hello version %d.%d", kMajorVersion, kMinorVersion)); CProtocolUtil::writef(output.get(), "Synergy%2i%2i%s", kMajorVersion, kMinorVersion, m_name.size(), m_name.data()); @@ -78,27 +85,27 @@ void CClient::run(const CNetworkAddress& serverAddress) m_output = output.get(); } catch (XIncompatibleClient& e) { - fprintf(stderr, "incompatible server version (%d.%d)\n", - e.getMajor(), e.getMinor()); + log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor())); return; } catch (XThread&) { - fprintf(stderr, "connection timed out\n"); + log((CLOG_ERR "connection timed out")); throw; } catch (XBase& e) { - fprintf(stderr, "connection failed: %s\n", e.what()); + log((CLOG_ERR "connection failed: %s", e.what())); return; } // connect to screen std::auto_ptr screenCleaner; try { + log((CLOG_DEBUG "creating secondary screen")); m_screen = new CXWindowsSecondaryScreen; screenCleaner.reset(new CScreenCleaner(this, m_screen)); } catch (XBase& e) { - fprintf(stderr, "cannot open screen: %s\n", e.what()); + log((CLOG_ERR "cannot open screen: %s", e.what())); return; } @@ -106,21 +113,24 @@ void CClient::run(const CNetworkAddress& serverAddress) // handle messages from server for (;;) { // wait for reply + log((CLOG_DEBUG "waiting for message")); UInt8 code[4]; UInt32 n = input->read(code, 4); // verify we got an entire code if (n == 0) { + log((CLOG_NOTE "server disconnected")); // server hungup break; } if (n != 4) { // client sent an incomplete message - fprintf(stderr, "incomplete message from server\n"); + log((CLOG_ERR "incomplete message from server")); break; } // parse message + log((CLOG_DEBUG "msg from server: %c%c%c%c", code[0], code[1], code[2], code[3])); if (memcmp(code, kMsgDMouseMove, 4) == 0) { onMouseMove(); } @@ -169,20 +179,22 @@ void CClient::run(const CNetworkAddress& serverAddress) } else { // unknown message - fprintf(stderr, "unknown message from server\n"); + log((CLOG_ERR "unknown message from server")); break; } } } catch (XBase& e) { - fprintf(stderr, "error: %s\n", e.what()); + log((CLOG_ERR "error: %s", e.what())); return; } // done with screen + log((CLOG_DEBUG "destroying secondary screen")); screenCleaner.reset(); // done with socket + log((CLOG_DEBUG "disconnecting from server")); socket->close(); } @@ -215,6 +227,7 @@ void CClient::onQueryInfo() SInt32 w, h; m_screen->getSize(&w, &h); SInt32 zoneSize = m_screen->getJumpZoneSize(); + log((CLOG_DEBUG "sending info size=%d,%d zone=%d", w, h, zoneSize)); CProtocolUtil::writef(m_output, kMsgDInfo, w, h, zoneSize); } diff --git a/synergy/CScreenMap.cpp b/synergy/CScreenMap.cpp index 7e59ea1d..eb2b4d7f 100644 --- a/synergy/CScreenMap.cpp +++ b/synergy/CScreenMap.cpp @@ -87,3 +87,9 @@ CString CScreenMap::getNeighbor(const CString& srcName, // return connection return index->second.m_neighbor[srcSide - kFirstDirection]; } + +const char* CScreenMap::dirName(EDirection dir) +{ + static const char* s_name[] = { "left", "right", "top", "bottom" }; + return s_name[dir - kFirstDirection]; +} diff --git a/synergy/CScreenMap.h b/synergy/CScreenMap.h index 234ae05b..816b8f93 100644 --- a/synergy/CScreenMap.h +++ b/synergy/CScreenMap.h @@ -33,6 +33,9 @@ class CScreenMap { // if there is no neighbor in that direction. CString getNeighbor(const CString&, EDirection) const throw(); + // get the name of a direction (for debugging) + static const char* dirName(EDirection); + private: class CCell { public: diff --git a/synergy/CServer.cpp b/synergy/CServer.cpp index 94b86968..5a579c30 100644 --- a/synergy/CServer.cpp +++ b/synergy/CServer.cpp @@ -16,7 +16,7 @@ #include "CTimerThread.h" #include "CStopwatch.h" #include "TMethodJob.h" -#include +#include "CLog.h" #include #include @@ -38,6 +38,8 @@ CServer::~CServer() void CServer::run() { try { + log((CLOG_NOTE "starting server")); + // connect to primary screen openPrimaryScreen(); @@ -48,23 +50,27 @@ void CServer::run() // FIXME // wait until done + log((CLOG_DEBUG "waiting for quit")); CLock lock(&m_mutex); while (m_done == false) { m_done.wait(); } // clean up + log((CLOG_DEBUG "stopping server")); closePrimaryScreen(); cleanupThreads(); } catch (XBase& e) { - fprintf(stderr, "server error: %s\n", e.what()); + log((CLOG_ERR "server error: %s\n", e.what())); // clean up closePrimaryScreen(); cleanupThreads(); } catch (...) { + log((CLOG_DEBUG "server shutdown")); + // clean up closePrimaryScreen(); cleanupThreads(); @@ -108,6 +114,7 @@ void CServer::setInfo(const CString& client, info->m_width = w; info->m_height = h; info->m_zoneSize = zoneSize; + log((CLOG_NOTE "client \"%s\" size=%dx%d zone=%d", client.c_str(), w, h, zoneSize)); } bool CServer::onCommandKey(KeyID /*id*/, @@ -118,6 +125,7 @@ bool CServer::onCommandKey(KeyID /*id*/, void CServer::onKeyDown(KeyID id, KeyModifierMask mask) { + log((CLOG_DEBUG "onKeyDown id=%d mask=0x%04x", id, mask)); assert(m_active != NULL); // handle command keys @@ -133,6 +141,7 @@ void CServer::onKeyDown(KeyID id, KeyModifierMask mask) void CServer::onKeyUp(KeyID id, KeyModifierMask mask) { + log((CLOG_DEBUG "onKeyUp id=%d mask=0x%04x", id, mask)); assert(m_active != NULL); // handle command keys @@ -148,6 +157,7 @@ void CServer::onKeyUp(KeyID id, KeyModifierMask mask) void CServer::onKeyRepeat(KeyID id, KeyModifierMask mask) { + log((CLOG_DEBUG "onKeyRepeat id=%d mask=0x%04x", id, mask)); assert(m_active != NULL); // handle command keys @@ -164,6 +174,7 @@ void CServer::onKeyRepeat(KeyID id, KeyModifierMask mask) void CServer::onMouseDown(ButtonID id) { + log((CLOG_DEBUG "onMouseDown id=%d", id)); assert(m_active != NULL); // relay @@ -174,6 +185,7 @@ void CServer::onMouseDown(ButtonID id) void CServer::onMouseUp(ButtonID id) { + log((CLOG_DEBUG "onMouseUp id=%d", id)); assert(m_active != NULL); // relay @@ -184,6 +196,8 @@ void CServer::onMouseUp(ButtonID id) void CServer::onMouseMovePrimary(SInt32 x, SInt32 y) { + log((CLOG_DEBUG "onMouseMovePrimary %d,%d", x, y)); + // mouse move on primary (server's) screen assert(m_active != NULL); assert(m_active->m_protocol == NULL); @@ -198,18 +212,22 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y) if (x < m_active->m_zoneSize) { x -= m_active->m_zoneSize; dir = CScreenMap::kLeft; + log((CLOG_DEBUG "switch to left")); } else if (x >= m_active->m_width - m_active->m_zoneSize) { x += m_active->m_zoneSize; dir = CScreenMap::kRight; + log((CLOG_DEBUG "switch to right")); } else if (y < m_active->m_zoneSize) { y -= m_active->m_zoneSize; dir = CScreenMap::kTop; + log((CLOG_DEBUG "switch to top")); } else if (y >= m_active->m_height - m_active->m_zoneSize) { y += m_active->m_zoneSize; dir = CScreenMap::kBottom; + log((CLOG_DEBUG "switch to bottom")); } else { // still on local screen @@ -233,6 +251,8 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y) void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy) { + log((CLOG_DEBUG "onMouseMoveSecondary %+d,%+d", dx, dy)); + // mouse move on secondary (client's) screen assert(m_active != NULL); assert(m_active->m_protocol != NULL); @@ -264,8 +284,7 @@ void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy) // get neighbor if we should switch if (newScreen == NULL) { -// TRACE(("leave %s on %s", m_activeScreen->getName().c_str(), -// s_dirName[dir])); + log((CLOG_DEBUG "leave \"%s\" on %s", m_active->m_name.c_str(), CScreenMap::dirName(dir))); SInt32 x = m_x, y = m_y; newScreen = getNeighbor(m_active, dir, x, y); @@ -290,7 +309,7 @@ void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy) } else { // clamp to edge when locked -// TRACE(("clamp to %s", m_activeScreen->getName().c_str())); + log((CLOG_DEBUG "clamp to \"%s\"", m_active->m_name.c_str())); if (m_x < 0) m_x = 0; else if (m_x > m_active->m_width - 1) @@ -305,8 +324,7 @@ void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy) if (newScreen == NULL || newScreen == m_active) { // do nothing if mouse didn't move if (m_x != xOld || m_y != yOld) { -// TRACE(("move on %s to %d,%d", -// m_activeScreen->getName().c_str(), m_x, m_y)); + log((CLOG_DEBUG "move on %s to %d,%d", m_active->m_name.c_str(), m_x, m_y)); m_active->m_protocol->sendMouseMove(m_x, m_y); } } @@ -319,6 +337,7 @@ void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy) void CServer::onMouseWheel(SInt32 delta) { + log((CLOG_DEBUG "onMouseWheel %+d", delta)); assert(m_active != NULL); // relay @@ -340,8 +359,7 @@ void CServer::switchScreen(CScreenInfo* dst, assert(x >= 0 && y >= 0 && x < dst->m_width && y < dst->m_height); assert(m_active != NULL); -// TRACE(("switch %s to %s at %d,%d", m_active->m_name.c_str(), -// dst->m_name.c_str(), x, y)); + log((CLOG_NOTE "switch from \"%s\" to \"%s\" at %d,%d", m_active->m_name.c_str(), dst->m_name.c_str(), x, y)); // wrapping means leaving the active screen and entering it again. // since that's a waste of time we skip that and just warp the @@ -387,22 +405,27 @@ CServer::CScreenInfo* CServer::getNeighbor(CScreenInfo* src, CString srcName = src->m_name; assert(!srcName.empty()); + log((CLOG_DEBUG "find neighbor on %s of \"%s\"", CScreenMap::dirName(dir), srcName.c_str())); for (;;) { // look up name of neighbor const CString dstName(m_screenMap.getNeighbor(srcName, dir)); // if nothing in that direction then return NULL - if (dstName.empty()) + if (dstName.empty()) { + log((CLOG_DEBUG "no neighbor on %s of \"%s\"", CScreenMap::dirName(dir), srcName.c_str())); return NULL; + } // look up neighbor cell. if the screen is connected then // we can stop. otherwise we skip over an unconnected // screen. CScreenList::const_iterator index = m_screens.find(dstName); if (index != m_screens.end()) { + log((CLOG_DEBUG "\"%s\" is on %s of \"%s\"", dstName.c_str(), CScreenMap::dirName(dir), srcName.c_str())); return index->second; } + log((CLOG_DEBUG "ignored \"%s\" on %s of \"%s\"", dstName.c_str(), CScreenMap::dirName(dir), srcName.c_str())); srcName = dstName; } } @@ -431,7 +454,7 @@ CServer::CScreenInfo* CServer::getNeighbor(CScreenInfo* src, if (x >= 0) { break; } -// TRACE(("skipping over screen %s", dst->m_name.c_str())); + log((CLOG_DEBUG "skipping over screen %s", dst->m_name.c_str())); dst = getNeighbor(lastGoodScreen, srcSide); } break; @@ -445,7 +468,7 @@ CServer::CScreenInfo* CServer::getNeighbor(CScreenInfo* src, if (x < w) { break; } -// TRACE(("skipping over screen %s", dst->m_name.c_str())); + log((CLOG_DEBUG "skipping over screen %s", dst->m_name.c_str())); dst = getNeighbor(lastGoodScreen, srcSide); } break; @@ -459,7 +482,7 @@ CServer::CScreenInfo* CServer::getNeighbor(CScreenInfo* src, if (y >= 0) { break; } -// TRACE(("skipping over screen %s", dst->m_name.c_str())); + log((CLOG_DEBUG "skipping over screen %s", dst->m_name.c_str())); dst = getNeighbor(lastGoodScreen, srcSide); } break; @@ -473,7 +496,7 @@ CServer::CScreenInfo* CServer::getNeighbor(CScreenInfo* src, if (y < h) { break; } -// TRACE(("skipping over screen %s", dst->m_name.c_str())); + log((CLOG_DEBUG "skipping over screen %s", dst->m_name.c_str())); dst = getNeighbor(lastGoodScreen, srcSide); } break; @@ -548,6 +571,8 @@ void CServer::mapPosition(CScreenInfo* src, #include "CTCPListenSocket.h" void CServer::acceptClients(void*) { + log((CLOG_DEBUG "starting to wait for clients")); + // add this thread to the list of threads to cancel. remove from // list in d'tor. CCleanupNote cleanupNote(this); @@ -564,25 +589,30 @@ void CServer::acceptClients(void*) CNetworkAddress addr(50001 /* FIXME -- m_port */); for (;;) { try { + log((CLOG_DEBUG "binding listen socket")); listen->bind(addr); break; } catch (XSocketAddressInUse&) { // give up if we've waited too long if (timer.getTime() >= m_bindTimeout) { + log((CLOG_DEBUG "waited too long to bind, giving up")); throw; } // wait a bit before retrying + log((CLOG_DEBUG "bind failed; waiting to retry")); CThread::sleep(5.0); } } // accept connections and begin processing them + log((CLOG_DEBUG "waiting for client connections")); for (;;) { // accept connection CThread::testCancel(); ISocket* socket = listen->accept(); + log((CLOG_NOTE "accepted client connection")); CThread::testCancel(); // start handshake thread @@ -591,13 +621,15 @@ void CServer::acceptClients(void*) } } catch (XBase& e) { - fprintf(stderr, "cannot listen for clients: %s\n", e.what()); + log((CLOG_ERR "cannot listen for clients: %s", e.what())); quit(); } } void CServer::handshakeClient(void* vsocket) { + log((CLOG_DEBUG "negotiating with new client")); + // get the socket pointer from the argument assert(vsocket != NULL); std::auto_ptr socket(reinterpret_cast(vsocket)); @@ -638,11 +670,13 @@ void CServer::handshakeClient(void* vsocket) static const UInt32 maxHelloLen = 1024; // say hello + log((CLOG_DEBUG "saying hello")); CProtocolUtil::writef(output.get(), "Synergy%2i%2i", kMajorVersion, kMinorVersion); output->flush(); // wait for the reply + log((CLOG_DEBUG "waiting for hello reply")); UInt32 n = input->getSize(); if (n > maxHelloLen) { throw XBadClient(); @@ -651,6 +685,7 @@ void CServer::handshakeClient(void* vsocket) // get and parse the reply to hello SInt32 major, minor; try { + log((CLOG_DEBUG "parsing hello reply")); CProtocolUtil::readf(input.get(), "Synergy%2i%2i%s", &major, &minor, &name); } @@ -662,6 +697,7 @@ void CServer::handshakeClient(void* vsocket) } // create a protocol interpreter for the version + log((CLOG_DEBUG "creating interpreter for client %s version %d.%d", name.c_str(), major, minor)); protocol.reset(CServerProtocol::create(major, minor, this, name, input.get(), output.get())); @@ -670,28 +706,28 @@ void CServer::handshakeClient(void* vsocket) name, protocol.get())); // ask and wait for the client's info + log((CLOG_DEBUG "waiting for info for client %s", name.c_str())); protocol->queryInfo(); } // handle messages from client. returns when the client // disconnects. + log((CLOG_NOTE "client %s is connected", name.c_str())); protocol->run(); } catch (XIncompatibleClient& e) { // client is incompatible - fprintf(stderr, "client is incompatible (%s, %d.%d)\n", - name.c_str(), e.getMajor(), e.getMinor()); + log((CLOG_WARN "client \"%s\" has incompatible version %d.%d)", name.c_str(), e.getMajor(), e.getMinor())); // FIXME -- could print network address if socket had suitable method } catch (XBadClient&) { // client not behaving - fprintf(stderr, "protocol error from client %s\n", name.c_str()); + log((CLOG_WARN "protocol error from client \"%s\"", name.c_str())); // FIXME -- could print network address if socket had suitable method } catch (XBase& e) { // misc error - fprintf(stderr, "error communicating with client %s: %s\n", - name.c_str(), e.what()); + log((CLOG_WARN "error communicating with client \"%s\": %s", name.c_str(), e.what())); // FIXME -- could print network address if socket had suitable method } } @@ -710,7 +746,9 @@ void CServer::openPrimaryScreen() assert(m_primary == NULL); // open screen + log((CLOG_DEBUG "creating primary screen")); m_primary = new CXWindowsPrimaryScreen; + log((CLOG_DEBUG "opening primary screen")); m_primary->open(this); // add connection @@ -719,6 +757,7 @@ void CServer::openPrimaryScreen() // update info m_primary->getSize(&m_active->m_width, &m_active->m_height); m_active->m_zoneSize = m_primary->getJumpZoneSize(); + log((CLOG_NOTE "server size=%dx%d zone=%d", m_active->m_width, m_active->m_height, m_active->m_zoneSize)); // FIXME -- need way for primary screen to call us back } @@ -731,6 +770,7 @@ void CServer::closePrimaryScreen() throw() // close the primary screen try { + log((CLOG_DEBUG "closing primary screen")); m_primary->close(); } catch (...) { @@ -738,6 +778,7 @@ void CServer::closePrimaryScreen() throw() } // clean up + log((CLOG_DEBUG "destroying primary screen")); delete m_primary; m_primary = NULL; } @@ -763,6 +804,7 @@ void CServer::removeCleanupThread(const CThread& thread) void CServer::cleanupThreads() throw() { + log((CLOG_DEBUG "cleaning up threads")); m_mutex.lock(); while (m_cleanupList.begin() != m_cleanupList.end()) { // get the next thread and cancel it @@ -778,11 +820,13 @@ void CServer::cleanupThreads() throw() // FIXME -- delete remaining threads from list m_mutex.unlock(); + log((CLOG_DEBUG "cleaned up threads")); } CServer::CScreenInfo* CServer::addConnection( const CString& name, IServerProtocol* protocol) { + log((CLOG_DEBUG "adding connection \"%s\"", name.c_str())); CLock lock(&m_mutex); assert(m_screens.count(name) == 0); CScreenInfo* newScreen = new CScreenInfo(name, protocol); @@ -792,6 +836,7 @@ CServer::CScreenInfo* CServer::addConnection( void CServer::removeConnection(const CString& name) { + log((CLOG_DEBUG "removing connection \"%s\"", name.c_str())); CLock lock(&m_mutex); CScreenList::iterator index = m_screens.find(name); assert(index == m_screens.end()); diff --git a/synergy/CServerProtocol1_0.cpp b/synergy/CServerProtocol1_0.cpp index eb6ab9cc..2efe6aa1 100644 --- a/synergy/CServerProtocol1_0.cpp +++ b/synergy/CServerProtocol1_0.cpp @@ -3,6 +3,7 @@ #include "CProtocolUtil.h" #include "ProtocolTypes.h" #include "IInputStream.h" +#include "CLog.h" #include // @@ -40,6 +41,7 @@ void CServerProtocol1_0::run() throw(XIO,XBadClient) } // parse message + log((CLOG_DEBUG "msg from \"%s\": %c%c%c%c", getClient().c_str(), code[0], code[1], code[2], code[3])); if (memcmp(code, kMsgDInfo, 4) == 0) { recvInfo(); } @@ -53,6 +55,8 @@ void CServerProtocol1_0::run() throw(XIO,XBadClient) void CServerProtocol1_0::queryInfo() throw(XIO,XBadClient) { + log((CLOG_INFO "querying client \"%s\" info", getClient().c_str())); + // send request CProtocolUtil::writef(getOutputStream(), kMsgQInfo); @@ -69,74 +73,87 @@ void CServerProtocol1_0::queryInfo() throw(XIO,XBadClient) void CServerProtocol1_0::sendClose() throw(XIO) { + log((CLOG_INFO "send close to \"%s\"", getClient().c_str())); CProtocolUtil::writef(getOutputStream(), kMsgCClose); } void CServerProtocol1_0::sendEnter( SInt32 xAbs, SInt32 yAbs) throw(XIO) { + log((CLOG_INFO "send enter to \"%s\", %d,%d", getClient().c_str(), xAbs, yAbs)); CProtocolUtil::writef(getOutputStream(), kMsgCEnter, xAbs, yAbs); } void CServerProtocol1_0::sendLeave() throw(XIO) { + log((CLOG_INFO "send leave to \"%s\"", getClient().c_str())); CProtocolUtil::writef(getOutputStream(), kMsgCLeave); } void CServerProtocol1_0::sendGrabClipboard() throw(XIO) { + log((CLOG_INFO "send grab clipboard to \"%s\"", getClient().c_str())); CProtocolUtil::writef(getOutputStream(), kMsgCClipboard); } void CServerProtocol1_0::sendQueryClipboard() throw(XIO) { + log((CLOG_INFO "query clipboard to \"%s\"", getClient().c_str())); CProtocolUtil::writef(getOutputStream(), kMsgQClipboard); } void CServerProtocol1_0::sendScreenSaver(bool on) throw(XIO) { + log((CLOG_INFO "send screen saver to \"%s\"", getClient().c_str())); CProtocolUtil::writef(getOutputStream(), kMsgCScreenSaver, on ? 1 : 0); } void CServerProtocol1_0::sendKeyDown( KeyID key, KeyModifierMask mask) throw(XIO) { + log((CLOG_INFO "send key down to \"%s\" id=%d, mask=0x%04x", getClient().c_str(), key, mask)); CProtocolUtil::writef(getOutputStream(), kMsgDKeyDown, key, mask); } void CServerProtocol1_0::sendKeyRepeat( KeyID key, KeyModifierMask mask) throw(XIO) { + log((CLOG_INFO "send key repeat to \"%s\" id=%d, mask=0x%04x", getClient().c_str(), key, mask)); CProtocolUtil::writef(getOutputStream(), kMsgDKeyRepeat, key, mask); } void CServerProtocol1_0::sendKeyUp( KeyID key, KeyModifierMask mask) throw(XIO) { + log((CLOG_INFO "send key up to \"%s\" id=%d, mask=0x%04x", getClient().c_str(), key, mask)); CProtocolUtil::writef(getOutputStream(), kMsgDKeyUp, key, mask); } void CServerProtocol1_0::sendMouseDown( ButtonID button) throw(XIO) { + log((CLOG_INFO "send mouse down to \"%s\" id=%d", getClient().c_str(), button)); CProtocolUtil::writef(getOutputStream(), kMsgDMouseDown, button); } void CServerProtocol1_0::sendMouseUp( ButtonID button) throw(XIO) { + log((CLOG_INFO "send mouse up to \"%s\" id=%d", getClient().c_str(), button)); CProtocolUtil::writef(getOutputStream(), kMsgDMouseUp, button); } void CServerProtocol1_0::sendMouseMove( SInt32 xAbs, SInt32 yAbs) throw(XIO) { + log((CLOG_INFO "send mouse move to \"%s\" %d,%d", getClient().c_str(), xAbs, yAbs)); CProtocolUtil::writef(getOutputStream(), kMsgDMouseMove, xAbs, yAbs); } void CServerProtocol1_0::sendMouseWheel( SInt32 delta) throw(XIO) { + log((CLOG_INFO "send mouse wheel to \"%s\" %+d", getClient().c_str(), delta)); CProtocolUtil::writef(getOutputStream(), kMsgDMouseWheel, delta); } @@ -145,6 +162,7 @@ void CServerProtocol1_0::recvInfo() throw(XIO,XBadClient) // parse the message SInt32 w, h, zoneInfo; CProtocolUtil::readf(getInputStream(), kMsgDInfo + 4, &w, &h, &zoneInfo); + log((CLOG_INFO "received client \"%s\" info size=%dx%d, zone=%d", getClient().c_str(), w, h, zoneInfo)); // validate if (w == 0 || h == 0) { diff --git a/synergy/CXWindowsPrimaryScreen.cpp b/synergy/CXWindowsPrimaryScreen.cpp index 9fbc5647..cafbbcb8 100644 --- a/synergy/CXWindowsPrimaryScreen.cpp +++ b/synergy/CXWindowsPrimaryScreen.cpp @@ -2,6 +2,7 @@ #include "CServer.h" #include "CThread.h" #include "TMethodJob.h" +#include "CLog.h" #include #include @@ -33,6 +34,7 @@ void CXWindowsPrimaryScreen::open(CServer* server) m_server = server; // open the display + log((CLOG_DEBUG "XOpenDisplay(%s)", "NULL")); m_display = ::XOpenDisplay(NULL); // FIXME -- allow non-default if (m_display == NULL) throw int(5); // FIXME -- make exception for this @@ -44,6 +46,7 @@ void CXWindowsPrimaryScreen::open(CServer* server) // get screen size m_w = WidthOfScreen(screen); m_h = HeightOfScreen(screen); + log((CLOG_INFO "primary display size: %dx%d", m_w, m_h)); // get the root window Window root = RootWindow(m_display, m_screen); @@ -80,10 +83,12 @@ void CXWindowsPrimaryScreen::close() assert(m_eventThread != NULL); // stop event thread + log((CLOG_DEBUG "stopping event thread")); m_eventThread->cancel(); m_eventThread->wait(); delete m_eventThread; m_eventThread = NULL; + log((CLOG_DEBUG "stopped event thread")); // destroy window ::XDestroyWindow(m_display, m_window); @@ -92,10 +97,12 @@ void CXWindowsPrimaryScreen::close() // close the display ::XCloseDisplay(m_display); m_display = NULL; + log((CLOG_DEBUG "closed display")); } void CXWindowsPrimaryScreen::enter(SInt32 x, SInt32 y) { + log((CLOG_INFO "entering primary at %d,%d", x, y)); assert(m_display != NULL); assert(m_window != None); assert(m_active == true); @@ -123,6 +130,7 @@ void CXWindowsPrimaryScreen::enter(SInt32 x, SInt32 y) void CXWindowsPrimaryScreen::leave() { + log((CLOG_INFO "leaving primary")); assert(m_display != NULL); assert(m_window != None); assert(m_active == false); @@ -141,9 +149,12 @@ void CXWindowsPrimaryScreen::leave() GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); assert(result != GrabNotViewable); - if (result != GrabSuccess) + if (result != GrabSuccess) { + log((CLOG_DEBUG "waiting to grab pointer")); CThread::sleep(0.25); + } } while (result != GrabSuccess); + log((CLOG_DEBUG "grabbed pointer")); // now the keyboard result = ::XGrabKeyboard(m_display, m_window, True, @@ -151,9 +162,11 @@ void CXWindowsPrimaryScreen::leave() assert(result != GrabNotViewable); if (result != GrabSuccess) { ::XUngrabPointer(m_display, CurrentTime); + log((CLOG_DEBUG "ungrabbed pointer, waiting to grab keyboard")); CThread::sleep(0.25); } } while (result != GrabSuccess); + log((CLOG_DEBUG "grabbed keyboard")); // move the mouse to the center of grab window warpCursor(m_w >> 1, m_h >> 1); @@ -169,6 +182,7 @@ void CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y) Window root = RootWindow(m_display, m_screen); ::XWarpPointer(m_display, None, root, 0, 0, 0, 0, x, y); ::XSync(m_display, False); + log((CLOG_DEBUG "warped to %d,%d", x, y)); // discard mouse events since we just added one we don't want XEvent xevent; @@ -237,6 +251,7 @@ void CXWindowsPrimaryScreen::eventThread(void*) break; case KeyPress: { + log((CLOG_DEBUG "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state)); const KeyModifierMask mask = mapModifier(xevent.xkey.state); const KeyID key = mapKey(xevent.xkey.keycode, mask); if (key != kKeyNone) { @@ -248,6 +263,7 @@ void CXWindowsPrimaryScreen::eventThread(void*) // FIXME -- simulate key repeat. X sends press/release for // repeat. must detect auto repeat and use kKeyRepeat. case KeyRelease: { + log((CLOG_DEBUG "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state)); const KeyModifierMask mask = mapModifier(xevent.xkey.state); const KeyID key = mapKey(xevent.xkey.keycode, mask); if (key != kKeyNone) { @@ -257,6 +273,7 @@ void CXWindowsPrimaryScreen::eventThread(void*) } case ButtonPress: { + log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button)); const ButtonID button = mapButton(xevent.xbutton.button); if (button != kButtonNone) { m_server->onMouseDown(button); @@ -265,6 +282,7 @@ void CXWindowsPrimaryScreen::eventThread(void*) } case ButtonRelease: { + log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button)); const ButtonID button = mapButton(xevent.xbutton.button); if (button != kButtonNone) { m_server->onMouseUp(button); @@ -273,6 +291,7 @@ void CXWindowsPrimaryScreen::eventThread(void*) } case MotionNotify: { + log((CLOG_DEBUG "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root)); SInt32 x, y; if (!m_active) { x = xevent.xmotion.x_root;