checkpoint. merging win32 code. server on X is currently broken
and client probably is.
This commit is contained in:
parent
51505783aa
commit
3f6146b15f
|
@ -13,7 +13,7 @@ RMR = /bin/rm -rf
|
|||
#
|
||||
# compiler options
|
||||
#
|
||||
GCXXDEFS = -D_XOPEN_SOURCE=500
|
||||
GCXXDEFS = -D_XOPEN_SOURCE=600
|
||||
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
||||
GCXXOPTS = -Wall -W -fexceptions
|
||||
CXXOPTIMIZER = -g
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# Microsoft Developer Studio Project File - Name="all" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Generic Project" 0x010a
|
||||
|
||||
CFG=all - 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 "all.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 "all.mak" CFG="all - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "all - Win32 Release" (based on "Win32 (x86) Generic Project")
|
||||
!MESSAGE "all - Win32 Debug" (based on "Win32 (x86) Generic Project")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
MTL=midl.exe
|
||||
|
||||
!IF "$(CFG)" == "all - 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 ""
|
||||
|
||||
!ELSEIF "$(CFG)" == "all - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "all___Win32_Debug"
|
||||
# PROP BASE Intermediate_Dir "all___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 "all - Win32 Release"
|
||||
# Name "all - Win32 Debug"
|
||||
# End Target
|
||||
# End Project
|
|
@ -37,7 +37,29 @@ typedef uint64_t UInt64;
|
|||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
|
||||
// FIXME
|
||||
// use VC++ extensions if available
|
||||
#if defined(_MSC_VER)
|
||||
typedef signed __int8 SInt8;
|
||||
typedef signed __int16 SInt16;
|
||||
typedef signed __int32 SInt32;
|
||||
typedef signed __int64 SInt64;
|
||||
|
||||
typedef unsigned __int8 UInt8;
|
||||
typedef unsigned __int16 UInt16;
|
||||
typedef unsigned __int32 UInt32;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef signed char SInt8;
|
||||
typedef short SInt16;
|
||||
typedef int SInt32;
|
||||
typedef long long SInt64;
|
||||
|
||||
typedef unsigned char UInt8;
|
||||
typedef unsigned short UInt16;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned long long UInt64;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_PLATFORM_WIN32
|
||||
|
||||
|
|
|
@ -1,14 +1,37 @@
|
|||
#include "CLog.h"
|
||||
#include "BasicTypes.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
#include <windows.h>
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
static int g_maxPriority = -1;
|
||||
static const char* g_priority[] = {
|
||||
"FATAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
};
|
||||
static const int g_numPriority = (int)(sizeof(g_priority) /
|
||||
sizeof(g_priority[0]));
|
||||
static const int g_maxPriorityLength = 7; // length of longest string
|
||||
static const int g_prioritySuffixLength = 2;
|
||||
static const int g_priorityPad = g_maxPriorityLength +
|
||||
g_prioritySuffixLength;
|
||||
static const int g_newlineLength = 2;
|
||||
|
||||
//
|
||||
// CLog
|
||||
//
|
||||
|
||||
static int g_maxPriority = -1;
|
||||
CLog::Outputter CLog::s_outputter = NULL;
|
||||
|
||||
void CLog::print(const char* fmt, ...)
|
||||
{
|
||||
|
@ -19,11 +42,14 @@ void CLog::print(const char* fmt, ...)
|
|||
fmt += 3;
|
||||
}
|
||||
|
||||
// compute prefix padding length
|
||||
int pad = g_priorityPad;
|
||||
|
||||
// print to buffer
|
||||
char stack[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char* buffer = vsprint(0, stack,
|
||||
char* buffer = vsprint(pad, stack,
|
||||
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
|
@ -48,17 +74,19 @@ void CLog::printt(const char* file, int line,
|
|||
// compute prefix padding length
|
||||
char stack[1024];
|
||||
sprintf(stack, "%d", line);
|
||||
int pad = strlen(file) + 1 + strlen(stack) + 1 + 1;
|
||||
int pad = strlen(file) + 1 /* comma */ +
|
||||
strlen(stack) + 1 /* colon */ + 1 /* space */ +
|
||||
g_priorityPad;
|
||||
|
||||
// print to buffer
|
||||
// print to buffer, leaving space for a newline at the end
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char* buffer = vsprint(pad, stack,
|
||||
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
// print the prefix to the buffer
|
||||
sprintf(buffer, "%s,%d:", file, line);
|
||||
// print the prefix to the buffer. leave space for priority label.
|
||||
sprintf(buffer + g_priorityPad, "%s,%d:", file, line);
|
||||
buffer[pad - 1] = ' ';
|
||||
|
||||
// output buffer
|
||||
|
@ -69,35 +97,51 @@ void CLog::printt(const char* file, int line,
|
|||
delete[] buffer;
|
||||
}
|
||||
|
||||
void CLog::output(int priority, const char* msg)
|
||||
void CLog::setOutputter(Outputter outputter)
|
||||
{
|
||||
static const char* s_priority[] = {
|
||||
"FATAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
};
|
||||
static const int s_numPriority = (int)(sizeof(s_priority) /
|
||||
sizeof(s_priority[0]));
|
||||
assert(priority >= 0 && priority < s_numPriority);
|
||||
s_outputter = outputter;
|
||||
}
|
||||
|
||||
void CLog::output(int priority, char* msg)
|
||||
{
|
||||
assert(priority >= 0 && priority < g_numPriority);
|
||||
assert(msg != 0);
|
||||
|
||||
if (g_maxPriority == -1) {
|
||||
g_maxPriority = s_numPriority - 1;
|
||||
g_maxPriority = g_numPriority - 1;
|
||||
const char* priEnv = getenv("SYN_LOG_PRI");
|
||||
if (priEnv != NULL) {
|
||||
for (int i = 0; i < s_numPriority; ++i)
|
||||
if (strcmp(priEnv, s_priority[i]) == 0) {
|
||||
for (int i = 0; i < g_numPriority; ++i)
|
||||
if (strcmp(priEnv, g_priority[i]) == 0) {
|
||||
g_maxPriority = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priority <= g_maxPriority)
|
||||
fprintf(stderr, "%s: %s\n", s_priority[priority], msg);
|
||||
if (priority <= g_maxPriority) {
|
||||
// insert priority label
|
||||
int n = strlen(g_priority[priority]);
|
||||
sprintf(msg + g_maxPriorityLength - n, "%s:", g_priority[priority]);
|
||||
msg[g_maxPriorityLength + 1] = ' ';
|
||||
|
||||
// put a newline at the end
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
strcat(msg + g_priorityPad, "\r\n");
|
||||
#else
|
||||
strcat(msg + g_priorityPad, "\n");
|
||||
#endif
|
||||
|
||||
// print it
|
||||
if (s_outputter)
|
||||
s_outputter(msg + g_maxPriorityLength - n);
|
||||
else
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
OutputDebugString(msg + g_maxPriorityLength - n);
|
||||
#else
|
||||
fprintf(stderr, "%s", msg + g_maxPriorityLength - n);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
char* CLog::vsprint(int pad, char* buffer, int len,
|
||||
|
@ -109,7 +153,7 @@ char* CLog::vsprint(int pad, char* buffer, int len,
|
|||
int n;
|
||||
if (len >= pad) {
|
||||
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
||||
if (n != -1 && n <= len - pad)
|
||||
if (n != -1 && n <= len - pad + g_newlineLength)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -120,7 +164,7 @@ char* CLog::vsprint(int pad, char* buffer, int len,
|
|||
len *= 2;
|
||||
buffer = new char[len + pad];
|
||||
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
||||
} while (n == -1 || n > len - pad);
|
||||
} while (n == -1 || n > len - pad + g_newlineLength);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,19 @@
|
|||
|
||||
class CLog {
|
||||
public:
|
||||
typedef void (*Outputter)(const char*);
|
||||
|
||||
static void print(const char*, ...);
|
||||
static void printt(const char* file, int line, const char*, ...);
|
||||
static void setOutputter(Outputter);
|
||||
|
||||
private:
|
||||
static void output(int priority, const char* msg);
|
||||
static void output(int priority, char* msg);
|
||||
static char* vsprint(int pad, char*, int len, const char*, va_list);
|
||||
static int nprint(const char*, va_list);
|
||||
|
||||
private:
|
||||
static Outputter s_outputter;
|
||||
};
|
||||
|
||||
#if defined(NOLOGGING)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
// win32 wants a const char* argument to std::exception c'tor
|
||||
#if CONFIG_PLATFORM_WIN32
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
#define STDEXCEPTARG ""
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
# Microsoft Developer Studio Project File - Name="base" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=base - 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 "base.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 "base.mak" CFG="base - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "base - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "base - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "base - 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 "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "base - 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 "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "base - Win32 Release"
|
||||
# Name "base - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CFunctionJob.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CLog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CStopwatch.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XBase.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BasicTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CFunctionJob.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CLog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CStopwatch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IInterface.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IJob.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TMethodJob.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XBase.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -15,10 +15,14 @@
|
|||
#define CONFIG_TYPES_X11
|
||||
#define CONFIG_PTHREADS
|
||||
|
||||
#elif defined(_WINDOWS) && defined(WIN32)
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#define CONFIG_PLATFORM_WIN32
|
||||
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#error unsupported platform
|
||||
|
|
|
@ -9,8 +9,17 @@
|
|||
#include "XSynergy.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CLog.h"
|
||||
#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
|
||||
|
||||
|
||||
//
|
||||
// CClient
|
||||
//
|
||||
|
@ -31,13 +40,50 @@ CClient::~CClient()
|
|||
|
||||
void CClient::run(const CNetworkAddress& serverAddress)
|
||||
{
|
||||
CThread* thread;
|
||||
try {
|
||||
log((CLOG_NOTE "starting client"));
|
||||
|
||||
// connect to secondary screen
|
||||
openSecondaryScreen();
|
||||
|
||||
// start server interactions
|
||||
m_serverAddress = &serverAddress;
|
||||
CThread thread(new TMethodJob<CClient>(this, &CClient::runSession));
|
||||
thread.wait();
|
||||
thread = new CThread(new TMethodJob<CClient>(this, &CClient::runSession));
|
||||
|
||||
// handle events
|
||||
log((CLOG_DEBUG "starting event handling"));
|
||||
m_screen->run();
|
||||
|
||||
// clean up
|
||||
log((CLOG_DEBUG "stopping client"));
|
||||
thread->cancel();
|
||||
thread->wait();
|
||||
delete thread;
|
||||
closeSecondaryScreen();
|
||||
}
|
||||
catch (XBase& e) {
|
||||
log((CLOG_ERR "client error: %s\n", e.what()));
|
||||
|
||||
// clean up
|
||||
thread->cancel();
|
||||
thread->wait();
|
||||
delete thread;
|
||||
closeSecondaryScreen();
|
||||
}
|
||||
catch (...) {
|
||||
log((CLOG_DEBUG "unknown client error"));
|
||||
|
||||
// clean up
|
||||
thread->cancel();
|
||||
thread->wait();
|
||||
delete thread;
|
||||
closeSecondaryScreen();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#include "CTCPSocket.h"
|
||||
#include "CXWindowsSecondaryScreen.h"
|
||||
#include "CTCPSocket.h" // FIXME
|
||||
void CClient::runSession(void*)
|
||||
{
|
||||
log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str()));
|
||||
|
@ -51,7 +97,7 @@ void CClient::runSession(void*)
|
|||
|
||||
// create socket and attempt to connect to server
|
||||
log((CLOG_DEBUG "connecting to server"));
|
||||
socket.reset(new CTCPSocket()); // FIXME -- use factory
|
||||
assign(socket, new CTCPSocket(), ISocket); // FIXME -- use factory
|
||||
socket->connect(*m_serverAddress);
|
||||
log((CLOG_INFO "connected to server"));
|
||||
|
||||
|
@ -72,8 +118,8 @@ void CClient::runSession(void*)
|
|||
*/
|
||||
|
||||
// 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);
|
||||
|
||||
// wait for hello from server
|
||||
log((CLOG_DEBUG "wait for hello"));
|
||||
|
@ -99,26 +145,17 @@ void CClient::runSession(void*)
|
|||
}
|
||||
catch (XIncompatibleClient& e) {
|
||||
log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor()));
|
||||
m_screen->stop();
|
||||
return;
|
||||
}
|
||||
catch (XThread&) {
|
||||
log((CLOG_ERR "connection timed out"));
|
||||
m_screen->stop();
|
||||
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()));
|
||||
m_screen->stop();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -199,16 +236,56 @@ void CClient::runSession(void*)
|
|||
}
|
||||
catch (XBase& e) {
|
||||
log((CLOG_ERR "error: %s", e.what()));
|
||||
m_screen->stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// done with screen
|
||||
log((CLOG_DEBUG "destroying secondary screen"));
|
||||
screenCleaner.reset();
|
||||
|
||||
// done with socket
|
||||
log((CLOG_DEBUG "disconnecting from server"));
|
||||
socket->close();
|
||||
|
||||
// exit event loop
|
||||
m_screen->stop();
|
||||
}
|
||||
|
||||
// FIXME -- use factory to create screen
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
#include "CMSWindowsSecondaryScreen.h"
|
||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||
#include "CXWindowsSecondaryScreen.h"
|
||||
#endif
|
||||
void CClient::openSecondaryScreen()
|
||||
{
|
||||
assert(m_screen == NULL);
|
||||
|
||||
// open screen
|
||||
log((CLOG_DEBUG "creating secondary screen"));
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
m_screen = new CMSWindowsSecondaryScreen;
|
||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||
m_screen = new CXWindowsSecondaryScreen;
|
||||
#endif
|
||||
log((CLOG_DEBUG "opening secondary screen"));
|
||||
m_screen->open(this);
|
||||
}
|
||||
|
||||
void CClient::closeSecondaryScreen()
|
||||
{
|
||||
assert(m_screen != NULL);
|
||||
|
||||
// close the secondary screen
|
||||
try {
|
||||
log((CLOG_DEBUG "closing secondary screen"));
|
||||
m_screen->close();
|
||||
}
|
||||
catch (...) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// clean up
|
||||
log((CLOG_DEBUG "destroying secondary screen"));
|
||||
delete m_screen;
|
||||
m_screen = NULL;
|
||||
}
|
||||
|
||||
void CClient::onEnter()
|
||||
|
@ -306,28 +383,3 @@ void CClient::onMouseWheel()
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ class CClient {
|
|||
private:
|
||||
void runSession(void*);
|
||||
|
||||
// open/close the primary screen
|
||||
void openSecondaryScreen();
|
||||
void closeSecondaryScreen();
|
||||
|
||||
// message handlers
|
||||
void onEnter();
|
||||
void onLeave();
|
||||
|
@ -40,16 +44,6 @@ class CClient {
|
|||
void onMouseMove();
|
||||
void onMouseWheel();
|
||||
|
||||
private:
|
||||
class CScreenCleaner {
|
||||
public:
|
||||
CScreenCleaner(CClient*, ISecondaryScreen*);
|
||||
~CScreenCleaner();
|
||||
|
||||
private:
|
||||
ISecondaryScreen* m_screen;
|
||||
};
|
||||
|
||||
private:
|
||||
CString m_name;
|
||||
IInputStream* m_input;
|
||||
|
|
|
@ -0,0 +1,839 @@
|
|||
#include "CMSWindowsSecondaryScreen.h"
|
||||
#include "CClient.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// CMSWindowsSecondaryScreen
|
||||
//
|
||||
|
||||
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen() :
|
||||
m_client(NULL),
|
||||
m_window(NULL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CMSWindowsSecondaryScreen::~CMSWindowsSecondaryScreen()
|
||||
{
|
||||
assert(m_window == 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 CMSWindowsSecondaryScreen::run()
|
||||
{
|
||||
CLog::setOutputter(&debugOutput);
|
||||
doRun();
|
||||
CLog::setOutputter(NULL);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::stop()
|
||||
{
|
||||
doStop();
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::open(CClient* client)
|
||||
{
|
||||
assert(m_client == NULL);
|
||||
assert(client != NULL);
|
||||
|
||||
// set the client
|
||||
m_client = client;
|
||||
|
||||
// open the display
|
||||
openDisplay();
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::close()
|
||||
{
|
||||
assert(m_client != NULL);
|
||||
|
||||
// close the display
|
||||
closeDisplay();
|
||||
|
||||
// done with client
|
||||
m_client = NULL;
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::enter(SInt32 x, SInt32 y)
|
||||
{
|
||||
assert(m_window != NULL);
|
||||
|
||||
// warp to requested location
|
||||
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);
|
||||
|
||||
// show cursor
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::leave()
|
||||
{
|
||||
assert(m_window != NULL);
|
||||
|
||||
// move hider window under the mouse (rather than moving the mouse
|
||||
// somewhere else on the screen)
|
||||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
MoveWindow(m_window, point.x, point.y, 1, 1, FALSE);
|
||||
|
||||
// raise and show the hider window. take activation.
|
||||
ShowWindow(m_window, SW_SHOWNORMAL);
|
||||
|
||||
// hide cursor by moving it into the hider window
|
||||
SetCursorPos(point.x, point.y);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::keyDown(
|
||||
KeyID key, KeyModifierMask mask)
|
||||
{
|
||||
const UINT vkey = mapKey(key, mask);
|
||||
if (vkey != 0) {
|
||||
const UINT code = MapVirtualKey(vkey, 0);
|
||||
keybd_event(vkey, code, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::keyRepeat(
|
||||
KeyID key, KeyModifierMask mask, SInt32 count)
|
||||
{
|
||||
const UINT vkey = mapKey(key, mask);
|
||||
if (vkey != 0) {
|
||||
const UINT code = MapVirtualKey(vkey, 0);
|
||||
for (SInt32 i = 0; i < count; ++i) {
|
||||
keybd_event(vkey, code, KEYEVENTF_KEYUP, 0);
|
||||
keybd_event(vkey, code, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::keyUp(
|
||||
KeyID key, KeyModifierMask mask)
|
||||
{
|
||||
const UINT vkey = mapKey(key, mask);
|
||||
if (vkey != 0) {
|
||||
const UINT code = MapVirtualKey(vkey, 0);
|
||||
keybd_event(vkey, code, KEYEVENTF_KEYUP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::mouseDown(ButtonID button)
|
||||
{
|
||||
// map button id to button flag
|
||||
DWORD flags;
|
||||
switch (button) {
|
||||
case kButtonLeft:
|
||||
flags = MOUSEEVENTF_LEFTDOWN;
|
||||
break;
|
||||
|
||||
case kButtonMiddle:
|
||||
flags = MOUSEEVENTF_MIDDLEDOWN;
|
||||
break;
|
||||
|
||||
case kButtonRight:
|
||||
flags = MOUSEEVENTF_RIGHTDOWN;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// send event
|
||||
mouse_event(flags, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::mouseUp(ButtonID button)
|
||||
{
|
||||
// map button id to button flag
|
||||
DWORD flags;
|
||||
switch (button) {
|
||||
case kButtonLeft:
|
||||
flags = MOUSEEVENTF_LEFTUP;
|
||||
break;
|
||||
|
||||
case kButtonMiddle:
|
||||
flags = MOUSEEVENTF_MIDDLEUP;
|
||||
break;
|
||||
|
||||
case kButtonRight:
|
||||
flags = MOUSEEVENTF_RIGHTUP;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// send event
|
||||
mouse_event(flags, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::mouseMove(SInt32 x, SInt32 y)
|
||||
{
|
||||
SInt32 w, h;
|
||||
getScreenSize(&w, &h);
|
||||
mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
||||
(SInt32)(65535.99 * x / (w - 1)),
|
||||
(SInt32)(65535.99 * y / (h - 1)),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::mouseWheel(SInt32 delta)
|
||||
{
|
||||
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, delta, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::getSize(
|
||||
SInt32* width, SInt32* height) const
|
||||
{
|
||||
getScreenSize(width, height);
|
||||
}
|
||||
|
||||
SInt32 CMSWindowsSecondaryScreen::getJumpZoneSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "resource.h" // FIXME
|
||||
|
||||
void CMSWindowsSecondaryScreen::onOpenDisplay()
|
||||
{
|
||||
assert(m_window == 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 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.
|
||||
m_window = CreateWindowEx(WS_EX_TOPMOST |
|
||||
WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,
|
||||
(LPCTSTR)getClass(), "Synergy",
|
||||
WS_POPUP | WS_DISABLED,
|
||||
0, 0, 1, 1, NULL, NULL,
|
||||
getInstance(),
|
||||
NULL);
|
||||
|
||||
// hide the cursor
|
||||
leave();
|
||||
}
|
||||
|
||||
void CMSWindowsSecondaryScreen::onCloseDisplay()
|
||||
{
|
||||
assert(m_window != NULL);
|
||||
|
||||
// destroy window
|
||||
DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
|
||||
CLog::setOutputter(NULL);
|
||||
DestroyWindow(s_debug);
|
||||
s_debug = NULL;
|
||||
s_thread = 0;
|
||||
}
|
||||
|
||||
bool CMSWindowsSecondaryScreen::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 WM_MOUSEMOVE:
|
||||
// mouse was moved. hide the hider window.
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
break;
|
||||
|
||||
case WM_ACTIVATEAPP:
|
||||
if (msg->wParam == FALSE) {
|
||||
// some other app activated. hide the hider window.
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
}
|
||||
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;
|
||||
*/
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const UINT g_latin1[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin2[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin3[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin4[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin5[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin6[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin7[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin8[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_latin9[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_terminal[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const UINT g_function[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
// FIXME -- will this work?
|
||||
// 0x100 + = shift
|
||||
// 0x200 + = ctrl
|
||||
// 0x400 + = alt
|
||||
/* XK_KP_Space to XK_KP_Equal */
|
||||
static const UINT g_miscellany[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ VK_BACK, VK_TAB, /*0x100 +*/ VK_RETURN, VK_CLEAR, 0, VK_RETURN, 0, 0,
|
||||
/* 0x10 */ 0, 0, 0, VK_PAUSE, VK_SCROLL, 0/*sys-req*/, 0, 0,
|
||||
/* 0x18 */ 0, 0, 0, VK_ESCAPE, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x50 */ VK_HOME, VK_LEFT, VK_UP, VK_RIGHT,
|
||||
/* 0x54 */ VK_DOWN, VK_PRIOR, VK_NEXT, VK_END,
|
||||
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x60 */ VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, VK_APPS,
|
||||
/* 0x68 */ 0, 0, VK_HELP, VK_CANCEL, 0, 0, 0, 0,
|
||||
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x78 */ 0, 0, 0, 0, 0, 0, VK_MODECHANGE, VK_NUMLOCK,
|
||||
/* 0x80 */ VK_SPACE, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x88 */ 0, VK_TAB, 0, 0, 0, VK_RETURN, 0, 0,
|
||||
/* 0x90 */ 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP,
|
||||
/* 0x98 */ VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT,
|
||||
/* 0x9c */ VK_END, 0, VK_INSERT, VK_DELETE,
|
||||
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xa8 */ 0, 0, VK_MULTIPLY, VK_ADD,
|
||||
/* 0xac */ VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL, VK_DIVIDE,
|
||||
/* 0xb0 */ VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
||||
/* 0xb4 */ VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
||||
/* 0xb8 */ VK_NUMPAD8, VK_NUMPAD9, 0, 0, 0, 0, VK_F1, VK_F2,
|
||||
/* 0xc0 */ VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10,
|
||||
/* 0xc8 */ VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18,
|
||||
/* 0xd0 */ VK_F19, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24, 0, 0,
|
||||
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xe0 */ 0, VK_LSHIFT, VK_RSHIFT, VK_LCONTROL,
|
||||
/* 0xe4 */ VK_RCONTROL, VK_CAPITAL, 0, VK_LWIN,
|
||||
/* 0xe8 */ VK_RWIN, VK_LMENU, VK_RMENU, 0, 0, 0, 0, 0,
|
||||
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, VK_DELETE
|
||||
};
|
||||
static const UINT* g_katakana = NULL;
|
||||
static const UINT* g_arabic = NULL;
|
||||
static const UINT* g_cyrillic = NULL;
|
||||
static const UINT* g_greek = NULL;
|
||||
static const UINT* g_technical = NULL;
|
||||
static const UINT* g_special = NULL;
|
||||
static const UINT* g_publishing = NULL;
|
||||
static const UINT* g_apl = NULL;
|
||||
static const UINT* g_hebrew = NULL;
|
||||
static const UINT* g_thai = NULL;
|
||||
static const UINT* g_korean = NULL;
|
||||
static const UINT* g_armenian = NULL;
|
||||
static const UINT* g_georgian = NULL;
|
||||
static const UINT* g_azeri = NULL;
|
||||
static const UINT* g_vietnamese = NULL;
|
||||
static const UINT* g_currency = NULL;
|
||||
static const UINT* g_mapTable[] =
|
||||
{
|
||||
/* 0x00 */ g_latin1, g_latin2, g_latin3, g_latin4,
|
||||
/* 0x04 */ g_katakana, g_arabic, g_cyrillic, g_greek,
|
||||
/* 0x08 */ g_technical, g_special, g_publishing, g_apl,
|
||||
/* 0x0c */ g_hebrew, g_thai, g_korean, NULL,
|
||||
/* 0x10 */ NULL, NULL, g_latin8, g_latin9,
|
||||
/* 0x14 */ g_armenian, g_georgian, g_azeri, NULL,
|
||||
/* 0x18 */ NULL, NULL, NULL, NULL, NULL, NULL, g_vietnamese, NULL,
|
||||
/* 0x20 */ g_currency, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x28 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x38 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x40 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x48 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x50 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x58 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x60 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x68 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x70 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x78 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x80 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x88 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x90 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0x98 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xa0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xa8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xb0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xb8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xc0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xc8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xd0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xd8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xe0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xe8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xf0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 0xf8 */ NULL, NULL, NULL, NULL,
|
||||
/* 0xfc */ NULL, g_terminal, g_function, g_miscellany
|
||||
};
|
||||
|
||||
UINT CMSWindowsSecondaryScreen::mapKey(
|
||||
KeyID id, KeyModifierMask /*mask*/) const
|
||||
{
|
||||
const UInt32 mapID = ((id >> 8) & 0xff);
|
||||
const UInt32 code = (id & 0xff);
|
||||
|
||||
// lookup the key table
|
||||
const UINT* map = g_mapTable[mapID];
|
||||
if (map == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mapID == 0) {
|
||||
SHORT scan = VkKeyScan(code);
|
||||
if (scan != 0xffff) {
|
||||
// FIXME -- must ensure shift state is correct. that means
|
||||
// tracking the shift state from the moment we enter until
|
||||
// the moment we leave (and probably disallowing leave if
|
||||
// any shift keys are down). if current shift state is
|
||||
// correct then do nothing extra, otherwise must surround
|
||||
// injected key event with injected shift key events to
|
||||
// get shift key in correct state then back to the previous
|
||||
// state.
|
||||
return (UINT)LOBYTE(scan);
|
||||
}
|
||||
}
|
||||
|
||||
// lookup the key in the table
|
||||
return map[code];
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef CMSWINDOWSSECONDARYSCREEN_H
|
||||
#define CMSWINDOWSSECONDARYSCREEN_H
|
||||
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "ISecondaryScreen.h"
|
||||
|
||||
class CMSWindowsSecondaryScreen : public CMSWindowsScreen, public ISecondaryScreen {
|
||||
public:
|
||||
CMSWindowsSecondaryScreen();
|
||||
virtual ~CMSWindowsSecondaryScreen();
|
||||
|
||||
// ISecondaryScreen overrides
|
||||
virtual void run();
|
||||
virtual void stop();
|
||||
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:
|
||||
// CMSWindowsScreen overrides
|
||||
virtual bool onEvent(MSG*);
|
||||
virtual void onOpenDisplay();
|
||||
virtual void onCloseDisplay();
|
||||
|
||||
private:
|
||||
UINT mapKey(KeyID, KeyModifierMask) const;
|
||||
|
||||
private:
|
||||
CClient* m_client;
|
||||
HWND m_window;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -22,6 +22,51 @@ CXWindowsSecondaryScreen::~CXWindowsSecondaryScreen()
|
|||
assert(m_window == None);
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::run()
|
||||
{
|
||||
assert(m_window != None);
|
||||
|
||||
for (;;) {
|
||||
// wait for and get the next event
|
||||
XEvent xevent;
|
||||
if (!getEvent(&xevent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 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::stop()
|
||||
{
|
||||
doStop();
|
||||
}
|
||||
|
||||
void CXWindowsSecondaryScreen::open(CClient* client)
|
||||
{
|
||||
assert(m_client == NULL);
|
||||
|
@ -174,44 +219,6 @@ void CXWindowsSecondaryScreen::onCloseDisplay()
|
|||
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);
|
||||
|
|
|
@ -10,6 +10,8 @@ class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen
|
|||
virtual ~CXWindowsSecondaryScreen();
|
||||
|
||||
// ISecondaryScreen overrides
|
||||
virtual void run();
|
||||
virtual void stop();
|
||||
virtual void open(CClient*);
|
||||
virtual void close();
|
||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||
|
@ -28,7 +30,6 @@ class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen
|
|||
// CXWindowsScreen overrides
|
||||
virtual void onOpenDisplay();
|
||||
virtual void onCloseDisplay();
|
||||
virtual void eventThread(void*);
|
||||
|
||||
private:
|
||||
void leaveNoLock(Display*);
|
||||
|
|
|
@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
|
|||
#
|
||||
# target file
|
||||
#
|
||||
TARGET = client
|
||||
TARGETS = client
|
||||
|
||||
#
|
||||
# source files
|
||||
|
@ -37,8 +37,8 @@ LLDLIBS = \
|
|||
-lpthread \
|
||||
$(NULL)
|
||||
|
||||
targets: $(TARGET)
|
||||
targets: $(TARGETS)
|
||||
|
||||
$(TARGET): $(OBJECTS) $(DEPLIBS)
|
||||
$(TARGETS): $(OBJECTS) $(DEPLIBS)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
||||
|
||||
|
|
|
@ -1,24 +1,76 @@
|
|||
#include "CClient.h"
|
||||
#include "CString.h"
|
||||
#include "CNetwork.h"
|
||||
#include "CNetworkAddress.h"
|
||||
#include "CThread.h"
|
||||
|
||||
void realMain(const CString& name,
|
||||
const CString& hostname,
|
||||
SInt32 port)
|
||||
{
|
||||
CThread::init();
|
||||
CNetwork::init();
|
||||
|
||||
CClient* client = NULL;
|
||||
try {
|
||||
CNetworkAddress addr(hostname, port);
|
||||
client = new CClient(name);
|
||||
client->run(addr);
|
||||
delete client;
|
||||
CNetwork::cleanup();
|
||||
}
|
||||
catch (...) {
|
||||
delete client;
|
||||
CNetwork::cleanup();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
|
||||
#include "CMSWindowsScreen.h"
|
||||
|
||||
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
CMSWindowsScreen::init(instance);
|
||||
|
||||
if (__argc != 2) {
|
||||
CString msg = "hostname required. exiting.";
|
||||
MessageBox(NULL, msg.c_str(), "error", MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
realMain("ingrid", __argv[1], 50001);
|
||||
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)
|
||||
{
|
||||
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));
|
||||
realMain("ingrid", argv[1], 50001);
|
||||
return 0;
|
||||
}
|
||||
catch (XBase& e) {
|
||||
fprintf(stderr, "failed: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
# Microsoft Developer Studio Project File - Name="client" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=client - 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 "client.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 "client.mak" CFG="client - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "client - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "client - 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)" == "client - 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)" == "client - 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 "client - Win32 Release"
|
||||
# Name "client - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClient.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsSecondaryScreen.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClient.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsSecondaryScreen.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
|
|
@ -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
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by client.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 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,150 @@
|
|||
# Microsoft Developer Studio Project File - Name="io" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=io - 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 "io.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 "io.mak" CFG="io - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "io - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "io - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "io - 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 "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /I "..\mt" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "io - 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 "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /I "..\mt" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "io - Win32 Release"
|
||||
# Name "io - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CBufferedInputStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CBufferedOutputStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CInputStreamFilter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\COutputStreamFilter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CStreamBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XIO.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CBufferedInputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CBufferedOutputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CInputStreamFilter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\COutputStreamFilter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CStreamBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IInputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IOutputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XIO.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -238,7 +238,7 @@ bool CCondVarBase::wait(
|
|||
}
|
||||
|
||||
// prepare to wait
|
||||
CRefCountedPtr<CThreadRep> currentRep(CThreadRep::getCurrentThreadRep());
|
||||
CThreadPtr currentRep = CThreadRep::getCurrentThreadRep();
|
||||
const DWORD winTimeout = (timeout < 0.0) ? INFINITE :
|
||||
static_cast<DWORD>(1000.0 * timeout);
|
||||
HANDLE* events = reinterpret_cast<HANDLE*>(m_cond);
|
||||
|
|
|
@ -5,26 +5,6 @@
|
|||
#include "CStopwatch.h"
|
||||
#include "CLog.h"
|
||||
|
||||
//
|
||||
// CThreadPtr
|
||||
//
|
||||
|
||||
class CThreadPtr {
|
||||
public:
|
||||
CThreadPtr(CThreadRep* rep) : m_rep(rep) { }
|
||||
~CThreadPtr() { m_rep->unref(); }
|
||||
|
||||
CThreadRep* operator->() const { return m_rep; }
|
||||
|
||||
private:
|
||||
// not implemented
|
||||
CThreadPtr(const CThreadPtr&);
|
||||
CThreadPtr& operator=(const CThreadPtr&);
|
||||
|
||||
private:
|
||||
CThreadRep* m_rep;
|
||||
};
|
||||
|
||||
//
|
||||
// CThread
|
||||
//
|
||||
|
|
|
@ -12,10 +12,17 @@
|
|||
#define SIGWAKEUP SIGUSR1
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
# if !defined(_MT)
|
||||
# error multithreading compile option is required
|
||||
# endif
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
// FIXME -- temporary exception type
|
||||
class XThreadUnavailable { };
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if defined(CONFIG_PLATFORM_UNIX) && !defined(NDEBUG)
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -145,7 +152,6 @@ void CThreadRep::initThreads()
|
|||
# ifndef NDEBUG
|
||||
act.sa_handler = &threadDebug;
|
||||
sigaction(SIGSEGV, &act, NULL);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
// set signal mask
|
||||
|
@ -159,6 +165,7 @@ void CThreadRep::initThreads()
|
|||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGPIPE);
|
||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +262,7 @@ void CThreadRep::doThreadFunc()
|
|||
m_job->run();
|
||||
}
|
||||
|
||||
catch (XThreadCancel& e) {
|
||||
catch (XThreadCancel&) {
|
||||
// client called cancel()
|
||||
log((CLOG_DEBUG "caught cancel on thread %p", this));
|
||||
}
|
||||
|
@ -421,8 +428,6 @@ void CThreadRep::threadCancel(int)
|
|||
|
||||
#elif defined(CONFIG_PLATFORM_WIN32)
|
||||
|
||||
#include <process.h>
|
||||
|
||||
void CThreadRep::init()
|
||||
{
|
||||
m_result = NULL;
|
||||
|
@ -485,7 +490,7 @@ bool CThreadRep::wait(CThreadRep* target, double timeout)
|
|||
{
|
||||
// get the current thread. if it's the same as the target thread
|
||||
// then the thread is waiting on itself.
|
||||
CRefCountedPtr<CThreadRep> currentRep(CThreadRep::getCurrentThreadRep());
|
||||
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
||||
if (target == this)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -122,4 +122,24 @@ class CThreadRep {
|
|||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// CThreadPtr -- auto unref'ing pointer to thread rep
|
||||
//
|
||||
|
||||
class CThreadPtr {
|
||||
public:
|
||||
CThreadPtr(CThreadRep* rep) : m_rep(rep) { }
|
||||
~CThreadPtr() { m_rep->unref(); }
|
||||
|
||||
CThreadRep* operator->() const { return m_rep; }
|
||||
|
||||
private:
|
||||
// not implemented
|
||||
CThreadPtr(const CThreadPtr&);
|
||||
CThreadPtr& operator=(const CThreadPtr&);
|
||||
|
||||
private:
|
||||
CThreadRep* m_rep;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
# Microsoft Developer Studio Project File - Name="mt" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=mt - 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 "mt.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 "mt.mak" CFG="mt - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "mt - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "mt - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "mt - 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 "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "mt - 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 "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "mt - Win32 Release"
|
||||
# Name "mt - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CCondVar.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CLock.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CThread.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CThreadRep.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTimerThread.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CCondVar.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CLock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMutex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CThread.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CThreadRep.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTimerThread.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XThread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,339 @@
|
|||
#include "CNetwork.h"
|
||||
#include "XNetwork.h"
|
||||
#include "CLog.h"
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// CNetwork
|
||||
//
|
||||
|
||||
CNetwork::Socket (PASCAL FAR *CNetwork::accept)(CNetwork::Socket s, CNetwork::Address FAR *addr, CNetwork::AddressLength FAR *addrlen);
|
||||
int (PASCAL FAR *CNetwork::bind)(CNetwork::Socket s, const CNetwork::Address FAR *addr, CNetwork::AddressLength namelen);
|
||||
int (PASCAL FAR *CNetwork::close)(CNetwork::Socket s);
|
||||
int (PASCAL FAR *CNetwork::connect)(CNetwork::Socket s, const CNetwork::Address FAR *name, CNetwork::AddressLength namelen);
|
||||
int (PASCAL FAR *CNetwork::ioctl)(CNetwork::Socket s, int cmd, ...);
|
||||
int (PASCAL FAR *CNetwork::getpeername)(CNetwork::Socket s, CNetwork::Address FAR *name, CNetwork::AddressLength FAR * namelen);
|
||||
int (PASCAL FAR *CNetwork::getsockname)(CNetwork::Socket s, CNetwork::Address FAR *name, CNetwork::AddressLength FAR * namelen);
|
||||
int (PASCAL FAR *CNetwork::getsockopt)(CNetwork::Socket s, int level, int optname, void FAR * optval, CNetwork::AddressLength FAR *optlen);
|
||||
UInt32 (PASCAL FAR *CNetwork::swaphtonl)(UInt32 hostlong);
|
||||
UInt16 (PASCAL FAR *CNetwork::swaphtons)(UInt16 hostshort);
|
||||
unsigned long (PASCAL FAR *CNetwork::inet_addr)(const char FAR * cp);
|
||||
char FAR * (PASCAL FAR *CNetwork::inet_ntoa)(struct in_addr in);
|
||||
int (PASCAL FAR *CNetwork::listen)(CNetwork::Socket s, int backlog);
|
||||
UInt32 (PASCAL FAR *CNetwork::swapntohl)(UInt32 netlong);
|
||||
UInt16 (PASCAL FAR *CNetwork::swapntohs)(UInt16 netshort);
|
||||
ssize_t (PASCAL FAR *CNetwork::read)(CNetwork::Socket s, void FAR * buf, size_t len);
|
||||
ssize_t (PASCAL FAR *CNetwork::recv)(CNetwork::Socket s, void FAR * buf, size_t len, int flags);
|
||||
ssize_t (PASCAL FAR *CNetwork::recvfrom)(CNetwork::Socket s, void FAR * buf, size_t len, int flags, CNetwork::Address FAR *from, CNetwork::AddressLength FAR * fromlen);
|
||||
int (PASCAL FAR *CNetwork::poll)(CNetwork::PollEntry fds[], int nfds, int timeout);
|
||||
ssize_t (PASCAL FAR *CNetwork::send)(CNetwork::Socket s, const void FAR * buf, size_t len, int flags);
|
||||
ssize_t (PASCAL FAR *CNetwork::sendto)(CNetwork::Socket s, const void FAR * buf, size_t len, int flags, const CNetwork::Address FAR *to, CNetwork::AddressLength tolen);
|
||||
int (PASCAL FAR *CNetwork::setsockopt)(CNetwork::Socket s, int level, int optname, const void FAR * optval, CNetwork::AddressLength optlen);
|
||||
int (PASCAL FAR *CNetwork::shutdown)(CNetwork::Socket s, int how);
|
||||
CNetwork::Socket (PASCAL FAR *CNetwork::socket)(int af, int type, int protocol);
|
||||
ssize_t (PASCAL FAR *CNetwork::write)(CNetwork::Socket s, const void FAR * buf, size_t len);
|
||||
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyaddr)(const char FAR * addr, int len, int type);
|
||||
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyname)(const char FAR * name);
|
||||
int (PASCAL FAR *CNetwork::gethostname)(char FAR * name, int namelen);
|
||||
struct servent FAR * (PASCAL FAR *CNetwork::getservbyport)(int port, const char FAR * proto);
|
||||
struct servent FAR * (PASCAL FAR *CNetwork::getservbyname)(const char FAR * name, const char FAR * proto);
|
||||
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobynumber)(int proto);
|
||||
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobyname)(const char FAR * name);
|
||||
int (PASCAL FAR *CNetwork::getsockerror)(void);
|
||||
int (PASCAL FAR *CNetwork::gethosterror)(void);
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
|
||||
int (PASCAL FAR *CNetwork::WSACleanup)(void);
|
||||
int (PASCAL FAR *CNetwork::__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
||||
const int CNetwork::Error = SOCKET_ERROR;
|
||||
const CNetwork::Socket CNetwork::Null = INVALID_SOCKET;
|
||||
|
||||
#undef FD_ISSET
|
||||
#define FD_ISSET(fd, set) CNetwork::__WSAFDIsSet((SOCKET)(fd), (fd_set FAR *)(set))
|
||||
|
||||
static HMODULE s_networkModule = NULL;
|
||||
|
||||
static FARPROC netGetProcAddress(HMODULE module, LPCSTR name)
|
||||
{
|
||||
FARPROC func = ::GetProcAddress(module, name);
|
||||
if (!func)
|
||||
throw XNetworkFunctionUnavailable(name);
|
||||
return func;
|
||||
}
|
||||
|
||||
void CNetwork::init()
|
||||
{
|
||||
assert(WSACleanup == NULL);
|
||||
assert(s_networkModule == NULL);
|
||||
|
||||
// try winsock 2
|
||||
HMODULE module = (HMODULE)::LoadLibrary("ws2_32.dll");
|
||||
if (module == NULL) {
|
||||
log((CLOG_DEBUG "ws2_32.dll not found"));
|
||||
}
|
||||
else {
|
||||
try {
|
||||
init2(module);
|
||||
return;
|
||||
}
|
||||
catch (XNetwork& e) {
|
||||
log((CLOG_DEBUG "ws2_32.dll error: %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// try winsock 1
|
||||
module = (HMODULE)::LoadLibrary("wsock32.dll");
|
||||
if (module == NULL) {
|
||||
log((CLOG_DEBUG "wsock32.dll not found"));
|
||||
}
|
||||
else {
|
||||
try {
|
||||
init2(module);
|
||||
return;
|
||||
}
|
||||
catch (XNetwork& e) {
|
||||
log((CLOG_DEBUG "wsock32.dll error: %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// no networking
|
||||
throw XNetworkUnavailable();
|
||||
}
|
||||
|
||||
void CNetwork::cleanup()
|
||||
{
|
||||
if (s_networkModule != NULL) {
|
||||
WSACleanup();
|
||||
::FreeLibrary(s_networkModule);
|
||||
|
||||
WSACleanup = NULL;
|
||||
s_networkModule = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define setfunc(var, name, type) var = (type)netGetProcAddress(module, #name)
|
||||
|
||||
void CNetwork::init2(HMODULE module)
|
||||
{
|
||||
assert(module != NULL);
|
||||
|
||||
// get startup function address
|
||||
int (PASCAL FAR *startup)(WORD, LPWSADATA);
|
||||
setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA));
|
||||
|
||||
// startup network library
|
||||
WORD version = MAKEWORD(1 /*major*/, 1 /*minor*/);
|
||||
WSADATA data;
|
||||
int err = startup(version, &data);
|
||||
if (data.wVersion != version)
|
||||
throw XNetworkVersion(LOBYTE(data.wVersion), HIBYTE(data.wVersion));
|
||||
if (err != 0)
|
||||
throw XNetworkFailed();
|
||||
|
||||
// get function addresses
|
||||
setfunc(accept, accept, Socket (PASCAL FAR *)(Socket s, Address FAR *addr, AddressLength FAR *addrlen));
|
||||
setfunc(bind, bind, int (PASCAL FAR *)(Socket s, const Address FAR *addr, AddressLength namelen));
|
||||
setfunc(close, closesocket, int (PASCAL FAR *)(Socket s));
|
||||
setfunc(connect, connect, int (PASCAL FAR *)(Socket s, const Address FAR *name, AddressLength namelen));
|
||||
setfunc(ioctl, ioctlsocket, int (PASCAL FAR *)(Socket s, int cmd, ...));
|
||||
setfunc(getpeername, getpeername, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
||||
setfunc(swaphtonl, htonl, UInt32 (PASCAL FAR *)(UInt32 hostlong));
|
||||
setfunc(swaphtons, htons, UInt16 (PASCAL FAR *)(UInt16 hostshort));
|
||||
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
||||
setfunc(inet_ntoa, inet_ntoa, char FAR * (PASCAL FAR *)(struct in_addr in));
|
||||
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
||||
setfunc(swapntohl, ntohl, UInt32 (PASCAL FAR *)(UInt32 netlong));
|
||||
setfunc(swapntohs, ntohs, UInt16 (PASCAL FAR *)(UInt16 netshort));
|
||||
setfunc(recv, recv, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags));
|
||||
setfunc(recvfrom, recvfrom, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags, Address FAR *from, AddressLength FAR * fromlen));
|
||||
setfunc(send, send, ssize_t (PASCAL FAR *)(Socket s, const void FAR * buf, size_t len, int flags));
|
||||
setfunc(sendto, sendto, ssize_t (PASCAL FAR *)(Socket s, const void FAR * buf, size_t len, int flags, const Address FAR *to, AddressLength tolen));
|
||||
setfunc(setsockopt, setsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, const void FAR * optval, AddressLength optlen));
|
||||
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
||||
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
||||
setfunc(gethostbyaddr, gethostbyaddr, struct hostent FAR * (PASCAL FAR *)(const char FAR * addr, int len, int type));
|
||||
setfunc(gethostbyname, gethostbyname, struct hostent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||
setfunc(gethostname, gethostname, int (PASCAL FAR *)(char FAR * name, int namelen));
|
||||
setfunc(getservbyport, getservbyport, struct servent FAR * (PASCAL FAR *)(int port, const char FAR * proto));
|
||||
setfunc(getservbyname, getservbyname, struct servent FAR * (PASCAL FAR *)(const char FAR * name, const char FAR * proto));
|
||||
setfunc(getprotobynumber, getprotobynumber, struct protoent FAR * (PASCAL FAR *)(int proto));
|
||||
setfunc(getprotobyname, getprotobyname, struct protoent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||
setfunc(getsockerror, WSAGetLastError, int (PASCAL FAR *)(void));
|
||||
setfunc(gethosterror, WSAGetLastError, int (PASCAL FAR *)(void));
|
||||
setfunc(WSACleanup, WSACleanup, int (PASCAL FAR *)(void));
|
||||
setfunc(__WSAFDIsSet, __WSAFDIsSet, int (PASCAL FAR *)(CNetwork::Socket, fd_set FAR *));
|
||||
setfunc(select, select, int (PASCAL FAR *)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout));
|
||||
poll = poll2;
|
||||
read = read2;
|
||||
write = write2;
|
||||
|
||||
s_networkModule = module;
|
||||
}
|
||||
|
||||
int PASCAL FAR CNetwork::poll2(PollEntry fd[], int nfds, int timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
// prepare sets for select
|
||||
fd_set readSet, writeSet, errSet;
|
||||
fd_set* readSetP = NULL;
|
||||
fd_set* writeSetP = NULL;
|
||||
fd_set* errSetP = NULL;
|
||||
FD_ZERO(&readSet);
|
||||
FD_ZERO(&writeSet);
|
||||
FD_ZERO(&errSet);
|
||||
for (i = 0; i < nfds; ++i) {
|
||||
if (fd[i].events & kPOLLIN) {
|
||||
FD_SET(fd[i].fd, &readSet);
|
||||
readSetP = &readSet;
|
||||
}
|
||||
if (fd[i].events & kPOLLOUT) {
|
||||
FD_SET(fd[i].fd, &writeSet);
|
||||
writeSetP = &writeSet;
|
||||
}
|
||||
if (true) {
|
||||
FD_SET(fd[i].fd, &errSet);
|
||||
errSetP = &errSet;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare timeout for select
|
||||
struct timeval timeout2;
|
||||
struct timeval* timeout2P;
|
||||
if (timeout < 0) {
|
||||
timeout2P = NULL;
|
||||
}
|
||||
else {
|
||||
timeout2P = &timeout2;
|
||||
timeout2.tv_sec = timeout / 1000;
|
||||
timeout2.tv_usec = 1000 * (timeout % 1000);
|
||||
}
|
||||
|
||||
// do the select. note that winsock ignores the first argument.
|
||||
int n = select(0, readSetP, writeSetP, errSetP, timeout2P);
|
||||
|
||||
// handle results
|
||||
if (n == Error)
|
||||
return Error;
|
||||
if (n == 0)
|
||||
return 0;
|
||||
for (i = 0; i < nfds; ++i) {
|
||||
fd[i].revents = 0;
|
||||
if (FD_ISSET(fd[i].fd, &readSet))
|
||||
fd[i].revents |= kPOLLIN;
|
||||
if (FD_ISSET(fd[i].fd, &writeSet))
|
||||
fd[i].revents |= kPOLLOUT;
|
||||
if (FD_ISSET(fd[i].fd, &errSet))
|
||||
fd[i].revents |= kPOLLERR;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t PASCAL FAR CNetwork::read2(Socket s, void FAR * buf, size_t len)
|
||||
{
|
||||
return recv(s, buf, len, 0);
|
||||
}
|
||||
|
||||
ssize_t PASCAL FAR CNetwork::write2(Socket s,
|
||||
const void FAR * buf, size_t len)
|
||||
{
|
||||
return send(s, buf, len, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PLATFORM_UNIX)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
// FIXME -- use reentrant versions of non-reentrant functions
|
||||
|
||||
#define setfunc(var, name, type) var = (type)::name
|
||||
|
||||
static UInt32 myhtonl(UInt32 v)
|
||||
{
|
||||
return htonl(v);
|
||||
}
|
||||
|
||||
static UInt16 myhtons(UInt16 v)
|
||||
{
|
||||
return htons(v);
|
||||
}
|
||||
|
||||
static UInt32 myntohl(UInt32 v)
|
||||
{
|
||||
return ntohl(v);
|
||||
}
|
||||
|
||||
static UInt16 myntohs(UInt16 v)
|
||||
{
|
||||
return ntohs(v);
|
||||
}
|
||||
|
||||
static int myerrno()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
static int myherrno()
|
||||
{
|
||||
return h_errno;
|
||||
}
|
||||
|
||||
static int mygethostname(char* name, int namelen)
|
||||
{
|
||||
return gethostname(name, namelen);
|
||||
}
|
||||
|
||||
const int CNetwork::Error = -1;
|
||||
const CNetwork::Socket CNetwork::Null = -1;
|
||||
|
||||
void CNetwork::init()
|
||||
{
|
||||
setfunc(accept, accept, Socket (PASCAL FAR *)(Socket s, Address FAR *addr, AddressLength FAR *addrlen));
|
||||
setfunc(bind, bind, int (PASCAL FAR *)(Socket s, const Address FAR *addr, AddressLength namelen));
|
||||
setfunc(close, close, int (PASCAL FAR *)(Socket s));
|
||||
setfunc(connect, connect, int (PASCAL FAR *)(Socket s, const Address FAR *name, AddressLength namelen));
|
||||
setfunc(ioctl, ioctl, int (PASCAL FAR *)(Socket s, int cmd, ...));
|
||||
setfunc(getpeername, getpeername, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
||||
setfunc(swaphtonl, myhtonl, UInt32 (PASCAL FAR *)(UInt32 hostlong));
|
||||
setfunc(swaphtons, myhtons, UInt16 (PASCAL FAR *)(UInt16 hostshort));
|
||||
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
||||
setfunc(inet_ntoa, inet_ntoa, char FAR * (PASCAL FAR *)(struct in_addr in));
|
||||
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
||||
setfunc(swapntohl, myntohl, UInt32 (PASCAL FAR *)(UInt32 netlong));
|
||||
setfunc(swapntohs, myntohs, UInt16 (PASCAL FAR *)(UInt16 netshort));
|
||||
setfunc(poll, poll, int (PASCAL FAR *)(CNetwork::PollEntry fds[], int nfds, int timeout));
|
||||
setfunc(read, read, ssize_t (PASCAL FAR *)(CNetwork::Socket s, void FAR * buf, size_t len));
|
||||
setfunc(recv, recv, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags));
|
||||
setfunc(recvfrom, recvfrom, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags, Address FAR *from, AddressLength FAR * fromlen));
|
||||
setfunc(send, send, ssize_t (PASCAL FAR *)(Socket s, const void FAR * buf, size_t len, int flags));
|
||||
setfunc(sendto, sendto, ssize_t (PASCAL FAR *)(Socket s, const void FAR * buf, size_t len, int flags, const Address FAR *to, AddressLength tolen));
|
||||
setfunc(setsockopt, setsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, const void FAR * optval, AddressLength optlen));
|
||||
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
||||
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
||||
setfunc(write, write, ssize_t (PASCAL FAR *)(CNetwork::Socket s, const void FAR * buf, size_t len));
|
||||
setfunc(gethostbyaddr, gethostbyaddr, struct hostent FAR * (PASCAL FAR *)(const char FAR * addr, int len, int type));
|
||||
setfunc(gethostbyname, gethostbyname, struct hostent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||
setfunc(gethostname, mygethostname, int (PASCAL FAR *)(char FAR * name, int namelen));
|
||||
setfunc(getservbyport, getservbyport, struct servent FAR * (PASCAL FAR *)(int port, const char FAR * proto));
|
||||
setfunc(getservbyname, getservbyname, struct servent FAR * (PASCAL FAR *)(const char FAR * name, const char FAR * proto));
|
||||
setfunc(getprotobynumber, getprotobynumber, struct protoent FAR * (PASCAL FAR *)(int proto));
|
||||
setfunc(getprotobyname, getprotobyname, struct protoent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||
setfunc(getsockerror, myerrno, int (PASCAL FAR *)(void));
|
||||
setfunc(gethosterror, myherrno, int (PASCAL FAR *)(void));
|
||||
}
|
||||
|
||||
void CNetwork::cleanup()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
#ifndef CNETWORK_H
|
||||
#define CNETWORK_H
|
||||
|
||||
#include "BasicTypes.h"
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
// declare no functions in winsock2
|
||||
# define INCL_WINSOCK_API_PROTOTYPES 0
|
||||
# define INCL_WINSOCK_API_TYPEDEFS 0
|
||||
# include <winsock2.h>
|
||||
typedef int ssize_t;
|
||||
#else
|
||||
# define FAR
|
||||
# define PASCAL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PLATFORM_UNIX)
|
||||
# include <sys/types.h>
|
||||
# include <sys/poll.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
// FIXME -- must handle htonl and ilk when defined as macros
|
||||
|
||||
class CNetwork {
|
||||
public:
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
typedef SOCKET Socket;
|
||||
typedef struct sockaddr Address;
|
||||
typedef int AddressLength;
|
||||
struct PollEntry {
|
||||
Socket fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
enum {
|
||||
kPOLLIN = 1,
|
||||
kPOLLOUT = 2,
|
||||
kPOLLERR = 4,
|
||||
kPOLLNVAL = 8
|
||||
};
|
||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||
typedef int Socket;
|
||||
typedef struct sockaddr Address;
|
||||
typedef socklen_t AddressLength;
|
||||
typedef struct pollfd PollEntry;
|
||||
enum {
|
||||
kPOLLIN = POLLIN,
|
||||
kPOLLOUT = POLLOUT,
|
||||
kPOLLERR = POLLERR,
|
||||
kPOLLNVAL = POLLNVAL
|
||||
};
|
||||
#endif
|
||||
|
||||
// manipulators
|
||||
|
||||
static void init();
|
||||
static void cleanup();
|
||||
|
||||
// constants
|
||||
|
||||
static const int Error;
|
||||
static const Socket Null;
|
||||
|
||||
// getsockerror() constants
|
||||
enum {
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
kEADDRINUSE = WSAEADDRINUSE,
|
||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||
kEADDRINUSE = EADDRINUSE,
|
||||
#endif
|
||||
kNone = 0
|
||||
};
|
||||
|
||||
// gethosterror() constants
|
||||
enum {
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
kHOST_NOT_FOUND = WSAHOST_NOT_FOUND,
|
||||
kNO_DATA = WSANO_DATA,
|
||||
kNO_RECOVERY = WSANO_RECOVERY,
|
||||
kTRY_AGAIN = WSATRY_AGAIN,
|
||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||
kHOST_NOT_FOUND = HOST_NOT_FOUND,
|
||||
kNO_DATA = NO_DATA,
|
||||
kNO_RECOVERY = NO_RECOVERY,
|
||||
kTRY_AGAIN = TRY_AGAIN,
|
||||
#endif
|
||||
kHNone = 0
|
||||
};
|
||||
|
||||
// socket interface
|
||||
|
||||
static Socket (PASCAL FAR *accept)(Socket s, Address FAR *addr, AddressLength FAR *addrlen);
|
||||
static int (PASCAL FAR *bind)(Socket s, const Address FAR *addr, AddressLength namelen);
|
||||
static int (PASCAL FAR *close)(Socket s);
|
||||
static int (PASCAL FAR *connect)(Socket s, const Address FAR *name, AddressLength namelen);
|
||||
static int (PASCAL FAR *ioctl)(Socket s, int cmd, ...);
|
||||
static int (PASCAL FAR *getpeername)(Socket s, Address FAR *name, AddressLength FAR * namelen);
|
||||
static int (PASCAL FAR *getsockname)(Socket s, Address FAR *name, AddressLength FAR * namelen);
|
||||
static int (PASCAL FAR *getsockopt)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen);
|
||||
static UInt32 (PASCAL FAR *swaphtonl)(UInt32 hostlong);
|
||||
static UInt16 (PASCAL FAR *swaphtons)(UInt16 hostshort);
|
||||
static unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);
|
||||
static char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);
|
||||
static int (PASCAL FAR *listen)(Socket s, int backlog);
|
||||
static UInt32 (PASCAL FAR *swapntohl)(UInt32 netlong);
|
||||
static UInt16 (PASCAL FAR *swapntohs)(UInt16 netshort);
|
||||
static ssize_t (PASCAL FAR *read)(Socket s, void FAR * buf, size_t len);
|
||||
static ssize_t (PASCAL FAR *recv)(Socket s, void FAR * buf, size_t len, int flags);
|
||||
static ssize_t (PASCAL FAR *recvfrom)(Socket s, void FAR * buf, size_t len, int flags, Address FAR *from, AddressLength FAR * fromlen);
|
||||
static int (PASCAL FAR *poll)(PollEntry[], int nfds, int timeout);
|
||||
static ssize_t (PASCAL FAR *send)(Socket s, const void FAR * buf, size_t len, int flags);
|
||||
static ssize_t (PASCAL FAR *sendto)(Socket s, const void FAR * buf, size_t len, int flags, const Address FAR *to, AddressLength tolen);
|
||||
static int (PASCAL FAR *setsockopt)(Socket s, int level, int optname, const void FAR * optval, AddressLength optlen);
|
||||
static int (PASCAL FAR *shutdown)(Socket s, int how);
|
||||
static Socket (PASCAL FAR *socket)(int af, int type, int protocol);
|
||||
static ssize_t (PASCAL FAR *write)(Socket s, const void FAR * buf, size_t len);
|
||||
static struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR * addr, int len, int type);
|
||||
static struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);
|
||||
static int (PASCAL FAR *gethostname)(char FAR * name, int namelen);
|
||||
static struct servent FAR * (PASCAL FAR *getservbyport)(int port, const char FAR * proto);
|
||||
static struct servent FAR * (PASCAL FAR *getservbyname)(const char FAR * name, const char FAR * proto);
|
||||
static struct protoent FAR * (PASCAL FAR *getprotobynumber)(int proto);
|
||||
static struct protoent FAR * (PASCAL FAR *getprotobyname)(const char FAR * name);
|
||||
static int (PASCAL FAR *getsockerror)(void);
|
||||
static int (PASCAL FAR *gethosterror)(void);
|
||||
|
||||
#if defined(CONFIG_PLATFORM_WIN32)
|
||||
private:
|
||||
static void init2(HMODULE);
|
||||
static int PASCAL FAR poll2(PollEntry[], int nfds, int timeout);
|
||||
static ssize_t PASCAL FAR read2(Socket s, void FAR * buf, size_t len);
|
||||
static ssize_t PASCAL FAR write2(Socket s, const void FAR * buf, size_t len);
|
||||
static int (PASCAL FAR *WSACleanup)(void);
|
||||
static int (PASCAL FAR *__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
||||
static int (PASCAL FAR *select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,8 +1,4 @@
|
|||
#include "CNetworkAddress.h"
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
//
|
||||
// CNetworkAddress
|
||||
|
@ -15,7 +11,7 @@ CNetworkAddress::CNetworkAddress(UInt16 port)
|
|||
|
||||
struct sockaddr_in* inetAddress = reinterpret_cast<struct sockaddr_in*>(&m_address);
|
||||
inetAddress->sin_family = AF_INET;
|
||||
inetAddress->sin_port = htons(port);
|
||||
inetAddress->sin_port = CNetwork::swaphtons(port);
|
||||
inetAddress->sin_addr.s_addr = INADDR_ANY;
|
||||
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
||||
}
|
||||
|
@ -25,17 +21,17 @@ CNetworkAddress::CNetworkAddress(const CString& hostname, UInt16 port)
|
|||
if (port == 0)
|
||||
throw XSocketAddress(XSocketAddress::kBadPort, hostname, port);
|
||||
|
||||
struct hostent* hent = gethostbyname(hostname.c_str());
|
||||
struct hostent* hent = CNetwork::gethostbyname(hostname.c_str());
|
||||
if (hent == NULL) {
|
||||
switch (h_errno) {
|
||||
case HOST_NOT_FOUND:
|
||||
switch (CNetwork::gethosterror()) {
|
||||
case CNetwork::kHOST_NOT_FOUND:
|
||||
throw XSocketAddress(XSocketAddress::kNotFound, hostname, port);
|
||||
|
||||
case NO_DATA:
|
||||
case CNetwork::kNO_DATA:
|
||||
throw XSocketAddress(XSocketAddress::kNoAddress, hostname, port);
|
||||
|
||||
case NO_RECOVERY:
|
||||
case TRY_AGAIN:
|
||||
case CNetwork::kNO_RECOVERY:
|
||||
case CNetwork::kTRY_AGAIN:
|
||||
default:
|
||||
throw XSocketAddress(XSocketAddress::kUnknown, hostname, port);
|
||||
}
|
||||
|
@ -43,7 +39,7 @@ CNetworkAddress::CNetworkAddress(const CString& hostname, UInt16 port)
|
|||
|
||||
struct sockaddr_in* inetAddress = reinterpret_cast<struct sockaddr_in*>(&m_address);
|
||||
inetAddress->sin_family = hent->h_addrtype;
|
||||
inetAddress->sin_port = htons(port);
|
||||
inetAddress->sin_port = CNetwork::swaphtons(port);
|
||||
memcpy(&inetAddress->sin_addr, hent->h_addr_list[0], hent->h_length);
|
||||
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
||||
}
|
||||
|
@ -53,12 +49,12 @@ CNetworkAddress::~CNetworkAddress()
|
|||
// do nothing
|
||||
}
|
||||
|
||||
const struct sockaddr* CNetworkAddress::getAddress() const
|
||||
const CNetwork::Address* CNetworkAddress::getAddress() const
|
||||
{
|
||||
return &m_address;
|
||||
}
|
||||
|
||||
int CNetworkAddress::getAddressLength() const
|
||||
CNetwork::AddressLength CNetworkAddress::getAddressLength() const
|
||||
{
|
||||
return sizeof(m_address);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#define CNETWORKADDRESS_H
|
||||
|
||||
#include "BasicTypes.h"
|
||||
#include "CNetwork.h"
|
||||
#include "XSocket.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
class CString;
|
||||
|
||||
|
@ -17,11 +17,11 @@ class CNetworkAddress {
|
|||
|
||||
// accessors
|
||||
|
||||
const struct sockaddr* getAddress() const;
|
||||
int getAddressLength() const;
|
||||
const CNetwork::Address* getAddress() const;
|
||||
CNetwork::AddressLength getAddressLength() const;
|
||||
|
||||
private:
|
||||
struct sockaddr m_address;
|
||||
CNetwork::Address m_address;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,11 +2,6 @@
|
|||
#include "CTCPSocket.h"
|
||||
#include "CNetworkAddress.h"
|
||||
#include "CThread.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
//
|
||||
// CTCPListenSocket
|
||||
|
@ -14,8 +9,8 @@
|
|||
|
||||
CTCPListenSocket::CTCPListenSocket()
|
||||
{
|
||||
m_fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (m_fd == -1) {
|
||||
m_fd = CNetwork::socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (m_fd == CNetwork::Null) {
|
||||
throw XSocketCreate();
|
||||
}
|
||||
}
|
||||
|
@ -33,40 +28,44 @@ CTCPListenSocket::~CTCPListenSocket()
|
|||
void CTCPListenSocket::bind(
|
||||
const CNetworkAddress& addr)
|
||||
{
|
||||
if (::bind(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
||||
if (errno == EADDRINUSE) {
|
||||
if (CNetwork::bind(m_fd, addr.getAddress(),
|
||||
addr.getAddressLength()) == CNetwork::Error) {
|
||||
if (CNetwork::getsockerror() == CNetwork::kEADDRINUSE) {
|
||||
throw XSocketAddressInUse();
|
||||
}
|
||||
throw XSocketBind();
|
||||
}
|
||||
if (listen(m_fd, 3) == -1) {
|
||||
if (CNetwork::listen(m_fd, 3) == CNetwork::Error) {
|
||||
throw XSocketBind();
|
||||
}
|
||||
}
|
||||
|
||||
ISocket* CTCPListenSocket::accept()
|
||||
{
|
||||
CNetwork::PollEntry pfds[1];
|
||||
pfds[0].fd = m_fd;
|
||||
pfds[0].events = CNetwork::kPOLLIN;
|
||||
for (;;) {
|
||||
struct sockaddr addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
CThread::testCancel();
|
||||
int fd = ::accept(m_fd, &addr, &addrlen);
|
||||
if (fd == -1) {
|
||||
CThread::testCancel();
|
||||
}
|
||||
else {
|
||||
const int status = CNetwork::poll(pfds, 1, 50);
|
||||
if (status > 0 && (pfds[0].revents & CNetwork::kPOLLIN) != 0) {
|
||||
CNetwork::Address addr;
|
||||
CNetwork::AddressLength addrlen = sizeof(addr);
|
||||
int fd = CNetwork::accept(m_fd, &addr, &addrlen);
|
||||
if (fd != CNetwork::Null) {
|
||||
return new CTCPSocket(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTCPListenSocket::close()
|
||||
{
|
||||
if (m_fd == -1) {
|
||||
if (m_fd == CNetwork::Null) {
|
||||
throw XIOClosed();
|
||||
}
|
||||
if (::close(m_fd) == -1) {
|
||||
if (CNetwork::close(m_fd) == CNetwork::Error) {
|
||||
throw XIOClose();
|
||||
}
|
||||
m_fd = -1;
|
||||
m_fd = CNetwork::Null;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CTCPLISTENSOCKET_H
|
||||
|
||||
#include "IListenSocket.h"
|
||||
#include "CNetwork.h"
|
||||
|
||||
class CTCPListenSocket : public IListenSocket {
|
||||
public:
|
||||
|
@ -18,7 +19,7 @@ class CTCPListenSocket : public IListenSocket {
|
|||
virtual void close();
|
||||
|
||||
private:
|
||||
int m_fd;
|
||||
CNetwork::Socket m_fd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,12 +8,6 @@
|
|||
#include "CThread.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CStopwatch.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/poll.h>
|
||||
#include <netinet/in.h>
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
|
@ -22,16 +16,16 @@
|
|||
|
||||
CTCPSocket::CTCPSocket()
|
||||
{
|
||||
m_fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (m_fd == -1) {
|
||||
m_fd = CNetwork::socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (m_fd == CNetwork::Null) {
|
||||
throw XSocketCreate();
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
CTCPSocket::CTCPSocket(int fd) : m_fd(fd)
|
||||
CTCPSocket::CTCPSocket(CNetwork::Socket fd) : m_fd(fd)
|
||||
{
|
||||
assert(m_fd != -1);
|
||||
assert(m_fd != CNetwork::Null);
|
||||
|
||||
init();
|
||||
|
||||
|
@ -60,8 +54,9 @@ CTCPSocket::~CTCPSocket()
|
|||
|
||||
void CTCPSocket::bind(const CNetworkAddress& addr)
|
||||
{
|
||||
if (::bind(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
||||
if (errno == EADDRINUSE) {
|
||||
if (CNetwork::bind(m_fd, addr.getAddress(),
|
||||
addr.getAddressLength()) == CNetwork::Error) {
|
||||
if (errno == CNetwork::kEADDRINUSE) {
|
||||
throw XSocketAddressInUse();
|
||||
}
|
||||
throw XSocketBind();
|
||||
|
@ -71,7 +66,8 @@ void CTCPSocket::bind(const CNetworkAddress& addr)
|
|||
void CTCPSocket::connect(const CNetworkAddress& addr)
|
||||
{
|
||||
CThread::testCancel();
|
||||
if (::connect(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
||||
if (CNetwork::connect(m_fd, addr.getAddress(),
|
||||
addr.getAddressLength()) == CNetwork::Error) {
|
||||
CThread::testCancel();
|
||||
throw XSocketConnect();
|
||||
}
|
||||
|
@ -103,11 +99,11 @@ void CTCPSocket::close()
|
|||
}
|
||||
|
||||
CLock lock(m_mutex);
|
||||
if (m_fd != -1) {
|
||||
if (::close(m_fd) == -1) {
|
||||
if (m_fd != CNetwork::Null) {
|
||||
if (CNetwork::close(m_fd) == CNetwork::Error) {
|
||||
throw XIOClose();
|
||||
}
|
||||
m_fd = -1;
|
||||
m_fd = CNetwork::Null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,10 +146,10 @@ void CTCPSocket::ioThread(void*)
|
|||
|
||||
void CTCPSocket::ioService()
|
||||
{
|
||||
assert(m_fd != -1);
|
||||
assert(m_fd != CNetwork::Null);
|
||||
|
||||
// now service the connection
|
||||
struct pollfd pfds[1];
|
||||
CNetwork::PollEntry pfds[1];
|
||||
pfds[0].fd = m_fd;
|
||||
for (;;) {
|
||||
{
|
||||
|
@ -162,31 +158,32 @@ void CTCPSocket::ioService()
|
|||
pfds[0].events = 0;
|
||||
if ((m_connected & kRead) != 0) {
|
||||
// still open for reading
|
||||
pfds[0].events |= POLLIN;
|
||||
pfds[0].events |= CNetwork::kPOLLIN;
|
||||
}
|
||||
if ((m_connected & kWrite) != 0 && m_output->getSize() > 0) {
|
||||
// data queued for writing
|
||||
pfds[0].events |= POLLOUT;
|
||||
pfds[0].events |= CNetwork::kPOLLOUT;
|
||||
}
|
||||
}
|
||||
|
||||
// check for status
|
||||
CThread::testCancel();
|
||||
const int status = poll(pfds, 1, 50);
|
||||
const int status = CNetwork::poll(pfds, 1, 50);
|
||||
CThread::testCancel();
|
||||
|
||||
// transfer data and handle errors
|
||||
if (status == 1) {
|
||||
if ((pfds[0].revents & (POLLERR | POLLNVAL)) != 0) {
|
||||
if ((pfds[0].revents & (CNetwork::kPOLLERR |
|
||||
CNetwork::kPOLLNVAL)) != 0) {
|
||||
// stream is no good anymore so bail
|
||||
m_input->hangup();
|
||||
return;
|
||||
}
|
||||
|
||||
// read some data
|
||||
if (pfds[0].revents & POLLIN) {
|
||||
if (pfds[0].revents & CNetwork::kPOLLIN) {
|
||||
UInt8 buffer[4096];
|
||||
ssize_t n = read(m_fd, buffer, sizeof(buffer));
|
||||
ssize_t n = CNetwork::read(m_fd, buffer, sizeof(buffer));
|
||||
if (n > 0) {
|
||||
CLock lock(m_mutex);
|
||||
m_input->write(buffer, n);
|
||||
|
@ -199,7 +196,7 @@ void CTCPSocket::ioService()
|
|||
}
|
||||
|
||||
// write some data
|
||||
if (pfds[0].revents & POLLOUT) {
|
||||
if (pfds[0].revents & CNetwork::kPOLLOUT) {
|
||||
CLock lock(m_mutex);
|
||||
|
||||
// get amount of data to write
|
||||
|
@ -211,13 +208,13 @@ void CTCPSocket::ioService()
|
|||
|
||||
// write data
|
||||
const void* buffer = m_output->peek(n);
|
||||
n = (UInt32)write(m_fd, buffer, n);
|
||||
n = (UInt32)CNetwork::write(m_fd, buffer, n);
|
||||
|
||||
// discard written data
|
||||
if (n > 0) {
|
||||
m_output->pop(n);
|
||||
}
|
||||
else if (n == (UInt32)-1 && errno == EPIPE) {
|
||||
else if (n == (UInt32)-1 && CNetwork::getsockerror() == EPIPE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -228,13 +225,13 @@ void CTCPSocket::ioService()
|
|||
void CTCPSocket::closeInput(void*)
|
||||
{
|
||||
// note -- m_mutex should already be locked
|
||||
shutdown(m_fd, 0);
|
||||
CNetwork::shutdown(m_fd, 0);
|
||||
m_connected &= ~kRead;
|
||||
}
|
||||
|
||||
void CTCPSocket::closeOutput(void*)
|
||||
{
|
||||
// note -- m_mutex should already be locked
|
||||
shutdown(m_fd, 1);
|
||||
CNetwork::shutdown(m_fd, 1);
|
||||
m_connected &= ~kWrite;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CTCPSOCKET_H
|
||||
|
||||
#include "ISocket.h"
|
||||
#include "CNetwork.h"
|
||||
#include "XThread.h"
|
||||
|
||||
class CMutex;
|
||||
|
@ -14,7 +15,7 @@ class CBufferedOutputStream;
|
|||
class CTCPSocket : public ISocket {
|
||||
public:
|
||||
CTCPSocket();
|
||||
CTCPSocket(int fd);
|
||||
CTCPSocket(CNetwork::Socket);
|
||||
~CTCPSocket();
|
||||
|
||||
// manipulators
|
||||
|
@ -38,7 +39,7 @@ class CTCPSocket : public ISocket {
|
|||
private:
|
||||
enum { kClosed = 0, kRead = 1, kWrite = 2, kReadWrite = 3 };
|
||||
|
||||
int m_fd;
|
||||
CNetwork::Socket m_fd;
|
||||
CBufferedInputStream* m_input;
|
||||
CBufferedOutputStream* m_output;
|
||||
|
||||
|
|
|
@ -15,10 +15,11 @@ LCXXINCS = \
|
|||
-I$(DEPTH)/io \
|
||||
$(NULL)
|
||||
CXXFILES = \
|
||||
XSocket.cpp \
|
||||
CNetwork.cpp \
|
||||
CNetworkAddress.cpp \
|
||||
CTCPSocket.cpp \
|
||||
CTCPListenSocket.cpp \
|
||||
XSocket.cpp \
|
||||
$(NULL)
|
||||
|
||||
targets: $(LIBTARGET)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#include "XNetwork.h"
|
||||
|
||||
//
|
||||
// XNetworkUnavailable
|
||||
//
|
||||
|
||||
CString XNetworkUnavailable::getWhat() const throw()
|
||||
{
|
||||
return format("XNetworkUnavailable", "network library is not available");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// XNetworkFailed
|
||||
//
|
||||
|
||||
CString XNetworkFailed::getWhat() const throw()
|
||||
{
|
||||
return format("XNetworkFailed", "cannot initialize network library");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// XNetworkVersion
|
||||
//
|
||||
|
||||
XNetworkVersion::XNetworkVersion(int major, int minor) throw() :
|
||||
m_major(major),
|
||||
m_minor(minor)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
int XNetworkVersion::getMajor() const throw()
|
||||
{
|
||||
return m_major;
|
||||
}
|
||||
|
||||
int XNetworkVersion::getMinor() const throw()
|
||||
{
|
||||
return m_minor;
|
||||
}
|
||||
|
||||
CString XNetworkVersion::getWhat() const throw()
|
||||
{
|
||||
return format("XNetworkVersion",
|
||||
"unsupported network version %d.%d",
|
||||
m_major, m_minor);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// XNetworkFunctionUnavailable
|
||||
//
|
||||
|
||||
XNetworkFunctionUnavailable::XNetworkFunctionUnavailable(
|
||||
const char* name) throw()
|
||||
{
|
||||
try {
|
||||
m_name = name;
|
||||
}
|
||||
catch (...) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
CString XNetworkFunctionUnavailable::getWhat() const throw()
|
||||
{
|
||||
return format("XNetworkFunctionUnavailable",
|
||||
"missing network function %s",
|
||||
m_name.c_str());
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef XNETWORK_H
|
||||
#define XNETWORK_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "XBase.h"
|
||||
#include "BasicTypes.h"
|
||||
|
||||
class XNetwork : public XBase { };
|
||||
|
||||
class XNetworkUnavailable : public XNetwork {
|
||||
protected:
|
||||
// XBase overrides
|
||||
virtual CString getWhat() const throw();
|
||||
};
|
||||
|
||||
class XNetworkFailed : public XNetwork {
|
||||
protected:
|
||||
// XBase overrides
|
||||
virtual CString getWhat() const throw();
|
||||
};
|
||||
|
||||
class XNetworkVersion : public XNetwork {
|
||||
public:
|
||||
XNetworkVersion(int major, int minor) throw();
|
||||
|
||||
// accessors
|
||||
|
||||
int getMajor() const throw();
|
||||
int getMinor() const throw();
|
||||
|
||||
protected:
|
||||
// XBase overrides
|
||||
virtual CString getWhat() const throw();
|
||||
|
||||
private:
|
||||
int m_major;
|
||||
int m_minor;
|
||||
};
|
||||
|
||||
class XNetworkFunctionUnavailable : public XNetwork {
|
||||
public:
|
||||
XNetworkFunctionUnavailable(const char* name) throw();
|
||||
|
||||
protected:
|
||||
// XBase overrides
|
||||
virtual CString getWhat() const throw();
|
||||
|
||||
private:
|
||||
CString m_name;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,174 @@
|
|||
# Microsoft Developer Studio Project File - Name="net" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=net - 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 "net.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 "net.mak" CFG="net - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "net - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "net - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "net - 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 "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "net - 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 "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "net - Win32 Release"
|
||||
# Name "net - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CNetwork.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CNetworkAddress.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketInputStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketOutputStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketStreamBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPListenSocket.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPSocket.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XNetwork.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XSocket.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CNetwork.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CNetworkAddress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketInputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketOutputStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CSocketStreamBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPListenSocket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPSocket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IListenSocket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ISocket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XNetwork.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XSocket.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
20
notes
20
notes
|
@ -78,3 +78,23 @@ server:
|
|||
asynchronously handle primary screen events
|
||||
comm
|
||||
send/recv messages to/from clients
|
||||
|
||||
---
|
||||
win32:
|
||||
double click support
|
||||
need to support window stations
|
||||
login screen on NT is a separate window station
|
||||
handle display changes
|
||||
|
||||
---
|
||||
win32 key translation (client)
|
||||
get character for key (with appropriate shift)
|
||||
keypad enter -> VK_???
|
||||
sys req -> VK_???
|
||||
compose -> VK_???
|
||||
|
||||
X11 key translation (server)
|
||||
handle compose key?
|
||||
* don't send compose, don't send dead keys, send composed key?
|
||||
* send all keys, let client do compose
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -22,6 +22,123 @@ CXWindowsPrimaryScreen::~CXWindowsPrimaryScreen()
|
|||
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)
|
||||
{
|
||||
assert(m_server == NULL);
|
||||
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -0,0 +1,215 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "all"=.\all.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name client
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name server
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "base"=.\base\base.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\base
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "client"=.\client\client.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\client
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name base
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name io
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name mt
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name net
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name synergy
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "io"=.\io\io.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\io
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "makehook"=.\server\makehook.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name synrgyhk
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "mt"=.\mt\mt.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\mt
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "net"=.\net\net.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\net
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "server"=.\server\server.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\server
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name base
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name io
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name mt
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name net
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name synergy
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name makehook
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "synergy"=.\synergy\synergy.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\synergy
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "synrgyhk"=.\server\synrgyhk.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
millpond
|
||||
.\server
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#include "CMSWindowsClipboard.h"
|
||||
#include "CString.h"
|
||||
#include "CLog.h"
|
||||
|
||||
//
|
||||
// CMSWindowsClipboard
|
||||
//
|
||||
|
||||
CMSWindowsClipboard::CMSWindowsClipboard()
|
||||
{
|
||||
}
|
||||
|
||||
CMSWindowsClipboard::~CMSWindowsClipboard()
|
||||
{
|
||||
}
|
||||
|
||||
void CMSWindowsClipboard::open()
|
||||
{
|
||||
log((CLOG_INFO "open clipboard"));
|
||||
}
|
||||
|
||||
void CMSWindowsClipboard::close()
|
||||
{
|
||||
log((CLOG_INFO "close clipboard"));
|
||||
}
|
||||
|
||||
void CMSWindowsClipboard::add(
|
||||
EFormat format, const CString& data)
|
||||
{
|
||||
log((CLOG_INFO "add clipboard format: %d\n%s", format, data.c_str()));
|
||||
}
|
||||
|
||||
bool CMSWindowsClipboard::has(EFormat /*format*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CString CMSWindowsClipboard::get(EFormat /*format*/) const
|
||||
{
|
||||
return CString();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef CMSWINDOWSCLIPBOARD_H
|
||||
#define CMSWINDOWSCLIPBOARD_H
|
||||
|
||||
#include "IClipboard.h"
|
||||
|
||||
class CMSWindowsClipboard : public IClipboard {
|
||||
public:
|
||||
CMSWindowsClipboard();
|
||||
virtual ~CMSWindowsClipboard();
|
||||
|
||||
// IClipboard overrides
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
virtual void add(EFormat, const CString& data);
|
||||
virtual bool has(EFormat) const;
|
||||
virtual CString get(EFormat) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,248 @@
|
|||
#include "CMSWindowsScreen.h"
|
||||
#include "CThread.h"
|
||||
#include "CLock.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CLog.h"
|
||||
#include "CString.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// CMSWindowsScreen
|
||||
//
|
||||
|
||||
HINSTANCE CMSWindowsScreen::s_instance = NULL;
|
||||
|
||||
CMSWindowsScreen::CMSWindowsScreen() :
|
||||
m_class(0),
|
||||
m_cursor(NULL),
|
||||
m_w(0), m_h(0),
|
||||
m_thread(0)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CMSWindowsScreen::~CMSWindowsScreen()
|
||||
{
|
||||
assert(m_class == 0);
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::init(HINSTANCE instance)
|
||||
{
|
||||
s_instance = instance;
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::doRun()
|
||||
{
|
||||
m_thread = GetCurrentThreadId();
|
||||
for (;;) {
|
||||
// wait for and get the next event
|
||||
MSG msg;
|
||||
getEvent(&msg);
|
||||
|
||||
// handle quit message
|
||||
if (msg.message == WM_QUIT) {
|
||||
break;
|
||||
}
|
||||
|
||||
// dispatch message
|
||||
if (!onEvent(&msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::doStop()
|
||||
{
|
||||
PostThreadMessage(m_thread, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::openDisplay()
|
||||
{
|
||||
assert(s_instance != NULL);
|
||||
assert(m_class == 0);
|
||||
|
||||
// create a transparent cursor
|
||||
int cw = GetSystemMetrics(SM_CXCURSOR);
|
||||
int ch = GetSystemMetrics(SM_CYCURSOR);
|
||||
UInt8* cursorBits = new UInt8[ch * ((cw + 31) >> 5)];
|
||||
memset(cursorBits, 0, ch * ((cw + 31) >> 5));
|
||||
m_cursor = CreateCursor(s_instance, 0, 0, cw, ch, cursorBits, cursorBits);
|
||||
delete[] cursorBits;
|
||||
|
||||
// register a window class
|
||||
WNDCLASSEX classInfo;
|
||||
classInfo.cbSize = sizeof(classInfo);
|
||||
classInfo.style = CS_DBLCLKS | CS_NOCLOSE;
|
||||
classInfo.lpfnWndProc = &CMSWindowsScreen::wndProc;
|
||||
classInfo.cbClsExtra = 0;
|
||||
classInfo.cbWndExtra = 0;
|
||||
classInfo.hInstance = s_instance;
|
||||
classInfo.hIcon = NULL;
|
||||
classInfo.hCursor = m_cursor;
|
||||
classInfo.hbrBackground = NULL;
|
||||
classInfo.lpszMenuName = NULL;
|
||||
classInfo.lpszClassName = "Synergy";
|
||||
classInfo.hIconSm = NULL;
|
||||
m_class = RegisterClassEx(&classInfo);
|
||||
|
||||
// get screen size
|
||||
// FIXME -- should handle multiple screens
|
||||
m_w = GetSystemMetrics(SM_CXSCREEN);
|
||||
m_h = GetSystemMetrics(SM_CYSCREEN);
|
||||
log((CLOG_INFO "display size: %dx%d", m_w, m_h));
|
||||
|
||||
// let subclass prep display
|
||||
onOpenDisplay();
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::closeDisplay()
|
||||
{
|
||||
assert(s_instance != NULL);
|
||||
assert(m_class != 0);
|
||||
|
||||
// let subclass close down display
|
||||
onCloseDisplay();
|
||||
|
||||
// unregister the window class
|
||||
UnregisterClass((LPCTSTR)m_class, s_instance);
|
||||
m_class = 0;
|
||||
|
||||
// delete resources
|
||||
DestroyCursor(m_cursor);
|
||||
m_cursor = NULL;
|
||||
|
||||
log((CLOG_DEBUG "closed display"));
|
||||
}
|
||||
|
||||
HINSTANCE CMSWindowsScreen::getInstance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
ATOM CMSWindowsScreen::getClass() const
|
||||
{
|
||||
return m_class;
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::getScreenSize(
|
||||
SInt32* w, SInt32* h) const
|
||||
{
|
||||
assert(m_class != 0);
|
||||
assert(w != NULL && h != NULL);
|
||||
|
||||
*w = m_w;
|
||||
*h = m_h;
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::getEvent(MSG* msg) const
|
||||
{
|
||||
// wait for an event in a cancellable way
|
||||
while (HIWORD(GetQueueStatus(QS_ALLINPUT)) == 0) {
|
||||
CThread::sleep(0.05);
|
||||
}
|
||||
GetMessage(msg, NULL, 0, 0);
|
||||
}
|
||||
|
||||
void CMSWindowsScreen::getDisplayClipboard(
|
||||
IClipboard* clipboard,
|
||||
HWND requestor) const
|
||||
{
|
||||
/* FIXME
|
||||
assert(clipboard != NULL);
|
||||
assert(requestor != None);
|
||||
|
||||
// clear the clipboard object
|
||||
clipboard->open();
|
||||
|
||||
// block others from using the display while we get the clipboard.
|
||||
// in particular, this prevents the event thread from stealing the
|
||||
// selection notify event we're expecting.
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// use PRIMARY selection as the "clipboard"
|
||||
Atom selection = XA_PRIMARY;
|
||||
|
||||
// ask the selection for all the formats it has. some owners return
|
||||
// the TARGETS atom and some the ATOM atom when TARGETS is requested.
|
||||
Atom format;
|
||||
CString targets;
|
||||
if (getDisplayClipboard(selection, m_atomTargets,
|
||||
requestor, timestamp, &format, &targets) &&
|
||||
(format == m_atomTargets || format == XA_ATOM)) {
|
||||
// get each target (that we can interpret). some owners return
|
||||
// some targets multiple times in the list so don't try to get
|
||||
// those multiple times.
|
||||
const Atom* targetAtoms = reinterpret_cast<const Atom*>(targets.data());
|
||||
const SInt32 numTargets = targets.size() / sizeof(Atom);
|
||||
std::set<IClipboard::EFormat> clipboardFormats;
|
||||
std::set<Atom> targets;
|
||||
log((CLOG_DEBUG "selection has %d targets", numTargets));
|
||||
for (SInt32 i = 0; i < numTargets; ++i) {
|
||||
Atom format = targetAtoms[i];
|
||||
log((CLOG_DEBUG " source target %d", format));
|
||||
|
||||
// skip already handled targets
|
||||
if (targets.count(format) > 0) {
|
||||
log((CLOG_DEBUG " skipping handled target %d", format));
|
||||
continue;
|
||||
}
|
||||
|
||||
// mark this target as done
|
||||
targets.insert(format);
|
||||
|
||||
// determine the expected clipboard format
|
||||
IClipboard::EFormat expectedFormat = getFormat(format);
|
||||
|
||||
// if we can use the format and we haven't already retrieved
|
||||
// it then get it
|
||||
if (expectedFormat == IClipboard::kNum) {
|
||||
log((CLOG_DEBUG " no format for target", format));
|
||||
continue;
|
||||
}
|
||||
if (clipboardFormats.count(expectedFormat) > 0) {
|
||||
log((CLOG_DEBUG " skipping handled format %d", expectedFormat));
|
||||
continue;
|
||||
}
|
||||
|
||||
CString data;
|
||||
if (!getDisplayClipboard(selection, format,
|
||||
requestor, timestamp, &format, &data)) {
|
||||
log((CLOG_DEBUG " no data for target", format));
|
||||
continue;
|
||||
}
|
||||
|
||||
// use the actual format, not the expected
|
||||
IClipboard::EFormat actualFormat = getFormat(format);
|
||||
if (actualFormat == IClipboard::kNum) {
|
||||
log((CLOG_DEBUG " no format for target", format));
|
||||
continue;
|
||||
}
|
||||
if (clipboardFormats.count(actualFormat) > 0) {
|
||||
log((CLOG_DEBUG " skipping handled format %d", actualFormat));
|
||||
continue;
|
||||
}
|
||||
|
||||
// add to clipboard and note we've done it
|
||||
clipboard->add(actualFormat, data);
|
||||
clipboardFormats.insert(actualFormat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// non-ICCCM conforming selection owner. try TEXT format.
|
||||
// FIXME
|
||||
log((CLOG_DEBUG "selection doesn't support TARGETS, format is %d", format));
|
||||
}
|
||||
|
||||
// done with clipboard
|
||||
clipboard->close();
|
||||
*/
|
||||
}
|
||||
|
||||
LRESULT CALLBACK CMSWindowsScreen::wndProc(
|
||||
HWND hwnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef CMSWINDOWSSCREEN_H
|
||||
#define CMSWINDOWSSCREEN_H
|
||||
|
||||
#include "CMutex.h"
|
||||
#include "IClipboard.h"
|
||||
#include "BasicTypes.h"
|
||||
#include <windows.h>
|
||||
|
||||
class CString;
|
||||
class CThread;
|
||||
|
||||
class CMSWindowsScreen {
|
||||
public:
|
||||
CMSWindowsScreen();
|
||||
virtual ~CMSWindowsScreen();
|
||||
|
||||
// manipulators
|
||||
|
||||
static void init(HINSTANCE);
|
||||
|
||||
protected:
|
||||
// runs an event loop and returns when WM_QUIT is received
|
||||
void doRun();
|
||||
|
||||
// sends WM_QUIT to force doRun() to return
|
||||
void doStop();
|
||||
|
||||
// open the X display. calls onOpenDisplay() after opening the display,
|
||||
// getting the screen, its size, and root window. then it starts the
|
||||
// event thread.
|
||||
void openDisplay();
|
||||
|
||||
// destroy the window and close the display. calls onCloseDisplay()
|
||||
// after the event thread has been shut down but before the display
|
||||
// is closed.
|
||||
void closeDisplay();
|
||||
|
||||
// get the application instance handle and the registered window
|
||||
// class atom
|
||||
static HINSTANCE getInstance();
|
||||
ATOM getClass() const;
|
||||
|
||||
// get the size of the screen
|
||||
void getScreenSize(SInt32* w, SInt32* h) const;
|
||||
|
||||
// wait for and get the next message. cancellable.
|
||||
void getEvent(MSG*) const;
|
||||
|
||||
// copy the clipboard contents to clipboard
|
||||
void getDisplayClipboard(IClipboard* clipboard, HWND) const;
|
||||
|
||||
// called by doRun() to handle an event
|
||||
virtual bool onEvent(MSG*) = 0;
|
||||
|
||||
// called by openDisplay() to allow subclasses to prepare the display
|
||||
virtual void onOpenDisplay() = 0;
|
||||
|
||||
// called by closeDisplay() to
|
||||
virtual void onCloseDisplay() = 0;
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
static HINSTANCE s_instance;
|
||||
ATOM m_class;
|
||||
HICON m_icon;
|
||||
HCURSOR m_cursor;
|
||||
SInt32 m_w, m_h;
|
||||
DWORD m_thread;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -17,4 +17,3 @@ class CXWindowsClipboard : public IClipboard {
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
CXWindowsScreen::CXWindowsScreen() :
|
||||
m_display(NULL),
|
||||
m_root(None),
|
||||
m_w(0), m_h(0)
|
||||
m_w(0), m_h(0),
|
||||
m_stop(false)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
@ -58,24 +59,11 @@ void CXWindowsScreen::openDisplay()
|
|||
|
||||
// let subclass prep display
|
||||
onOpenDisplay();
|
||||
|
||||
// start processing events
|
||||
m_eventThread = new CThread(new TMethodJob<CXWindowsScreen>(
|
||||
this, &CXWindowsScreen::eventThread));
|
||||
}
|
||||
|
||||
void CXWindowsScreen::closeDisplay()
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
assert(m_eventThread != NULL);
|
||||
|
||||
// stop event thread
|
||||
log((CLOG_DEBUG "stopping event thread"));
|
||||
m_eventThread->cancel();
|
||||
m_eventThread->wait();
|
||||
delete m_eventThread;
|
||||
m_eventThread = NULL;
|
||||
log((CLOG_DEBUG "stopped event thread"));
|
||||
|
||||
// let subclass close down display
|
||||
onCloseDisplay();
|
||||
|
@ -143,18 +131,31 @@ Cursor CXWindowsScreen::createBlankCursor() const
|
|||
return cursor;
|
||||
}
|
||||
|
||||
void CXWindowsScreen::getEvent(XEvent* xevent) const
|
||||
bool CXWindowsScreen::getEvent(XEvent* xevent) const
|
||||
{
|
||||
// wait for an event in a cancellable way and don't lock the
|
||||
// display while we're waiting.
|
||||
m_mutex.lock();
|
||||
while (XPending(m_display) == 0) {
|
||||
while (!m_stop && XPending(m_display) == 0) {
|
||||
m_mutex.unlock();
|
||||
CThread::sleep(0.05);
|
||||
m_mutex.lock();
|
||||
}
|
||||
if (m_stop) {
|
||||
m_mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
XNextEvent(m_display, xevent);
|
||||
m_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CXWindowsScreen::doStop()
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
m_stop = true;
|
||||
}
|
||||
|
||||
void CXWindowsScreen::getDisplayClipboard(
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <X11/Xlib.h>
|
||||
|
||||
class CString;
|
||||
class CThread;
|
||||
|
||||
class CXWindowsScreen {
|
||||
public:
|
||||
|
@ -50,7 +49,10 @@ class CXWindowsScreen {
|
|||
Cursor createBlankCursor() const;
|
||||
|
||||
// wait for and get the next X event. cancellable.
|
||||
void getEvent(XEvent*) const;
|
||||
bool getEvent(XEvent*) const;
|
||||
|
||||
// cause getEvent() to return false immediately and forever after
|
||||
void doStop();
|
||||
|
||||
// copy the clipboard contents to clipboard. requestor must be a
|
||||
// valid window; it will be used to receive the transfer. timestamp
|
||||
|
@ -64,9 +66,6 @@ class CXWindowsScreen {
|
|||
// called by closeDisplay() to
|
||||
virtual void onCloseDisplay() = 0;
|
||||
|
||||
// override to process X events
|
||||
virtual void eventThread(void*) = 0;
|
||||
|
||||
private:
|
||||
struct PropertyNotifyInfo {
|
||||
public:
|
||||
|
@ -87,11 +86,11 @@ class CXWindowsScreen {
|
|||
XEvent* xevent, XPointer arg);
|
||||
|
||||
private:
|
||||
CThread* m_eventThread;
|
||||
Display* m_display;
|
||||
int m_screen;
|
||||
Window m_root;
|
||||
SInt32 m_w, m_h;
|
||||
bool m_stop;
|
||||
|
||||
// atoms we'll need
|
||||
Atom m_atomTargets;
|
||||
|
|
|
@ -41,4 +41,3 @@ class IClipboard : public IInterface {
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -11,6 +11,15 @@ class IPrimaryScreen : public IInterface {
|
|||
public:
|
||||
// manipulators
|
||||
|
||||
// enter the screen's message loop. this returns when it detects
|
||||
// the application should terminate or when stop() is called.
|
||||
// the screen must be open()'d before run() and must not be
|
||||
// close()'d until run() returns.
|
||||
virtual void run() = 0;
|
||||
|
||||
// cause run() to return
|
||||
virtual void stop() = 0;
|
||||
|
||||
// initialize the screen and start reporting events to the server.
|
||||
// events should be reported no matter where on the screen they
|
||||
// occur but do not interfere with normal event dispatch. the
|
||||
|
@ -26,8 +35,9 @@ class IPrimaryScreen : public IInterface {
|
|||
|
||||
// called when the user navigates back to the primary screen.
|
||||
// warp the cursor to the given coordinates, unhide it, and
|
||||
// ungrab the input devices. every call to method has a matching
|
||||
// call to leave() which preceeds it.
|
||||
// ungrab the input devices. every call to enter has a matching
|
||||
// call to leave() which preceeds it, however the screen can
|
||||
// assume an implicit call to enter() in the call to open().
|
||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute) = 0;
|
||||
|
||||
// called when the user navigates off the primary screen. hide
|
||||
|
|
|
@ -13,6 +13,15 @@ class ISecondaryScreen : public IInterface {
|
|||
public:
|
||||
// manipulators
|
||||
|
||||
// enter the screen's message loop. this returns when it detects
|
||||
// the application should terminate or when stop() is called.
|
||||
// the screen must be open()'d before run() and must not be
|
||||
// close()'d until run() returns.
|
||||
virtual void run() = 0;
|
||||
|
||||
// cause run() to return
|
||||
virtual void stop() = 0;
|
||||
|
||||
// initialize the screen, hide the cursor, and disable the screen
|
||||
// saver. start reporting certain events to the client (clipboard
|
||||
// stolen and screen size changed).
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
# Microsoft Developer Studio Project File - Name="synergy" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=synergy - 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 "synergy.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 "synergy.mak" CFG="synergy - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "synergy - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "synergy - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "millpond"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "synergy - 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 "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "synergy - 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 "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "synergy - Win32 Release"
|
||||
# Name "synergy - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CInputPacketStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboard.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsScreen.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\COutputPacketStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CProtocolUtil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPSocketFactory.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XSynergy.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CInputPacketStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboard.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsScreen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\COutputPacketStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CProtocolUtil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CTCPSocketFactory.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IClipboard.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IPrimaryScreen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ISecondaryScreen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IServerProtocol.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ISocketFactory.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\KeyTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MouseTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ProtocolTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XSynergy.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
|
Loading…
Reference in New Issue