294 lines
7.5 KiB
C++
294 lines
7.5 KiB
C++
#include "CClient.h"
|
|
#include "CString.h"
|
|
#include "TMethodJob.h"
|
|
#include "IScreen.h"
|
|
#include "ISocket.h"
|
|
#include "CMessageSocket.h"
|
|
#include "CSocketFactory.h"
|
|
#include "IEventQueue.h"
|
|
#include "CEvent.h"
|
|
#include "CTrace.h"
|
|
#include <assert.h>
|
|
|
|
//
|
|
// CClient
|
|
//
|
|
|
|
CClient::CClient(IScreen* screen) : m_screen(screen),
|
|
m_socket(NULL)
|
|
{
|
|
assert(m_screen != NULL);
|
|
assert(!m_screen->getName().empty());
|
|
}
|
|
|
|
CClient::~CClient()
|
|
{
|
|
assert(m_socket == NULL);
|
|
}
|
|
|
|
void CClient::run(const CString& hostname)
|
|
{
|
|
assert(m_socket == NULL);
|
|
|
|
try {
|
|
// create socket and
|
|
m_socket = CSOCKETFACTORY->create();
|
|
m_socket->setWriteJob(new TMethodJob<CClient>(this,
|
|
&CClient::onConnect));
|
|
TRACE(("connecting to %s...", hostname.c_str()));
|
|
m_socket->connect(hostname, 40001); // CProtocol::kDefaultPort
|
|
|
|
bool m_done = false; // FIXME
|
|
|
|
IEventQueue* queue = CEQ;
|
|
while (!m_done) {
|
|
// wait for connection, network messages, and events
|
|
queue->wait(-1.0);
|
|
|
|
// handle events
|
|
while (!queue->isEmpty()) {
|
|
// get the next event
|
|
CEvent event;
|
|
queue->pop(&event);
|
|
|
|
// handle it
|
|
switch (event.m_any.m_type) {
|
|
case CEventBase::kScreenSize: {
|
|
sendScreenSize();
|
|
break;
|
|
}
|
|
|
|
case CEventBase::kNull:
|
|
case CEventBase::kKeyDown:
|
|
case CEventBase::kKeyRepeat:
|
|
case CEventBase::kKeyUp:
|
|
case CEventBase::kMouseDown:
|
|
case CEventBase::kMouseUp:
|
|
case CEventBase::kMouseMove:
|
|
case CEventBase::kMouseWheel:
|
|
// FIXME -- other cases
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete m_socket;
|
|
m_socket = NULL;
|
|
}
|
|
|
|
catch (...) {
|
|
delete m_socket;
|
|
m_socket = NULL;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void CClient::onConnect()
|
|
{
|
|
TRACE(("connected"));
|
|
|
|
// say hello
|
|
const CString name(m_screen->getName());
|
|
char buf[512];
|
|
memcpy(buf, "SYNERGY\000\001", 9);
|
|
buf[9] = static_cast<char>(name.length());
|
|
memcpy(buf + 10, name.c_str(), name.length());
|
|
m_socket->write(buf, 10 + name.length());
|
|
|
|
// handle messages
|
|
m_socket->setWriteJob(NULL);
|
|
m_socket = new CMessageSocket(m_socket);
|
|
m_socket->setReadJob(new TMethodJob<CClient>(this, &CClient::onRead));
|
|
}
|
|
|
|
void CClient::onRead()
|
|
{
|
|
char buf[512];
|
|
SInt32 n = m_socket->read(buf, sizeof(buf));
|
|
if (n == -1) {
|
|
// disconnect
|
|
TRACE(("hangup"));
|
|
}
|
|
else if (n > 0) {
|
|
TRACE(("msg: 0x%02x length %d", buf[0], n));
|
|
switch (buf[0]) {
|
|
case '\002':
|
|
TRACE((" open"));
|
|
|
|
// open the screen
|
|
m_screen->open(buf[1] != 0);
|
|
|
|
// send initial size
|
|
sendScreenSize();
|
|
break;
|
|
|
|
case '\003':
|
|
TRACE((" close"));
|
|
m_screen->close();
|
|
break;
|
|
|
|
case '\004': {
|
|
const SInt32 x = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const SInt32 y = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
TRACE((" enter: %d,%d", x, y));
|
|
m_screen->enterScreen(x, y);
|
|
break;
|
|
}
|
|
|
|
case '\005':
|
|
TRACE((" leave"));
|
|
m_screen->leaveScreen();
|
|
break;
|
|
|
|
case '\007': {
|
|
const KeyID k = static_cast<KeyID>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const KeyModifierMask m = static_cast<KeyModifierMask>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
TRACE((" key down: %d 0x%08x", k, m));
|
|
m_screen->onKeyDown(k, m);
|
|
break;
|
|
}
|
|
|
|
case '\010': {
|
|
const KeyID k = static_cast<KeyID>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const KeyModifierMask m = static_cast<KeyModifierMask>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
const SInt32 n = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[9]) << 24) +
|
|
(static_cast<UInt32>(buf[10]) << 16) +
|
|
(static_cast<UInt32>(buf[11]) << 8) +
|
|
(static_cast<UInt32>(buf[12]) ));
|
|
TRACE((" key repeat: %d 0x%08x x%d", k, m, n));
|
|
m_screen->onKeyRepeat(k, m, n);
|
|
break;
|
|
}
|
|
|
|
case '\011': {
|
|
const KeyID k = static_cast<KeyID>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const KeyModifierMask m = static_cast<KeyModifierMask>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
TRACE((" key up: %d 0x%08x", k, m));
|
|
m_screen->onKeyUp(k, m);
|
|
break;
|
|
}
|
|
|
|
case '\013': {
|
|
const ButtonID b = static_cast<ButtonID>(
|
|
static_cast<UInt32>(buf[1]));
|
|
TRACE((" mouse down: %d", b));
|
|
m_screen->onMouseDown(b);
|
|
break;
|
|
}
|
|
|
|
case '\014': {
|
|
const ButtonID b = static_cast<ButtonID>(
|
|
static_cast<UInt32>(buf[1]));
|
|
TRACE((" mouse up: %d", b));
|
|
m_screen->onMouseUp(b);
|
|
break;
|
|
}
|
|
|
|
case '\015': {
|
|
const SInt32 x = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const SInt32 y = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
TRACE((" mouse move: %d,%d", x, y));
|
|
m_screen->onMouseMove(x, y);
|
|
break;
|
|
}
|
|
|
|
case '\016': {
|
|
const SInt32 n = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
TRACE((" mouse wheel: %d", n));
|
|
m_screen->onMouseWheel(n);
|
|
break;
|
|
}
|
|
|
|
case '\017': {
|
|
TRACE((" screen saver: %s", buf[1] ? "on" : "off"));
|
|
m_screen->onScreenSaver(buf[1] != 0);
|
|
break;
|
|
}
|
|
|
|
case '\020': {
|
|
const SInt32 x = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[1]) << 24) +
|
|
(static_cast<UInt32>(buf[2]) << 16) +
|
|
(static_cast<UInt32>(buf[3]) << 8) +
|
|
(static_cast<UInt32>(buf[4]) ));
|
|
const SInt32 y = static_cast<SInt32>(
|
|
(static_cast<UInt32>(buf[5]) << 24) +
|
|
(static_cast<UInt32>(buf[6]) << 16) +
|
|
(static_cast<UInt32>(buf[7]) << 8) +
|
|
(static_cast<UInt32>(buf[8]) ));
|
|
TRACE((" warp: %d,%d", x, y));
|
|
m_screen->warpCursor(x, y);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
TRACE((" unknown message"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CClient::sendScreenSize()
|
|
{
|
|
// get the size
|
|
SInt32 w, h;
|
|
m_screen->getSize(&w, &h);
|
|
|
|
// send it
|
|
char buf[9];
|
|
memcpy(buf, "\201", 1);
|
|
buf[1] = static_cast<char>((w >> 24) & 0xff);
|
|
buf[2] = static_cast<char>((w >> 16) & 0xff);
|
|
buf[3] = static_cast<char>((w >> 8) & 0xff);
|
|
buf[4] = static_cast<char>(w & 0xff);
|
|
buf[5] = static_cast<char>((h >> 24) & 0xff);
|
|
buf[6] = static_cast<char>((h >> 16) & 0xff);
|
|
buf[7] = static_cast<char>((h >> 8) & 0xff);
|
|
buf[8] = static_cast<char>(h & 0xff);
|
|
m_socket->write(buf, sizeof(buf));
|
|
}
|