fixes, mainly for windows. first, had to add a notification from

CServer to the primary screen when the configuration changes so it
can make necessary adjustments (the win32 primary screen must tell
the hook dll about the new jump zones).

changed includes of some std c++ library files to go through
our own include files.  these wrap the include with stuff to
keep vc++ quiet when compiling at warning level 4, which is
what it does now.  it also works around missing <istream> and
<ostream> on g++2.96.

added missing std:: where necessary.  g++ doesn't really support
namespaces so it lets references without the namespace slip
through.

added workaround or fix.  not sure if istringstream::str(string)
should reset eofbit.  it does on g++ but does not on vc++.
added clear() after str() so it works either way.

added low-level keyboard hook to win32.  if available (it's only
available on NT SP3 and up) it allows us to catch and handle
alt+tab, alt+esc, ctrl+esc, and windows key hot keys.  i think
that leaves only ctrl+alt+del and accessibility functions
uncaught on those systems.
This commit is contained in:
crs
2002-06-01 19:26:11 +00:00
parent 1ac62a9533
commit d2135af0d9
46 changed files with 576 additions and 203 deletions

View File

@@ -1,12 +1,7 @@
#include "CConfig.h"
#include "stdistream.h"
#include "stdostream.h"
#include <assert.h>
// FIXME -- fix this with automake and config.h
#if !defined(CONFIG_PLATFORM_LINUX)
#include <istream>
#include <ostream>
#else
#include <iostream>
#endif
//
// CConfig
@@ -160,10 +155,10 @@ const char* CConfig::dirName(EDirection dir)
return s_name[dir - kFirstDirection];
}
bool CConfig::readLine(istream& s, CString& line)
bool CConfig::readLine(std::istream& s, CString& line)
{
s >> std::ws;
while (getline(s, line)) {
while (std::getline(s, line)) {
// strip comments and then trailing whitespace
CString::size_type i = line.rfind('#');
if (i != CString::npos) {
@@ -183,7 +178,7 @@ bool CConfig::readLine(istream& s, CString& line)
return false;
}
void CConfig::readSection(istream& s)
void CConfig::readSection(std::istream& s)
{
static const char s_section[] = "section:";
static const char s_screens[] = "screens";
@@ -223,7 +218,7 @@ void CConfig::readSection(istream& s)
}
}
void CConfig::readSectionScreens(istream& s)
void CConfig::readSectionScreens(std::istream& s)
{
CString line;
CString name;
@@ -256,7 +251,7 @@ void CConfig::readSectionScreens(istream& s)
throw XConfigRead("unexpected end of screens section");
}
void CConfig::readSectionLinks(istream& s)
void CConfig::readSectionLinks(std::istream& s)
{
CString line;
CString screen;
@@ -338,7 +333,7 @@ void CConfig::readSectionLinks(istream& s)
// CConfig I/O
//
istream& operator>>(istream& s, CConfig& config)
std::istream& operator>>(std::istream& s, CConfig& config)
{
// FIXME -- should track line and column to improve error reporting
@@ -350,44 +345,44 @@ istream& operator>>(istream& s, CConfig& config)
return s;
}
ostream& operator<<(ostream& s, const CConfig& config)
std::ostream& operator<<(std::ostream& s, const CConfig& config)
{
// screens section
s << "section: screens" << endl;
s << "section: screens" << std::endl;
for (CConfig::const_iterator screen = config.begin();
screen != config.end(); ++screen) {
s << "\t" << screen->c_str() << ":" << endl;
s << "\t" << screen->c_str() << ":" << std::endl;
}
s << "end" << endl;
s << "end" << std::endl;
// links section
CString neighbor;
s << "section: links" << endl;
s << "section: links" << std::endl;
for (CConfig::const_iterator screen = config.begin();
screen != config.end(); ++screen) {
s << "\t" << screen->c_str() << ":" << endl;
s << "\t" << screen->c_str() << ":" << std::endl;
neighbor = config.getNeighbor(*screen, CConfig::kLeft);
if (!neighbor.empty()) {
s << "\t\tleft=" << neighbor.c_str() << endl;
s << "\t\tleft=" << neighbor.c_str() << std::endl;
}
neighbor = config.getNeighbor(*screen, CConfig::kRight);
if (!neighbor.empty()) {
s << "\t\tright=" << neighbor.c_str() << endl;
s << "\t\tright=" << neighbor.c_str() << std::endl;
}
neighbor = config.getNeighbor(*screen, CConfig::kTop);
if (!neighbor.empty()) {
s << "\t\tup=" << neighbor.c_str() << endl;
s << "\t\tup=" << neighbor.c_str() << std::endl;
}
neighbor = config.getNeighbor(*screen, CConfig::kBottom);
if (!neighbor.empty()) {
s << "\t\tdown=" << neighbor.c_str() << endl;
s << "\t\tdown=" << neighbor.c_str() << std::endl;
}
}
s << "end" << endl;
s << "end" << std::endl;
return s;
}

View File

@@ -5,7 +5,7 @@
#include "CString.h"
#include "XBase.h"
#include <iosfwd>
#include <map>
#include "stdmap.h"
class CConfig;
@@ -57,7 +57,7 @@ public:
}
private:
CConfig::internal_const_iterator m_i;
internal_const_iterator m_i;
};
CConfig();
@@ -98,17 +98,17 @@ public:
// read/write a configuration. operator>> will throw XConfigRead
// on error.
friend istream& operator>>(istream&, CConfig&);
friend ostream& operator<<(ostream&, const CConfig&);
friend std::istream& operator>>(std::istream&, CConfig&);
friend std::ostream& operator<<(std::ostream&, const CConfig&);
// get the name of a direction (for debugging)
static const char* dirName(EDirection);
private:
static bool readLine(istream&, CString&);
void readSection(istream&);
void readSectionScreens(istream&);
void readSectionLinks(istream&);
static bool readLine(std::istream&, CString&);
void readSection(std::istream&);
void readSectionScreens(std::istream&);
void readSectionLinks(std::istream&);
private:
CCellMap m_map;

View File

@@ -6,8 +6,9 @@
#include "CLog.h"
#include "XThread.h"
#include "ISocket.h"
#include <set>
#include <sstream>
#include "stdset.h"
#include "stdsstream.h"
#include <assert.h>
//
// CHTTPServer
@@ -158,7 +159,7 @@ void CHTTPServer::doProcessGetEditMap(
static const char* s_editMapScreenEnd =
"</td>\r\n";
ostringstream s;
std::ostringstream s;
// convert screen map into a temporary screen map
CScreenArray screens;
@@ -236,7 +237,7 @@ void CHTTPServer::doProcessPostEditMap(
}
try {
ostringstream s;
std::ostringstream s;
// convert post data into a temporary screen map. also check
// that no screen name is invalid or used more than once.
@@ -309,7 +310,7 @@ void CHTTPServer::doProcessPostEditMap(
// now reply with current map
doProcessGetEditMap(request, reply);
}
catch (XHTTP& e) {
catch (XHTTP&) {
// FIXME -- construct a more meaningful error?
throw;
}
@@ -318,7 +319,7 @@ void CHTTPServer::doProcessPostEditMap(
bool CHTTPServer::parseXY(
const CString& xy, SInt32& x, SInt32& y)
{
istringstream s(xy);
std::istringstream s(xy);
char delimiter;
s >> x;
s.get(delimiter);
@@ -326,65 +327,10 @@ bool CHTTPServer::parseXY(
return (!!s && delimiter == 'x');
}
/*
#include <iostream> // FIXME
// FIXME
cout << "method: " << request.m_method << endl;
cout << "uri: " << request.m_uri << endl;
cout << "version: " << request.m_majorVersion << "." <<
request.m_majorVersion << endl;
cout << "headers:" << endl;
for (CHTTPRequest::CHeaderMap::const_iterator
index = request.m_headerIndexByName.begin();
index != request.m_headerIndexByName.end();
++index) {
assert(index->second < request.m_headers.size());
cout << " " << index->first << ": " <<
request.m_headers[index->second] << endl;
}
cout << endl;
cout << request.m_body << endl;
// FIXME
reply.m_majorVersion = request.m_majorVersion;
reply.m_minorVersion = request.m_minorVersion;
reply.m_status = 200;
reply.m_reason = "OK";
reply.m_method = request.m_method;
reply.m_headers.push_back(std::make_pair(CString("Content-Type"),
CString("text/html")));
if (request.m_uri != "/bar") {
reply.m_body =
"<html>\r\n"
" <head>\r\n"
" <title>test</title>\r\n"
" </head>\r\n"
" <body>\r\n"
" <h2>test</h2>\r\n"
" <form method=POST action=\"bar\" enctype=\"multipart/form-data\">\r\n"
" <input type=text name=a size=8 maxlength=40 value=\"aValue\">\r\n"
" <input type=submit name=b value=\"blah\">\r\n"
" </form>\r\n"
" </body>\r\n"
"</html>\r\n"
;
}
else {
reply.m_body =
"<html>\r\n"
" <head>\r\n"
" <title>test reply</title>\r\n"
" </head>\r\n"
" <body>\r\n"
" <h2>test reply</h2>\r\n"
" </body>\r\n"
"</html>\r\n"
;
}
// FIXME
*/
//
// CHTTPServer::CScreenArray
//
CHTTPServer::CScreenArray::CScreenArray() : m_w(0), m_h(0)
{

View File

@@ -3,7 +3,7 @@
#include "BasicTypes.h"
#include "CString.h"
#include <vector>
#include "stdvector.h"
class CServer;
class CConfig;

View File

@@ -22,7 +22,13 @@ CMSWindowsPrimaryScreen::CMSWindowsPrimaryScreen() :
m_mark(0),
m_markReceived(0)
{
// do nothing
// detect operating system
OSVERSIONINFO version;
version.dwOSVersionInfoSize = sizeof(version);
if (GetVersionEx(&version) == 0) {
log((CLOG_WARN "cannot determine OS: %d", GetLastError()));
}
m_is95Family = (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
}
CMSWindowsPrimaryScreen::~CMSWindowsPrimaryScreen()
@@ -97,7 +103,19 @@ void CMSWindowsPrimaryScreen::doEnter()
// not active anymore
m_active = false;
// set the zones that should cause a jump
// release keyboard/mouse and set the zones that should cause a jump
/* FIXME
if (UnregisterHotKey(m_window, 0x0001) != 0) {
log((CLOG_INFO "released hot key"));
}
else {
log((CLOG_INFO "failed to release hot key: %d", GetLastError()));
}
*/
if (m_is95Family) {
DWORD dummy = 0;
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, &dummy, 0);
}
SInt32 w, h;
getScreenSize(&w, &h);
SetZoneFunc setZone = (SetZoneFunc)GetProcAddress(
@@ -159,6 +177,19 @@ void CMSWindowsPrimaryScreen::leave()
SetRelayFunc setRelay = (SetRelayFunc)GetProcAddress(
m_hookLibrary, "setRelay");
setRelay();
if (m_is95Family) {
// disable ctrl+alt+del, alt+tab, ctrl+esc
DWORD dummy = 0;
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0);
}
/* FIXME
if (RegisterHotKey(m_window, 0x0001, MOD_ALT, VK_TAB) != 0) {
log((CLOG_INFO "got hot key"));
}
else {
log((CLOG_INFO "failed to get hot key: %d", GetLastError()));
}
*/
// get keyboard input and capture mouse
SetActiveWindow(m_window);
@@ -203,6 +234,17 @@ void CMSWindowsPrimaryScreen::leave()
}
}
void CMSWindowsPrimaryScreen::onConfigure()
{
if (!m_active) {
SInt32 w, h;
getScreenSize(&w, &h);
SetZoneFunc setZone = (SetZoneFunc)GetProcAddress(
m_hookLibrary, "setZone");
setZone(m_server->getActivePrimarySides(), w, h, getJumpZoneSize());
}
}
void CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
{
// set the cursor position without generating an event
@@ -479,7 +521,12 @@ LRESULT CMSWindowsPrimaryScreen::onEvent(
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
// FIXME -- handle display changes (and resize full-screen window)
/*
case WM_HOTKEY:
log((CLOG_INFO "hot key: %d, %d, %s %s %s", wParam, HIWORD(lParam), (LOWORD(lParam) & MOD_ALT) ? "ALT" : "", (LOWORD(lParam) & MOD_CONTROL) ? "CTRL" : "", (LOWORD(lParam) & MOD_SHIFT) ? "SHIFT" : "", (LOWORD(lParam) & MOD_WIN) ? "WIN" : ""));
return 0;
*/
case WM_PAINT:
ValidateRect(hwnd, NULL);
return 0;

View File

@@ -20,6 +20,7 @@ public:
virtual void close();
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void leave();
virtual void onConfigure();
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void setClipboard(ClipboardID, const IClipboard*);
virtual void grabClipboard(ClipboardID);
@@ -49,6 +50,7 @@ private:
private:
CServer* m_server;
bool m_is95Family;
bool m_active;
HWND m_window;
HWND m_nextClipboardWindow;

View File

@@ -151,6 +151,11 @@ bool CServer::setConfig(const CConfig& config)
// cut over
m_config = config;
// tell primary screen about reconfiguration
if (m_primary != NULL) {
m_primary->onConfigure();
}
}
// wait for old secondary screen threads to disconnect. must

View File

@@ -10,8 +10,8 @@
#include "CString.h"
#include "CThread.h"
#include "XBase.h"
#include <list>
#include <map>
#include "stdlist.h"
#include "stdmap.h"
class CThread;
class IServerProtocol;

View File

@@ -42,6 +42,10 @@ static HHOOK g_keyboard = NULL;
static HHOOK g_mouse = NULL;
static HHOOK g_cbt = NULL;
static HHOOK g_getMessage = NULL;
static HANDLE g_keyHookThread = NULL;
static DWORD g_keyHookThreadID = 0;
static HANDLE g_keyHookEvent = NULL;
static HHOOK g_keyboardLL = NULL;
static bool g_relay = false;
static SInt32 g_zoneSize = 0;
static UInt32 g_zoneSides = 0;
@@ -103,7 +107,9 @@ static LRESULT CALLBACK keyboardHook(int code, WPARAM wParam, LPARAM lParam)
case VK_CAPITAL:
case VK_NUMLOCK:
case VK_SCROLL:
// pass event
// pass event on. we want to let these through to
// the window proc because otherwise the keyboard
// lights may not stay synchronized.
break;
default:
@@ -250,6 +256,119 @@ static LRESULT CALLBACK getMessageHook(int code, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(g_getMessage, code, wParam, lParam);
}
#if (_WIN32_WINNT >= 0x0400)
//
// low-level keyboard hook -- this allows us to capture and handle
// alt+tab, alt+esc, ctrl+esc, and windows key hot keys. on the down
// side, key repeats are not compressed for us.
//
static LRESULT CALLBACK keyboardLLHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code >= 0) {
if (g_relay) {
KBDLLHOOKSTRUCT* info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
// let certain keys pass through
switch (info->vkCode) {
case VK_CAPITAL:
case VK_NUMLOCK:
case VK_SCROLL:
// pass event on. we want to let these through to
// the window proc because otherwise the keyboard
// lights may not stay synchronized.
break;
default:
// construct lParam for WM_KEYDOWN, etc.
DWORD lParam = 1; // repeat code
lParam |= (info->scanCode << 16); // scan code
if (info->flags & LLKHF_EXTENDED) {
lParam |= (1lu << 24); // extended key
}
if (info->flags & LLKHF_ALTDOWN) {
lParam |= (1lu << 29); // context code
}
if (info->flags & LLKHF_UP) {
lParam |= (1lu << 31); // transition
}
// FIXME -- bit 30 should be set if key was already down
// forward message to our window
PostMessage(g_hwnd, SYNERGY_MSG_KEY, info->vkCode, lParam);
// discard event
return 1;
}
}
}
return CallNextHookEx(g_keyboardLL, code, wParam, lParam);
}
static DWORD WINAPI getKeyboardLLProc(void*)
{
// thread proc for low-level keyboard hook. this does nothing but
// install the hook, process events, and uninstall the hook.
// force this thread to have a message queue
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// install low-level keyboard hook
g_keyboardLL = SetWindowsHookEx(WH_KEYBOARD_LL,
&keyboardLLHook,
g_hinstance,
0);
if (g_keyboardLL == NULL) {
// indicate failure and exit
g_keyHookThreadID = 0;
SetEvent(g_keyHookEvent);
return 1;
}
// ready
SetEvent(g_keyHookEvent);
// message loop
bool done = false;
while (!done) {
switch (GetMessage(&msg, NULL, 0, 0)) {
case -1:
break;
case 0:
done = true;
break;
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
// uninstall hook
UnhookWindowsHookEx(g_keyboardLL);
g_keyboardLL = NULL;
return 0;
}
#else // (_WIN32_WINNT < 0x0400)
#error foo
static DWORD WINAPI getKeyboardLLProc(void*)
{
g_keyHookThreadID = 0;
SetEvent(g_keyHookEvent);
return 1;
}
#endif
static EWheelSupport GetWheelSupport()
{
// get operating system
@@ -286,8 +405,8 @@ static EWheelSupport GetWheelSupport()
// assume modern. we don't do anything special in this case
// except respond to WM_MOUSEWHEEL messages. GetSystemMetrics()
// can apparently return FALSE even if a mouse wheel is present
// though i'm not sure exactly when it does that (but WinME does
// for my logitech usb trackball).
// though i'm not sure exactly when it does that (WinME returns
// FALSE for my logitech USB trackball).
return kWheelModern;
}
@@ -387,6 +506,34 @@ int install(HWND hwnd)
// ignore failure; we just won't get mouse wheel messages
}
// install low-level keyboard hook, if possible. since this hook
// is called in the context of the installing thread and that
// thread must have a message loop but we don't want the caller's
// message loop to do the work, we'll fire up a separate thread
// just for the hook. note that low-level keyboard hooks are only
// available on windows NT SP3 and above.
g_keyHookEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_keyHookEvent != NULL) {
g_keyHookThread = CreateThread(NULL, 0, &getKeyboardLLProc, 0,
CREATE_SUSPENDED, &g_keyHookThreadID);
if (g_keyHookThread != NULL) {
// start the thread and wait for it to initialize
ResumeThread(g_keyHookThread);
WaitForSingleObject(g_keyHookEvent, INFINITE);
ResetEvent(g_keyHookEvent);
// the thread clears g_keyHookThreadID if it failed
if (g_keyHookThreadID == 0) {
CloseHandle(g_keyHookThread);
g_keyHookThread = NULL;
}
}
if (g_keyHookThread == NULL) {
CloseHandle(g_keyHookEvent);
g_keyHookEvent = NULL;
}
}
return 1;
}
@@ -397,6 +544,15 @@ int uninstall(void)
assert(g_cbt != NULL);
// uninstall hooks
if (g_keyHookThread != NULL) {
PostThreadMessage(g_keyHookThreadID, WM_QUIT, 0, 0);
WaitForSingleObject(g_keyHookThread, INFINITE);
CloseHandle(g_keyHookEvent);
CloseHandle(g_keyHookThread);
g_keyHookEvent = NULL;
g_keyHookThread = NULL;
g_keyHookThreadID = 0;
}
UnhookWindowsHookEx(g_keyboard);
UnhookWindowsHookEx(g_mouse);
UnhookWindowsHookEx(g_cbt);

View File

@@ -303,6 +303,11 @@ void CXWindowsPrimaryScreen::leave()
m_active = true;
}
void CXWindowsPrimaryScreen::onConfigure()
{
// do nothing
}
void CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
{
CDisplayLock display(this);

View File

@@ -18,6 +18,7 @@ public:
virtual void close();
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void leave();
virtual void onConfigure();
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void setClipboard(ClipboardID, const IClipboard*);
virtual void grabClipboard(ClipboardID);

View File

@@ -4,7 +4,8 @@
#include "CMutex.h"
#include "CNetwork.h"
#include "CThread.h"
#include <fstream>
#include "stdfstream.h"
#include <assert.h>
//
// config file stuff
@@ -54,7 +55,7 @@ void realMain()
CConfig config;
{
log((CLOG_DEBUG "opening configuration"));
ifstream configStream(s_configFileName);
std::ifstream configStream(s_configFileName);
if (!configStream) {
throw XConfigRead("cannot open configuration");
}

View File

@@ -42,7 +42,7 @@ RSC=rc.exe
# 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
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\http" /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
@@ -68,7 +68,7 @@ LINK32=link.exe
# 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
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\http" /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
@@ -92,11 +92,15 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.cpp
SOURCE=.\CConfig.cpp
# End Source File
# Begin Source File
SOURCE=.\CConfig.cpp
SOURCE=.\CHTTPServer.cpp
# End Source File
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.cpp
# End Source File
# Begin Source File
@@ -124,11 +128,15 @@ SOURCE=.\server.rc
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.h
SOURCE=.\CConfig.h
# End Source File
# Begin Source File
SOURCE=.\CConfig.h
SOURCE=.\CHTTPServer.h
# End Source File
# Begin Source File
SOURCE=.\CMSWindowsPrimaryScreen.h
# End Source File
# Begin Source File

View File

@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "ReleaseHook"
# 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
# ADD CPP /nologo /MT /W4 /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
@@ -68,7 +68,7 @@ LINK32=link.exe
# PROP Intermediate_Dir "DebugHook"
# 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
# ADD CPP /nologo /MTd /W4 /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
@@ -93,6 +93,7 @@ LINK32=link.exe
# Begin Source File
SOURCE=.\CSynergyHook.cpp
# ADD CPP /D _WIN32_WINNT=0x0400
# End Source File
# End Group
# Begin Group "Header Files"