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