checkpoint. first cut of client and server apps. not tested
yet but they compile and *should* work as is.
This commit is contained in:
parent
23f1b1aba1
commit
23f948d55a
3
Makefile
3
Makefile
|
@ -42,6 +42,7 @@ LCXXINCS = \
|
||||||
-I$(DEPTH)/mt \
|
-I$(DEPTH)/mt \
|
||||||
-I$(DEPTH)/io \
|
-I$(DEPTH)/io \
|
||||||
-I$(DEPTH)/net \
|
-I$(DEPTH)/net \
|
||||||
|
-I$(DEPTH)/synergy \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
CXXFILES = test.cpp
|
CXXFILES = test.cpp
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ CXXFILES = test.cpp
|
||||||
# libraries we depend on
|
# libraries we depend on
|
||||||
#
|
#
|
||||||
DEPLIBS = \
|
DEPLIBS = \
|
||||||
|
$(LIBDIR)/libsynergy.a \
|
||||||
$(LIBDIR)/libnet.a \
|
$(LIBDIR)/libnet.a \
|
||||||
$(LIBDIR)/libio.a \
|
$(LIBDIR)/libio.a \
|
||||||
$(LIBDIR)/libmt.a \
|
$(LIBDIR)/libmt.a \
|
||||||
|
@ -61,3 +63,4 @@ LLDLIBS = \
|
||||||
|
|
||||||
test: $(OBJECTS) $(DEPLIBS)
|
test: $(OBJECTS) $(DEPLIBS)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
1
notes
1
notes
|
@ -9,7 +9,6 @@ CServer
|
||||||
* put mutex locks wherever necessary (like accessing m_active)
|
* put mutex locks wherever necessary (like accessing m_active)
|
||||||
|
|
||||||
CClient
|
CClient
|
||||||
* need thread to handle screen
|
|
||||||
* need methods for screen event handler to call as appropriate
|
* need methods for screen event handler to call as appropriate
|
||||||
|
|
||||||
server client
|
server client
|
||||||
|
|
|
@ -2,15 +2,22 @@
|
||||||
#include "CInputPacketStream.h"
|
#include "CInputPacketStream.h"
|
||||||
#include "COutputPacketStream.h"
|
#include "COutputPacketStream.h"
|
||||||
#include "CProtocolUtil.h"
|
#include "CProtocolUtil.h"
|
||||||
|
#include "ISecondaryScreen.h"
|
||||||
|
#include "ProtocolTypes.h"
|
||||||
#include "CTimerThread.h"
|
#include "CTimerThread.h"
|
||||||
|
#include "XSynergy.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
//
|
//
|
||||||
// CClient
|
// CClient
|
||||||
//
|
//
|
||||||
|
|
||||||
CClient::CClient(const CString& clientName) :
|
CClient::CClient(const CString& clientName) :
|
||||||
m_name(clientName)
|
m_name(clientName),
|
||||||
|
m_input(NULL),
|
||||||
|
m_output(NULL),
|
||||||
|
m_screen(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +26,7 @@ CClient::~CClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "CTCPSocket.h"
|
#include "CTCPSocket.h"
|
||||||
|
#include "CXWindowsSecondaryScreen.h"
|
||||||
void CClient::run(const CNetworkAddress& serverAddress)
|
void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
{
|
{
|
||||||
std::auto_ptr<ISocket> socket;
|
std::auto_ptr<ISocket> socket;
|
||||||
|
@ -84,12 +92,18 @@ void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to screen
|
// connect to screen
|
||||||
// FIXME -- make object that closes and destroys screen in
|
std::auto_ptr<CScreenCleaner> screenCleaner;
|
||||||
// it's d'tor. screen must not be handling event queue by
|
|
||||||
// the time the streams are destroyed.
|
|
||||||
|
|
||||||
// handle messages from server
|
|
||||||
try {
|
try {
|
||||||
|
m_screen = new CXWindowsSecondaryScreen;
|
||||||
|
screenCleaner.reset(new CScreenCleaner(this, m_screen));
|
||||||
|
}
|
||||||
|
catch (XBase& e) {
|
||||||
|
fprintf(stderr, "cannot open screen: %s\n", e.what());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// handle messages from server
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// wait for reply
|
// wait for reply
|
||||||
UInt8 code[4];
|
UInt8 code[4];
|
||||||
|
@ -108,46 +122,46 @@ void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
|
|
||||||
// parse message
|
// parse message
|
||||||
if (memcmp(code, kMsgDMouseMove, 4) == 0) {
|
if (memcmp(code, kMsgDMouseMove, 4) == 0) {
|
||||||
onMouseMove(input.get());
|
onMouseMove();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDMouseWheel, 4) == 0) {
|
else if (memcmp(code, kMsgDMouseWheel, 4) == 0) {
|
||||||
onMouseWheel(input.get());
|
onMouseWheel();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDKeyDown, 4) == 0) {
|
else if (memcmp(code, kMsgDKeyDown, 4) == 0) {
|
||||||
onKeyDown(input.get());
|
onKeyDown();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDKeyUp, 4) == 0) {
|
else if (memcmp(code, kMsgDKeyUp, 4) == 0) {
|
||||||
onKeyUp(input.get());
|
onKeyUp();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDMouseDown, 4) == 0) {
|
else if (memcmp(code, kMsgDMouseDown, 4) == 0) {
|
||||||
onMouseDown(input.get());
|
onMouseDown();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDMouseUp, 4) == 0) {
|
else if (memcmp(code, kMsgDMouseUp, 4) == 0) {
|
||||||
onMouseUp(input.get());
|
onMouseUp();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDKeyRepeat, 4) == 0) {
|
else if (memcmp(code, kMsgDKeyRepeat, 4) == 0) {
|
||||||
onKeyRepeat(input.get());
|
onKeyRepeat();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgCEnter, 4) == 0) {
|
else if (memcmp(code, kMsgCEnter, 4) == 0) {
|
||||||
onEnter(input.get());
|
onEnter();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgCLeave, 4) == 0) {
|
else if (memcmp(code, kMsgCLeave, 4) == 0) {
|
||||||
onLeave(input.get());
|
onLeave();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
|
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
|
||||||
onGrabClipboard(input.get());
|
onGrabClipboard();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
|
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
|
||||||
onScreenSaver(input.get());
|
onScreenSaver();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgQInfo, 4) == 0) {
|
else if (memcmp(code, kMsgQInfo, 4) == 0) {
|
||||||
onQueryInfo(input.get());
|
onQueryInfo();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgQClipboard, 4) == 0) {
|
else if (memcmp(code, kMsgQClipboard, 4) == 0) {
|
||||||
onQueryClipboard(input.get());
|
onQueryClipboard();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
|
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
|
||||||
onSetClipboard(input.get());
|
onSetClipboard();
|
||||||
}
|
}
|
||||||
else if (memcmp(code, kMsgCClose, 4) == 0) {
|
else if (memcmp(code, kMsgCClose, 4) == 0) {
|
||||||
// server wants us to hangup
|
// server wants us to hangup
|
||||||
|
@ -159,14 +173,17 @@ void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// done with socket
|
|
||||||
m_socket->close();
|
|
||||||
}
|
}
|
||||||
catch (XBase& e) {
|
catch (XBase& e) {
|
||||||
fprintf(stderr, "error: %s\n", e.what());
|
fprintf(stderr, "error: %s\n", e.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// done with screen
|
||||||
|
screenCleaner.reset();
|
||||||
|
|
||||||
|
// done with socket
|
||||||
|
socket->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::onEnter()
|
void CClient::onEnter()
|
||||||
|
@ -196,7 +213,7 @@ void CClient::onScreenSaver()
|
||||||
void CClient::onQueryInfo()
|
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();
|
||||||
CProtocolUtil::writef(m_output, kMsgDInfo, w, h, zoneSize);
|
CProtocolUtil::writef(m_output, kMsgDInfo, w, h, zoneSize);
|
||||||
}
|
}
|
||||||
|
@ -215,16 +232,16 @@ void CClient::onKeyDown()
|
||||||
{
|
{
|
||||||
SInt32 id, mask;
|
SInt32 id, mask;
|
||||||
CProtocolUtil::readf(m_input, kMsgDKeyDown + 4, &id, &mask);
|
CProtocolUtil::readf(m_input, kMsgDKeyDown + 4, &id, &mask);
|
||||||
m_screen->onKeyDown(reinterpret_cast<KeyID>(id),
|
m_screen->onKeyDown(static_cast<KeyID>(id),
|
||||||
reinterpret_cast<KeyModifierMask>(mask));
|
static_cast<KeyModifierMask>(mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::onKeyRepeat()
|
void CClient::onKeyRepeat()
|
||||||
{
|
{
|
||||||
SInt32 id, mask, count;
|
SInt32 id, mask, count;
|
||||||
CProtocolUtil::readf(m_input, kMsgDKeyRepeat + 4, &id, &mask, &count);
|
CProtocolUtil::readf(m_input, kMsgDKeyRepeat + 4, &id, &mask, &count);
|
||||||
m_screen->onKeyRepeat(reinterpret_cast<KeyID>(id),
|
m_screen->onKeyRepeat(static_cast<KeyID>(id),
|
||||||
reinterpret_cast<KeyModifierMask>(mask),
|
static_cast<KeyModifierMask>(mask),
|
||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,22 +249,22 @@ void CClient::onKeyUp()
|
||||||
{
|
{
|
||||||
SInt32 id, mask;
|
SInt32 id, mask;
|
||||||
CProtocolUtil::readf(m_input, kMsgDKeyUp + 4, &id, &mask);
|
CProtocolUtil::readf(m_input, kMsgDKeyUp + 4, &id, &mask);
|
||||||
m_screen->onKeyUp(reinterpret_cast<KeyID>(id),
|
m_screen->onKeyUp(static_cast<KeyID>(id),
|
||||||
reinterpret_cast<KeyModifierMask>(mask));
|
static_cast<KeyModifierMask>(mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::onMouseDown()
|
void CClient::onMouseDown()
|
||||||
{
|
{
|
||||||
SInt32 id;
|
SInt32 id;
|
||||||
CProtocolUtil::readf(m_input, kMsgDMouseDown + 4, &id);
|
CProtocolUtil::readf(m_input, kMsgDMouseDown + 4, &id);
|
||||||
m_screen->onMouseDown(reinterpret_cast<ButonID>(id));
|
m_screen->onMouseDown(static_cast<ButtonID>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::onMouseUp()
|
void CClient::onMouseUp()
|
||||||
{
|
{
|
||||||
SInt32 id;
|
SInt32 id;
|
||||||
CProtocolUtil::readf(m_input, kMsgDMouseUp + 4, &id);
|
CProtocolUtil::readf(m_input, kMsgDMouseUp + 4, &id);
|
||||||
m_screen->onMouseUp(reinterpret_cast<ButonID>(id));
|
m_screen->onMouseUp(static_cast<ButtonID>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::onMouseMove()
|
void CClient::onMouseMove()
|
||||||
|
@ -263,3 +280,28 @@ void CClient::onMouseWheel()
|
||||||
CProtocolUtil::readf(m_input, kMsgDMouseWheel + 4, &delta);
|
CProtocolUtil::readf(m_input, kMsgDMouseWheel + 4, &delta);
|
||||||
m_screen->onMouseWheel(delta);
|
m_screen->onMouseWheel(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;
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
class CNetworkAddress;
|
class CNetworkAddress;
|
||||||
class IInputStream;
|
class IInputStream;
|
||||||
class IOutputStream;
|
class IOutputStream;
|
||||||
|
class ISecondaryScreen;
|
||||||
|
|
||||||
class CClient {
|
class CClient {
|
||||||
public:
|
public:
|
||||||
|
@ -37,10 +38,21 @@ class CClient {
|
||||||
void onMouseMove();
|
void onMouseMove();
|
||||||
void onMouseWheel();
|
void onMouseWheel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class CScreenCleaner {
|
||||||
|
public:
|
||||||
|
CScreenCleaner(CClient*, ISecondaryScreen*);
|
||||||
|
~CScreenCleaner();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ISecondaryScreen* m_screen;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CString m_name;
|
CString m_name;
|
||||||
IInputStream* m_output;
|
IInputStream* m_input;
|
||||||
IOutputStream* m_output;
|
IOutputStream* m_output;
|
||||||
|
ISecondaryScreen* m_screen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -545,6 +545,7 @@ void CServer::mapPosition(CScreenInfo* src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "CTCPListenSocket.h"
|
||||||
void CServer::acceptClients(void*)
|
void CServer::acceptClients(void*)
|
||||||
{
|
{
|
||||||
// add this thread to the list of threads to cancel. remove from
|
// add this thread to the list of threads to cancel. remove from
|
||||||
|
@ -554,7 +555,8 @@ void CServer::acceptClients(void*)
|
||||||
std::auto_ptr<IListenSocket> listen;
|
std::auto_ptr<IListenSocket> listen;
|
||||||
try {
|
try {
|
||||||
// create socket listener
|
// create socket listener
|
||||||
listen.reset(m_socketFactory->createListen());
|
// listen.reset(m_socketFactory->createListen());
|
||||||
|
listen.reset(new CTCPListenSocket); // FIXME
|
||||||
|
|
||||||
// bind to the desired port. keep retrying if we can't bind
|
// bind to the desired port. keep retrying if we can't bind
|
||||||
// the address immediately.
|
// the address immediately.
|
||||||
|
@ -712,7 +714,12 @@ void CServer::openPrimaryScreen()
|
||||||
m_primary->open(this);
|
m_primary->open(this);
|
||||||
|
|
||||||
// add connection
|
// add connection
|
||||||
m_active = addConnection(CString("primary"/* FIXME */), NULL);
|
m_active = addConnection(CString("primary"/* FIXME */), NULL);
|
||||||
|
|
||||||
|
// update info
|
||||||
|
m_primary->getSize(&m_active->m_width, &m_active->m_height);
|
||||||
|
m_active->m_zoneSize = m_primary->getJumpZoneSize();
|
||||||
|
// FIXME -- need way for primary screen to call us back
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::closePrimaryScreen() throw()
|
void CServer::closePrimaryScreen() throw()
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "TMethodJob.h"
|
#include "TMethodJob.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/extensions/XTest.h>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CXWindowsPrimaryScreen
|
// CXWindowsPrimaryScreen
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
#include "CXWindowsSecondaryScreen.h"
|
||||||
|
#include "CClient.h"
|
||||||
|
#include "CThread.h"
|
||||||
|
#include "TMethodJob.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/extensions/XTest.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// CXWindowsSecondaryScreen
|
||||||
|
//
|
||||||
|
|
||||||
|
CXWindowsSecondaryScreen::CXWindowsSecondaryScreen() :
|
||||||
|
m_client(NULL),
|
||||||
|
m_display(NULL),
|
||||||
|
m_window(None),
|
||||||
|
m_w(0), m_h(0)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
CXWindowsSecondaryScreen::~CXWindowsSecondaryScreen()
|
||||||
|
{
|
||||||
|
assert(m_display == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::open(CClient* client)
|
||||||
|
{
|
||||||
|
assert(m_client == NULL);
|
||||||
|
assert(client != NULL);
|
||||||
|
|
||||||
|
// set the client
|
||||||
|
m_client = client;
|
||||||
|
|
||||||
|
// open the display
|
||||||
|
m_display = ::XOpenDisplay(NULL); // FIXME -- allow non-default
|
||||||
|
if (m_display == NULL)
|
||||||
|
throw int(5); // FIXME -- make exception for this
|
||||||
|
|
||||||
|
// get default screen
|
||||||
|
m_screen = DefaultScreen(m_display);
|
||||||
|
Screen* screen = ScreenOfDisplay(m_display, m_screen);
|
||||||
|
|
||||||
|
// get screen size
|
||||||
|
m_w = WidthOfScreen(screen);
|
||||||
|
m_h = HeightOfScreen(screen);
|
||||||
|
|
||||||
|
// verify the availability of the XTest extension
|
||||||
|
int majorOpcode, firstEvent, firstError;
|
||||||
|
if (!::XQueryExtension(m_display, XTestExtensionName,
|
||||||
|
&majorOpcode, &firstEvent, &firstError))
|
||||||
|
throw int(6); // FIXME -- make exception for this
|
||||||
|
|
||||||
|
// become impervious to server grabs
|
||||||
|
::XTestGrabControl(m_display, True);
|
||||||
|
|
||||||
|
// start processing events
|
||||||
|
m_eventThread = new CThread(new TMethodJob<CXWindowsSecondaryScreen>(
|
||||||
|
this, &CXWindowsSecondaryScreen::eventThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::close()
|
||||||
|
{
|
||||||
|
assert(m_client != NULL);
|
||||||
|
assert(m_eventThread != NULL);
|
||||||
|
|
||||||
|
// stop event thread
|
||||||
|
m_eventThread->cancel();
|
||||||
|
m_eventThread->wait();
|
||||||
|
delete m_eventThread;
|
||||||
|
m_eventThread = NULL;
|
||||||
|
|
||||||
|
// no longer impervious to server grabs
|
||||||
|
::XTestGrabControl(m_display, False);
|
||||||
|
|
||||||
|
// close the display
|
||||||
|
::XCloseDisplay(m_display);
|
||||||
|
m_display = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::enter(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
// warp to requested location
|
||||||
|
warpCursor(x, y);
|
||||||
|
|
||||||
|
// show cursor
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::leave()
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
// hide cursor
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeMotionEvent(m_display, m_screen, x, y, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onKeyDown(
|
||||||
|
KeyID key, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeKeyEvent(m_display, mapKey(key, mask), True, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onKeyRepeat(
|
||||||
|
KeyID, KeyModifierMask, SInt32)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onKeyUp(
|
||||||
|
KeyID key, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeKeyEvent(m_display, mapKey(key, mask), False, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onMouseDown(ButtonID button)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeButtonEvent(m_display, mapButton(button), True, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onMouseUp(ButtonID button)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeButtonEvent(m_display, mapButton(button), False, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onMouseMove(
|
||||||
|
SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
::XTestFakeMotionEvent(m_display, m_screen, x, y, CurrentTime);
|
||||||
|
::XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::onMouseWheel(SInt32)
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::getSize(
|
||||||
|
SInt32* width, SInt32* height) const
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
assert(width != NULL && height != NULL);
|
||||||
|
|
||||||
|
*width = m_w;
|
||||||
|
*height = m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
SInt32 CXWindowsSecondaryScreen::getJumpZoneSize() const
|
||||||
|
{
|
||||||
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsSecondaryScreen::eventThread(void*)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
// wait for and then get the next event
|
||||||
|
while (XPending(m_display) == 0) {
|
||||||
|
CThread::sleep(0.05);
|
||||||
|
}
|
||||||
|
XEvent xevent;
|
||||||
|
XNextEvent(m_display, &xevent);
|
||||||
|
|
||||||
|
// handle event
|
||||||
|
switch (xevent.type) {
|
||||||
|
case LeaveNotify:
|
||||||
|
// mouse moved out of window somehow. hide the window.
|
||||||
|
// ::XUnmapWindow(m_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;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyCode CXWindowsSecondaryScreen::mapKey(
|
||||||
|
KeyID id, KeyModifierMask /*mask*/) const
|
||||||
|
{
|
||||||
|
// FIXME -- use mask
|
||||||
|
return ::XKeysymToKeycode(m_display, static_cast<KeySym>(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CXWindowsSecondaryScreen::mapButton(
|
||||||
|
ButtonID id) const
|
||||||
|
{
|
||||||
|
// FIXME -- should use button mapping?
|
||||||
|
return static_cast<unsigned int>(id);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef CXWINDOWSSECONDARYSCREEN_H
|
||||||
|
#define CXWINDOWSSECONDARYSCREEN_H
|
||||||
|
|
||||||
|
#include "ISecondaryScreen.h"
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
class CThread;
|
||||||
|
|
||||||
|
class CXWindowsSecondaryScreen : 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 warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
|
virtual void onKeyDown(KeyID, KeyModifierMask);
|
||||||
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
||||||
|
virtual void onKeyUp(KeyID, KeyModifierMask);
|
||||||
|
virtual void onMouseDown(ButtonID);
|
||||||
|
virtual void onMouseUp(ButtonID);
|
||||||
|
virtual void onMouseMove(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
|
virtual void onMouseWheel(SInt32 delta);
|
||||||
|
virtual void getSize(SInt32* width, SInt32* height) const;
|
||||||
|
virtual SInt32 getJumpZoneSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void eventThread(void*);
|
||||||
|
KeyCode mapKey(KeyID, KeyModifierMask) const;
|
||||||
|
unsigned int mapButton(ButtonID button) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CClient* m_client;
|
||||||
|
CThread* m_eventThread;
|
||||||
|
Display* m_display;
|
||||||
|
int m_screen;
|
||||||
|
Window m_window;
|
||||||
|
SInt32 m_w, m_h;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "IInterface.h"
|
#include "IInterface.h"
|
||||||
#include "BasicTypes.h"
|
#include "BasicTypes.h"
|
||||||
|
#include "KeyTypes.h"
|
||||||
|
#include "MouseTypes.h"
|
||||||
|
|
||||||
class CClient;
|
class CClient;
|
||||||
//class IClipboard;
|
//class IClipboard;
|
||||||
|
|
|
@ -15,11 +15,13 @@ CXXFILES = \
|
||||||
COutputPacketStream.cpp \
|
COutputPacketStream.cpp \
|
||||||
CTCPSocketFactory.cpp \
|
CTCPSocketFactory.cpp \
|
||||||
CProtocolUtil.cpp \
|
CProtocolUtil.cpp \
|
||||||
|
CClient.cpp \
|
||||||
CServerProtocol.cpp \
|
CServerProtocol.cpp \
|
||||||
CServerProtocol1_0.cpp \
|
CServerProtocol1_0.cpp \
|
||||||
CScreenMap.cpp \
|
CScreenMap.cpp \
|
||||||
CServer.cpp \
|
CServer.cpp \
|
||||||
CXWindowsPrimaryScreen.cpp \
|
CXWindowsPrimaryScreen.cpp \
|
||||||
|
CXWindowsSecondaryScreen.cpp \
|
||||||
XSynergy.cpp \
|
XSynergy.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -37,8 +39,11 @@ LLDLIBS = \
|
||||||
-lpthread \
|
-lpthread \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
targets: server
|
targets: server client
|
||||||
|
|
||||||
server: $(OBJECTS) $(DEPLIBS)
|
server: server.o $(OBJECTS) $(DEPLIBS)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
$(CXX) $(CXXFLAGS) -o $@ server.o $(OBJECTS) $(LDFLAGS)
|
||||||
|
|
||||||
|
client: client.o $(OBJECTS) $(DEPLIBS)
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ client.o $(OBJECTS) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "CClient.h"
|
||||||
|
#include "CNetworkAddress.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "CServer.h"
|
||||||
|
#include "CScreenMap.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScreenMap screenMap;
|
||||||
|
screenMap.addScreen("primary");
|
||||||
|
screenMap.addScreen("ingrid");
|
||||||
|
screenMap.connect("primary", CScreenMap::kRight, "ingrid");
|
||||||
|
screenMap.connect("ingrid", CScreenMap::kLeft, "primary");
|
||||||
|
|
||||||
|
try {
|
||||||
|
CServer* server = new CServer();
|
||||||
|
server->setScreenMap(screenMap);
|
||||||
|
server->run();
|
||||||
|
}
|
||||||
|
catch (XBase& e) {
|
||||||
|
fprintf(stderr, "failed: %s\n", e.what());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue