mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-11 00:58:14 +08:00
moved client and server files into their own respective
directories.
This commit is contained in:
333
client/CClient.cpp
Normal file
333
client/CClient.cpp
Normal file
@@ -0,0 +1,333 @@
|
||||
#include "CClient.h"
|
||||
#include "CInputPacketStream.h"
|
||||
#include "COutputPacketStream.h"
|
||||
#include "CProtocolUtil.h"
|
||||
#include "ISecondaryScreen.h"
|
||||
#include "ProtocolTypes.h"
|
||||
#include "CThread.h"
|
||||
#include "CTimerThread.h"
|
||||
#include "XSynergy.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CLog.h"
|
||||
#include <memory>
|
||||
|
||||
//
|
||||
// CClient
|
||||
//
|
||||
|
||||
CClient::CClient(const CString& clientName) :
|
||||
m_name(clientName),
|
||||
m_input(NULL),
|
||||
m_output(NULL),
|
||||
m_screen(NULL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CClient::~CClient()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void CClient::run(const CNetworkAddress& serverAddress)
|
||||
{
|
||||
m_serverAddress = &serverAddress;
|
||||
CThread thread(new TMethodJob<CClient>(this, &CClient::runSession));
|
||||
thread.wait();
|
||||
}
|
||||
|
||||
#include "CTCPSocket.h"
|
||||
#include "CXWindowsSecondaryScreen.h"
|
||||
void CClient::runSession(void*)
|
||||
{
|
||||
log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str()));
|
||||
|
||||
std::auto_ptr<ISocket> socket;
|
||||
std::auto_ptr<IInputStream> input;
|
||||
std::auto_ptr<IOutputStream> output;
|
||||
try {
|
||||
// allow connect this much time to succeed
|
||||
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(*m_serverAddress);
|
||||
log((CLOG_INFO "connected to server"));
|
||||
|
||||
// get the input and output streams
|
||||
IInputStream* srcInput = socket->getInputStream();
|
||||
IOutputStream* srcOutput = socket->getOutputStream();
|
||||
|
||||
// attach the encryption layer
|
||||
bool own = false;
|
||||
/* FIXME -- implement ISecurityFactory
|
||||
if (m_securityFactory != NULL) {
|
||||
input.reset(m_securityFactory->createInputFilter(srcInput, own));
|
||||
output.reset(m_securityFactory->createOutputFilter(srcOutput, own));
|
||||
srcInput = input.get();
|
||||
srcOutput = output.get();
|
||||
own = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// attach the packetizing filters
|
||||
input.reset(new CInputPacketStream(srcInput, own));
|
||||
output.reset(new COutputPacketStream(srcOutput, own));
|
||||
|
||||
// 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());
|
||||
|
||||
// record streams in a more useful place
|
||||
m_input = input.get();
|
||||
m_output = output.get();
|
||||
}
|
||||
catch (XIncompatibleClient& e) {
|
||||
log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor()));
|
||||
return;
|
||||
}
|
||||
catch (XThread&) {
|
||||
log((CLOG_ERR "connection timed out"));
|
||||
throw;
|
||||
}
|
||||
catch (XBase& e) {
|
||||
log((CLOG_ERR "connection failed: %s", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// connect to screen
|
||||
std::auto_ptr<CScreenCleaner> screenCleaner;
|
||||
try {
|
||||
log((CLOG_DEBUG "creating secondary screen"));
|
||||
m_screen = new CXWindowsSecondaryScreen;
|
||||
screenCleaner.reset(new CScreenCleaner(this, m_screen));
|
||||
}
|
||||
catch (XBase& e) {
|
||||
log((CLOG_ERR "cannot open screen: %s", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 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
|
||||
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();
|
||||
}
|
||||
else if (memcmp(code, kMsgDMouseWheel, 4) == 0) {
|
||||
onMouseWheel();
|
||||
}
|
||||
else if (memcmp(code, kMsgDKeyDown, 4) == 0) {
|
||||
onKeyDown();
|
||||
}
|
||||
else if (memcmp(code, kMsgDKeyUp, 4) == 0) {
|
||||
onKeyUp();
|
||||
}
|
||||
else if (memcmp(code, kMsgDMouseDown, 4) == 0) {
|
||||
onMouseDown();
|
||||
}
|
||||
else if (memcmp(code, kMsgDMouseUp, 4) == 0) {
|
||||
onMouseUp();
|
||||
}
|
||||
else if (memcmp(code, kMsgDKeyRepeat, 4) == 0) {
|
||||
onKeyRepeat();
|
||||
}
|
||||
else if (memcmp(code, kMsgCEnter, 4) == 0) {
|
||||
onEnter();
|
||||
}
|
||||
else if (memcmp(code, kMsgCLeave, 4) == 0) {
|
||||
onLeave();
|
||||
}
|
||||
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
|
||||
onGrabClipboard();
|
||||
}
|
||||
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
|
||||
onScreenSaver();
|
||||
}
|
||||
else if (memcmp(code, kMsgQInfo, 4) == 0) {
|
||||
onQueryInfo();
|
||||
}
|
||||
else if (memcmp(code, kMsgQClipboard, 4) == 0) {
|
||||
onQueryClipboard();
|
||||
}
|
||||
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
|
||||
onSetClipboard();
|
||||
}
|
||||
else if (memcmp(code, kMsgCClose, 4) == 0) {
|
||||
// server wants us to hangup
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// unknown message
|
||||
log((CLOG_ERR "unknown message from server"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (XBase& e) {
|
||||
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();
|
||||
}
|
||||
|
||||
void CClient::onEnter()
|
||||
{
|
||||
SInt32 x, y;
|
||||
CProtocolUtil::readf(m_input, kMsgCEnter + 4, &x, &y);
|
||||
m_screen->enter(x, y);
|
||||
}
|
||||
|
||||
void CClient::onLeave()
|
||||
{
|
||||
m_screen->leave();
|
||||
}
|
||||
|
||||
void CClient::onGrabClipboard()
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void CClient::onScreenSaver()
|
||||
{
|
||||
SInt32 on;
|
||||
CProtocolUtil::readf(m_input, kMsgCScreenSaver + 4, &on);
|
||||
// FIXME
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void CClient::onQueryClipboard()
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void CClient::onSetClipboard()
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void CClient::onKeyDown()
|
||||
{
|
||||
SInt32 id, mask;
|
||||
CProtocolUtil::readf(m_input, kMsgDKeyDown + 4, &id, &mask);
|
||||
m_screen->keyDown(static_cast<KeyID>(id),
|
||||
static_cast<KeyModifierMask>(mask));
|
||||
}
|
||||
|
||||
void CClient::onKeyRepeat()
|
||||
{
|
||||
SInt32 id, mask, count;
|
||||
CProtocolUtil::readf(m_input, kMsgDKeyRepeat + 4, &id, &mask, &count);
|
||||
m_screen->keyRepeat(static_cast<KeyID>(id),
|
||||
static_cast<KeyModifierMask>(mask),
|
||||
count);
|
||||
}
|
||||
|
||||
void CClient::onKeyUp()
|
||||
{
|
||||
SInt32 id, mask;
|
||||
CProtocolUtil::readf(m_input, kMsgDKeyUp + 4, &id, &mask);
|
||||
m_screen->keyUp(static_cast<KeyID>(id),
|
||||
static_cast<KeyModifierMask>(mask));
|
||||
}
|
||||
|
||||
void CClient::onMouseDown()
|
||||
{
|
||||
SInt32 id;
|
||||
CProtocolUtil::readf(m_input, kMsgDMouseDown + 4, &id);
|
||||
m_screen->mouseDown(static_cast<ButtonID>(id));
|
||||
}
|
||||
|
||||
void CClient::onMouseUp()
|
||||
{
|
||||
SInt32 id;
|
||||
CProtocolUtil::readf(m_input, kMsgDMouseUp + 4, &id);
|
||||
m_screen->mouseUp(static_cast<ButtonID>(id));
|
||||
}
|
||||
|
||||
void CClient::onMouseMove()
|
||||
{
|
||||
SInt32 x, y;
|
||||
CProtocolUtil::readf(m_input, kMsgDMouseMove + 4, &x, &y);
|
||||
m_screen->mouseMove(x, y);
|
||||
}
|
||||
|
||||
void CClient::onMouseWheel()
|
||||
{
|
||||
SInt32 delta;
|
||||
CProtocolUtil::readf(m_input, kMsgDMouseWheel + 4, &delta);
|
||||
m_screen->mouseWheel(delta);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CClient::CScreenCleaner
|
||||
//
|
||||
|
||||
CClient::CScreenCleaner::CScreenCleaner(CClient* client,
|
||||
ISecondaryScreen* screen) :
|
||||
m_screen(screen)
|
||||
{
|
||||
assert(m_screen != NULL);
|
||||
try {
|
||||
m_screen->open(client);
|
||||
}
|
||||
catch (...) {
|
||||
delete m_screen;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
CClient::CScreenCleaner::~CScreenCleaner()
|
||||
{
|
||||
m_screen->close();
|
||||
delete m_screen;
|
||||
}
|
||||
61
client/CClient.h
Normal file
61
client/CClient.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef CCLIENT_H
|
||||
#define CCLIENT_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "BasicTypes.h"
|
||||
|
||||
class CNetworkAddress;
|
||||
class IInputStream;
|
||||
class IOutputStream;
|
||||
class ISecondaryScreen;
|
||||
|
||||
class CClient {
|
||||
public:
|
||||
CClient(const CString& clientName);
|
||||
~CClient();
|
||||
|
||||
// manipulators
|
||||
|
||||
void run(const CNetworkAddress& serverAddress);
|
||||
|
||||
// accessors
|
||||
|
||||
|
||||
private:
|
||||
void runSession(void*);
|
||||
|
||||
// message handlers
|
||||
void onEnter();
|
||||
void onLeave();
|
||||
void onGrabClipboard();
|
||||
void onScreenSaver();
|
||||
void onQueryInfo();
|
||||
void onQueryClipboard();
|
||||
void onSetClipboard();
|
||||
void onKeyDown();
|
||||
void onKeyRepeat();
|
||||
void onKeyUp();
|
||||
void onMouseDown();
|
||||
void onMouseUp();
|
||||
void onMouseMove();
|
||||
void onMouseWheel();
|
||||
|
||||
private:
|
||||
class CScreenCleaner {
|
||||
public:
|
||||
CScreenCleaner(CClient*, ISecondaryScreen*);
|
||||
~CScreenCleaner();
|
||||
|
||||
private:
|
||||
ISecondaryScreen* m_screen;
|
||||
};
|
||||
|
||||
private:
|
||||
CString m_name;
|
||||
IInputStream* m_input;
|
||||
IOutputStream* m_output;
|
||||
ISecondaryScreen* m_screen;
|
||||
const CNetworkAddress* m_serverAddress;
|
||||
};
|
||||
|
||||
#endif
|
||||
249
client/CXWindowsSecondaryScreen.cpp
Normal file
249
client/CXWindowsSecondaryScreen.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
#include "CXWindowsSecondaryScreen.h"
|
||||
#include "CClient.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
#include <assert.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
|
||||
//
|
||||
// CXWindowsSecondaryScreen
|
||||
//
|
||||
|
||||
CXWindowsSecondaryScreen::CXWindowsSecondaryScreen() :
|
||||
m_client(NULL),
|
||||
m_window(None)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CXWindowsSecondaryScreen::~CXWindowsSecondaryScreen()
|
||||
{
|
||||
assert(m_window == None);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::open(CClient* client)
|
||||
{
|
||||
assert(m_client == NULL);
|
||||
assert(client != NULL);
|
||||
|
||||
// set the client
|
||||
m_client = client;
|
||||
|
||||
// open the display
|
||||
openDisplay();
|
||||
|
||||
// verify the availability of the XTest extension
|
||||
CDisplayLock display(this);
|
||||
int majorOpcode, firstEvent, firstError;
|
||||
if (!XQueryExtension(display, XTestExtensionName,
|
||||
&majorOpcode, &firstEvent, &firstError))
|
||||
throw int(6); // FIXME -- make exception for this
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::close()
|
||||
{
|
||||
assert(m_client != NULL);
|
||||
|
||||
// close the display
|
||||
closeDisplay();
|
||||
|
||||
// done with client
|
||||
m_client = NULL;
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::enter(SInt32 x, SInt32 y)
|
||||
{
|
||||
assert(m_window != None);
|
||||
|
||||
CDisplayLock display(this);
|
||||
|
||||
// warp to requested location
|
||||
XTestFakeMotionEvent(display, getScreen(), x, y, CurrentTime);
|
||||
XSync(display, False);
|
||||
|
||||
// show cursor
|
||||
XUnmapWindow(display, m_window);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::leave()
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
leaveNoLock(display);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::keyDown(
|
||||
KeyID key, KeyModifierMask mask)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
XTestFakeKeyEvent(display, mapKey(key, mask), True, CurrentTime);
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::keyRepeat(
|
||||
KeyID, KeyModifierMask, SInt32)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::keyUp(
|
||||
KeyID key, KeyModifierMask mask)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
XTestFakeKeyEvent(display, mapKey(key, mask), False, CurrentTime);
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::mouseDown(ButtonID button)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
XTestFakeButtonEvent(display, mapButton(button), True, CurrentTime);
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::mouseUp(ButtonID button)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
XTestFakeButtonEvent(display, mapButton(button), False, CurrentTime);
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::mouseMove(SInt32 x, SInt32 y)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
XTestFakeMotionEvent(display, getScreen(), x, y, CurrentTime);
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::mouseWheel(SInt32)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::getSize(
|
||||
SInt32* width, SInt32* height) const
|
||||
{
|
||||
getScreenSize(width, height);
|
||||
}
|
||||
|
||||
SInt32 CXWindowsSecondaryScreen::getJumpZoneSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::onOpenDisplay()
|
||||
{
|
||||
assert(m_window == None);
|
||||
|
||||
CDisplayLock display(this);
|
||||
|
||||
// create the cursor hiding window. this window is used to hide the
|
||||
// cursor when it's not on the screen. the window is hidden as soon
|
||||
// as the cursor enters the screen or the display's real cursor is
|
||||
// moved.
|
||||
XSetWindowAttributes attr;
|
||||
attr.event_mask = LeaveWindowMask;
|
||||
attr.do_not_propagate_mask = 0;
|
||||
attr.override_redirect = True;
|
||||
attr.cursor = createBlankCursor();
|
||||
m_window = XCreateWindow(display, getRoot(), 0, 0, 1, 1, 0, 0,
|
||||
InputOnly, CopyFromParent,
|
||||
CWDontPropagate | CWEventMask |
|
||||
CWOverrideRedirect | CWCursor,
|
||||
&attr);
|
||||
|
||||
// become impervious to server grabs
|
||||
XTestGrabControl(display, True);
|
||||
|
||||
// hide the cursor
|
||||
leaveNoLock(display);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::onCloseDisplay()
|
||||
{
|
||||
assert(m_window != None);
|
||||
|
||||
// no longer impervious to server grabs
|
||||
CDisplayLock display(this);
|
||||
XTestGrabControl(display, False);
|
||||
|
||||
// destroy window
|
||||
XDestroyWindow(display, m_window);
|
||||
m_window = None;
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::eventThread(void*)
|
||||
{
|
||||
assert(m_window != None);
|
||||
|
||||
for (;;) {
|
||||
// wait for and get the next event
|
||||
XEvent xevent;
|
||||
getEvent(&xevent);
|
||||
|
||||
// handle event
|
||||
switch (xevent.type) {
|
||||
case LeaveNotify: {
|
||||
// mouse moved out of hider window somehow. hide the window.
|
||||
assert(m_window != None);
|
||||
CDisplayLock display(this);
|
||||
XUnmapWindow(display, m_window);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
// FIXME -- handle screen resolution changes
|
||||
|
||||
case SelectionClear:
|
||||
target->XXX(xevent.xselectionclear.);
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
target->XXX(xevent.xselection.);
|
||||
break;
|
||||
|
||||
case SelectionRequest:
|
||||
target->XXX(xevent.xselectionrequest.);
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::leaveNoLock(Display* display)
|
||||
{
|
||||
assert(display != NULL);
|
||||
assert(m_window != None);
|
||||
|
||||
// move hider window under the mouse (rather than moving the mouse
|
||||
// somewhere else on the screen)
|
||||
int x, y, dummy;
|
||||
unsigned int dummyMask;
|
||||
Window dummyWindow;
|
||||
XQueryPointer(display, getRoot(), &dummyWindow, &dummyWindow,
|
||||
&x, &y, &dummy, &dummy, &dummyMask);
|
||||
XMoveWindow(display, m_window, x, y);
|
||||
|
||||
// raise and show the hider window
|
||||
XMapRaised(display, m_window);
|
||||
|
||||
// hide cursor by moving it into the hider window
|
||||
XWarpPointer(display, None, m_window, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
KeyCode CXWindowsSecondaryScreen::mapKey(
|
||||
KeyID id, KeyModifierMask /*mask*/) const
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
// FIXME -- use mask
|
||||
return XKeysymToKeycode(display, static_cast<KeySym>(id));
|
||||
}
|
||||
|
||||
unsigned int CXWindowsSecondaryScreen::mapButton(
|
||||
ButtonID id) const
|
||||
{
|
||||
// FIXME -- should use button mapping?
|
||||
return static_cast<unsigned int>(id);
|
||||
}
|
||||
43
client/CXWindowsSecondaryScreen.h
Normal file
43
client/CXWindowsSecondaryScreen.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef CXWINDOWSSECONDARYSCREEN_H
|
||||
#define CXWINDOWSSECONDARYSCREEN_H
|
||||
|
||||
#include "CXWindowsScreen.h"
|
||||
#include "ISecondaryScreen.h"
|
||||
|
||||
class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen {
|
||||
public:
|
||||
CXWindowsSecondaryScreen();
|
||||
virtual ~CXWindowsSecondaryScreen();
|
||||
|
||||
// ISecondaryScreen overrides
|
||||
virtual void open(CClient*);
|
||||
virtual void close();
|
||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||
virtual void leave();
|
||||
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 xAbsolute, SInt32 yAbsolute);
|
||||
virtual void mouseWheel(SInt32 delta);
|
||||
virtual void getSize(SInt32* width, SInt32* height) const;
|
||||
virtual SInt32 getJumpZoneSize() const;
|
||||
|
||||
protected:
|
||||
// CXWindowsScreen overrides
|
||||
virtual void onOpenDisplay();
|
||||
virtual void onCloseDisplay();
|
||||
virtual void eventThread(void*);
|
||||
|
||||
private:
|
||||
void leaveNoLock(Display*);
|
||||
KeyCode mapKey(KeyID, KeyModifierMask) const;
|
||||
unsigned int mapButton(ButtonID button) const;
|
||||
|
||||
private:
|
||||
CClient* m_client;
|
||||
Window m_window;
|
||||
};
|
||||
|
||||
#endif
|
||||
44
client/Makefile
Normal file
44
client/Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
DEPTH=..
|
||||
include $(DEPTH)/Makecommon
|
||||
|
||||
#
|
||||
# target file
|
||||
#
|
||||
TARGET = client
|
||||
|
||||
#
|
||||
# source files
|
||||
#
|
||||
LCXXINCS = \
|
||||
-I$(DEPTH)/base \
|
||||
-I$(DEPTH)/mt \
|
||||
-I$(DEPTH)/io \
|
||||
-I$(DEPTH)/net \
|
||||
-I$(DEPTH)/synergy \
|
||||
$(NULL)
|
||||
CXXFILES = \
|
||||
CXWindowsSecondaryScreen.cpp \
|
||||
CClient.cpp \
|
||||
client.cpp \
|
||||
$(NULL)
|
||||
|
||||
#
|
||||
# libraries we depend on
|
||||
#
|
||||
DEPLIBS = \
|
||||
$(LIBDIR)/libsynergy.a \
|
||||
$(LIBDIR)/libnet.a \
|
||||
$(LIBDIR)/libio.a \
|
||||
$(LIBDIR)/libmt.a \
|
||||
$(LIBDIR)/libbase.a \
|
||||
$(NULL)
|
||||
LLDLIBS = \
|
||||
$(DEPLIBS) \
|
||||
-lpthread \
|
||||
$(NULL)
|
||||
|
||||
targets: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS) $(DEPLIBS)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
||||
|
||||
24
client/client.cpp
Normal file
24
client/client.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "CClient.h"
|
||||
#include "CNetworkAddress.h"
|
||||
#include "CThread.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CThread::init();
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
CClient* client = new CClient("ingrid");
|
||||
client->run(CNetworkAddress(argv[1], 50001));
|
||||
}
|
||||
catch (XBase& e) {
|
||||
fprintf(stderr, "failed: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user