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
|
# compiler options
|
||||||
#
|
#
|
||||||
GCXXDEFS = -D_XOPEN_SOURCE=500
|
GCXXDEFS = -D_XOPEN_SOURCE=600
|
||||||
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
||||||
GCXXOPTS = -Wall -W -fexceptions
|
GCXXOPTS = -Wall -W -fexceptions
|
||||||
CXXOPTIMIZER = -g
|
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)
|
#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
|
#endif // CONFIG_PLATFORM_WIN32
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,37 @@
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
|
#include "BasicTypes.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.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
|
// CLog
|
||||||
//
|
//
|
||||||
|
|
||||||
static int g_maxPriority = -1;
|
CLog::Outputter CLog::s_outputter = NULL;
|
||||||
|
|
||||||
void CLog::print(const char* fmt, ...)
|
void CLog::print(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -19,11 +42,14 @@ void CLog::print(const char* fmt, ...)
|
||||||
fmt += 3;
|
fmt += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute prefix padding length
|
||||||
|
int pad = g_priorityPad;
|
||||||
|
|
||||||
// print to buffer
|
// print to buffer
|
||||||
char stack[1024];
|
char stack[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
char* buffer = vsprint(0, stack,
|
char* buffer = vsprint(pad, stack,
|
||||||
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
@ -48,17 +74,19 @@ void CLog::printt(const char* file, int line,
|
||||||
// compute prefix padding length
|
// compute prefix padding length
|
||||||
char stack[1024];
|
char stack[1024];
|
||||||
sprintf(stack, "%d", line);
|
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_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
char* buffer = vsprint(pad, stack,
|
char* buffer = vsprint(pad, stack,
|
||||||
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
sizeof(stack) / sizeof(stack[0]), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
// print the prefix to the buffer
|
// print the prefix to the buffer. leave space for priority label.
|
||||||
sprintf(buffer, "%s,%d:", file, line);
|
sprintf(buffer + g_priorityPad, "%s,%d:", file, line);
|
||||||
buffer[pad - 1] = ' ';
|
buffer[pad - 1] = ' ';
|
||||||
|
|
||||||
// output buffer
|
// output buffer
|
||||||
|
@ -69,35 +97,51 @@ void CLog::printt(const char* file, int line,
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::output(int priority, const char* msg)
|
void CLog::setOutputter(Outputter outputter)
|
||||||
{
|
{
|
||||||
static const char* s_priority[] = {
|
s_outputter = outputter;
|
||||||
"FATAL",
|
}
|
||||||
"ERROR",
|
|
||||||
"WARNING",
|
void CLog::output(int priority, char* msg)
|
||||||
"NOTE",
|
{
|
||||||
"INFO",
|
assert(priority >= 0 && priority < g_numPriority);
|
||||||
"DEBUG",
|
|
||||||
};
|
|
||||||
static const int s_numPriority = (int)(sizeof(s_priority) /
|
|
||||||
sizeof(s_priority[0]));
|
|
||||||
assert(priority >= 0 && priority < s_numPriority);
|
|
||||||
assert(msg != 0);
|
assert(msg != 0);
|
||||||
|
|
||||||
if (g_maxPriority == -1) {
|
if (g_maxPriority == -1) {
|
||||||
g_maxPriority = s_numPriority - 1;
|
g_maxPriority = g_numPriority - 1;
|
||||||
const char* priEnv = getenv("SYN_LOG_PRI");
|
const char* priEnv = getenv("SYN_LOG_PRI");
|
||||||
if (priEnv != NULL) {
|
if (priEnv != NULL) {
|
||||||
for (int i = 0; i < s_numPriority; ++i)
|
for (int i = 0; i < g_numPriority; ++i)
|
||||||
if (strcmp(priEnv, s_priority[i]) == 0) {
|
if (strcmp(priEnv, g_priority[i]) == 0) {
|
||||||
g_maxPriority = i;
|
g_maxPriority = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority <= g_maxPriority)
|
if (priority <= g_maxPriority) {
|
||||||
fprintf(stderr, "%s: %s\n", s_priority[priority], msg);
|
// 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,
|
char* CLog::vsprint(int pad, char* buffer, int len,
|
||||||
|
@ -109,7 +153,7 @@ char* CLog::vsprint(int pad, char* buffer, int len,
|
||||||
int n;
|
int n;
|
||||||
if (len >= pad) {
|
if (len >= pad) {
|
||||||
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
||||||
if (n != -1 && n <= len - pad)
|
if (n != -1 && n <= len - pad + g_newlineLength)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +164,7 @@ char* CLog::vsprint(int pad, char* buffer, int len,
|
||||||
len *= 2;
|
len *= 2;
|
||||||
buffer = new char[len + pad];
|
buffer = new char[len + pad];
|
||||||
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
n = vsnprintf(buffer + pad, len - pad, fmt, args);
|
||||||
} while (n == -1 || n > len - pad);
|
} while (n == -1 || n > len - pad + g_newlineLength);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,19 @@
|
||||||
|
|
||||||
class CLog {
|
class CLog {
|
||||||
public:
|
public:
|
||||||
|
typedef void (*Outputter)(const char*);
|
||||||
|
|
||||||
static void print(const char*, ...);
|
static void print(const char*, ...);
|
||||||
static void printt(const char* file, int line, const char*, ...);
|
static void printt(const char* file, int line, const char*, ...);
|
||||||
|
static void setOutputter(Outputter);
|
||||||
|
|
||||||
private:
|
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 char* vsprint(int pad, char*, int len, const char*, va_list);
|
||||||
static int nprint(const char*, va_list);
|
static int nprint(const char*, va_list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Outputter s_outputter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(NOLOGGING)
|
#if defined(NOLOGGING)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
// win32 wants a const char* argument to std::exception c'tor
|
// win32 wants a const char* argument to std::exception c'tor
|
||||||
#if CONFIG_PLATFORM_WIN32
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
#define STDEXCEPTARG ""
|
#define STDEXCEPTARG ""
|
||||||
#endif
|
#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_TYPES_X11
|
||||||
#define CONFIG_PTHREADS
|
#define CONFIG_PTHREADS
|
||||||
|
|
||||||
#elif defined(_WINDOWS) && defined(WIN32)
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
#define CONFIG_PLATFORM_WIN32
|
#define CONFIG_PLATFORM_WIN32
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1200)
|
||||||
|
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#error unsupported platform
|
#error unsupported platform
|
||||||
|
|
|
@ -9,8 +9,17 @@
|
||||||
#include "XSynergy.h"
|
#include "XSynergy.h"
|
||||||
#include "TMethodJob.h"
|
#include "TMethodJob.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <memory>
|
#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
|
// CClient
|
||||||
//
|
//
|
||||||
|
@ -31,13 +40,50 @@ CClient::~CClient()
|
||||||
|
|
||||||
void CClient::run(const CNetworkAddress& serverAddress)
|
void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
{
|
{
|
||||||
m_serverAddress = &serverAddress;
|
CThread* thread;
|
||||||
CThread thread(new TMethodJob<CClient>(this, &CClient::runSession));
|
try {
|
||||||
thread.wait();
|
log((CLOG_NOTE "starting client"));
|
||||||
|
|
||||||
|
// connect to secondary screen
|
||||||
|
openSecondaryScreen();
|
||||||
|
|
||||||
|
// start server interactions
|
||||||
|
m_serverAddress = &serverAddress;
|
||||||
|
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 "CTCPSocket.h" // FIXME
|
||||||
#include "CXWindowsSecondaryScreen.h"
|
|
||||||
void CClient::runSession(void*)
|
void CClient::runSession(void*)
|
||||||
{
|
{
|
||||||
log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str()));
|
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
|
// create socket and attempt to connect to server
|
||||||
log((CLOG_DEBUG "connecting 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);
|
socket->connect(*m_serverAddress);
|
||||||
log((CLOG_INFO "connected to server"));
|
log((CLOG_INFO "connected to server"));
|
||||||
|
|
||||||
|
@ -72,8 +118,8 @@ void CClient::runSession(void*)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// attach the packetizing filters
|
// attach the packetizing filters
|
||||||
input.reset(new CInputPacketStream(srcInput, own));
|
assign(input, new CInputPacketStream(srcInput, own), IInputStream);
|
||||||
output.reset(new COutputPacketStream(srcOutput, own));
|
assign(output, new COutputPacketStream(srcOutput, own), IOutputStream);
|
||||||
|
|
||||||
// wait for hello from server
|
// wait for hello from server
|
||||||
log((CLOG_DEBUG "wait for hello"));
|
log((CLOG_DEBUG "wait for hello"));
|
||||||
|
@ -99,26 +145,17 @@ void CClient::runSession(void*)
|
||||||
}
|
}
|
||||||
catch (XIncompatibleClient& e) {
|
catch (XIncompatibleClient& e) {
|
||||||
log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor()));
|
log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor()));
|
||||||
|
m_screen->stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (XThread&) {
|
catch (XThread&) {
|
||||||
log((CLOG_ERR "connection timed out"));
|
log((CLOG_ERR "connection timed out"));
|
||||||
|
m_screen->stop();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (XBase& e) {
|
catch (XBase& e) {
|
||||||
log((CLOG_ERR "connection failed: %s", e.what()));
|
log((CLOG_ERR "connection failed: %s", e.what()));
|
||||||
return;
|
m_screen->stop();
|
||||||
}
|
|
||||||
|
|
||||||
// connect to screen
|
|
||||||
std::auto_ptr<CScreenCleaner> screenCleaner;
|
|
||||||
try {
|
|
||||||
log((CLOG_DEBUG "creating secondary screen"));
|
|
||||||
m_screen = new CXWindowsSecondaryScreen;
|
|
||||||
screenCleaner.reset(new CScreenCleaner(this, m_screen));
|
|
||||||
}
|
|
||||||
catch (XBase& e) {
|
|
||||||
log((CLOG_ERR "cannot open screen: %s", e.what()));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,16 +236,56 @@ void CClient::runSession(void*)
|
||||||
}
|
}
|
||||||
catch (XBase& e) {
|
catch (XBase& e) {
|
||||||
log((CLOG_ERR "error: %s", e.what()));
|
log((CLOG_ERR "error: %s", e.what()));
|
||||||
|
m_screen->stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done with screen
|
|
||||||
log((CLOG_DEBUG "destroying secondary screen"));
|
|
||||||
screenCleaner.reset();
|
|
||||||
|
|
||||||
// done with socket
|
// done with socket
|
||||||
log((CLOG_DEBUG "disconnecting from server"));
|
log((CLOG_DEBUG "disconnecting from server"));
|
||||||
socket->close();
|
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()
|
void CClient::onEnter()
|
||||||
|
@ -306,28 +383,3 @@ void CClient::onMouseWheel()
|
||||||
CProtocolUtil::readf(m_input, kMsgDMouseWheel + 4, &delta);
|
CProtocolUtil::readf(m_input, kMsgDMouseWheel + 4, &delta);
|
||||||
m_screen->mouseWheel(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:
|
private:
|
||||||
void runSession(void*);
|
void runSession(void*);
|
||||||
|
|
||||||
|
// open/close the primary screen
|
||||||
|
void openSecondaryScreen();
|
||||||
|
void closeSecondaryScreen();
|
||||||
|
|
||||||
// message handlers
|
// message handlers
|
||||||
void onEnter();
|
void onEnter();
|
||||||
void onLeave();
|
void onLeave();
|
||||||
|
@ -40,16 +44,6 @@ class CClient {
|
||||||
void onMouseMove();
|
void onMouseMove();
|
||||||
void onMouseWheel();
|
void onMouseWheel();
|
||||||
|
|
||||||
private:
|
|
||||||
class CScreenCleaner {
|
|
||||||
public:
|
|
||||||
CScreenCleaner(CClient*, ISecondaryScreen*);
|
|
||||||
~CScreenCleaner();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ISecondaryScreen* m_screen;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CString m_name;
|
CString m_name;
|
||||||
IInputStream* m_input;
|
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);
|
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)
|
void CXWindowsSecondaryScreen::open(CClient* client)
|
||||||
{
|
{
|
||||||
assert(m_client == NULL);
|
assert(m_client == NULL);
|
||||||
|
@ -174,44 +219,6 @@ void CXWindowsSecondaryScreen::onCloseDisplay()
|
||||||
m_window = None;
|
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)
|
void CXWindowsSecondaryScreen::leaveNoLock(Display* display)
|
||||||
{
|
{
|
||||||
assert(display != NULL);
|
assert(display != NULL);
|
||||||
|
|
|
@ -10,6 +10,8 @@ class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen
|
||||||
virtual ~CXWindowsSecondaryScreen();
|
virtual ~CXWindowsSecondaryScreen();
|
||||||
|
|
||||||
// ISecondaryScreen overrides
|
// ISecondaryScreen overrides
|
||||||
|
virtual void run();
|
||||||
|
virtual void stop();
|
||||||
virtual void open(CClient*);
|
virtual void open(CClient*);
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
|
@ -28,7 +30,6 @@ class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen
|
||||||
// CXWindowsScreen overrides
|
// CXWindowsScreen overrides
|
||||||
virtual void onOpenDisplay();
|
virtual void onOpenDisplay();
|
||||||
virtual void onCloseDisplay();
|
virtual void onCloseDisplay();
|
||||||
virtual void eventThread(void*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void leaveNoLock(Display*);
|
void leaveNoLock(Display*);
|
||||||
|
|
|
@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
|
||||||
#
|
#
|
||||||
# target file
|
# target file
|
||||||
#
|
#
|
||||||
TARGET = client
|
TARGETS = client
|
||||||
|
|
||||||
#
|
#
|
||||||
# source files
|
# source files
|
||||||
|
@ -37,8 +37,8 @@ LLDLIBS = \
|
||||||
-lpthread \
|
-lpthread \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
targets: $(TARGET)
|
targets: $(TARGETS)
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS) $(DEPLIBS)
|
$(TARGETS): $(OBJECTS) $(DEPLIBS)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,76 @@
|
||||||
#include "CClient.h"
|
#include "CClient.h"
|
||||||
|
#include "CString.h"
|
||||||
|
#include "CNetwork.h"
|
||||||
#include "CNetworkAddress.h"
|
#include "CNetworkAddress.h"
|
||||||
#include "CThread.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>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CThread::init();
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
|
fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CClient* client = new CClient("ingrid");
|
realMain("ingrid", argv[1], 50001);
|
||||||
client->run(CNetworkAddress(argv[1], 50001));
|
return 0;
|
||||||
}
|
}
|
||||||
catch (XBase& e) {
|
catch (XBase& e) {
|
||||||
fprintf(stderr, "failed: %s\n", e.what());
|
fprintf(stderr, "failed: %s\n", e.what());
|
||||||
return 1;
|
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
|
// prepare to wait
|
||||||
CRefCountedPtr<CThreadRep> currentRep(CThreadRep::getCurrentThreadRep());
|
CThreadPtr currentRep = CThreadRep::getCurrentThreadRep();
|
||||||
const DWORD winTimeout = (timeout < 0.0) ? INFINITE :
|
const DWORD winTimeout = (timeout < 0.0) ? INFINITE :
|
||||||
static_cast<DWORD>(1000.0 * timeout);
|
static_cast<DWORD>(1000.0 * timeout);
|
||||||
HANDLE* events = reinterpret_cast<HANDLE*>(m_cond);
|
HANDLE* events = reinterpret_cast<HANDLE*>(m_cond);
|
||||||
|
|
|
@ -5,26 +5,6 @@
|
||||||
#include "CStopwatch.h"
|
#include "CStopwatch.h"
|
||||||
#include "CLog.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
|
// CThread
|
||||||
//
|
//
|
||||||
|
|
|
@ -12,10 +12,17 @@
|
||||||
#define SIGWAKEUP SIGUSR1
|
#define SIGWAKEUP SIGUSR1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
# if !defined(_MT)
|
||||||
|
# error multithreading compile option is required
|
||||||
|
# endif
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME -- temporary exception type
|
// FIXME -- temporary exception type
|
||||||
class XThreadUnavailable { };
|
class XThreadUnavailable { };
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#if defined(CONFIG_PLATFORM_UNIX) && !defined(NDEBUG)
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -146,19 +153,19 @@ void CThreadRep::initThreads()
|
||||||
act.sa_handler = &threadDebug;
|
act.sa_handler = &threadDebug;
|
||||||
sigaction(SIGSEGV, &act, NULL);
|
sigaction(SIGSEGV, &act, NULL);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
|
||||||
|
|
||||||
// set signal mask
|
// set signal mask
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
sigemptyset(&sigset);
|
sigemptyset(&sigset);
|
||||||
sigaddset(&sigset, SIGWAKEUP);
|
sigaddset(&sigset, SIGWAKEUP);
|
||||||
#ifndef NDEBUG
|
# ifndef NDEBUG
|
||||||
sigaddset(&sigset, SIGSEGV);
|
sigaddset(&sigset, SIGSEGV);
|
||||||
#endif
|
# endif
|
||||||
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
|
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
sigemptyset(&sigset);
|
sigemptyset(&sigset);
|
||||||
sigaddset(&sigset, SIGPIPE);
|
sigaddset(&sigset, SIGPIPE);
|
||||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +262,7 @@ void CThreadRep::doThreadFunc()
|
||||||
m_job->run();
|
m_job->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (XThreadCancel& e) {
|
catch (XThreadCancel&) {
|
||||||
// client called cancel()
|
// client called cancel()
|
||||||
log((CLOG_DEBUG "caught cancel on thread %p", this));
|
log((CLOG_DEBUG "caught cancel on thread %p", this));
|
||||||
}
|
}
|
||||||
|
@ -421,8 +428,6 @@ void CThreadRep::threadCancel(int)
|
||||||
|
|
||||||
#elif defined(CONFIG_PLATFORM_WIN32)
|
#elif defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
|
||||||
#include <process.h>
|
|
||||||
|
|
||||||
void CThreadRep::init()
|
void CThreadRep::init()
|
||||||
{
|
{
|
||||||
m_result = NULL;
|
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
|
// get the current thread. if it's the same as the target thread
|
||||||
// then the thread is waiting on itself.
|
// then the thread is waiting on itself.
|
||||||
CRefCountedPtr<CThreadRep> currentRep(CThreadRep::getCurrentThreadRep());
|
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
||||||
if (target == this)
|
if (target == this)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -122,4 +122,24 @@ class CThreadRep {
|
||||||
#endif
|
#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
|
#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 "CNetworkAddress.h"
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CNetworkAddress
|
// CNetworkAddress
|
||||||
|
@ -15,7 +11,7 @@ CNetworkAddress::CNetworkAddress(UInt16 port)
|
||||||
|
|
||||||
struct sockaddr_in* inetAddress = reinterpret_cast<struct sockaddr_in*>(&m_address);
|
struct sockaddr_in* inetAddress = reinterpret_cast<struct sockaddr_in*>(&m_address);
|
||||||
inetAddress->sin_family = AF_INET;
|
inetAddress->sin_family = AF_INET;
|
||||||
inetAddress->sin_port = htons(port);
|
inetAddress->sin_port = CNetwork::swaphtons(port);
|
||||||
inetAddress->sin_addr.s_addr = INADDR_ANY;
|
inetAddress->sin_addr.s_addr = INADDR_ANY;
|
||||||
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
||||||
}
|
}
|
||||||
|
@ -25,17 +21,17 @@ CNetworkAddress::CNetworkAddress(const CString& hostname, UInt16 port)
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
throw XSocketAddress(XSocketAddress::kBadPort, hostname, port);
|
throw XSocketAddress(XSocketAddress::kBadPort, hostname, port);
|
||||||
|
|
||||||
struct hostent* hent = gethostbyname(hostname.c_str());
|
struct hostent* hent = CNetwork::gethostbyname(hostname.c_str());
|
||||||
if (hent == NULL) {
|
if (hent == NULL) {
|
||||||
switch (h_errno) {
|
switch (CNetwork::gethosterror()) {
|
||||||
case HOST_NOT_FOUND:
|
case CNetwork::kHOST_NOT_FOUND:
|
||||||
throw XSocketAddress(XSocketAddress::kNotFound, hostname, port);
|
throw XSocketAddress(XSocketAddress::kNotFound, hostname, port);
|
||||||
|
|
||||||
case NO_DATA:
|
case CNetwork::kNO_DATA:
|
||||||
throw XSocketAddress(XSocketAddress::kNoAddress, hostname, port);
|
throw XSocketAddress(XSocketAddress::kNoAddress, hostname, port);
|
||||||
|
|
||||||
case NO_RECOVERY:
|
case CNetwork::kNO_RECOVERY:
|
||||||
case TRY_AGAIN:
|
case CNetwork::kTRY_AGAIN:
|
||||||
default:
|
default:
|
||||||
throw XSocketAddress(XSocketAddress::kUnknown, hostname, port);
|
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);
|
struct sockaddr_in* inetAddress = reinterpret_cast<struct sockaddr_in*>(&m_address);
|
||||||
inetAddress->sin_family = hent->h_addrtype;
|
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);
|
memcpy(&inetAddress->sin_addr, hent->h_addr_list[0], hent->h_length);
|
||||||
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
||||||
}
|
}
|
||||||
|
@ -53,12 +49,12 @@ CNetworkAddress::~CNetworkAddress()
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sockaddr* CNetworkAddress::getAddress() const
|
const CNetwork::Address* CNetworkAddress::getAddress() const
|
||||||
{
|
{
|
||||||
return &m_address;
|
return &m_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CNetworkAddress::getAddressLength() const
|
CNetwork::AddressLength CNetworkAddress::getAddressLength() const
|
||||||
{
|
{
|
||||||
return sizeof(m_address);
|
return sizeof(m_address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define CNETWORKADDRESS_H
|
#define CNETWORKADDRESS_H
|
||||||
|
|
||||||
#include "BasicTypes.h"
|
#include "BasicTypes.h"
|
||||||
|
#include "CNetwork.h"
|
||||||
#include "XSocket.h"
|
#include "XSocket.h"
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
class CString;
|
class CString;
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@ class CNetworkAddress {
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
const struct sockaddr* getAddress() const;
|
const CNetwork::Address* getAddress() const;
|
||||||
int getAddressLength() const;
|
CNetwork::AddressLength getAddressLength() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct sockaddr m_address;
|
CNetwork::Address m_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
#include "CTCPSocket.h"
|
#include "CTCPSocket.h"
|
||||||
#include "CNetworkAddress.h"
|
#include "CNetworkAddress.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CTCPListenSocket
|
// CTCPListenSocket
|
||||||
|
@ -14,8 +9,8 @@
|
||||||
|
|
||||||
CTCPListenSocket::CTCPListenSocket()
|
CTCPListenSocket::CTCPListenSocket()
|
||||||
{
|
{
|
||||||
m_fd = socket(PF_INET, SOCK_STREAM, 0);
|
m_fd = CNetwork::socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (m_fd == -1) {
|
if (m_fd == CNetwork::Null) {
|
||||||
throw XSocketCreate();
|
throw XSocketCreate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,40 +28,44 @@ CTCPListenSocket::~CTCPListenSocket()
|
||||||
void CTCPListenSocket::bind(
|
void CTCPListenSocket::bind(
|
||||||
const CNetworkAddress& addr)
|
const CNetworkAddress& addr)
|
||||||
{
|
{
|
||||||
if (::bind(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
if (CNetwork::bind(m_fd, addr.getAddress(),
|
||||||
if (errno == EADDRINUSE) {
|
addr.getAddressLength()) == CNetwork::Error) {
|
||||||
|
if (CNetwork::getsockerror() == CNetwork::kEADDRINUSE) {
|
||||||
throw XSocketAddressInUse();
|
throw XSocketAddressInUse();
|
||||||
}
|
}
|
||||||
throw XSocketBind();
|
throw XSocketBind();
|
||||||
}
|
}
|
||||||
if (listen(m_fd, 3) == -1) {
|
if (CNetwork::listen(m_fd, 3) == CNetwork::Error) {
|
||||||
throw XSocketBind();
|
throw XSocketBind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ISocket* CTCPListenSocket::accept()
|
ISocket* CTCPListenSocket::accept()
|
||||||
{
|
{
|
||||||
|
CNetwork::PollEntry pfds[1];
|
||||||
|
pfds[0].fd = m_fd;
|
||||||
|
pfds[0].events = CNetwork::kPOLLIN;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct sockaddr addr;
|
|
||||||
socklen_t addrlen = sizeof(addr);
|
|
||||||
CThread::testCancel();
|
CThread::testCancel();
|
||||||
int fd = ::accept(m_fd, &addr, &addrlen);
|
const int status = CNetwork::poll(pfds, 1, 50);
|
||||||
if (fd == -1) {
|
if (status > 0 && (pfds[0].revents & CNetwork::kPOLLIN) != 0) {
|
||||||
CThread::testCancel();
|
CNetwork::Address addr;
|
||||||
}
|
CNetwork::AddressLength addrlen = sizeof(addr);
|
||||||
else {
|
int fd = CNetwork::accept(m_fd, &addr, &addrlen);
|
||||||
return new CTCPSocket(fd);
|
if (fd != CNetwork::Null) {
|
||||||
|
return new CTCPSocket(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTCPListenSocket::close()
|
void CTCPListenSocket::close()
|
||||||
{
|
{
|
||||||
if (m_fd == -1) {
|
if (m_fd == CNetwork::Null) {
|
||||||
throw XIOClosed();
|
throw XIOClosed();
|
||||||
}
|
}
|
||||||
if (::close(m_fd) == -1) {
|
if (CNetwork::close(m_fd) == CNetwork::Error) {
|
||||||
throw XIOClose();
|
throw XIOClose();
|
||||||
}
|
}
|
||||||
m_fd = -1;
|
m_fd = CNetwork::Null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CTCPLISTENSOCKET_H
|
#define CTCPLISTENSOCKET_H
|
||||||
|
|
||||||
#include "IListenSocket.h"
|
#include "IListenSocket.h"
|
||||||
|
#include "CNetwork.h"
|
||||||
|
|
||||||
class CTCPListenSocket : public IListenSocket {
|
class CTCPListenSocket : public IListenSocket {
|
||||||
public:
|
public:
|
||||||
|
@ -18,7 +19,7 @@ class CTCPListenSocket : public IListenSocket {
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_fd;
|
CNetwork::Socket m_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,12 +8,6 @@
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "TMethodJob.h"
|
#include "TMethodJob.h"
|
||||||
#include "CStopwatch.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>
|
#include <assert.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -22,16 +16,16 @@
|
||||||
|
|
||||||
CTCPSocket::CTCPSocket()
|
CTCPSocket::CTCPSocket()
|
||||||
{
|
{
|
||||||
m_fd = socket(PF_INET, SOCK_STREAM, 0);
|
m_fd = CNetwork::socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (m_fd == -1) {
|
if (m_fd == CNetwork::Null) {
|
||||||
throw XSocketCreate();
|
throw XSocketCreate();
|
||||||
}
|
}
|
||||||
init();
|
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();
|
init();
|
||||||
|
|
||||||
|
@ -60,8 +54,9 @@ CTCPSocket::~CTCPSocket()
|
||||||
|
|
||||||
void CTCPSocket::bind(const CNetworkAddress& addr)
|
void CTCPSocket::bind(const CNetworkAddress& addr)
|
||||||
{
|
{
|
||||||
if (::bind(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
if (CNetwork::bind(m_fd, addr.getAddress(),
|
||||||
if (errno == EADDRINUSE) {
|
addr.getAddressLength()) == CNetwork::Error) {
|
||||||
|
if (errno == CNetwork::kEADDRINUSE) {
|
||||||
throw XSocketAddressInUse();
|
throw XSocketAddressInUse();
|
||||||
}
|
}
|
||||||
throw XSocketBind();
|
throw XSocketBind();
|
||||||
|
@ -71,7 +66,8 @@ void CTCPSocket::bind(const CNetworkAddress& addr)
|
||||||
void CTCPSocket::connect(const CNetworkAddress& addr)
|
void CTCPSocket::connect(const CNetworkAddress& addr)
|
||||||
{
|
{
|
||||||
CThread::testCancel();
|
CThread::testCancel();
|
||||||
if (::connect(m_fd, addr.getAddress(), addr.getAddressLength()) == -1) {
|
if (CNetwork::connect(m_fd, addr.getAddress(),
|
||||||
|
addr.getAddressLength()) == CNetwork::Error) {
|
||||||
CThread::testCancel();
|
CThread::testCancel();
|
||||||
throw XSocketConnect();
|
throw XSocketConnect();
|
||||||
}
|
}
|
||||||
|
@ -103,11 +99,11 @@ void CTCPSocket::close()
|
||||||
}
|
}
|
||||||
|
|
||||||
CLock lock(m_mutex);
|
CLock lock(m_mutex);
|
||||||
if (m_fd != -1) {
|
if (m_fd != CNetwork::Null) {
|
||||||
if (::close(m_fd) == -1) {
|
if (CNetwork::close(m_fd) == CNetwork::Error) {
|
||||||
throw XIOClose();
|
throw XIOClose();
|
||||||
}
|
}
|
||||||
m_fd = -1;
|
m_fd = CNetwork::Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,10 +146,10 @@ void CTCPSocket::ioThread(void*)
|
||||||
|
|
||||||
void CTCPSocket::ioService()
|
void CTCPSocket::ioService()
|
||||||
{
|
{
|
||||||
assert(m_fd != -1);
|
assert(m_fd != CNetwork::Null);
|
||||||
|
|
||||||
// now service the connection
|
// now service the connection
|
||||||
struct pollfd pfds[1];
|
CNetwork::PollEntry pfds[1];
|
||||||
pfds[0].fd = m_fd;
|
pfds[0].fd = m_fd;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
{
|
{
|
||||||
|
@ -162,31 +158,32 @@ void CTCPSocket::ioService()
|
||||||
pfds[0].events = 0;
|
pfds[0].events = 0;
|
||||||
if ((m_connected & kRead) != 0) {
|
if ((m_connected & kRead) != 0) {
|
||||||
// still open for reading
|
// still open for reading
|
||||||
pfds[0].events |= POLLIN;
|
pfds[0].events |= CNetwork::kPOLLIN;
|
||||||
}
|
}
|
||||||
if ((m_connected & kWrite) != 0 && m_output->getSize() > 0) {
|
if ((m_connected & kWrite) != 0 && m_output->getSize() > 0) {
|
||||||
// data queued for writing
|
// data queued for writing
|
||||||
pfds[0].events |= POLLOUT;
|
pfds[0].events |= CNetwork::kPOLLOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for status
|
// check for status
|
||||||
CThread::testCancel();
|
CThread::testCancel();
|
||||||
const int status = poll(pfds, 1, 50);
|
const int status = CNetwork::poll(pfds, 1, 50);
|
||||||
CThread::testCancel();
|
CThread::testCancel();
|
||||||
|
|
||||||
// transfer data and handle errors
|
// transfer data and handle errors
|
||||||
if (status == 1) {
|
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
|
// stream is no good anymore so bail
|
||||||
m_input->hangup();
|
m_input->hangup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read some data
|
// read some data
|
||||||
if (pfds[0].revents & POLLIN) {
|
if (pfds[0].revents & CNetwork::kPOLLIN) {
|
||||||
UInt8 buffer[4096];
|
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) {
|
if (n > 0) {
|
||||||
CLock lock(m_mutex);
|
CLock lock(m_mutex);
|
||||||
m_input->write(buffer, n);
|
m_input->write(buffer, n);
|
||||||
|
@ -199,7 +196,7 @@ void CTCPSocket::ioService()
|
||||||
}
|
}
|
||||||
|
|
||||||
// write some data
|
// write some data
|
||||||
if (pfds[0].revents & POLLOUT) {
|
if (pfds[0].revents & CNetwork::kPOLLOUT) {
|
||||||
CLock lock(m_mutex);
|
CLock lock(m_mutex);
|
||||||
|
|
||||||
// get amount of data to write
|
// get amount of data to write
|
||||||
|
@ -211,13 +208,13 @@ void CTCPSocket::ioService()
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
const void* buffer = m_output->peek(n);
|
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
|
// discard written data
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
m_output->pop(n);
|
m_output->pop(n);
|
||||||
}
|
}
|
||||||
else if (n == (UInt32)-1 && errno == EPIPE) {
|
else if (n == (UInt32)-1 && CNetwork::getsockerror() == EPIPE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,13 +225,13 @@ void CTCPSocket::ioService()
|
||||||
void CTCPSocket::closeInput(void*)
|
void CTCPSocket::closeInput(void*)
|
||||||
{
|
{
|
||||||
// note -- m_mutex should already be locked
|
// note -- m_mutex should already be locked
|
||||||
shutdown(m_fd, 0);
|
CNetwork::shutdown(m_fd, 0);
|
||||||
m_connected &= ~kRead;
|
m_connected &= ~kRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTCPSocket::closeOutput(void*)
|
void CTCPSocket::closeOutput(void*)
|
||||||
{
|
{
|
||||||
// note -- m_mutex should already be locked
|
// note -- m_mutex should already be locked
|
||||||
shutdown(m_fd, 1);
|
CNetwork::shutdown(m_fd, 1);
|
||||||
m_connected &= ~kWrite;
|
m_connected &= ~kWrite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CTCPSOCKET_H
|
#define CTCPSOCKET_H
|
||||||
|
|
||||||
#include "ISocket.h"
|
#include "ISocket.h"
|
||||||
|
#include "CNetwork.h"
|
||||||
#include "XThread.h"
|
#include "XThread.h"
|
||||||
|
|
||||||
class CMutex;
|
class CMutex;
|
||||||
|
@ -14,7 +15,7 @@ class CBufferedOutputStream;
|
||||||
class CTCPSocket : public ISocket {
|
class CTCPSocket : public ISocket {
|
||||||
public:
|
public:
|
||||||
CTCPSocket();
|
CTCPSocket();
|
||||||
CTCPSocket(int fd);
|
CTCPSocket(CNetwork::Socket);
|
||||||
~CTCPSocket();
|
~CTCPSocket();
|
||||||
|
|
||||||
// manipulators
|
// manipulators
|
||||||
|
@ -38,7 +39,7 @@ class CTCPSocket : public ISocket {
|
||||||
private:
|
private:
|
||||||
enum { kClosed = 0, kRead = 1, kWrite = 2, kReadWrite = 3 };
|
enum { kClosed = 0, kRead = 1, kWrite = 2, kReadWrite = 3 };
|
||||||
|
|
||||||
int m_fd;
|
CNetwork::Socket m_fd;
|
||||||
CBufferedInputStream* m_input;
|
CBufferedInputStream* m_input;
|
||||||
CBufferedOutputStream* m_output;
|
CBufferedOutputStream* m_output;
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,11 @@ LCXXINCS = \
|
||||||
-I$(DEPTH)/io \
|
-I$(DEPTH)/io \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
CXXFILES = \
|
CXXFILES = \
|
||||||
XSocket.cpp \
|
CNetwork.cpp \
|
||||||
CNetworkAddress.cpp \
|
CNetworkAddress.cpp \
|
||||||
CTCPSocket.cpp \
|
CTCPSocket.cpp \
|
||||||
CTCPListenSocket.cpp \
|
CTCPListenSocket.cpp \
|
||||||
|
XSocket.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
targets: $(LIBTARGET)
|
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
|
asynchronously handle primary screen events
|
||||||
comm
|
comm
|
||||||
send/recv messages to/from clients
|
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:
|
public:
|
||||||
enum EDirection { kLeft, kRight, kTop, kBottom,
|
enum EDirection { kLeft, kRight, kTop, kBottom,
|
||||||
kFirstDirection = kLeft, kLastDirection = kBottom };
|
kFirstDirection = kLeft, kLastDirection = kBottom };
|
||||||
|
enum EDirectionMask { kLeftMask = 1, kRightMask = 2,
|
||||||
|
kTopMask = 4, kBottomMask = 8 };
|
||||||
|
|
||||||
CScreenMap();
|
CScreenMap();
|
||||||
virtual ~CScreenMap();
|
virtual ~CScreenMap();
|
||||||
|
|
|
@ -20,6 +20,14 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <memory>
|
#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
|
/* XXX
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -33,8 +41,7 @@ else { wait(0); exit(1); }
|
||||||
// CServer
|
// CServer
|
||||||
//
|
//
|
||||||
|
|
||||||
CServer::CServer() : m_done(&m_mutex, false),
|
CServer::CServer() : m_primary(NULL),
|
||||||
m_primary(NULL),
|
|
||||||
m_active(NULL),
|
m_active(NULL),
|
||||||
m_primaryInfo(NULL)
|
m_primaryInfo(NULL)
|
||||||
{
|
{
|
||||||
|
@ -61,31 +68,28 @@ void CServer::run()
|
||||||
// start listening for configuration connections
|
// start listening for configuration connections
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
// wait until done
|
// handle events
|
||||||
log((CLOG_DEBUG "waiting for quit"));
|
log((CLOG_DEBUG "starting event handling"));
|
||||||
CLock lock(&m_mutex);
|
m_primary->run();
|
||||||
while (m_done == false) {
|
|
||||||
m_done.wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
log((CLOG_DEBUG "stopping server"));
|
log((CLOG_DEBUG "stopping server"));
|
||||||
closePrimaryScreen();
|
|
||||||
cleanupThreads();
|
cleanupThreads();
|
||||||
|
closePrimaryScreen();
|
||||||
}
|
}
|
||||||
catch (XBase& e) {
|
catch (XBase& e) {
|
||||||
log((CLOG_ERR "server error: %s\n", e.what()));
|
log((CLOG_ERR "server error: %s\n", e.what()));
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
closePrimaryScreen();
|
|
||||||
cleanupThreads();
|
cleanupThreads();
|
||||||
|
closePrimaryScreen();
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
log((CLOG_DEBUG "server shutdown"));
|
log((CLOG_DEBUG "unknown server error"));
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
closePrimaryScreen();
|
|
||||||
cleanupThreads();
|
cleanupThreads();
|
||||||
|
closePrimaryScreen();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,6 +111,21 @@ void CServer::getScreenMap(CScreenMap* screenMap) const
|
||||||
*screenMap = m_screenMap;
|
*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,
|
void CServer::setInfo(const CString& client,
|
||||||
SInt32 w, SInt32 h, SInt32 zoneSize)
|
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));
|
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
|
// ignore if mouse is locked to screen
|
||||||
if (isLockedToScreen()) {
|
if (isLockedToScreen()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if we should change screens
|
// see if we should change screens
|
||||||
|
@ -243,7 +262,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// still on local screen
|
// still on local screen
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get jump destination
|
// 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 no screen in jump direction then ignore the move
|
||||||
if (newScreen == NULL) {
|
if (newScreen == NULL) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remap position to account for resolution differences
|
// remap position to account for resolution differences
|
||||||
|
@ -259,6 +278,7 @@ void CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
|
|
||||||
// switch screen
|
// switch screen
|
||||||
switchScreen(newScreen, x, y);
|
switchScreen(newScreen, x, y);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
|
void CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
|
||||||
|
@ -365,7 +385,11 @@ bool CServer::isLockedToScreen() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
#include "CMSWindowsClipboard.h" // FIXME
|
||||||
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
#include "CXWindowsClipboard.h" // FIXME
|
#include "CXWindowsClipboard.h" // FIXME
|
||||||
|
#endif
|
||||||
void CServer::switchScreen(CScreenInfo* dst,
|
void CServer::switchScreen(CScreenInfo* dst,
|
||||||
SInt32 x, SInt32 y)
|
SInt32 x, SInt32 y)
|
||||||
{
|
{
|
||||||
|
@ -384,7 +408,11 @@ void CServer::switchScreen(CScreenInfo* dst,
|
||||||
m_primary->leave();
|
m_primary->leave();
|
||||||
|
|
||||||
// FIXME -- testing
|
// FIXME -- testing
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
CMSWindowsClipboard clipboard;
|
||||||
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
CXWindowsClipboard clipboard;
|
CXWindowsClipboard clipboard;
|
||||||
|
#endif
|
||||||
m_primary->getClipboard(&clipboard);
|
m_primary->getClipboard(&clipboard);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -610,8 +638,8 @@ void CServer::acceptClients(void*)
|
||||||
std::auto_ptr<IListenSocket> listen;
|
std::auto_ptr<IListenSocket> listen;
|
||||||
try {
|
try {
|
||||||
// create socket listener
|
// create socket listener
|
||||||
// listen.reset(m_socketFactory->createListen());
|
// listen = std::auto_ptr<IListenSocket>(m_socketFactory->createListen());
|
||||||
listen.reset(new CTCPListenSocket); // FIXME
|
assign(listen, new CTCPListenSocket, IListenSocket); // FIXME
|
||||||
|
|
||||||
// bind to the desired port. keep retrying if we can't bind
|
// bind to the desired port. keep retrying if we can't bind
|
||||||
// the address immediately.
|
// the address immediately.
|
||||||
|
@ -689,8 +717,8 @@ void CServer::handshakeClient(void* vsocket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach the packetizing filters
|
// attach the packetizing filters
|
||||||
input.reset(new CInputPacketStream(srcInput, own));
|
assign(input, new CInputPacketStream(srcInput, own), IInputStream);
|
||||||
output.reset(new COutputPacketStream(srcOutput, own));
|
assign(output, new COutputPacketStream(srcOutput, own), IOutputStream);
|
||||||
|
|
||||||
std::auto_ptr<IServerProtocol> protocol;
|
std::auto_ptr<IServerProtocol> protocol;
|
||||||
std::auto_ptr<CConnectionNote> connectedNote;
|
std::auto_ptr<CConnectionNote> connectedNote;
|
||||||
|
@ -730,12 +758,13 @@ void CServer::handshakeClient(void* vsocket)
|
||||||
|
|
||||||
// create a protocol interpreter for the version
|
// create a protocol interpreter for the version
|
||||||
log((CLOG_DEBUG "creating interpreter for client %s version %d.%d", name.c_str(), major, minor));
|
log((CLOG_DEBUG "creating interpreter for client %s version %d.%d", name.c_str(), major, minor));
|
||||||
protocol.reset(CServerProtocol::create(major, minor,
|
assign(protocol, CServerProtocol::create(major, minor,
|
||||||
this, name, input.get(), output.get()));
|
this, name, input.get(), output.get()),
|
||||||
|
IServerProtocol);
|
||||||
|
|
||||||
// client is now pending
|
// client is now pending
|
||||||
connectedNote.reset(new CConnectionNote(this,
|
assign(connectedNote, new CConnectionNote(this,
|
||||||
name, protocol.get()));
|
name, protocol.get()), CConnectionNote);
|
||||||
|
|
||||||
// ask and wait for the client's info
|
// ask and wait for the client's info
|
||||||
log((CLOG_DEBUG "waiting for info for client %s", name.c_str()));
|
log((CLOG_DEBUG "waiting for info for client %s", name.c_str()));
|
||||||
|
@ -766,20 +795,26 @@ void CServer::handshakeClient(void* vsocket)
|
||||||
|
|
||||||
void CServer::quit()
|
void CServer::quit()
|
||||||
{
|
{
|
||||||
CLock lock(&m_mutex);
|
m_primary->stop();
|
||||||
m_done = true;
|
|
||||||
m_done.broadcast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME -- use factory to create screen
|
// FIXME -- use factory to create screen
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
#include "CMSWindowsPrimaryScreen.h"
|
||||||
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
#include "CXWindowsPrimaryScreen.h"
|
#include "CXWindowsPrimaryScreen.h"
|
||||||
|
#endif
|
||||||
void CServer::openPrimaryScreen()
|
void CServer::openPrimaryScreen()
|
||||||
{
|
{
|
||||||
assert(m_primary == NULL);
|
assert(m_primary == NULL);
|
||||||
|
|
||||||
// open screen
|
// open screen
|
||||||
log((CLOG_DEBUG "creating primary 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;
|
m_primary = new CXWindowsPrimaryScreen;
|
||||||
|
#endif
|
||||||
log((CLOG_DEBUG "opening primary screen"));
|
log((CLOG_DEBUG "opening primary screen"));
|
||||||
m_primary->open(this);
|
m_primary->open(this);
|
||||||
|
|
||||||
|
@ -828,8 +863,9 @@ void CServer::removeCleanupThread(const CThread& thread)
|
||||||
for (CThreadList::iterator index = m_cleanupList.begin();
|
for (CThreadList::iterator index = m_cleanupList.begin();
|
||||||
index != m_cleanupList.end(); ++index) {
|
index != m_cleanupList.end(); ++index) {
|
||||||
if (**index == thread) {
|
if (**index == thread) {
|
||||||
|
CThread* thread = *index;
|
||||||
m_cleanupList.erase(index);
|
m_cleanupList.erase(index);
|
||||||
delete *index;
|
delete thread;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,7 +913,7 @@ void CServer::removeConnection(const CString& name)
|
||||||
assert(index != m_screens.end());
|
assert(index != m_screens.end());
|
||||||
|
|
||||||
// if this is active screen then we have to jump off of it
|
// 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)
|
// record new position (center of primary screen)
|
||||||
m_x = m_primaryInfo->m_width >> 1;
|
m_x = m_primaryInfo->m_width >> 1;
|
||||||
m_y = m_primaryInfo->m_height >> 1;
|
m_y = m_primaryInfo->m_height >> 1;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "KeyTypes.h"
|
#include "KeyTypes.h"
|
||||||
#include "MouseTypes.h"
|
#include "MouseTypes.h"
|
||||||
#include "CScreenMap.h"
|
#include "CScreenMap.h"
|
||||||
#include "CCondVar.h"
|
|
||||||
#include "CMutex.h"
|
#include "CMutex.h"
|
||||||
#include "CString.h"
|
#include "CString.h"
|
||||||
#include "XBase.h"
|
#include "XBase.h"
|
||||||
|
@ -24,18 +23,23 @@ class CServer {
|
||||||
|
|
||||||
// manipulators
|
// manipulators
|
||||||
|
|
||||||
|
// start the server. does not return until quit() is called.
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
// tell server to exit gracefully
|
||||||
|
void quit();
|
||||||
|
|
||||||
// update screen map
|
// update screen map
|
||||||
void setScreenMap(const CScreenMap&);
|
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 onKeyDown(KeyID, KeyModifierMask);
|
||||||
void onKeyUp(KeyID, KeyModifierMask);
|
void onKeyUp(KeyID, KeyModifierMask);
|
||||||
void onKeyRepeat(KeyID, KeyModifierMask);
|
void onKeyRepeat(KeyID, KeyModifierMask);
|
||||||
void onMouseDown(ButtonID);
|
void onMouseDown(ButtonID);
|
||||||
void onMouseUp(ButtonID);
|
void onMouseUp(ButtonID);
|
||||||
void onMouseMovePrimary(SInt32 x, SInt32 y);
|
bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
||||||
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
||||||
void onMouseWheel(SInt32 delta);
|
void onMouseWheel(SInt32 delta);
|
||||||
|
|
||||||
|
@ -50,9 +54,11 @@ class CServer {
|
||||||
// get the current screen map
|
// get the current screen map
|
||||||
void getScreenMap(CScreenMap*) const;
|
void getScreenMap(CScreenMap*) const;
|
||||||
|
|
||||||
|
// get the sides of the primary screen that have neighbors
|
||||||
|
UInt32 getActivePrimarySides() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
||||||
void quit();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CCleanupNote {
|
class CCleanupNote {
|
||||||
|
@ -137,7 +143,6 @@ class CServer {
|
||||||
typedef std::map<CString, CScreenInfo*> CScreenList;
|
typedef std::map<CString, CScreenInfo*> CScreenList;
|
||||||
|
|
||||||
CMutex m_mutex;
|
CMutex m_mutex;
|
||||||
CCondVar<bool> m_done;
|
|
||||||
|
|
||||||
double m_bindTimeout;
|
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
|
|
@ -19,7 +19,124 @@ CXWindowsPrimaryScreen::CXWindowsPrimaryScreen() :
|
||||||
|
|
||||||
CXWindowsPrimaryScreen::~CXWindowsPrimaryScreen()
|
CXWindowsPrimaryScreen::~CXWindowsPrimaryScreen()
|
||||||
{
|
{
|
||||||
assert(m_window == None);
|
assert(m_window == None);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsPrimaryScreen::run()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
// wait for and get the next event
|
||||||
|
XEvent xevent;
|
||||||
|
if (!getEvent(&xevent)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle event
|
||||||
|
switch (xevent.type) {
|
||||||
|
case CreateNotify: {
|
||||||
|
// select events on new window
|
||||||
|
CDisplayLock display(this);
|
||||||
|
selectEvents(display, xevent.xcreatewindow.window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KeyPress: {
|
||||||
|
log((CLOG_DEBUG "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||||
|
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
||||||
|
const KeyID key = mapKey(xevent.xkey.keycode, mask);
|
||||||
|
if (key != kKeyNone) {
|
||||||
|
m_server->onKeyDown(key, mask);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME -- simulate key repeat. X sends press/release for
|
||||||
|
// repeat. must detect auto repeat and use kKeyRepeat.
|
||||||
|
case KeyRelease: {
|
||||||
|
log((CLOG_DEBUG "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||||
|
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
||||||
|
const KeyID key = mapKey(xevent.xkey.keycode, mask);
|
||||||
|
if (key != kKeyNone) {
|
||||||
|
m_server->onKeyUp(key, mask);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ButtonPress: {
|
||||||
|
log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button));
|
||||||
|
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||||
|
if (button != kButtonNone) {
|
||||||
|
m_server->onMouseDown(button);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ButtonRelease: {
|
||||||
|
log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button));
|
||||||
|
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||||
|
if (button != kButtonNone) {
|
||||||
|
m_server->onMouseUp(button);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MotionNotify: {
|
||||||
|
log((CLOG_DEBUG "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root));
|
||||||
|
SInt32 x, y;
|
||||||
|
if (!m_active) {
|
||||||
|
x = xevent.xmotion.x_root;
|
||||||
|
y = xevent.xmotion.y_root;
|
||||||
|
m_server->onMouseMovePrimary(x, y);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FIXME -- slurp up all remaining motion events?
|
||||||
|
// probably not since key strokes may go to wrong place.
|
||||||
|
|
||||||
|
// get mouse deltas
|
||||||
|
{
|
||||||
|
CDisplayLock display(this);
|
||||||
|
Window root, window;
|
||||||
|
int xRoot, yRoot, xWindow, yWindow;
|
||||||
|
unsigned int mask;
|
||||||
|
if (!XQueryPointer(display, m_window, &root, &window,
|
||||||
|
&xRoot, &yRoot, &xWindow, &yWindow, &mask))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// compute position of center of window
|
||||||
|
SInt32 w, h;
|
||||||
|
getScreenSize(&w, &h);
|
||||||
|
x = xRoot - (w >> 1);
|
||||||
|
y = yRoot - (h >> 1);
|
||||||
|
|
||||||
|
// warp mouse back to center
|
||||||
|
warpCursorNoLock(display, w >> 1, h >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_server->onMouseMoveSecondary(x, y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
case SelectionClear:
|
||||||
|
target->XXX(xevent.xselectionclear.);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
target->XXX(xevent.xselection.);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectionRequest:
|
||||||
|
target->XXX(xevent.xselectionrequest.);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXWindowsPrimaryScreen::stop()
|
||||||
|
{
|
||||||
|
doStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWindowsPrimaryScreen::open(CServer* server)
|
void CXWindowsPrimaryScreen::open(CServer* server)
|
||||||
|
@ -251,116 +368,6 @@ void CXWindowsPrimaryScreen::selectEvents(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWindowsPrimaryScreen::eventThread(void*)
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
// wait for and get the next event
|
|
||||||
XEvent xevent;
|
|
||||||
getEvent(&xevent);
|
|
||||||
|
|
||||||
// handle event
|
|
||||||
switch (xevent.type) {
|
|
||||||
case CreateNotify: {
|
|
||||||
// select events on new window
|
|
||||||
CDisplayLock display(this);
|
|
||||||
selectEvents(display, xevent.xcreatewindow.window);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KeyPress: {
|
|
||||||
log((CLOG_DEBUG "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
|
||||||
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
|
||||||
const KeyID key = mapKey(xevent.xkey.keycode, mask);
|
|
||||||
if (key != kKeyNone) {
|
|
||||||
m_server->onKeyDown(key, mask);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME -- simulate key repeat. X sends press/release for
|
|
||||||
// repeat. must detect auto repeat and use kKeyRepeat.
|
|
||||||
case KeyRelease: {
|
|
||||||
log((CLOG_DEBUG "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
|
||||||
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
|
||||||
const KeyID key = mapKey(xevent.xkey.keycode, mask);
|
|
||||||
if (key != kKeyNone) {
|
|
||||||
m_server->onKeyUp(key, mask);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ButtonPress: {
|
|
||||||
log((CLOG_DEBUG "event: ButtonPress button=%d", xevent.xbutton.button));
|
|
||||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
|
||||||
if (button != kButtonNone) {
|
|
||||||
m_server->onMouseDown(button);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ButtonRelease: {
|
|
||||||
log((CLOG_DEBUG "event: ButtonRelease button=%d", xevent.xbutton.button));
|
|
||||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
|
||||||
if (button != kButtonNone) {
|
|
||||||
m_server->onMouseUp(button);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MotionNotify: {
|
|
||||||
log((CLOG_DEBUG "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root));
|
|
||||||
SInt32 x, y;
|
|
||||||
if (!m_active) {
|
|
||||||
x = xevent.xmotion.x_root;
|
|
||||||
y = xevent.xmotion.y_root;
|
|
||||||
m_server->onMouseMovePrimary(x, y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// FIXME -- slurp up all remaining motion events?
|
|
||||||
// probably not since key strokes may go to wrong place.
|
|
||||||
|
|
||||||
// get mouse deltas
|
|
||||||
{
|
|
||||||
CDisplayLock display(this);
|
|
||||||
Window root, window;
|
|
||||||
int xRoot, yRoot, xWindow, yWindow;
|
|
||||||
unsigned int mask;
|
|
||||||
if (!XQueryPointer(display, m_window, &root, &window,
|
|
||||||
&xRoot, &yRoot, &xWindow, &yWindow, &mask))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// compute position of center of window
|
|
||||||
SInt32 w, h;
|
|
||||||
getScreenSize(&w, &h);
|
|
||||||
x = xRoot - (w >> 1);
|
|
||||||
y = yRoot - (h >> 1);
|
|
||||||
|
|
||||||
// warp mouse back to center
|
|
||||||
warpCursorNoLock(display, w >> 1, h >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_server->onMouseMoveSecondary(x, y);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
case SelectionClear:
|
|
||||||
target->XXX(xevent.xselectionclear.);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionNotify:
|
|
||||||
target->XXX(xevent.xselection.);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionRequest:
|
|
||||||
target->XXX(xevent.xselectionrequest.);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyModifierMask CXWindowsPrimaryScreen::mapModifier(
|
KeyModifierMask CXWindowsPrimaryScreen::mapModifier(
|
||||||
unsigned int state) const
|
unsigned int state) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@ class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
|
||||||
virtual ~CXWindowsPrimaryScreen();
|
virtual ~CXWindowsPrimaryScreen();
|
||||||
|
|
||||||
// IPrimaryScreen overrides
|
// IPrimaryScreen overrides
|
||||||
|
virtual void run();
|
||||||
|
virtual void stop();
|
||||||
virtual void open(CServer*);
|
virtual void open(CServer*);
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
|
@ -26,7 +28,6 @@ class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
|
||||||
// CXWindowsScreen overrides
|
// CXWindowsScreen overrides
|
||||||
virtual void onOpenDisplay();
|
virtual void onOpenDisplay();
|
||||||
virtual void onCloseDisplay();
|
virtual void onCloseDisplay();
|
||||||
virtual void eventThread(void*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void selectEvents(Display*, Window) const;
|
void selectEvents(Display*, Window) const;
|
||||||
|
|
|
@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
|
||||||
#
|
#
|
||||||
# target file
|
# target file
|
||||||
#
|
#
|
||||||
TARGET = server
|
TARGETS = server
|
||||||
|
|
||||||
#
|
#
|
||||||
# source files
|
# source files
|
||||||
|
@ -40,8 +40,8 @@ LLDLIBS = \
|
||||||
-lpthread \
|
-lpthread \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
targets: $(TARGET)
|
targets: $(TARGETS)
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS) $(DEPLIBS)
|
$(TARGETS): $(OBJECTS) $(DEPLIBS)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
$(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 "CServer.h"
|
||||||
#include "CScreenMap.h"
|
#include "CScreenMap.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include <stdio.h>
|
#include "CNetwork.h"
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
void realMain()
|
||||||
{
|
{
|
||||||
CThread::init();
|
CThread::init();
|
||||||
|
CNetwork::init();
|
||||||
if (argc != 1) {
|
|
||||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CScreenMap screenMap;
|
CScreenMap screenMap;
|
||||||
screenMap.addScreen("primary");
|
screenMap.addScreen("primary");
|
||||||
|
@ -18,15 +14,66 @@ int main(int argc, char** argv)
|
||||||
screenMap.connect("primary", CScreenMap::kRight, "ingrid");
|
screenMap.connect("primary", CScreenMap::kRight, "ingrid");
|
||||||
screenMap.connect("ingrid", CScreenMap::kLeft, "primary");
|
screenMap.connect("ingrid", CScreenMap::kLeft, "primary");
|
||||||
|
|
||||||
|
CServer* server = NULL;
|
||||||
try {
|
try {
|
||||||
CServer* server = new CServer();
|
server = new CServer();
|
||||||
server->setScreenMap(screenMap);
|
server->setScreenMap(screenMap);
|
||||||
server->run();
|
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) {
|
catch (XBase& e) {
|
||||||
fprintf(stderr, "failed: %s\n", e.what());
|
fprintf(stderr, "failed: %s\n", e.what());
|
||||||
return 1;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
CXWindowsScreen::CXWindowsScreen() :
|
CXWindowsScreen::CXWindowsScreen() :
|
||||||
m_display(NULL),
|
m_display(NULL),
|
||||||
m_root(None),
|
m_root(None),
|
||||||
m_w(0), m_h(0)
|
m_w(0), m_h(0),
|
||||||
|
m_stop(false)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -58,24 +59,11 @@ void CXWindowsScreen::openDisplay()
|
||||||
|
|
||||||
// let subclass prep display
|
// let subclass prep display
|
||||||
onOpenDisplay();
|
onOpenDisplay();
|
||||||
|
|
||||||
// start processing events
|
|
||||||
m_eventThread = new CThread(new TMethodJob<CXWindowsScreen>(
|
|
||||||
this, &CXWindowsScreen::eventThread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWindowsScreen::closeDisplay()
|
void CXWindowsScreen::closeDisplay()
|
||||||
{
|
{
|
||||||
assert(m_display != NULL);
|
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
|
// let subclass close down display
|
||||||
onCloseDisplay();
|
onCloseDisplay();
|
||||||
|
@ -143,18 +131,31 @@ Cursor CXWindowsScreen::createBlankCursor() const
|
||||||
return cursor;
|
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
|
// wait for an event in a cancellable way and don't lock the
|
||||||
// display while we're waiting.
|
// display while we're waiting.
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
while (XPending(m_display) == 0) {
|
while (!m_stop && XPending(m_display) == 0) {
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
CThread::sleep(0.05);
|
CThread::sleep(0.05);
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
}
|
}
|
||||||
XNextEvent(m_display, xevent);
|
if (m_stop) {
|
||||||
m_mutex.unlock();
|
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(
|
void CXWindowsScreen::getDisplayClipboard(
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
class CString;
|
class CString;
|
||||||
class CThread;
|
|
||||||
|
|
||||||
class CXWindowsScreen {
|
class CXWindowsScreen {
|
||||||
public:
|
public:
|
||||||
|
@ -50,7 +49,10 @@ class CXWindowsScreen {
|
||||||
Cursor createBlankCursor() const;
|
Cursor createBlankCursor() const;
|
||||||
|
|
||||||
// wait for and get the next X event. cancellable.
|
// 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
|
// copy the clipboard contents to clipboard. requestor must be a
|
||||||
// valid window; it will be used to receive the transfer. timestamp
|
// valid window; it will be used to receive the transfer. timestamp
|
||||||
|
@ -64,9 +66,6 @@ class CXWindowsScreen {
|
||||||
// called by closeDisplay() to
|
// called by closeDisplay() to
|
||||||
virtual void onCloseDisplay() = 0;
|
virtual void onCloseDisplay() = 0;
|
||||||
|
|
||||||
// override to process X events
|
|
||||||
virtual void eventThread(void*) = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PropertyNotifyInfo {
|
struct PropertyNotifyInfo {
|
||||||
public:
|
public:
|
||||||
|
@ -87,11 +86,11 @@ class CXWindowsScreen {
|
||||||
XEvent* xevent, XPointer arg);
|
XEvent* xevent, XPointer arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CThread* m_eventThread;
|
|
||||||
Display* m_display;
|
Display* m_display;
|
||||||
int m_screen;
|
int m_screen;
|
||||||
Window m_root;
|
Window m_root;
|
||||||
SInt32 m_w, m_h;
|
SInt32 m_w, m_h;
|
||||||
|
bool m_stop;
|
||||||
|
|
||||||
// atoms we'll need
|
// atoms we'll need
|
||||||
Atom m_atomTargets;
|
Atom m_atomTargets;
|
||||||
|
|
|
@ -41,4 +41,3 @@ class IClipboard : public IInterface {
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,15 @@ class IPrimaryScreen : public IInterface {
|
||||||
public:
|
public:
|
||||||
// manipulators
|
// 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.
|
// initialize the screen and start reporting events to the server.
|
||||||
// events should be reported no matter where on the screen they
|
// events should be reported no matter where on the screen they
|
||||||
// occur but do not interfere with normal event dispatch. the
|
// 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.
|
// called when the user navigates back to the primary screen.
|
||||||
// warp the cursor to the given coordinates, unhide it, and
|
// warp the cursor to the given coordinates, unhide it, and
|
||||||
// ungrab the input devices. every call to method has a matching
|
// ungrab the input devices. every call to enter has a matching
|
||||||
// call to leave() which preceeds it.
|
// 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;
|
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute) = 0;
|
||||||
|
|
||||||
// called when the user navigates off the primary screen. hide
|
// called when the user navigates off the primary screen. hide
|
||||||
|
|
|
@ -13,6 +13,15 @@ class ISecondaryScreen : public IInterface {
|
||||||
public:
|
public:
|
||||||
// manipulators
|
// 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
|
// initialize the screen, hide the cursor, and disable the screen
|
||||||
// saver. start reporting certain events to the client (clipboard
|
// saver. start reporting certain events to the client (clipboard
|
||||||
// stolen and screen size changed).
|
// 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