checkpoint. merging win32 code. server on X is currently broken

and client probably is.
This commit is contained in:
crs
2001-11-19 00:33:36 +00:00
parent 51505783aa
commit 3f6146b15f
66 changed files with 5222 additions and 424 deletions

View File

@@ -0,0 +1,509 @@
#include "CMSWindowsPrimaryScreen.h"
#include "CServer.h"
#include "CSynergyHook.h"
#include "CThread.h"
#include "CLog.h"
#include <assert.h>
//
// CMSWindowsPrimaryScreen
//
CMSWindowsPrimaryScreen::CMSWindowsPrimaryScreen() :
m_server(NULL),
m_active(false),
m_window(NULL),
m_hookLibrary(NULL),
m_mark(0),
m_markReceived(0)
{
// do nothing
}
CMSWindowsPrimaryScreen::~CMSWindowsPrimaryScreen()
{
assert(m_window == NULL);
assert(m_hookLibrary == NULL);
}
static HWND s_debug = NULL;
static HWND s_debugLog = NULL;
static DWORD s_thread = 0;
static BOOL CALLBACK WINAPI debugProc(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
PostQuitMessage(0);
return TRUE;
}
return FALSE;
}
static void debugOutput(const char* msg)
{
if (s_thread != 0) {
const DWORD threadID = ::GetCurrentThreadId();
if (threadID != s_thread) {
GetDesktopWindow();
AttachThreadInput(threadID, s_thread, TRUE);
}
}
DWORD len = SendMessage(s_debugLog, WM_GETTEXTLENGTH, 0, 0);
if (len > 20000) {
SendMessage(s_debugLog, EM_SETSEL, -1, 0);
SendMessage(s_debugLog, WM_SETTEXT, FALSE, (LPARAM)(LPCTSTR)msg);
}
else {
SendMessage(s_debugLog, EM_SETSEL, -1, len);
SendMessage(s_debugLog, EM_REPLACESEL, FALSE, (LPARAM)(LPCTSTR)msg);
}
SendMessage(s_debugLog, EM_SCROLLCARET, 0, 0);
}
void CMSWindowsPrimaryScreen::run()
{
CLog::setOutputter(&debugOutput);
doRun();
CLog::setOutputter(NULL);
}
void CMSWindowsPrimaryScreen::stop()
{
doStop();
}
void CMSWindowsPrimaryScreen::open(CServer* server)
{
assert(m_server == NULL);
assert(server != NULL);
// set the server
m_server = server;
// open the display
openDisplay();
// enter the screen
doEnter();
}
void CMSWindowsPrimaryScreen::close()
{
assert(m_server != NULL);
// close the display
closeDisplay();
// done with server
m_server = NULL;
}
void CMSWindowsPrimaryScreen::enter(SInt32 x, SInt32 y)
{
log((CLOG_INFO "entering primary at %d,%d", x, y));
assert(m_active == true);
// do non-warp enter stuff
doEnter();
// warp to requested location
warpCursor(x, y);
}
void CMSWindowsPrimaryScreen::doEnter()
{
// set the zones that should cause a jump
SInt32 w, h;
getScreenSize(&w, &h);
SetZoneFunc setZone = (SetZoneFunc)GetProcAddress(
m_hookLibrary, "setZone");
setZone(m_server->getActivePrimarySides(), w, h, getJumpZoneSize());
// all messages prior to now are invalid
nextMark();
// not active anymore
m_active = false;
}
void CMSWindowsPrimaryScreen::leave()
{
log((CLOG_INFO "leaving primary"));
assert(m_active == false);
// all messages prior to now are invalid
nextMark();
// relay all mouse and keyboard events
SetRelayFunc setRelay = (SetRelayFunc)GetProcAddress(
m_hookLibrary, "setRelay");
setRelay();
// warp the mouse to the center of the screen
SInt32 w, h;
getScreenSize(&w, &h);
warpCursor(w >> 1, h >> 1);
// warp is also invalid
nextMark();
// local client now active
m_active = true;
}
void CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
{
SInt32 w, h;
getScreenSize(&w, &h);
mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
(DWORD)((65535.99 * x) / (w - 1)),
(DWORD)((65535.99 * y) / (h - 1)),
0, 0);
}
void CMSWindowsPrimaryScreen::setClipboard(
const IClipboard* /*clipboard*/)
{
assert(m_window != NULL);
// FIXME -- should we retry until we get it?
if (!OpenClipboard(m_window))
return;
if (EmptyClipboard()) {
log((CLOG_DEBUG "grabbed clipboard"));
// FIXME -- set the clipboard data
}
CloseClipboard();
}
void CMSWindowsPrimaryScreen::getSize(
SInt32* width, SInt32* height) const
{
getScreenSize(width, height);
}
SInt32 CMSWindowsPrimaryScreen::getJumpZoneSize() const
{
return 1;
}
void CMSWindowsPrimaryScreen::getClipboard(
IClipboard* clipboard) const
{
// FIXME -- put this in superclass?
// FIXME -- don't use CurrentTime
// getDisplayClipboard(clipboard, m_window, CurrentTime);
}
#include "resource.h" // FIXME
void CMSWindowsPrimaryScreen::onOpenDisplay()
{
assert(m_window == NULL);
assert(m_server != NULL);
// create debug dialog
s_thread = GetCurrentThreadId();;
s_debug = CreateDialog(getInstance(), MAKEINTRESOURCE(IDD_SYNERGY), NULL, &debugProc);
s_debugLog = ::GetDlgItem(s_debug, IDC_LOG);
CLog::setOutputter(&debugOutput);
ShowWindow(s_debug, SW_SHOWNORMAL);
// create the window
m_window = CreateWindowEx(WS_EX_TOPMOST |
WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,
(LPCTSTR)getClass(), "Synergy",
WS_POPUP,
0, 0, 1, 1, NULL, NULL,
getInstance(),
NULL);
// load the hook library
bool hooked = false;
m_hookLibrary = LoadLibrary("synrgyhk");
if (m_hookLibrary != NULL) {
// install input hooks
InstallFunc install = (InstallFunc)GetProcAddress(
m_hookLibrary, "install");
if (install != NULL) {
hooked = (install(m_window) != 0);
}
}
if (!hooked) {
DestroyWindow(m_window);
m_window = NULL;
// FIXME -- throw
}
// initialize marks
m_mark = 0;
m_markReceived = 0;
nextMark();
}
void CMSWindowsPrimaryScreen::onCloseDisplay()
{
assert(m_window != NULL);
// uninstall input hooks
UninstallFunc uninstall = (UninstallFunc)GetProcAddress(
m_hookLibrary, "uninstall");
if (uninstall != NULL) {
uninstall();
}
// done with hook library
FreeLibrary(m_hookLibrary);
m_hookLibrary = NULL;
// destroy window
DestroyWindow(m_window);
m_window = NULL;
CLog::setOutputter(NULL);
DestroyWindow(s_debug);
s_debug = NULL;
s_thread = 0;
}
bool CMSWindowsPrimaryScreen::onEvent(MSG* msg)
{
if (IsDialogMessage(s_debug, msg)) {
return true;
}
// handle event
switch (msg->message) {
// FIXME -- handle display changes
case WM_PAINT:
ValidateRect(m_window, NULL);
return true;
case SYNERGY_MSG_MARK:
m_markReceived = msg->wParam;
return true;
case SYNERGY_MSG_KEY:
// ignore if not at current mark
if (m_mark == m_markReceived) {
// FIXME -- vk code; key data
}
return true;
case SYNERGY_MSG_MOUSE_BUTTON:
// ignore if not at current mark
if (m_mark == m_markReceived) {
const ButtonID button = mapButton(msg->wParam);
switch (msg->wParam) {
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
log((CLOG_DEBUG "event: button press button=%d", button));
if (button != kButtonNone) {
m_server->onMouseDown(button);
}
break;
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
log((CLOG_DEBUG "event: button release button=%d", button));
if (button != kButtonNone) {
m_server->onMouseUp(button);
}
break;
}
}
return true;
case SYNERGY_MSG_MOUSE_MOVE:
// ignore if not at current mark
if (m_mark == m_markReceived) {
SInt32 x = (SInt32)msg->wParam;
SInt32 y = (SInt32)msg->lParam;
if (!m_active) {
log((CLOG_DEBUG "event: inactive move %d,%d", x, y));
m_server->onMouseMovePrimary(x, y);
}
else {
log((CLOG_DEBUG "event: active move %d,%d", x, y));
// get screen size
SInt32 w, h;
getScreenSize(&w, &h);
// get center pixel
w >>= 1;
h >>= 1;
// ignore and discard message if motion is to center of
// screen. those are caused by us warping the mouse.
if (x != w || y != h) {
// get mouse deltas
x -= w;
y -= h;
// warp mouse back to center
warpCursor(w, h);
// send motion
m_server->onMouseMoveSecondary(x, y);
}
}
}
return true;
}
return false;
/*
case WM_MOUSEMOVE: {
if (!m_active) {
// mouse entered a jump zone window
POINT p;
p.x = (short)LOWORD(msg.lParam);
p.y = (short)HIWORD(msg.lParam);
ClientToScreen(msg.hwnd, &p);
log((CLOG_DEBUG "event: WM_MOUSEMOVE %d,%d", p.x, p.y));
m_server->onMouseMovePrimary((SInt32)p.x, (SInt32)p.y);
}
break;
}
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNULL) {
m_server->onKeyDown(key, mask);
}
break;
}
// FIXME -- simulate key repeat. X sends press/release for
// repeat. must detect auto repeat and use kKeyRepeat.
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNULL) {
m_server->onKeyUp(key, mask);
}
break;
}
case ButtonPress: {
log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNULL) {
m_server->onMouseDown(button);
}
break;
}
case ButtonRelease: {
log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNULL) {
m_server->onMouseUp(button);
}
break;
}
case SelectionClear:
target->XXX(xevent.xselectionclear.);
break;
case SelectionNotify:
target->XXX(xevent.xselection.);
break;
case SelectionRequest:
target->XXX(xevent.xselectionrequest.);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
*/
}
void CMSWindowsPrimaryScreen::nextMark()
{
assert(m_window != NULL);
PostMessage(m_window, SYNERGY_MSG_MARK, ++m_mark, 0);
}
#if 0
bool CMSWindowsPrimaryScreen::keyboardHook(
int /*code*/, WPARAM wParam, LPARAM lParam)
{
if (m_active) {
// handle keyboard events
const KeyID key = mapKey(wParam, lParam);
if (key != kKeyNone) {
const KeyModifierMask modifiers = mapModifier(wParam, lParam);
if ((lParam & KF_UP) == 0) {
log((CLOG_DEBUG "event: key press key=%d", key));
m_server->onKeyDown(key, modifiers);
}
else {
log((CLOG_DEBUG "event: key release key=%d", key));
m_server->onKeyUp(key, modifiers);
}
return true;
}
}
return false;
}
#endif
KeyModifierMask CMSWindowsPrimaryScreen::mapModifier(
WPARAM keycode, LPARAM info) const
{
// FIXME -- should be configurable
KeyModifierMask mask = 0;
if (GetKeyState(VK_SHIFT) < 0)
mask |= KeyModifierShift;
if ((GetKeyState(VK_CAPITAL) & 1) != 0)
mask |= KeyModifierCapsLock;
if (GetKeyState(VK_CONTROL) < 0)
mask |= KeyModifierControl;
if (GetKeyState(VK_MENU) < 0)
mask |= KeyModifierAlt;
if ((GetKeyState(VK_NUMLOCK) & 1) != 0)
mask |= KeyModifierNumLock;
if (GetKeyState(VK_LWIN) < 0 || GetKeyState(VK_RWIN) < 0)
mask |= KeyModifierMeta;
if ((GetKeyState(VK_SCROLL) & 1) != 0)
mask |= KeyModifierScrollLock;
return mask;
}
KeyID CMSWindowsPrimaryScreen::mapKey(
WPARAM keycode, LPARAM info) const
{
// FIXME -- must convert to X keysyms
return keycode;
}
ButtonID CMSWindowsPrimaryScreen::mapButton(
WPARAM button) const
{
switch (button) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
return kButtonLeft;
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
return kButtonMiddle;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
return kButtonRight;
default:
return kButtonNone;
}
}

View File

@@ -0,0 +1,56 @@
#ifndef CMSWINDOWSPRIMARYSCREEN_H
#define CMSWINDOWSPRIMARYSCREEN_H
#include "KeyTypes.h"
#include "MouseTypes.h"
#include "CMSWindowsScreen.h"
#include "IPrimaryScreen.h"
class CMSWindowsPrimaryScreen : public CMSWindowsScreen, public IPrimaryScreen {
public:
typedef bool (CMSWindowsPrimaryScreen::*HookMethod)(int, WPARAM, LPARAM);
CMSWindowsPrimaryScreen();
virtual ~CMSWindowsPrimaryScreen();
// IPrimaryScreen overrides
virtual void run();
virtual void stop();
virtual void open(CServer*);
virtual void close();
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void leave();
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void setClipboard(const IClipboard*);
virtual void getSize(SInt32* width, SInt32* height) const;
virtual SInt32 getJumpZoneSize() const;
virtual void getClipboard(IClipboard*) const;
protected:
// CMSWindowsScreen overrides
virtual bool onEvent(MSG*);
virtual void onOpenDisplay();
virtual void onCloseDisplay();
private:
void doEnter();
void nextMark();
// bool keyboardHook(int, WPARAM, LPARAM);
// bool mouseHook(int, WPARAM, LPARAM);
KeyModifierMask mapModifier(WPARAM keycode, LPARAM info) const;
KeyID mapKey(WPARAM keycode, LPARAM info) const;
ButtonID mapButton(WPARAM button) const;
private:
CServer* m_server;
bool m_active;
HWND m_window;
HINSTANCE m_hookLibrary;
UInt32 m_mark;
UInt32 m_markReceived;
};
#endif

View File

@@ -9,6 +9,8 @@ class CScreenMap {
public:
enum EDirection { kLeft, kRight, kTop, kBottom,
kFirstDirection = kLeft, kLastDirection = kBottom };
enum EDirectionMask { kLeftMask = 1, kRightMask = 2,
kTopMask = 4, kBottomMask = 8 };
CScreenMap();
virtual ~CScreenMap();

View File

@@ -20,6 +20,14 @@
#include <assert.h>
#include <memory>
// hack to work around operator=() bug in STL in g++ prior to v3
#if defined(__GNUC__) && (__GNUC__ < 3)
#define assign(_dst, _src, _type) _dst.reset(_src)
#else
#define assign(_dst, _src, _type) _dst = std::auto_ptr<_type >(_src)
#endif
/* XXX
#include <stdlib.h>
#include <unistd.h>
@@ -33,8 +41,7 @@ else { wait(0); exit(1); }
// CServer
//
CServer::CServer() : m_done(&m_mutex, false),
m_primary(NULL),
CServer::CServer() : m_primary(NULL),
m_active(NULL),
m_primaryInfo(NULL)
{
@@ -61,31 +68,28 @@ void CServer::run()
// start listening for configuration connections
// FIXME
// wait until done
log((CLOG_DEBUG "waiting for quit"));
CLock lock(&m_mutex);
while (m_done == false) {
m_done.wait();
}
// handle events
log((CLOG_DEBUG "starting event handling"));
m_primary->run();
// clean up
log((CLOG_DEBUG "stopping server"));
closePrimaryScreen();
cleanupThreads();
closePrimaryScreen();
}
catch (XBase& e) {
log((CLOG_ERR "server error: %s\n", e.what()));
// clean up
closePrimaryScreen();
cleanupThreads();
closePrimaryScreen();
}
catch (...) {
log((CLOG_DEBUG "server shutdown"));
log((CLOG_DEBUG "unknown server error"));
// clean up
closePrimaryScreen();
cleanupThreads();
closePrimaryScreen();
throw;
}
}
@@ -107,6 +111,21 @@ void CServer::getScreenMap(CScreenMap* screenMap) const
*screenMap = m_screenMap;
}
UInt32 CServer::getActivePrimarySides() const
{
UInt32 sides = 0;
CLock lock(&m_mutex);
if (!m_screenMap.getNeighbor("primary", CScreenMap::kLeft).empty())
sides |= CScreenMap::kLeftMask;
if (!m_screenMap.getNeighbor("primary", CScreenMap::kRight).empty())
sides |= CScreenMap::kRightMask;
if (!m_screenMap.getNeighbor("primary", CScreenMap::kTop).empty())
sides |= CScreenMap::kTopMask;
if (!m_screenMap.getNeighbor("primary", CScreenMap::kBottom).empty())
sides |= CScreenMap::kBottomMask;
return sides;
}
void CServer::setInfo(const CString& client,
SInt32 w, SInt32 h, SInt32 zoneSize)
{
@@ -206,7 +225,7 @@ void CServer::onMouseUp(ButtonID id)
}
}
void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
bool CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
{
log((CLOG_DEBUG "onMouseMovePrimary %d,%d", x, y));
@@ -216,7 +235,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
// ignore if mouse is locked to screen
if (isLockedToScreen()) {
return;
return false;
}
// see if we should change screens
@@ -243,7 +262,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
}
else {
// still on local screen
return;
return false;
}
// get jump destination
@@ -251,7 +270,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
// if no screen in jump direction then ignore the move
if (newScreen == NULL) {
return;
return false;
}
// remap position to account for resolution differences
@@ -259,6 +278,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
// switch screen
switchScreen(newScreen, x, y);
return true;
}
void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
@@ -365,7 +385,11 @@ bool CServer::isLockedToScreen() const
return false;
}
#if defined(CONFIG_PLATFORM_WIN32)
#include "CMSWindowsClipboard.h" // FIXME
#elif defined(CONFIG_PLATFORM_UNIX)
#include "CXWindowsClipboard.h" // FIXME
#endif
void CServer::switchScreen(CScreenInfo* dst,
SInt32 x, SInt32 y)
{
@@ -384,7 +408,11 @@ void CServer::switchScreen(CScreenInfo* dst,
m_primary->leave();
// FIXME -- testing
#if defined(CONFIG_PLATFORM_WIN32)
CMSWindowsClipboard clipboard;
#elif defined(CONFIG_PLATFORM_UNIX)
CXWindowsClipboard clipboard;
#endif
m_primary->getClipboard(&clipboard);
}
else {
@@ -610,8 +638,8 @@ void CServer::acceptClients(void*)
std::auto_ptr<IListenSocket> listen;
try {
// create socket listener
// listen.reset(m_socketFactory->createListen());
listen.reset(new CTCPListenSocket); // FIXME
// listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen());
assign(listen, new CTCPListenSocket, IListenSocket); // FIXME
// bind to the desired port. keep retrying if we can't bind
// the address immediately.
@@ -689,8 +717,8 @@ void CServer::handshakeClient(void* vsocket)
}
// attach the packetizing filters
input.reset(new CInputPacketStream(srcInput, own));
output.reset(new COutputPacketStream(srcOutput, own));
assign(input, new CInputPacketStream(srcInput, own), IInputStream);
assign(output, new COutputPacketStream(srcOutput, own), IOutputStream);
std::auto_ptr<IServerProtocol> protocol;
std::auto_ptr<CConnectionNote> connectedNote;
@@ -730,12 +758,13 @@ void CServer::handshakeClient(void* vsocket)
// 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,
this, name, input.get(), output.get()));
assign(protocol, CServerProtocol::create(major, minor,
this, name, input.get(), output.get()),
IServerProtocol);
// client is now pending
connectedNote.reset(new CConnectionNote(this,
name, protocol.get()));
assign(connectedNote, new CConnectionNote(this,
name, protocol.get()), CConnectionNote);
// ask and wait for the client's info
log((CLOG_DEBUG "waiting for info for client %s", name.c_str()));
@@ -766,20 +795,26 @@ void CServer::handshakeClient(void* vsocket)
void CServer::quit()
{
CLock lock(&m_mutex);
m_done = true;
m_done.broadcast();
m_primary->stop();
}
// FIXME -- use factory to create screen
#if defined(CONFIG_PLATFORM_WIN32)
#include "CMSWindowsPrimaryScreen.h"
#elif defined(CONFIG_PLATFORM_UNIX)
#include "CXWindowsPrimaryScreen.h"
#endif
void CServer::openPrimaryScreen()
{
assert(m_primary == NULL);
// open screen
log((CLOG_DEBUG "creating primary screen"));
#if defined(CONFIG_PLATFORM_WIN32)
m_primary = new CMSWindowsPrimaryScreen;
#elif defined(CONFIG_PLATFORM_UNIX)
m_primary = new CXWindowsPrimaryScreen;
#endif
log((CLOG_DEBUG "opening primary screen"));
m_primary->open(this);
@@ -828,8 +863,9 @@ void CServer::removeCleanupThread(const CThread& thread)
for (CThreadList::iterator index = m_cleanupList.begin();
index != m_cleanupList.end(); ++index) {
if (**index == thread) {
CThread* thread = *index;
m_cleanupList.erase(index);
delete *index;
delete thread;
return;
}
}
@@ -877,7 +913,7 @@ void CServer::removeConnection(const CString& name)
assert(index != m_screens.end());
// if this is active screen then we have to jump off of it
if (m_active == index->second) {
if (m_active == index->second && m_active != m_primaryInfo) {
// record new position (center of primary screen)
m_x = m_primaryInfo->m_width >> 1;
m_y = m_primaryInfo->m_height >> 1;

View File

@@ -4,7 +4,6 @@
#include "KeyTypes.h"
#include "MouseTypes.h"
#include "CScreenMap.h"
#include "CCondVar.h"
#include "CMutex.h"
#include "CString.h"
#include "XBase.h"
@@ -24,18 +23,23 @@ class CServer {
// manipulators
// start the server. does not return until quit() is called.
void run();
// tell server to exit gracefully
void quit();
// update screen map
void setScreenMap(const CScreenMap&);
// handle events on server's screen
// handle events on server's screen. onMouseMovePrimary() returns
// true iff the mouse enters a jump zone and jumps.
void onKeyDown(KeyID, KeyModifierMask);
void onKeyUp(KeyID, KeyModifierMask);
void onKeyRepeat(KeyID, KeyModifierMask);
void onMouseDown(ButtonID);
void onMouseUp(ButtonID);
void onMouseMovePrimary(SInt32 x, SInt32 y);
bool onMouseMovePrimary(SInt32 x, SInt32 y);
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
void onMouseWheel(SInt32 delta);
@@ -50,9 +54,11 @@ class CServer {
// get the current screen map
void getScreenMap(CScreenMap*) const;
// get the sides of the primary screen that have neighbors
UInt32 getActivePrimarySides() const;
protected:
bool onCommandKey(KeyID, KeyModifierMask, bool down);
void quit();
private:
class CCleanupNote {
@@ -137,7 +143,6 @@ class CServer {
typedef std::map<CString, CScreenInfo*> CScreenList;
CMutex m_mutex;
CCondVar<bool> m_done;
double m_bindTimeout;

242
server/CSynergyHook.cpp Normal file
View File

@@ -0,0 +1,242 @@
#include "CSynergyHook.h"
#include "CScreenMap.h"
#include <assert.h>
//
// globals
//
#pragma comment(linker, "-section:shared,rws")
#pragma data_seg("shared")
// all data in this shared section *must* be initialized
static HINSTANCE g_hinstance = NULL;
static DWORD g_process = NULL;
static HWND g_hwnd = NULL;
static HHOOK g_keyboard = NULL;
static HHOOK g_mouse = NULL;
static bool g_relay = false;
static SInt32 g_zoneSize = 0;
static UInt32 g_zoneSides = 0;
static SInt32 g_wScreen = 0;
static SInt32 g_hScreen = 0;
static HCURSOR g_cursor = NULL;
static DWORD g_cursorThread = 0;
#pragma data_seg()
//
// internal functions
//
static void hideCursor(DWORD thread)
{
// we should be running the context of the window who's cursor
// we want to hide so we shouldn't have to attach thread input.
g_cursor = GetCursor();
g_cursorThread = thread;
SetCursor(NULL);
}
static void restoreCursor()
{
// restore the show cursor in the window we hid it last
if (g_cursor != NULL && g_cursorThread != 0) {
DWORD myThread = GetCurrentThreadId();
if (myThread != g_cursorThread)
AttachThreadInput(myThread, g_cursorThread, TRUE);
SetCursor(g_cursor);
if (myThread != g_cursorThread)
AttachThreadInput(myThread, g_cursorThread, FALSE);
}
g_cursor = NULL;
g_cursorThread = 0;
}
static LRESULT CALLBACK keyboardHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code >= 0) {
// FIXME
}
return CallNextHookEx(g_keyboard, code, wParam, lParam);
}
static LRESULT CALLBACK mouseHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code >= 0) {
if (g_relay) {
switch (wParam) {
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
PostMessage(g_hwnd, SYNERGY_MSG_MOUSE_BUTTON, wParam, 0);
return 1;
case WM_MOUSEMOVE: {
const MOUSEHOOKSTRUCT* info = (const MOUSEHOOKSTRUCT*)lParam;
SInt32 x = (SInt32)info->pt.x;
SInt32 y = (SInt32)info->pt.y;
// we want the cursor to be hidden at all times so we
// hide the cursor on whatever window has it. but then
// we have to show the cursor whenever we leave that
// window (or at some later time before we stop relaying).
// so check the window with the cursor. if it's not the
// same window that had it before then show the cursor
// in the last window and hide it in this window.
DWORD thread = GetWindowThreadProcessId(info->hwnd, NULL);
if (thread != g_cursorThread) {
restoreCursor();
hideCursor(thread);
}
// relay the motion
PostMessage(g_hwnd, SYNERGY_MSG_MOUSE_MOVE, x, y);
return 1;
}
}
}
else {
// check for mouse inside jump zone
bool inside = false;
const MOUSEHOOKSTRUCT* info = (const MOUSEHOOKSTRUCT*)lParam;
SInt32 x = (SInt32)info->pt.x;
SInt32 y = (SInt32)info->pt.y;
if (!inside && (g_zoneSides & CScreenMap::kLeftMask) != 0) {
inside = (x < g_zoneSize);
}
if (!inside && (g_zoneSides & CScreenMap::kRightMask) != 0) {
inside = (x >= g_wScreen - g_zoneSize);
}
if (!inside && (g_zoneSides & CScreenMap::kTopMask) != 0) {
inside = (y < g_zoneSize);
}
if (!inside && (g_zoneSides & CScreenMap::kBottomMask) != 0) {
inside = (y >= g_hScreen - g_zoneSize);
}
// if inside then eat event and notify our window
if (inside) {
restoreCursor();
PostMessage(g_hwnd, SYNERGY_MSG_MOUSE_MOVE, x, y);
return 1;
}
}
}
return CallNextHookEx(g_mouse, code, wParam, lParam);
}
//
// external functions
//
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
{
if (reason == DLL_PROCESS_ATTACH) {
if (g_hinstance == NULL) {
g_hinstance = instance;
g_process = GetCurrentProcessId();
}
}
else if (reason == DLL_PROCESS_DETACH) {
if (g_process == GetCurrentProcessId()) {
if (g_keyboard != NULL || g_mouse != NULL) {
uninstall();
}
g_process = NULL;
}
}
return TRUE;
}
extern "C" {
int install(HWND hwnd)
{
assert(g_hinstance != NULL);
assert(g_keyboard == NULL);
assert(g_mouse == NULL);
// save window
g_hwnd = hwnd;
// set defaults
g_relay = false;
g_zoneSize = 0;
g_zoneSides = 0;
g_wScreen = 0;
g_hScreen = 0;
g_cursor = NULL;
g_cursorThread = 0;
// install keyboard hook
g_keyboard = SetWindowsHookEx(WH_KEYBOARD,
&keyboardHook,
g_hinstance,
0);
if (g_keyboard == NULL) {
g_hwnd = NULL;
return 0;
}
// install mouse hook
g_mouse = SetWindowsHookEx(WH_MOUSE,
&mouseHook,
g_hinstance,
0);
if (g_mouse == NULL) {
// uninstall keyboard hook before failing
UnhookWindowsHookEx(g_keyboard);
g_keyboard = NULL;
g_hwnd = NULL;
return 0;
}
return 1;
}
int uninstall(void)
{
assert(g_keyboard != NULL);
assert(g_mouse != NULL);
// uninstall hooks
UnhookWindowsHookEx(g_keyboard);
UnhookWindowsHookEx(g_mouse);
g_keyboard = NULL;
g_mouse = NULL;
g_hwnd = NULL;
// show the cursor
restoreCursor();
return 1;
}
void setZone(UInt32 sides,
SInt32 w, SInt32 h, SInt32 jumpZoneSize)
{
g_zoneSize = jumpZoneSize;
g_zoneSides = sides;
g_wScreen = w;
g_hScreen = h;
g_relay = false;
restoreCursor();
}
void setRelay(void)
{
g_relay = true;
g_zoneSize = 0;
g_zoneSides = 0;
g_wScreen = 0;
g_hScreen = 0;
}
}

37
server/CSynergyHook.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef CSYNERGYHOOK_H
#define CSYNERGYHOOK_H
#include "BasicTypes.h"
#include <windows.h>
#if defined(CONFIG_PLATFORM_WIN32)
#if defined(SYNRGYHK_EXPORTS)
#define CSYNERGYHOOK_API __declspec(dllexport)
#else
#define CSYNERGYHOOK_API __declspec(dllimport)
#endif
#else
#define CSYNERGYHOOK_API
#endif
#define SYNERGY_MSG_MARK WM_APP + 0x0001 // mark id; <unused>
#define SYNERGY_MSG_KEY WM_APP + 0x0002 // vk code; key data
#define SYNERGY_MSG_MOUSE_BUTTON WM_APP + 0x0003 // button msg; <unused>
#define SYNERGY_MSG_MOUSE_MOVE WM_APP + 0x0004 // x; y
typedef int (*InstallFunc)(HWND);
typedef int (*UninstallFunc)(void);
typedef void (*SetZoneFunc)(UInt32, SInt32, SInt32, SInt32);
typedef void (*SetRelayFunc)(void);
extern "C" {
CSYNERGYHOOK_API int install(HWND);
CSYNERGYHOOK_API int uninstall(void);
CSYNERGYHOOK_API void setZone(UInt32 sides,
SInt32 w, SInt32 h, SInt32 jumpZoneSize);
CSYNERGYHOOK_API void setRelay(void);
}
#endif

View File

@@ -19,7 +19,124 @@ CXWindowsPrimaryScreen::CXWindowsPrimaryScreen() :
CXWindowsPrimaryScreen::~CXWindowsPrimaryScreen()
{
assert(m_window == None);
assert(m_window == None);
}
void CXWindowsPrimaryScreen::run()
{
for (;;) {
// wait for and get the next event
XEvent xevent;
if (!getEvent(&xevent)) {
break;
}
// handle event
switch (xevent.type) {
case CreateNotify: {
// select events on new window
CDisplayLock display(this);
selectEvents(display, xevent.xcreatewindow.window);
break;
}
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNone) {
m_server->onKeyDown(key, mask);
}
break;
}
// FIXME -- simulate key repeat. X sends press/release for
// repeat. must detect auto repeat and use kKeyRepeat.
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNone) {
m_server->onKeyUp(key, mask);
}
break;
}
case ButtonPress: {
log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNone) {
m_server->onMouseDown(button);
}
break;
}
case ButtonRelease: {
log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNone) {
m_server->onMouseUp(button);
}
break;
}
case MotionNotify: {
log((CLOG_DEBUG "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root));
SInt32 x, y;
if (!m_active) {
x = xevent.xmotion.x_root;
y = xevent.xmotion.y_root;
m_server->onMouseMovePrimary(x, y);
}
else {
// FIXME -- slurp up all remaining motion events?
// probably not since key strokes may go to wrong place.
// get mouse deltas
{
CDisplayLock display(this);
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int mask;
if (!XQueryPointer(display, m_window, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &mask))
break;
// compute position of center of window
SInt32 w, h;
getScreenSize(&w, &h);
x = xRoot - (w >> 1);
y = yRoot - (h >> 1);
// warp mouse back to center
warpCursorNoLock(display, w >> 1, h >> 1);
}
m_server->onMouseMoveSecondary(x, y);
}
break;
}
/*
case SelectionClear:
target->XXX(xevent.xselectionclear.);
break;
case SelectionNotify:
target->XXX(xevent.xselection.);
break;
case SelectionRequest:
target->XXX(xevent.xselectionrequest.);
break;
*/
}
}
}
void CXWindowsPrimaryScreen::stop()
{
doStop();
}
void CXWindowsPrimaryScreen::open(CServer* server)
@@ -251,116 +368,6 @@ void CXWindowsPrimaryScreen::selectEvents(
}
}
void CXWindowsPrimaryScreen::eventThread(void*)
{
for (;;) {
// wait for and get the next event
XEvent xevent;
getEvent(&xevent);
// handle event
switch (xevent.type) {
case CreateNotify: {
// select events on new window
CDisplayLock display(this);
selectEvents(display, xevent.xcreatewindow.window);
break;
}
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNone) {
m_server->onKeyDown(key, mask);
}
break;
}
// FIXME -- simulate key repeat. X sends press/release for
// repeat. must detect auto repeat and use kKeyRepeat.
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 KeyID key = mapKey(xevent.xkey.keycode, mask);
if (key != kKeyNone) {
m_server->onKeyUp(key, mask);
}
break;
}
case ButtonPress: {
log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNone) {
m_server->onMouseDown(button);
}
break;
}
case ButtonRelease: {
log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button));
const ButtonID button = mapButton(xevent.xbutton.button);
if (button != kButtonNone) {
m_server->onMouseUp(button);
}
break;
}
case MotionNotify: {
log((CLOG_DEBUG "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root));
SInt32 x, y;
if (!m_active) {
x = xevent.xmotion.x_root;
y = xevent.xmotion.y_root;
m_server->onMouseMovePrimary(x, y);
}
else {
// FIXME -- slurp up all remaining motion events?
// probably not since key strokes may go to wrong place.
// get mouse deltas
{
CDisplayLock display(this);
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int mask;
if (!XQueryPointer(display, m_window, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &mask))
break;
// compute position of center of window
SInt32 w, h;
getScreenSize(&w, &h);
x = xRoot - (w >> 1);
y = yRoot - (h >> 1);
// warp mouse back to center
warpCursorNoLock(display, w >> 1, h >> 1);
}
m_server->onMouseMoveSecondary(x, y);
}
break;
}
/*
case SelectionClear:
target->XXX(xevent.xselectionclear.);
break;
case SelectionNotify:
target->XXX(xevent.xselection.);
break;
case SelectionRequest:
target->XXX(xevent.xselectionrequest.);
break;
*/
}
}
}
KeyModifierMask CXWindowsPrimaryScreen::mapModifier(
unsigned int state) const
{

View File

@@ -12,6 +12,8 @@ class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
virtual ~CXWindowsPrimaryScreen();
// IPrimaryScreen overrides
virtual void run();
virtual void stop();
virtual void open(CServer*);
virtual void close();
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
@@ -26,7 +28,6 @@ class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
// CXWindowsScreen overrides
virtual void onOpenDisplay();
virtual void onCloseDisplay();
virtual void eventThread(void*);
private:
void selectEvents(Display*, Window) const;

View File

@@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
#
# target file
#
TARGET = server
TARGETS = server
#
# source files
@@ -40,8 +40,8 @@ LLDLIBS = \
-lpthread \
$(NULL)
targets: $(TARGET)
targets: $(TARGETS)
$(TARGET): $(OBJECTS) $(DEPLIBS)
$(TARGETS): $(OBJECTS) $(DEPLIBS)
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)

63
server/makehook.dsp Normal file
View File

@@ -0,0 +1,63 @@
# Microsoft Developer Studio Project File - Name="makehook" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Generic Project" 0x010a
CFG=makehook - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "makehook.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "makehook.mak" CFG="makehook - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "makehook - Win32 Release" (based on "Win32 (x86) Generic Project")
!MESSAGE "makehook - Win32 Debug" (based on "Win32 (x86) Generic Project")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
MTL=midl.exe
!IF "$(CFG)" == "makehook - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "makehook___Win32_Release"
# PROP BASE Intermediate_Dir "makehook___Win32_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "makehook - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "makehook___Win32_Debug"
# PROP BASE Intermediate_Dir "makehook___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
!ENDIF
# Begin Target
# Name "makehook - Win32 Release"
# Name "makehook - Win32 Debug"
# End Target
# End Project

17
server/resource.h Normal file
View File

@@ -0,0 +1,17 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by server.rc
//
#define IDD_SYNERGY 101
#define IDC_LOG 1000
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -1,16 +1,12 @@
#include "CServer.h"
#include "CScreenMap.h"
#include "CThread.h"
#include <stdio.h>
#include "CNetwork.h"
int main(int argc, char** argv)
void realMain()
{
CThread::init();
if (argc != 1) {
fprintf(stderr, "usage: %s\n", argv[0]);
return 1;
}
CNetwork::init();
CScreenMap screenMap;
screenMap.addScreen("primary");
@@ -18,15 +14,66 @@ int main(int argc, char** argv)
screenMap.connect("primary", CScreenMap::kRight, "ingrid");
screenMap.connect("ingrid", CScreenMap::kLeft, "primary");
CServer* server = NULL;
try {
CServer* server = new CServer();
server = new CServer();
server->setScreenMap(screenMap);
server->run();
delete server;
CNetwork::cleanup();
}
catch (...) {
delete server;
CNetwork::cleanup();
throw;
}
}
#if defined(CONFIG_PLATFORM_WIN32)
#include "CMSWindowsScreen.h"
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
{
CMSWindowsScreen::init(instance);
if (__argc != 1) {
CString msg = "no arguments allowed. exiting.";
MessageBox(NULL, msg.c_str(), "error", MB_OK | MB_ICONERROR);
return 1;
}
try {
realMain();
return 0;
}
catch (XBase& e) {
CString msg = "failed: ";
msg += e.what();
MessageBox(NULL, msg.c_str(), "error", MB_OK | MB_ICONERROR);
return 1;
}
}
#else
#include <stdio.h>
int main(int argc, char** argv)
{
if (argc != 1) {
fprintf(stderr, "usage: %s\n", argv[0]);
return 1;
}
try {
realMain();
return 0;
}
catch (XBase& e) {
fprintf(stderr, "failed: %s\n", e.what());
return 1;
}
return 0;
}
#endif

155
server/server.dsp Normal file
View File

@@ -0,0 +1,155 @@
# Microsoft Developer Studio Project File - Name="server" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=server - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "server.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "server.mak" CFG="server - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "server - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "server - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "millpond"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "server - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "server - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "server - Win32 Release"
# Name "server - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.cpp
# End Source File
# Begin Source File
SOURCE=.\CScreenMap.cpp
# End Source File
# Begin Source File
SOURCE=.\CServer.cpp
# End Source File
# Begin Source File
SOURCE=.\CServerProtocol.cpp
# End Source File
# Begin Source File
SOURCE=.\CServerProtocol1_0.cpp
# End Source File
# Begin Source File
SOURCE=.\server.cpp
# End Source File
# Begin Source File
SOURCE=.\server.rc
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.h
# End Source File
# Begin Source File
SOURCE=.\CScreenMap.h
# End Source File
# Begin Source File
SOURCE=.\CServer.h
# End Source File
# Begin Source File
SOURCE=.\CServerProtocol.h
# End Source File
# Begin Source File
SOURCE=.\CServerProtocol1_0.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

97
server/server.rc Normal file
View File

@@ -0,0 +1,97 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SYNERGY DIALOG DISCARDABLE 0, 0, 329, 158
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Synergy"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_LOG,7,7,315,144,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_SYNERGY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 322
TOPMARGIN, 7
BOTTOMMARGIN, 151
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

111
server/synrgyhk.dsp Normal file
View File

@@ -0,0 +1,111 @@
# Microsoft Developer Studio Project File - Name="synrgyhk" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=synrgyhk - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "synrgyhk.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "synrgyhk.mak" CFG="synrgyhk - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "synrgyhk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "synrgyhk - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "millpond"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "synrgyhk - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "synrgyhk___Win32_Release"
# PROP BASE Intermediate_Dir "synrgyhk___Win32_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SYNRGYHK_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SYNRGYHK_EXPORTS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
!ELSEIF "$(CFG)" == "synrgyhk - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "synrgyhk___Win32_Debug"
# PROP BASE Intermediate_Dir "synrgyhk___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SYNRGYHK_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SYNRGYHK_EXPORTS" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "synrgyhk - Win32 Release"
# Name "synrgyhk - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CSynergyHook.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CSynergyHook.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project