#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 // // 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(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(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(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( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const SInt32 y = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(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( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const KeyModifierMask m = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(buf[8]) )); TRACE((" key down: %d 0x%08x", k, m)); m_screen->onKeyDown(k, m); break; } case '\010': { const KeyID k = static_cast( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const KeyModifierMask m = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(buf[8]) )); const SInt32 n = static_cast( (static_cast(buf[9]) << 24) + (static_cast(buf[10]) << 16) + (static_cast(buf[11]) << 8) + (static_cast(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( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const KeyModifierMask m = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(buf[8]) )); TRACE((" key up: %d 0x%08x", k, m)); m_screen->onKeyUp(k, m); break; } case '\013': { const ButtonID b = static_cast( static_cast(buf[1])); TRACE((" mouse down: %d", b)); m_screen->onMouseDown(b); break; } case '\014': { const ButtonID b = static_cast( static_cast(buf[1])); TRACE((" mouse up: %d", b)); m_screen->onMouseUp(b); break; } case '\015': { const SInt32 x = static_cast( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const SInt32 y = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(buf[8]) )); TRACE((" mouse move: %d,%d", x, y)); m_screen->onMouseMove(x, y); break; } case '\016': { const SInt32 n = static_cast( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(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( (static_cast(buf[1]) << 24) + (static_cast(buf[2]) << 16) + (static_cast(buf[3]) << 8) + (static_cast(buf[4]) )); const SInt32 y = static_cast( (static_cast(buf[5]) << 24) + (static_cast(buf[6]) << 16) + (static_cast(buf[7]) << 8) + (static_cast(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((w >> 24) & 0xff); buf[2] = static_cast((w >> 16) & 0xff); buf[3] = static_cast((w >> 8) & 0xff); buf[4] = static_cast(w & 0xff); buf[5] = static_cast((h >> 24) & 0xff); buf[6] = static_cast((h >> 16) & 0xff); buf[7] = static_cast((h >> 8) & 0xff); buf[8] = static_cast(h & 0xff); m_socket->write(buf, sizeof(buf)); }