merged 1.4 r1007:1008 into trunk

This commit is contained in:
Nick Bolton 2011-05-21 00:30:08 +00:00
parent bebf8c2c2c
commit 5a315324ca
39 changed files with 808 additions and 2854 deletions

2327
.cproject

File diff suppressed because it is too large Load Diff

110
.project
View File

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>synergy-Debug@synergy-plus-git-svn</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.make.core.makeBuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.command</key>
<value>/opt/local/bin/gmake</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.inc</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.arguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>/Users/jason/programming/synergy-plus-git-svn</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.environment</key>
<value>VERBOSE=1|CMAKE_NO_VERBOSE=1|</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.auto</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.clean</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.location</key>
<value>/Users/jason/programming/synergy-plus-git-svn</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.core.errorOutputParser</key>
<value>org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.make.core.makeNature</nature>
<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
</natures>
</projectDescription>

View File

@ -39,16 +39,15 @@ endif()
project(synergy C CXX) project(synergy C CXX)
# put binaries in a different dir to make them easier to find. # put binaries in a different dir to make them easier to find.
if (WIN32) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
elseif (UNIX) # for unix, put debug files in a separate bin "debug" dir.
# release bin files should stay in the root of the bin dir.
if (UNIX)
if (CMAKE_BUILD_TYPE STREQUAL Debug) if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/debug) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/debug)
elseif (CMAKE_BUILD_TYPE STREQUAL Release)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/release)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/release)
endif() endif()
endif() endif()

2
configure vendored Normal file
View File

@ -0,0 +1,2 @@
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .

21
hm.py
View File

@ -46,21 +46,17 @@ requiredMajor = 2
requiredMinor = 3 requiredMinor = 3
# options used by all commands # options used by all commands
global_options = 'g:v' globalOptions = 'v'
global_options_long = ['no-prompts', 'generator=', 'verbose', 'make-gui'] globalOptionsLong = ['no-prompts', 'generator=', 'verbose', 'make-gui']
# options used by build related commands
build_options = 'dr'
build_options_long = ['debug', 'release']
# list of valid commands as keys. the values are optarg strings, but most # list of valid commands as keys. the values are optarg strings, but most
# are None for now (this is mainly for extensibility) # are None for now (this is mainly for extensibility)
cmd_opt_dict = { cmd_opt_dict = {
'about' : ['', []], 'about' : ['', []],
'setup' : ['', []], 'setup' : ['g:', []],
'configure' : [build_options, build_options_long], 'configure' : ['g:dr', ['debug', 'release']],
'build' : [build_options, build_options_long], 'build' : ['dr', ['debug', 'release']],
'clean' : [build_options, build_options_long], 'clean' : ['dr', ['debug', 'release']],
'update' : ['', []], 'update' : ['', []],
'install' : ['', []], 'install' : ['', []],
'doxygen' : ['', []], 'doxygen' : ['', []],
@ -170,10 +166,10 @@ def run_cmd(cmd, argv = []):
try: try:
options_pair = cmd_opt_dict[cmd] options_pair = cmd_opt_dict[cmd]
options = global_options + options_pair[0] options = globalOptions + options_pair[0]
options_long = [] options_long = []
options_long.extend(global_options_long) options_long.extend(globalOptionsLong)
options_long.extend(options_pair[1]) options_long.extend(options_pair[1])
opts, args = gnu_getopt(argv, options, options_long) opts, args = gnu_getopt(argv, options, options_long)
@ -214,3 +210,4 @@ def main(argv):
# Start the program. # Start the program.
main(sys.argv) main(sys.argv)

View File

@ -64,24 +64,6 @@ CEvent::getFlags() const
return m_flags; return m_flags;
} }
CEvent::Type
CEvent::registerType(const char* name)
{
return EVENTQUEUE->registerType(name);
}
CEvent::Type
CEvent::registerTypeOnce(Type& type, const char* name)
{
return EVENTQUEUE->registerTypeOnce(type, name);
}
const char*
CEvent::getTypeName(Type type)
{
return EVENTQUEUE->getTypeName(type);
}
void void
CEvent::deleteData(const CEvent& event) CEvent::deleteData(const CEvent& event)
{ {

View File

@ -59,27 +59,6 @@ public:
//! @name manipulators //! @name manipulators
//@{ //@{
//! Creates a new event type
/*!
Returns a unique event type id.
*/
static Type registerType(const char* name);
//! Creates a new event type
/*!
If \p type contains \c kUnknown then it is set to a unique event
type id otherwise it is left alone. The final value of \p type
is returned.
*/
static Type registerTypeOnce(Type& type, const char* name);
//! Get name for event
/*!
Returns the name for the event \p type. This is primarily for
debugging.
*/
static const char* getTypeName(Type type);
//! Release event data //! Release event data
/*! /*!
Deletes event data for the given event (using free()). Deletes event data for the given event (using free()).

View File

@ -187,21 +187,21 @@ CClient::getServerAddress() const
CEvent::Type CEvent::Type
CClient::getConnectedEvent() CClient::getConnectedEvent()
{ {
return CEvent::registerTypeOnce(s_connectedEvent, return EVENTQUEUE->registerTypeOnce(s_connectedEvent,
"CClient::connected"); "CClient::connected");
} }
CEvent::Type CEvent::Type
CClient::getConnectionFailedEvent() CClient::getConnectionFailedEvent()
{ {
return CEvent::registerTypeOnce(s_connectionFailedEvent, return EVENTQUEUE->registerTypeOnce(s_connectionFailedEvent,
"CClient::failed"); "CClient::failed");
} }
CEvent::Type CEvent::Type
CClient::getDisconnectedEvent() CClient::getDisconnectedEvent()
{ {
return CEvent::registerTypeOnce(s_disconnectedEvent, return EVENTQUEUE->registerTypeOnce(s_disconnectedEvent,
"CClient::disconnected"); "CClient::disconnected");
} }

View File

@ -33,6 +33,7 @@ if (WIN32)
endif() endif()
set(inc set(inc
../arch
../base ../base
../common ../common
) )

View File

@ -16,6 +16,7 @@
*/ */
#include "IStream.h" #include "IStream.h"
#include "CEventQueue.h"
// //
// IStream // IStream
@ -30,34 +31,34 @@ CEvent::Type IStream::s_outputShutdownEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
IStream::getInputReadyEvent() IStream::getInputReadyEvent()
{ {
return CEvent::registerTypeOnce(s_inputReadyEvent, return EVENTQUEUE->registerTypeOnce(s_inputReadyEvent,
"IStream::inputReady"); "IStream::inputReady");
} }
CEvent::Type CEvent::Type
IStream::getOutputFlushedEvent() IStream::getOutputFlushedEvent()
{ {
return CEvent::registerTypeOnce(s_outputFlushedEvent, return EVENTQUEUE->registerTypeOnce(s_outputFlushedEvent,
"IStream::outputFlushed"); "IStream::outputFlushed");
} }
CEvent::Type CEvent::Type
IStream::getOutputErrorEvent() IStream::getOutputErrorEvent()
{ {
return CEvent::registerTypeOnce(s_outputErrorEvent, return EVENTQUEUE->registerTypeOnce(s_outputErrorEvent,
"IStream::outputError"); "IStream::outputError");
} }
CEvent::Type CEvent::Type
IStream::getInputShutdownEvent() IStream::getInputShutdownEvent()
{ {
return CEvent::registerTypeOnce(s_inputShutdownEvent, return EVENTQUEUE->registerTypeOnce(s_inputShutdownEvent,
"IStream::inputShutdown"); "IStream::inputShutdown");
} }
CEvent::Type CEvent::Type
IStream::getOutputShutdownEvent() IStream::getOutputShutdownEvent()
{ {
return CEvent::registerTypeOnce(s_outputShutdownEvent, return EVENTQUEUE->registerTypeOnce(s_outputShutdownEvent,
"IStream::outputShutdown"); "IStream::outputShutdown");
} }

View File

@ -16,6 +16,7 @@
*/ */
#include "IDataSocket.h" #include "IDataSocket.h"
#include "CEventQueue.h"
// //
// IDataSocket // IDataSocket
@ -27,14 +28,14 @@ CEvent::Type IDataSocket::s_failedEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
IDataSocket::getConnectedEvent() IDataSocket::getConnectedEvent()
{ {
return CEvent::registerTypeOnce(s_connectedEvent, return EVENTQUEUE->registerTypeOnce(s_connectedEvent,
"IDataSocket::connected"); "IDataSocket::connected");
} }
CEvent::Type CEvent::Type
IDataSocket::getConnectionFailedEvent() IDataSocket::getConnectionFailedEvent()
{ {
return CEvent::registerTypeOnce(s_failedEvent, return EVENTQUEUE->registerTypeOnce(s_failedEvent,
"IDataSocket::failed"); "IDataSocket::failed");
} }

View File

@ -16,6 +16,7 @@
*/ */
#include "IListenSocket.h" #include "IListenSocket.h"
#include "CEventQueue.h"
// //
// IListenSocket // IListenSocket
@ -26,6 +27,6 @@ CEvent::Type IListenSocket::s_connectingEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
IListenSocket::getConnectingEvent() IListenSocket::getConnectingEvent()
{ {
return CEvent::registerTypeOnce(s_connectingEvent, return EVENTQUEUE->registerTypeOnce(s_connectingEvent,
"IListenSocket::connecting"); "IListenSocket::connecting");
} }

View File

@ -16,6 +16,7 @@
*/ */
#include "ISocket.h" #include "ISocket.h"
#include "CEventQueue.h"
// //
// ISocket // ISocket
@ -26,6 +27,6 @@ CEvent::Type ISocket::s_disconnectedEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
ISocket::getDisconnectedEvent() ISocket::getDisconnectedEvent()
{ {
return CEvent::registerTypeOnce(s_disconnectedEvent, return EVENTQUEUE->registerTypeOnce(s_disconnectedEvent,
"ISocket::disconnected"); "ISocket::disconnected");
} }

View File

@ -115,7 +115,7 @@ CClientListener::getNextClient()
CEvent::Type CEvent::Type
CClientListener::getConnectedEvent() CClientListener::getConnectedEvent()
{ {
return CEvent::registerTypeOnce(s_connectedEvent, return EVENTQUEUE->registerTypeOnce(s_connectedEvent,
"CClientListener::connected"); "CClientListener::connected");
} }

View File

@ -19,6 +19,7 @@
#include "CProtocolUtil.h" #include "CProtocolUtil.h"
#include "IStream.h" #include "IStream.h"
#include "CLog.h" #include "CLog.h"
#include "CEventQueue.h"
// //
// CClientProxy // CClientProxy
@ -59,21 +60,21 @@ CClientProxy::getStream() const
CEvent::Type CEvent::Type
CClientProxy::getReadyEvent() CClientProxy::getReadyEvent()
{ {
return CEvent::registerTypeOnce(s_readyEvent, return EVENTQUEUE->registerTypeOnce(s_readyEvent,
"CClientProxy::ready"); "CClientProxy::ready");
} }
CEvent::Type CEvent::Type
CClientProxy::getDisconnectedEvent() CClientProxy::getDisconnectedEvent()
{ {
return CEvent::registerTypeOnce(s_disconnectedEvent, return EVENTQUEUE->registerTypeOnce(s_disconnectedEvent,
"CClientProxy::disconnected"); "CClientProxy::disconnected");
} }
CEvent::Type CEvent::Type
CClientProxy::getClipboardChangedEvent() CClientProxy::getClipboardChangedEvent()
{ {
return CEvent::registerTypeOnce(s_clipboardChangedEvent, return EVENTQUEUE->registerTypeOnce(s_clipboardChangedEvent,
"CClientProxy::clipboardChanged"); "CClientProxy::clipboardChanged");
} }

View File

@ -79,14 +79,14 @@ CClientProxyUnknown::orphanClientProxy()
CEvent::Type CEvent::Type
CClientProxyUnknown::getSuccessEvent() CClientProxyUnknown::getSuccessEvent()
{ {
return CEvent::registerTypeOnce(s_successEvent, return EVENTQUEUE->registerTypeOnce(s_successEvent,
"CClientProxy::success"); "CClientProxy::success");
} }
CEvent::Type CEvent::Type
CClientProxyUnknown::getFailureEvent() CClientProxyUnknown::getFailureEvent()
{ {
return CEvent::registerTypeOnce(s_failureEvent, return EVENTQUEUE->registerTypeOnce(s_failureEvent,
"CClientProxy::failure"); "CClientProxy::failure");
} }

View File

@ -536,8 +536,8 @@ CInputFilter::CKeystrokeAction::format() const
void void
CInputFilter::CKeystrokeAction::perform(const CEvent& event) CInputFilter::CKeystrokeAction::perform(const CEvent& event)
{ {
CEvent::Type type = m_press ? IPlatformScreen::getKeyDownEvent() : CEvent::Type type = m_press ? IPlatformScreen::getKeyDownEvent(*EVENTQUEUE) :
IPlatformScreen::getKeyUpEvent(); IPlatformScreen::getKeyUpEvent(*EVENTQUEUE);
EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getFakeInputBeginEvent(), EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getFakeInputBeginEvent(),
event.getTarget(), NULL, event.getTarget(), NULL,
CEvent::kDeliverImmediately)); CEvent::kDeliverImmediately));
@ -609,7 +609,7 @@ CInputFilter::CMouseButtonAction::perform(const CEvent& event)
KeyID key = m_press ? kKeySetModifiers : kKeyClearModifiers; KeyID key = m_press ? kKeySetModifiers : kKeyClearModifiers;
modifierInfo = modifierInfo =
IKeyState::CKeyInfo::alloc(key, m_buttonInfo->m_mask, 0, 1); IKeyState::CKeyInfo::alloc(key, m_buttonInfo->m_mask, 0, 1);
EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getKeyDownEvent(), EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
event.getTarget(), modifierInfo, event.getTarget(), modifierInfo,
CEvent::kDeliverImmediately)); CEvent::kDeliverImmediately));
} }
@ -937,11 +937,11 @@ CInputFilter::setPrimaryClient(CPrimaryClient* client)
rule->disable(m_primaryClient); rule->disable(m_primaryClient);
} }
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget()); m_primaryClient->getEventTarget());
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyUpEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget()); m_primaryClient->getEventTarget());
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyRepeatEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyRepeatEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget()); m_primaryClient->getEventTarget());
EVENTQUEUE->removeHandler(IPlatformScreen::getButtonDownEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getButtonDownEvent(),
m_primaryClient->getEventTarget()); m_primaryClient->getEventTarget());
@ -958,15 +958,15 @@ CInputFilter::setPrimaryClient(CPrimaryClient* client)
m_primaryClient = client; m_primaryClient = client;
if (m_primaryClient != NULL) { if (m_primaryClient != NULL) {
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyDownEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget(), m_primaryClient->getEventTarget(),
new TMethodEventJob<CInputFilter>(this, new TMethodEventJob<CInputFilter>(this,
&CInputFilter::handleEvent)); &CInputFilter::handleEvent));
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyUpEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget(), m_primaryClient->getEventTarget(),
new TMethodEventJob<CInputFilter>(this, new TMethodEventJob<CInputFilter>(this,
&CInputFilter::handleEvent)); &CInputFilter::handleEvent));
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyRepeatEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyRepeatEvent(*EVENTQUEUE),
m_primaryClient->getEventTarget(), m_primaryClient->getEventTarget(),
new TMethodEventJob<CInputFilter>(this, new TMethodEventJob<CInputFilter>(this,
&CInputFilter::handleEvent)); &CInputFilter::handleEvent));

View File

@ -95,15 +95,15 @@ CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient) :
EVENTQUEUE->adoptHandler(CEvent::kTimer, this, EVENTQUEUE->adoptHandler(CEvent::kTimer, this,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleSwitchWaitTimeout)); &CServer::handleSwitchWaitTimeout));
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyDownEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_inputFilter, m_inputFilter,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleKeyDownEvent)); &CServer::handleKeyDownEvent));
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyUpEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
m_inputFilter, m_inputFilter,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleKeyUpEvent)); &CServer::handleKeyUpEvent));
EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyRepeatEvent(), EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyRepeatEvent(* EVENTQUEUE),
m_inputFilter, m_inputFilter,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleKeyRepeatEvent)); &CServer::handleKeyRepeatEvent));
@ -182,11 +182,11 @@ CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient) :
CServer::~CServer() CServer::~CServer()
{ {
// remove event handlers and timers // remove event handlers and timers
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_inputFilter); m_inputFilter);
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyUpEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
m_inputFilter); m_inputFilter);
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyRepeatEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getKeyRepeatEvent(*EVENTQUEUE),
m_inputFilter); m_inputFilter);
EVENTQUEUE->removeHandler(IPlatformScreen::getButtonDownEvent(), EVENTQUEUE->removeHandler(IPlatformScreen::getButtonDownEvent(),
m_inputFilter); m_inputFilter);
@ -345,49 +345,49 @@ CServer::getClients(std::vector<CString>& list) const
CEvent::Type CEvent::Type
CServer::getErrorEvent() CServer::getErrorEvent()
{ {
return CEvent::registerTypeOnce(s_errorEvent, return EVENTQUEUE->registerTypeOnce(s_errorEvent,
"CServer::error"); "CServer::error");
} }
CEvent::Type CEvent::Type
CServer::getConnectedEvent() CServer::getConnectedEvent()
{ {
return CEvent::registerTypeOnce(s_connectedEvent, return EVENTQUEUE->registerTypeOnce(s_connectedEvent,
"CServer::connected"); "CServer::connected");
} }
CEvent::Type CEvent::Type
CServer::getDisconnectedEvent() CServer::getDisconnectedEvent()
{ {
return CEvent::registerTypeOnce(s_disconnectedEvent, return EVENTQUEUE->registerTypeOnce(s_disconnectedEvent,
"CServer::disconnected"); "CServer::disconnected");
} }
CEvent::Type CEvent::Type
CServer::getSwitchToScreenEvent() CServer::getSwitchToScreenEvent()
{ {
return CEvent::registerTypeOnce(s_switchToScreen, return EVENTQUEUE->registerTypeOnce(s_switchToScreen,
"CServer::switchToScreen"); "CServer::switchToScreen");
} }
CEvent::Type CEvent::Type
CServer::getSwitchInDirectionEvent() CServer::getSwitchInDirectionEvent()
{ {
return CEvent::registerTypeOnce(s_switchInDirection, return EVENTQUEUE->registerTypeOnce(s_switchInDirection,
"CServer::switchInDirection"); "CServer::switchInDirection");
} }
CEvent::Type CEvent::Type
CServer::getKeyboardBroadcastEvent() CServer::getKeyboardBroadcastEvent()
{ {
return CEvent::registerTypeOnce(s_keyboardBroadcast, return EVENTQUEUE->registerTypeOnce(s_keyboardBroadcast,
"CServer:keyboardBroadcast"); "CServer:keyboardBroadcast");
} }
CEvent::Type CEvent::Type
CServer::getLockCursorToScreenEvent() CServer::getLockCursorToScreenEvent()
{ {
return CEvent::registerTypeOnce(s_lockCursorToScreen, return EVENTQUEUE->registerTypeOnce(s_lockCursorToScreen,
"CServer::lockCursorToScreen"); "CServer::lockCursorToScreen");
} }

View File

@ -123,7 +123,7 @@ public:
//@{ //@{
//! Swap with another \c CKeyMap //! Swap with another \c CKeyMap
void swap(CKeyMap&); virtual void swap(CKeyMap&);
//! Add a key entry //! Add a key entry
/*! /*!
@ -189,19 +189,19 @@ public:
Records that modifier key \p key is half-duplex. This is called to Records that modifier key \p key is half-duplex. This is called to
set user configurable half-duplex settings. set user configurable half-duplex settings.
*/ */
void addHalfDuplexModifier(KeyID key); virtual void addHalfDuplexModifier(KeyID key);
//! Finish adding entries //! Finish adding entries
/*! /*!
Called after adding entries, this does some internal housekeeping. Called after adding entries, this does some internal housekeeping.
*/ */
void finish(); virtual void finish();
//! Iterate over all added keys items //! Iterate over all added keys items
/*! /*!
Calls \p cb for every key item. Calls \p cb for every key item.
*/ */
void foreachKey(ForeachKeyCallback cb, void* userData); virtual void foreachKey(ForeachKeyCallback cb, void* userData);
//@} //@}
//! @name accessors //! @name accessors
@ -251,7 +251,7 @@ public:
Returns \c true iff modifier key \p key or button \p button is Returns \c true iff modifier key \p key or button \p button is
half-duplex. half-duplex.
*/ */
bool isHalfDuplex(KeyID key, KeyButton button) const; virtual bool isHalfDuplex(KeyID key, KeyButton button) const;
//! Test if modifiers indicate a command //! Test if modifiers indicate a command
/*! /*!

View File

@ -16,7 +16,6 @@
*/ */
#include "CKeyState.h" #include "CKeyState.h"
#include "IEventQueue.h"
#include "CLog.h" #include "CLog.h"
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
@ -383,7 +382,31 @@ static const KeyID s_numpadTable[] = {
// //
CKeyState::CKeyState() : CKeyState::CKeyState() :
m_mask(0) IKeyState(),
m_mask(0),
m_keyMapPtr(new CKeyMap()),
m_keyMap(*m_keyMapPtr)
{
init();
}
CKeyState::CKeyState(IEventQueue& eventQueue, CKeyMap& keyMap) :
IKeyState(eventQueue),
m_mask(0),
m_keyMapPtr(0),
m_keyMap(keyMap)
{
init();
}
CKeyState::~CKeyState()
{
if (m_keyMapPtr)
delete m_keyMapPtr;
}
void
CKeyState::init()
{ {
memset(&m_keys, 0, sizeof(m_keys)); memset(&m_keys, 0, sizeof(m_keys));
memset(&m_syntheticKeys, 0, sizeof(m_syntheticKeys)); memset(&m_syntheticKeys, 0, sizeof(m_syntheticKeys));
@ -391,11 +414,6 @@ CKeyState::CKeyState() :
memset(&m_serverKeys, 0, sizeof(m_serverKeys)); memset(&m_serverKeys, 0, sizeof(m_serverKeys));
} }
CKeyState::~CKeyState()
{
// do nothing
}
void void
CKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState) CKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState)
{ {
@ -431,23 +449,23 @@ CKeyState::sendKeyEvent(
// ignore auto-repeat on half-duplex keys // ignore auto-repeat on half-duplex keys
} }
else { else {
EVENTQUEUE->addEvent(CEvent(getKeyDownEvent(), target, getEventQueue().addEvent(CEvent(getKeyDownEvent(), target,
CKeyInfo::alloc(key, mask, button, 1))); CKeyInfo::alloc(key, mask, button, 1)));
EVENTQUEUE->addEvent(CEvent(getKeyUpEvent(), target, getEventQueue().addEvent(CEvent(getKeyUpEvent(), target,
CKeyInfo::alloc(key, mask, button, 1))); CKeyInfo::alloc(key, mask, button, 1)));
} }
} }
else { else {
if (isAutoRepeat) { if (isAutoRepeat) {
EVENTQUEUE->addEvent(CEvent(getKeyRepeatEvent(), target, getEventQueue().addEvent(CEvent(getKeyRepeatEvent(), target,
CKeyInfo::alloc(key, mask, button, count))); CKeyInfo::alloc(key, mask, button, count)));
} }
else if (press) { else if (press) {
EVENTQUEUE->addEvent(CEvent(getKeyDownEvent(), target, getEventQueue().addEvent(CEvent(getKeyDownEvent(), target,
CKeyInfo::alloc(key, mask, button, 1))); CKeyInfo::alloc(key, mask, button, 1)));
} }
else { else {
EVENTQUEUE->addEvent(CEvent(getKeyUpEvent(), target, getEventQueue().addEvent(CEvent(getKeyUpEvent(), target,
CKeyInfo::alloc(key, mask, button, 1))); CKeyInfo::alloc(key, mask, button, 1)));
} }
} }

View File

@ -29,6 +29,7 @@ platform specific methods.
class CKeyState : public IKeyState { class CKeyState : public IKeyState {
public: public:
CKeyState(); CKeyState();
CKeyState(IEventQueue& eventQueue, CKeyMap& keyMap);
virtual ~CKeyState(); virtual ~CKeyState();
//! @name manipulators //! @name manipulators
@ -137,6 +138,7 @@ protected:
private: private:
typedef CKeyMap::Keystrokes Keystrokes; typedef CKeyMap::Keystrokes Keystrokes;
typedef CKeyMap::ModifierToKeys ModifierToKeys; typedef CKeyMap::ModifierToKeys ModifierToKeys;
public:
struct CAddActiveModifierContext { struct CAddActiveModifierContext {
public: public:
CAddActiveModifierContext(SInt32 group, KeyModifierMask mask, CAddActiveModifierContext(SInt32 group, KeyModifierMask mask,
@ -152,6 +154,7 @@ private:
CAddActiveModifierContext(const CAddActiveModifierContext&); CAddActiveModifierContext(const CAddActiveModifierContext&);
CAddActiveModifierContext& operator=(const CAddActiveModifierContext&); CAddActiveModifierContext& operator=(const CAddActiveModifierContext&);
}; };
private:
class ButtonToKeyLess { class ButtonToKeyLess {
public: public:
@ -166,6 +169,9 @@ private:
CKeyState(const CKeyState&); CKeyState(const CKeyState&);
CKeyState& operator=(const CKeyState&); CKeyState& operator=(const CKeyState&);
// called by all ctors.
void init();
// adds alias key sequences. these are sequences that are equivalent // adds alias key sequences. these are sequences that are equivalent
// to other sequences. // to other sequences.
void addAliasEntries(); void addAliasEntries();
@ -190,8 +196,11 @@ private:
CKeyMap::KeyItem& keyItem, void* vcontext); CKeyMap::KeyItem& keyItem, void* vcontext);
private: private:
// must be declared before m_keyMap. used when this class owns the key map.
CKeyMap* m_keyMapPtr;
// the keyboard map // the keyboard map
CKeyMap m_keyMap; CKeyMap& m_keyMap;
// current modifier state // current modifier state
KeyModifierMask m_mask; KeyModifierMask m_mask;

View File

@ -289,7 +289,7 @@ CServerApp::loadConfig(const CString& pathname)
CEvent::Type CEvent::Type
CServerApp::getReloadConfigEvent() CServerApp::getReloadConfigEvent()
{ {
return CEvent::registerTypeOnce(s_reloadConfigEvent, "reloadConfig"); return EVENTQUEUE->registerTypeOnce(s_reloadConfigEvent, "reloadConfig");
} }
void void
@ -303,13 +303,13 @@ CServerApp::forceReconnect(const CEvent&, void*)
CEvent::Type CEvent::Type
CServerApp::getForceReconnectEvent() CServerApp::getForceReconnectEvent()
{ {
return CEvent::registerTypeOnce(s_forceReconnectEvent, "forceReconnect"); return EVENTQUEUE->registerTypeOnce(s_forceReconnectEvent, "forceReconnect");
} }
CEvent::Type CEvent::Type
CServerApp::getResetServerEvent() CServerApp::getResetServerEvent()
{ {
return CEvent::registerTypeOnce(s_resetServerEvent, "resetServer"); return EVENTQUEUE->registerTypeOnce(s_resetServerEvent, "resetServer");
} }
void void

View File

@ -16,6 +16,7 @@
*/ */
#include "IKeyState.h" #include "IKeyState.h"
#include "CEventQueue.h"
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
@ -27,28 +28,37 @@ CEvent::Type IKeyState::s_keyDownEvent = CEvent::kUnknown;
CEvent::Type IKeyState::s_keyUpEvent = CEvent::kUnknown; CEvent::Type IKeyState::s_keyUpEvent = CEvent::kUnknown;
CEvent::Type IKeyState::s_keyRepeatEvent = CEvent::kUnknown; CEvent::Type IKeyState::s_keyRepeatEvent = CEvent::kUnknown;
CEvent::Type IKeyState::IKeyState() :
IKeyState::getKeyDownEvent() m_eventQueue(*EVENTQUEUE)
{ {
return CEvent::registerTypeOnce(s_keyDownEvent, }
IKeyState::IKeyState(IEventQueue& eventQueue) :
m_eventQueue(eventQueue)
{
}
CEvent::Type
IKeyState::getKeyDownEvent(IEventQueue& eventQueue)
{
return eventQueue.registerTypeOnce(s_keyDownEvent,
"IKeyState::keyDown"); "IKeyState::keyDown");
} }
CEvent::Type CEvent::Type
IKeyState::getKeyUpEvent() IKeyState::getKeyUpEvent(IEventQueue& eventQueue)
{ {
return CEvent::registerTypeOnce(s_keyUpEvent, return eventQueue.registerTypeOnce(s_keyUpEvent,
"IKeyState::keyUp"); "IKeyState::keyUp");
} }
CEvent::Type CEvent::Type
IKeyState::getKeyRepeatEvent() IKeyState::getKeyRepeatEvent(IEventQueue& eventQueue)
{ {
return CEvent::registerTypeOnce(s_keyRepeatEvent, return eventQueue.registerTypeOnce(s_keyRepeatEvent,
"IKeyState::keyRepeat"); "IKeyState::keyRepeat");
} }
// //
// IKeyState::CKeyInfo // IKeyState::CKeyInfo
// //

View File

@ -23,6 +23,7 @@
#include "CEvent.h" #include "CEvent.h"
#include "CString.h" #include "CString.h"
#include "stdset.h" #include "stdset.h"
#include "IEventQueue.h"
//! Key state interface //! Key state interface
/*! /*!
@ -31,6 +32,9 @@ to synthesize key events.
*/ */
class IKeyState : public IInterface { class IKeyState : public IInterface {
public: public:
IKeyState();
IKeyState(IEventQueue& eventQueue);
enum { enum {
kNumButtons = 0x200 kNumButtons = 0x200
}; };
@ -160,18 +164,33 @@ public:
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const = 0; virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const = 0;
//! Get key down event type. Event data is CKeyInfo*, count == 1. //! Get key down event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyDownEvent(); CEvent::Type getKeyDownEvent() { return getKeyDownEvent(m_eventQueue); }
//! Get key up event type. Event data is CKeyInfo*, count == 1. //! Get key up event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyUpEvent(); CEvent::Type getKeyUpEvent() { return getKeyUpEvent(m_eventQueue); }
//! Get key repeat event type. Event data is CKeyInfo*. //! Get key repeat event type. Event data is CKeyInfo*.
static CEvent::Type getKeyRepeatEvent(); CEvent::Type getKeyRepeatEvent() { return getKeyRepeatEvent(m_eventQueue); }
//! Get key down event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyDownEvent(IEventQueue& eventQueue);
//! Get key up event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyUpEvent(IEventQueue& eventQueue);
//! Get key repeat event type. Event data is CKeyInfo*.
static CEvent::Type getKeyRepeatEvent(IEventQueue& eventQueue);
//@} //@}
protected:
IEventQueue& getEventQueue() const { return m_eventQueue; }
private: private:
static CEvent::Type s_keyDownEvent; static CEvent::Type s_keyDownEvent;
static CEvent::Type s_keyUpEvent; static CEvent::Type s_keyUpEvent;
static CEvent::Type s_keyRepeatEvent; static CEvent::Type s_keyRepeatEvent;
IEventQueue& m_eventQueue;
}; };
#endif #endif

View File

@ -16,6 +16,7 @@
*/ */
#include "IPrimaryScreen.h" #include "IPrimaryScreen.h"
#include "CEventQueue.h"
#include <cstdlib> #include <cstdlib>
// //
@ -37,77 +38,77 @@ CEvent::Type IPrimaryScreen::s_fakeInputEnd = CEvent::kUnknown;
CEvent::Type CEvent::Type
IPrimaryScreen::getButtonDownEvent() IPrimaryScreen::getButtonDownEvent()
{ {
return CEvent::registerTypeOnce(s_buttonDownEvent, return EVENTQUEUE->registerTypeOnce(s_buttonDownEvent,
"IPrimaryScreen::buttonDown"); "IPrimaryScreen::buttonDown");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getButtonUpEvent() IPrimaryScreen::getButtonUpEvent()
{ {
return CEvent::registerTypeOnce(s_buttonUpEvent, return EVENTQUEUE->registerTypeOnce(s_buttonUpEvent,
"IPrimaryScreen::buttonUp"); "IPrimaryScreen::buttonUp");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getMotionOnPrimaryEvent() IPrimaryScreen::getMotionOnPrimaryEvent()
{ {
return CEvent::registerTypeOnce(s_motionPrimaryEvent, return EVENTQUEUE->registerTypeOnce(s_motionPrimaryEvent,
"IPrimaryScreen::motionPrimary"); "IPrimaryScreen::motionPrimary");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getMotionOnSecondaryEvent() IPrimaryScreen::getMotionOnSecondaryEvent()
{ {
return CEvent::registerTypeOnce(s_motionSecondaryEvent, return EVENTQUEUE->registerTypeOnce(s_motionSecondaryEvent,
"IPrimaryScreen::motionSecondary"); "IPrimaryScreen::motionSecondary");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getWheelEvent() IPrimaryScreen::getWheelEvent()
{ {
return CEvent::registerTypeOnce(s_wheelEvent, return EVENTQUEUE->registerTypeOnce(s_wheelEvent,
"IPrimaryScreen::wheel"); "IPrimaryScreen::wheel");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getScreensaverActivatedEvent() IPrimaryScreen::getScreensaverActivatedEvent()
{ {
return CEvent::registerTypeOnce(s_ssActivatedEvent, return EVENTQUEUE->registerTypeOnce(s_ssActivatedEvent,
"IPrimaryScreen::screensaverActivated"); "IPrimaryScreen::screensaverActivated");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getScreensaverDeactivatedEvent() IPrimaryScreen::getScreensaverDeactivatedEvent()
{ {
return CEvent::registerTypeOnce(s_ssDeactivatedEvent, return EVENTQUEUE->registerTypeOnce(s_ssDeactivatedEvent,
"IPrimaryScreen::screensaverDeactivated"); "IPrimaryScreen::screensaverDeactivated");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getHotKeyDownEvent() IPrimaryScreen::getHotKeyDownEvent()
{ {
return CEvent::registerTypeOnce(s_hotKeyDownEvent, return EVENTQUEUE->registerTypeOnce(s_hotKeyDownEvent,
"IPrimaryScreen::hotKeyDown"); "IPrimaryScreen::hotKeyDown");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getHotKeyUpEvent() IPrimaryScreen::getHotKeyUpEvent()
{ {
return CEvent::registerTypeOnce(s_hotKeyUpEvent, return EVENTQUEUE->registerTypeOnce(s_hotKeyUpEvent,
"IPrimaryScreen::hotKeyUp"); "IPrimaryScreen::hotKeyUp");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getFakeInputBeginEvent() IPrimaryScreen::getFakeInputBeginEvent()
{ {
return CEvent::registerTypeOnce(s_fakeInputBegin, return EVENTQUEUE->registerTypeOnce(s_fakeInputBegin,
"IPrimaryScreen::fakeInputBegin"); "IPrimaryScreen::fakeInputBegin");
} }
CEvent::Type CEvent::Type
IPrimaryScreen::getFakeInputEndEvent() IPrimaryScreen::getFakeInputEndEvent()
{ {
return CEvent::registerTypeOnce(s_fakeInputEnd, return EVENTQUEUE->registerTypeOnce(s_fakeInputEnd,
"IPrimaryScreen::fakeInputEnd"); "IPrimaryScreen::fakeInputEnd");
} }

View File

@ -16,6 +16,7 @@
*/ */
#include "IScreen.h" #include "IScreen.h"
#include "CEventQueue.h"
// //
// IScreen // IScreen
@ -30,34 +31,34 @@ CEvent::Type IScreen::s_resumeEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
IScreen::getErrorEvent() IScreen::getErrorEvent()
{ {
return CEvent::registerTypeOnce(s_errorEvent, return EVENTQUEUE->registerTypeOnce(s_errorEvent,
"IScreen::error"); "IScreen::error");
} }
CEvent::Type CEvent::Type
IScreen::getShapeChangedEvent() IScreen::getShapeChangedEvent()
{ {
return CEvent::registerTypeOnce(s_shapeChangedEvent, return EVENTQUEUE->registerTypeOnce(s_shapeChangedEvent,
"IScreen::shapeChanged"); "IScreen::shapeChanged");
} }
CEvent::Type CEvent::Type
IScreen::getClipboardGrabbedEvent() IScreen::getClipboardGrabbedEvent()
{ {
return CEvent::registerTypeOnce(s_clipboardGrabbedEvent, return EVENTQUEUE->registerTypeOnce(s_clipboardGrabbedEvent,
"IScreen::clipboardGrabbed"); "IScreen::clipboardGrabbed");
} }
CEvent::Type CEvent::Type
IScreen::getSuspendEvent() IScreen::getSuspendEvent()
{ {
return CEvent::registerTypeOnce(s_suspendEvent, return EVENTQUEUE->registerTypeOnce(s_suspendEvent,
"IScreen::suspend"); "IScreen::suspend");
} }
CEvent::Type CEvent::Type
IScreen::getResumeEvent() IScreen::getResumeEvent()
{ {
return CEvent::registerTypeOnce(s_resumeEvent, return EVENTQUEUE->registerTypeOnce(s_resumeEvent,
"IScreen::resume"); "IScreen::resume");
} }

View File

@ -77,7 +77,7 @@ TEST_F(CXWindowsClipboardTests, empty_singleFormat_hasReturnsFalse)
clipboard.empty(); clipboard.empty();
bool actual = clipboard.has(CXWindowsClipboard::kText); bool actual = clipboard.has(CXWindowsClipboard::kText);
EXPECT_EQ(false, actual); EXPECT_FALSE(actual);
} }
TEST_F(CXWindowsClipboardTests, add_newValue_valueWasStored) TEST_F(CXWindowsClipboardTests, add_newValue_valueWasStored)
@ -127,7 +127,7 @@ TEST_F(CXWindowsClipboardTests, has_withNoFormats_returnsFalse)
bool actual = clipboard.has(IClipboard::kText); bool actual = clipboard.has(IClipboard::kText);
EXPECT_EQ(false, actual); EXPECT_FALSE(actual);
} }
TEST_F(CXWindowsClipboardTests, get_withNoFormats_returnsEmpty) TEST_F(CXWindowsClipboardTests, get_withNoFormats_returnsEmpty)

View File

@ -13,7 +13,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
set(h
synergy/CKeyStateImpl.h
synergy/CMockEventQueue.h
synergy/CMockKeyMap.h
)
set(src set(src
${h}
Main.cpp Main.cpp
synergy/CClipboardTests.cpp synergy/CClipboardTests.cpp
synergy/CKeyStateTests.cpp synergy/CKeyStateTests.cpp

View File

@ -37,7 +37,7 @@ TEST(CClipboardTests, empty_singleFormat_hasReturnsFalse)
clipboard.empty(); clipboard.empty();
bool actual = clipboard.has(CClipboard::kText); bool actual = clipboard.has(CClipboard::kText);
EXPECT_EQ(false, actual); EXPECT_FALSE(actual);
} }
TEST(CClipboardTests, add_newValue_valueWasStored) TEST(CClipboardTests, add_newValue_valueWasStored)
@ -130,7 +130,7 @@ TEST(CClipboardTests, has_withNoFormats_returnsFalse)
bool actual = clipboard.has(IClipboard::kText); bool actual = clipboard.has(IClipboard::kText);
EXPECT_EQ(false, actual); EXPECT_FALSE(actual);
} }
TEST(CClipboardTests, get_withNoFormats_returnsEmpty) TEST(CClipboardTests, get_withNoFormats_returnsEmpty)
@ -281,7 +281,7 @@ TEST(CClipboardTests, unmarshall_emptyData_hasTextIsFalse)
clipboard.open(0); clipboard.open(0);
bool actual = clipboard.has(IClipboard::kText); bool actual = clipboard.has(IClipboard::kText);
EXPECT_EQ(false, actual); EXPECT_FALSE(actual);
} }
TEST(CClipboardTests, unmarshall_withTextSize285_getTextIsValid) TEST(CClipboardTests, unmarshall_withTextSize285_getTextIsValid)

View File

@ -0,0 +1,60 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2011 Chris Schoeneman, Nick Bolton, Sorin Sbarnea
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CKEYSTATEIMPL_H
#define CKEYSTATEIMPL_H
#include "CKeyState.h"
#include "gmock/gmock.h"
class CMockKeyMap;
class CMockEventQueue;
// while the class name indicates that this is actually a mock, we use a
// typedef later to rename it (so the name matches the compilation unit)
// so the tests are less confusing.
class CMockKeyState : public CKeyState
{
public:
CMockKeyState() : CKeyState()
{
}
CMockKeyState(const CMockEventQueue& eventQueue, const CMockKeyMap& keyMap) :
CKeyState((IEventQueue&)eventQueue, (CKeyMap&)keyMap)
{
}
MOCK_CONST_METHOD0(pollActiveGroup, SInt32());
MOCK_CONST_METHOD0(pollActiveModifiers, KeyModifierMask());
MOCK_METHOD0(fakeCtrlAltDel, bool());
MOCK_METHOD1(getKeyMap, void(CKeyMap&));
MOCK_METHOD1(fakeKey, void(const Keystroke&));
MOCK_CONST_METHOD1(pollPressedKeys, void(KeyButtonSet&));
};
// hide that we're actually testing a mock to make the unit tests less
// confusing. use NiceMock so that we don't get warnings for unexpected
// calls.
typedef ::testing::NiceMock<CMockKeyState> CKeyStateImpl;
typedef UInt32 KeyID;
typedef void (*ForeachKeyCallback)(
KeyID, SInt32 group, CKeyMap::KeyItem&, void* userData);
#endif

View File

@ -16,66 +16,205 @@
*/ */
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "CKeyState.h" #include <gmock/gmock.h>
#include "CKeyStateImpl.h"
#include "CMockEventQueue.h"
#include "CMockKeyMap.h"
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArg;
enum { enum {
kAKey = 30 kAKey = 30
}; };
class CKeyStateImpl : public CKeyState TEST(CKeyStateTests, onKey_aKeyDown_keyStateOne)
{ {
protected: CMockKeyMap keyMap;
virtual SInt32 pollActiveGroup() const CMockEventQueue eventQueue;
{ CKeyStateImpl keyState(eventQueue, keyMap);
return 0;
}
virtual KeyModifierMask pollActiveModifiers() const
{
return 0;
}
virtual bool fakeCtrlAltDel()
{
return false;
}
virtual void getKeyMap(CKeyMap& keyMap)
{
}
virtual void fakeKey(const Keystroke& keystroke)
{
}
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const
{
}
};
TEST(CKeyStateTests, onKey_aKeyPressed_keyStateOne)
{
CKeyStateImpl keyState;
keyState.onKey(kAKey, true, KeyModifierAlt); keyState.onKey(kAKey, true, KeyModifierAlt);
EXPECT_EQ(1, keyState.getKeyState(kAKey)); EXPECT_EQ(1, keyState.getKeyState(kAKey));
} }
TEST(CKeyStateTests, onKey_validButtonUp_keyStateZero) TEST(CKeyStateTests, onKey_aKeyUp_keyStateZero)
{ {
CKeyStateImpl keyState; CMockKeyMap keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
keyState.onKey(kAKey, false, KeyModifierAlt);
EXPECT_EQ(0, keyState.getKeyState(kAKey));
}
TEST(CKeyStateTests, onKey_invalidKey_keyStateZero)
{
CMockKeyMap keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
keyState.onKey(0, true, KeyModifierAlt); keyState.onKey(0, true, KeyModifierAlt);
EXPECT_EQ(0, keyState.getKeyState(0)); EXPECT_EQ(0, keyState.getKeyState(0));
} }
TEST(CKeyStateTests, onKey_bogusButtonDown_keyStateZero) TEST(CKeyStateTests, sendKeyEvent_halfDuplexAndRepeat_addEventNotCalled)
{ {
CKeyStateImpl keyState; NiceMock<CMockKeyMap> keyMap;
NiceMock<CMockEventQueue> eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
ON_CALL(keyMap, isHalfDuplex(_, _)).WillByDefault(Return(true));
keyState.onKey(0, true, KeyModifierAlt); EXPECT_CALL(eventQueue, addEvent(_)).Times(0);
EXPECT_EQ(0, keyState.getKeyState(0)); keyState.sendKeyEvent(NULL, false, true, kKeyCapsLock, 0, 0, 0);
}
TEST(CKeyStateTests, sendKeyEvent_halfDuplex_addEventCalledTwice)
{
CMockKeyMap keyMap;
NiceMock<CMockEventQueue> eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
ON_CALL(keyMap, isHalfDuplex(_, _)).WillByDefault(Return(true));
EXPECT_CALL(eventQueue, addEvent(_)).Times(2);
keyState.sendKeyEvent(NULL, false, false, kKeyCapsLock, 0, 0, 0);
}
TEST(CKeyStateTests, sendKeyEvent_keyRepeat_addEventCalledOnce)
{
CMockKeyMap keyMap;
NiceMock<CMockEventQueue> eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(eventQueue, addEvent(_)).Times(1);
keyState.sendKeyEvent(NULL, false, true, kAKey, 0, 0, 0);
}
TEST(CKeyStateTests, sendKeyEvent_keyDown_addEventCalledOnce)
{
CMockKeyMap keyMap;
NiceMock<CMockEventQueue> eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(eventQueue, addEvent(_)).Times(1);
keyState.sendKeyEvent(NULL, true, false, kAKey, 0, 0, 0);
}
TEST(CKeyStateTests, sendKeyEvent_keyUp_addEventCalledOnce)
{
CMockKeyMap keyMap;
NiceMock<CMockEventQueue> eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(eventQueue, addEvent(_)).Times(1);
keyState.sendKeyEvent(NULL, false, false, kAKey, 0, 0, 0);
}
TEST(CKeyStateTests, updateKeyMap_mockKeyMap_keyMapGotMock)
{
CMockKeyMap keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(keyMap, swap(_));
EXPECT_CALL(keyMap, finish());
keyState.updateKeyMap();
}
void
stubPollPressedKeys(IKeyState::KeyButtonSet& pressedKeys)
{
pressedKeys.insert(kAKey);
}
TEST(CKeyStateTests, updateKeyState_pollInsertsSingleKey_keyIsDown)
{
NiceMock<CMockKeyMap> keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
ON_CALL(keyState, pollPressedKeys(_)).WillByDefault(Invoke(stubPollPressedKeys));
keyState.updateKeyState();
bool actual = keyState.isKeyDown(kAKey);
ASSERT_TRUE(actual);
}
TEST(CKeyStateTests, updateKeyState_pollDoesNothing_keyNotSet)
{
NiceMock<CMockKeyMap> keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
keyState.updateKeyState();
bool actual = keyState.isKeyDown(kAKey);
ASSERT_FALSE(actual);
}
TEST(CKeyStateTests, updateKeyState_activeModifiers_maskSet)
{
NiceMock<CMockKeyMap> keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
ON_CALL(keyState, pollActiveModifiers()).WillByDefault(Return(KeyModifierAlt));
keyState.updateKeyState();
KeyModifierMask actual = keyState.getActiveModifiers();
ASSERT_EQ(KeyModifierAlt, actual);
}
TEST(CKeyStateTests, updateKeyState_activeModifiers_maskNotSet)
{
NiceMock<CMockKeyMap> keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
keyState.updateKeyState();
KeyModifierMask actual = keyState.getActiveModifiers();
ASSERT_EQ(0, actual);
}
void
assertMaskIsOne(ForeachKeyCallback cb, void* userData)
{
ASSERT_EQ(1, ((CKeyState::CAddActiveModifierContext*)userData)->m_mask);
}
TEST(CKeyStateTests, updateKeyState_activeModifiers_keyMapGotModifers)
{
CMockKeyMap keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(keyMap, foreachKey(_, _));
ON_CALL(keyState, pollActiveModifiers()).WillByDefault(Return(1));
ON_CALL(keyMap, foreachKey(_, _)).WillByDefault(Invoke(assertMaskIsOne));
keyState.updateKeyState();
}
TEST(CKeyStateTests, setHalfDuplexMask_capsLock_halfDuplexCapsLockAdded)
{
CMockKeyMap keyMap;
CMockEventQueue eventQueue;
CKeyStateImpl keyState(eventQueue, keyMap);
EXPECT_CALL(keyMap, addHalfDuplexModifier(kKeyCapsLock));
keyState.setHalfDuplexMask(KeyModifierCapsLock);
} }

View File

@ -0,0 +1,44 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2011 Chris Schoeneman, Nick Bolton, Sorin Sbarnea
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CMOCKEVENTQUEUE_H
#define CMOCKEVENTQUEUE_H
#include <gmock/gmock.h>
#include "IEventQueue.h"
class CMockEventQueue : public IEventQueue
{
public:
MOCK_METHOD2(newOneShotTimer, CEventQueueTimer*(double, void*));
MOCK_METHOD2(newTimer, CEventQueueTimer*(double, void*));
MOCK_METHOD2(getEvent, bool(CEvent&, double));
MOCK_METHOD1(adoptBuffer, void(IEventQueueBuffer*));
MOCK_METHOD2(registerTypeOnce, CEvent::Type(CEvent::Type&, const char*));
MOCK_METHOD1(removeHandlers, void(void*));
MOCK_METHOD1(registerType, CEvent::Type(const char*));
MOCK_CONST_METHOD0(isEmpty, bool());
MOCK_METHOD3(adoptHandler, void(CEvent::Type, void*, IEventJob*));
MOCK_METHOD1(getTypeName, const char*(CEvent::Type));
MOCK_METHOD1(addEvent, void(const CEvent&));
MOCK_METHOD2(removeHandler, void(CEvent::Type, void*));
MOCK_METHOD1(dispatchEvent, bool(const CEvent&));
MOCK_CONST_METHOD2(getHandler, IEventJob*(CEvent::Type, void*));
MOCK_METHOD1(deleteTimer, void(CEventQueueTimer*));
};
#endif

View File

@ -0,0 +1,34 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2011 Chris Schoeneman, Nick Bolton, Sorin Sbarnea
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CMOCKKEYMAP_H
#define CMOCKKEYMAP_H
#include <gmock/gmock.h>
#include "CKeyMap.h"
class CMockKeyMap : public CKeyMap
{
public:
MOCK_METHOD1(swap, void(CKeyMap&));
MOCK_METHOD0(finish, void());
MOCK_METHOD2(foreachKey, void(ForeachKeyCallback, void*));
MOCK_METHOD1(addHalfDuplexModifier, void(KeyID));
MOCK_CONST_METHOD2(isHalfDuplex, bool(KeyID, KeyButton));
};
#endif

View File

@ -12,3 +12,5 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from build import generators

50
tools/build/generators.py Normal file
View File

@ -0,0 +1,50 @@
class Generator(object):
def __init__(self, cmakeName, buildDir='build', sourceDir='..', binDir='bin'):
self.cmakeName = cmakeName
self.buildDir = buildDir
self.sourceDir = sourceDir
self.binDir = binDir
def getBuildDir(self, target):
return self.buildDir
def getBinDir(self, target=''):
return self.binDir
def getSourceDir(self):
return self.sourceDir
class MakefilesGenerator(Generator):
def __init__(self):
super(MakefilesGenerator, self).__init__('Unix Makefiles', 'build', '..', 'bin')
def getBuildDir(self, target):
return super(MakefilesGenerator, self).getBuildDir(target) + '/' + target
def getBinDir(self, target=''):
workingDir = super(MakefilesGenerator, self).getBinDir(target)
# only put debug files in separate bin dir
if target == 'debug':
workingDir += '/debug'
return workingDir
def getSourceDir(self):
return super(MakefilesGenerator, self).getSourceDir() + '/..'
class EclipseGenerator(Generator):
def __init__(self):
super(EclipseGenerator, self).__init__('Eclipse CDT4 - Unix Makefiles', '', '')
def getBuildDir(self, target):
# eclipse only works with in-source build.
return ''
def getBinDir(self, target=''):
# eclipse only works with in-source build.
return 'bin'
def getSourceDir(self):
return ''

View File

@ -16,6 +16,7 @@
# TODO: split this file up, it's too long! # TODO: split this file up, it's too long!
import sys, os, ConfigParser, shutil, re, ftputil import sys, os, ConfigParser, shutil, re, ftputil
from generators import Generator, EclipseGenerator, MakefilesGenerator
if sys.version_info >= (2, 4): if sys.version_info >= (2, 4):
import subprocess import subprocess
@ -23,7 +24,7 @@ if sys.version_info >= (2, 4):
class InternalCommands: class InternalCommands:
project = 'synergy' project = 'synergy'
setup_version = 4 # increment to force setup/config setup_version = 5 # increment to force setup/config
website_url = 'http://synergy-foss.org/' website_url = 'http://synergy-foss.org/'
this_cmd = 'hm' this_cmd = 'hm'
@ -33,11 +34,9 @@ class InternalCommands:
xcodebuild_cmd = 'xcodebuild' xcodebuild_cmd = 'xcodebuild'
w32_make_cmd = 'mingw32-make' w32_make_cmd = 'mingw32-make'
w32_qt_version = '4.6.2' w32_qt_version = '4.6.2'
defaultTarget = 'release'
source_dir = '..' # Source, relative to build.
cmake_dir = 'res' cmake_dir = 'res'
build_dir = 'build'
bin_dir = 'bin'
gui_dir = 'src/gui' gui_dir = 'src/gui'
doc_dir = 'doc' doc_dir = 'doc'
@ -69,37 +68,33 @@ class InternalCommands:
enable_make_gui = False enable_make_gui = False
win32_generators = { win32_generators = {
1 : 'Visual Studio 10', 1 : Generator('Visual Studio 10'),
2 : 'Visual Studio 10 Win64', 2 : Generator('Visual Studio 10 Win64'),
3 : 'Visual Studio 9 2008', 3 : Generator('Visual Studio 9 2008'),
4 : 'Visual Studio 9 2008 Win64', 4 : Generator('Visual Studio 9 2008 Win64'),
5 : 'Visual Studio 8 2005', 5 : Generator('Visual Studio 8 2005'),
6 : 'Visual Studio 8 2005 Win64', 6 : Generator('Visual Studio 8 2005 Win64')
} }
unix_generators = { unix_generators = {
1 : 'Unix Makefiles', 1 : MakefilesGenerator(),
2 : EclipseGenerator(),
} }
darwin_generators = { darwin_generators = {
1 : 'Unix Makefiles', 1 : MakefilesGenerator(),
2 : 'Xcode', 2 : Generator('Xcode'),
3 : EclipseGenerator(),
} }
def getBuildDir(self, target=''): def getBuildDir(self, target=''):
workingDir = self.build_dir return self.getGenerator().getBuildDir(target)
if target != '':
workingDir += '/' + target
return workingDir
def getBinDir(self, target=''): def getBinDir(self, target=''):
workingDir = self.bin_dir return self.getGenerator().getBinDir(target)
if target != '':
workingDir += '/' + target
return workingDir
def config_filepath(self, target=''): def getConfigDir(self):
return '%s/%s' % (self.getBuildDir(target), self.config_filename) return self.config_filename
def sln_filepath(self): def sln_filepath(self):
return '%s\%s' % (self.getBuildDir(), self.sln_filename) return '%s\%s' % (self.getBuildDir(), self.sln_filename)
@ -130,15 +125,16 @@ class InternalCommands:
'Example: %s build -g 3' 'Example: %s build -g 3'
) % (app, app) ) % (app, app)
def configure(self, target): def configureAll(self, targets):
self.configure_internal(target)
print ('Configure complete!\n\n' # if no mode specified, use default
'Open project now: %s open\n' if len(targets) == 0:
'Command line build: %s build' targets += [self.defaultTarget,]
) % (self.this_cmd, self.this_cmd)
def configure_internal(self, target='', extraArgs=''): for target in targets:
self.configure(target)
def configure(self, target='', extraArgs=''):
cmake_args = '' cmake_args = ''
@ -152,33 +148,38 @@ class InternalCommands:
# now that we know we've got the latest setup, we can ask the config # now that we know we've got the latest setup, we can ask the config
# file for the generator (but again, we only fall back to this if not # file for the generator (but again, we only fall back to this if not
# specified as arg). # specified as arg).
generator = self.get_generator_from_config() generator = self.getGenerator()
if generator != '': if generator != self.findGeneratorFromConfig():
cmake_args += ' -G "' + generator + '"' print('Generator changed, running setup.')
self.setup(target)
if generator.cmakeName != '':
cmake_args += ' -G "' + generator.cmakeName + '"'
# default is release
if target == '':
print 'Defaulting target to: ' + self.defaultTarget
target = self.defaultTarget
# for non-vs always specify a build type (debug, release, etc) # for non-vs always specify a build type (debug, release, etc)
if not generator.startswith('Visual Studio'): if not generator.cmakeName.startswith('Visual Studio'):
# default is default for non-vs
if target == '':
target = 'debug'
cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize() cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize()
# if not visual studio, use parent dir # if not visual studio, use parent dir
sourceDir = self.source_dir sourceDir = generator.getSourceDir()
if not generator.startswith('Visual Studio'):
sourceDir += '/..'
if extraArgs != '': if extraArgs != '':
cmake_args += ' ' + extraArgs cmake_args += ' ' + extraArgs
cmake_cmd_string = _cmake_cmd + cmake_args + ' ' + sourceDir cmake_cmd_string = _cmake_cmd + cmake_args + ' ' + sourceDir
print "CMake command: " + cmake_cmd_string
# Run from build dir so we have an out-of-source build. # Run from build dir so we have an out-of-source build.
self.try_chdir(self.getBuildDir(target)) self.try_chdir(self.getBuildDir(target))
print "CMake command: " + cmake_cmd_string
err = os.system(cmake_cmd_string) err = os.system(cmake_cmd_string)
self.restore_chdir() self.restore_chdir()
if err != 0: if err != 0:
@ -201,7 +202,7 @@ class InternalCommands:
if err != 0: if err != 0:
raise Exception('QMake encountered error: ' + str(err)) raise Exception('QMake encountered error: ' + str(err))
self.set_conf_run() self.setConfRun(target)
def persist_cmake(self): def persist_cmake(self):
# even though we're running `cmake --version`, we're only doing this for the 0 return # even though we're running `cmake --version`, we're only doing this for the 0 return
@ -220,8 +221,6 @@ class InternalCommands:
def persist_qt(self): def persist_qt(self):
self.persist_qmake() self.persist_qmake()
if sys.platform == 'win32':
self.persist_w32_make()
def persist_qmake(self): def persist_qmake(self):
# cannot use subprocess on < python 2.4 # cannot use subprocess on < python 2.4
@ -261,46 +260,47 @@ class InternalCommands:
else: else:
raise Exception('Could not find qmake version.') raise Exception('Could not find qmake version.')
def persist_w32_make(): def ensureConfHasRun(self, target, skipConfig):
# TODO if self.hasConfRun(target):
pass print 'Skipping config for target: ' + target
skipConfig = True
if not skipConfig:
self.configure(target)
def build(self, targets=[], skipConfig=False): def build(self, targets=[], skipConfig=False):
# if no mode specified, default to debug # if no mode specified, use default
if len(targets) == 0: if len(targets) == 0:
targets += ['debug',] targets += [self.defaultTarget,]
self.ensure_setup_latest() self.ensure_setup_latest()
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
if generator.startswith('Visual Studio'): if generator.startswith('Visual Studio'):
# only need to configure once for vs self.ensureConfHasRun('all', skipConfig)
if not self.has_conf_run() and not skipConfig:
self.configure_internal()
for target in targets: for target in targets:
self.run_vcbuild(generator, target) self.run_vcbuild(generator, target)
else: else:
for target in targets:
self.ensureConfHasRun(target, skipConfig)
cmd = '' cmd = ''
if generator == "Unix Makefiles": if generator.find("Unix Makefiles") != -1:
print 'Building with GNU Make...' print 'Building with GNU Make...'
cmd = self.make_cmd cmd = self.make_cmd
elif generator == 'Xcode': elif generator == 'Xcode':
print 'Building with Xcode...' print 'Building with Xcode...'
cmd = self.xcodebuild_cmd cmd = self.xcodebuild_cmd
else: else:
raise Exception('Not supported with generator: ' + generator) raise Exception('Build command not supported with generator: ' + generator)
for target in targets: for target in targets:
if not self.has_conf_run(target) and not skipConfig:
self.configure_internal(target)
self.try_chdir(self.getBuildDir(target)) self.try_chdir(self.getBuildDir(target))
err = os.system(cmd) err = os.system(cmd)
self.restore_chdir() self.restore_chdir()
@ -314,11 +314,11 @@ class InternalCommands:
def clean(self, targets=[]): def clean(self, targets=[]):
# if no mode specified, default to debug # if no mode specified, use default
if len(targets) == 0: if len(targets) == 0:
targets += ['debug',] targets += [self.defaultTarget,]
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
if generator.startswith('Visual Studio'): if generator.startswith('Visual Studio'):
# special case for version 10, use new /target:clean # special case for version 10, use new /target:clean
@ -391,7 +391,7 @@ class InternalCommands:
self.restore_chdir() self.restore_chdir()
def open(self): def open(self):
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
if generator.startswith('Visual Studio'): if generator.startswith('Visual Studio'):
print 'Opening with %s...' % generator print 'Opening with %s...' % generator
self.open_internal(self.sln_filepath()) self.open_internal(self.sln_filepath())
@ -437,8 +437,8 @@ class InternalCommands:
def doxygen(self): def doxygen(self):
# The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in # The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in
if not self.has_conf_run(): if not self.hasConfRun():
self.configure_internal() self.configure()
err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename)) err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename))
@ -449,13 +449,13 @@ class InternalCommands:
# Package is supported by default. # Package is supported by default.
package_unsupported = False package_unsupported = False
unixTarget = 'release' unixTarget = self.defaultTarget
if type != 'win' and type != 'mac': if type != 'win' and type != 'mac':
self.configure_internal(unixTarget, '-DCONF_CPACK:BOOL=TRUE') self.configure(unixTarget, '-DCONF_CPACK:BOOL=TRUE')
# make sure we have a release build to package # make sure we have a release build to package
self.build(['release'], skipConfig=True) self.build([self.defaultTarget], skipConfig=True)
moveExt = '' moveExt = ''
@ -500,8 +500,8 @@ class InternalCommands:
if moveExt != '': if moveExt != '':
self.unixMove( self.unixMove(
self.build_dir + '/release/*.' + moveExt, self.getGenerator().buildDir + '/release/*.' + moveExt,
self.bin_dir) self.getGenerator().binDir)
if package_unsupported: if package_unsupported:
raise Exception( raise Exception(
@ -511,7 +511,7 @@ class InternalCommands:
def distSrc(self): def distSrc(self):
version = self.getVersionFromCmake() version = self.getVersionFromCmake()
name = (self.project + '-' + version + '-Source') name = (self.project + '-' + version + '-Source')
exportPath = self.build_dir + '/' + name exportPath = self.getGenerator().buildDir + '/' + name
if os.path.exists(exportPath): if os.path.exists(exportPath):
print "Removing existing export..." print "Removing existing export..."
@ -523,10 +523,10 @@ class InternalCommands:
if err != 0: if err != 0:
raise Exception('Repository export failed: ' + str(err)) raise Exception('Repository export failed: ' + str(err))
packagePath = '../' + self.bin_dir + '/' + name + '.tar.gz' packagePath = '../' + self.getGenerator().binDir + '/' + name + '.tar.gz'
try: try:
self.try_chdir(self.build_dir) self.try_chdir(self.getGenerator().buildDir)
print 'Packaging to: ' + packagePath print 'Packaging to: ' + packagePath
err = os.system('tar cfvz ' + packagePath + ' ' + name) err = os.system('tar cfvz ' + packagePath + ' ' + name)
if err != 0: if err != 0:
@ -570,7 +570,7 @@ class InternalCommands:
else: else:
shutil.copy2(f, zipFile + '/') shutil.copy2(f, zipFile + '/')
zipCmd = ('zip -r ../../' + self.bin_dir + '/' + zipFile + '.zip ' + zipFile); zipCmd = ('zip -r ../../' + self.getGenerator().binDir + '/' + zipFile + '.zip ' + zipFile);
print 'Creating package: ' + zipCmd print 'Creating package: ' + zipCmd
err = os.system(zipCmd) err = os.system(zipCmd)
@ -590,7 +590,7 @@ class InternalCommands:
raise Exception( raise Exception(
'QT SDK dir path not specified (--qt-dir).') 'QT SDK dir path not specified (--qt-dir).')
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
arch = 'x86' arch = 'x86'
installDirVar = '$PROGRAMFILES32' installDirVar = '$PROGRAMFILES32'
@ -608,7 +608,7 @@ class InternalCommands:
template = template.replace('${in:qtDir}', qtDir) template = template.replace('${in:qtDir}', qtDir)
template = template.replace('${in:installDirVar}', installDirVar) template = template.replace('${in:installDirVar}', installDirVar)
nsiPath = self.build_dir + '\Installer.nsi' nsiPath = self.getGenerator().buildDir + '\Installer.nsi'
nsiFile = open(nsiPath, 'w') nsiFile = open(nsiPath, 'w')
nsiFile.write(template) nsiFile.write(template)
nsiFile.close() nsiFile.close()
@ -646,7 +646,7 @@ class InternalCommands:
print 'Uploading %s to FTP server %s...' % (dest, ftp.host) print 'Uploading %s to FTP server %s...' % (dest, ftp.host)
srcDir = 'bin/' srcDir = 'bin/'
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
#if not generator.startswith('Visual Studio'): #if not generator.startswith('Visual Studio'):
# srcDir += 'release/' # srcDir += 'release/'
@ -678,7 +678,7 @@ class InternalCommands:
# get platform based on last generator used # get platform based on last generator used
ext = 'exe' ext = 'exe'
generator = self.get_generator_from_config() generator = self.getGeneratorFromConfig().cmakeName
if generator.find('Win64') != -1: if generator.find('Win64') != -1:
platform = 'Windows-x64' platform = 'Windows-x64'
else: else:
@ -696,8 +696,6 @@ class InternalCommands:
# only use release dir if not windows # only use release dir if not windows
target = '' target = ''
#if type != 'win':
# target = 'release'
for filename in os.listdir(self.getBinDir(target)): for filename in os.listdir(self.getBinDir(target)):
if re.search(pattern, filename): if re.search(pattern, filename):
@ -740,12 +738,17 @@ class InternalCommands:
def try_chdir(self, dir): def try_chdir(self, dir):
global prevdir
if dir == '':
prevdir = ''
return
# Ensure temp build dir exists. # Ensure temp build dir exists.
if not os.path.exists(dir): if not os.path.exists(dir):
print 'Creating dir: ' + dir print 'Creating dir: ' + dir
os.mkdir(dir) os.makedirs(dir)
global prevdir
prevdir = os.path.abspath(os.curdir) prevdir = os.path.abspath(os.curdir)
# It will exist by this point, so it's safe to chdir. # It will exist by this point, so it's safe to chdir.
@ -754,6 +757,8 @@ class InternalCommands:
def restore_chdir(self): def restore_chdir(self):
global prevdir global prevdir
if prevdir == '':
return
print 'Going back to: ' + prevdir print 'Going back to: ' + prevdir
os.chdir(prevdir) os.chdir(prevdir)
@ -774,17 +779,26 @@ class InternalCommands:
def setup(self, target=''): def setup(self, target=''):
print "Running setup..." print "Running setup..."
oldGenerator = self.findGeneratorFromConfig()
if not oldGenerator == None:
for target in ['debug', 'release']:
buildDir = oldGenerator.getBuildDir(target)
cmakeCacheFilename = 'CMakeCache.txt'
if buildDir != '':
cmakeCacheFilename = buildDir + '/' + cmakeCacheFilename
if os.path.exists(cmakeCacheFilename):
print "Removing %s, since generator changed." % cmakeCacheFilename
os.remove(cmakeCacheFilename)
# always either get generator from args, or prompt user when # always either get generator from args, or prompt user when
# running setup # running setup
generator = self.get_generator_from_prompt() generator = self.get_generator_from_prompt()
# Create build dir, since config file resides there. if os.path.exists(self.getConfigDir()):
if not os.path.exists(self.getBuildDir(target)):
os.mkdir(self.getBuildDir(target))
if os.path.exists(self.config_filepath()):
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
config.read(self.config_filepath()) config.read(self.getConfigDir())
else: else:
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
@ -801,29 +815,46 @@ class InternalCommands:
self.write_config(config) self.write_config(config)
cmakecache_filename = '%s/CMakeCache.txt' % self.getBuildDir(target) # for all targets, set conf not run
if os.path.exists(cmakecache_filename): self.setConfRun('all', False)
print "Removing %s, since generator changed." % cmakecache_filename self.setConfRun('debug', False)
os.remove(cmakecache_filename) self.setConfRun('release', False)
print "\nSetup complete." print "Setup complete."
def write_config(self, config, target=''): def write_config(self, config, target=''):
configfile = open(self.config_filepath(target), 'wb') configfile = open(self.getConfigDir(), 'wb')
config.write(configfile) config.write(configfile)
def get_generator_from_config(self): def getGeneratorFromConfig(self):
if self.generator_id: generator = self.findGeneratorFromConfig()
return self.getGenerator() if generator:
else: return generator
config = ConfigParser.RawConfigParser()
config.read(self.config_filepath()) raise Exception("Could not find generator: " + name)
return config.get('cmake', 'generator')
def findGeneratorFromConfig(self):
config = ConfigParser.RawConfigParser()
config.read(self.getConfigDir())
if not config.has_section('cmake'):
return None
name = config.get('cmake', 'generator')
generators = self.get_generators()
keys = generators.keys()
keys.sort()
for k in keys:
if generators[k].cmakeName == name:
return generators[k]
return None
def min_setup_version(self, version): def min_setup_version(self, version):
if os.path.exists(self.config_filepath()): if os.path.exists(self.getConfigDir()):
config = ConfigParser.RawConfigParser() config = ConfigParser.RawConfigParser()
config.read(self.config_filepath()) config.read(self.getConfigDir())
try: try:
return config.getint('hm', 'setup_version') >= version return config.getint('hm', 'setup_version') >= version
@ -832,22 +863,22 @@ class InternalCommands:
else: else:
return False return False
def has_conf_run(self, target=''): def hasConfRun(self, target):
if self.min_setup_version(2): if self.min_setup_version(2):
config = ConfigParser.RawConfigParser() config = ConfigParser.RawConfigParser()
config.read(self.config_filepath(target)) config.read(self.getConfigDir())
try: try:
return config.getboolean('hm', 'has_conf_run') return config.getboolean('hm', 'conf_done_' + target)
except: except:
return False return False
else: else:
return False return False
def set_conf_run(self): def setConfRun(self, target, hasRun=True):
if self.min_setup_version(3): if self.min_setup_version(3):
config = ConfigParser.RawConfigParser() config = ConfigParser.RawConfigParser()
config.read(self.config_filepath()) config.read(self.getConfigDir())
config.set('hm', 'has_conf_run', True) config.set('hm', 'conf_done_' + target, hasRun)
self.write_config(config) self.write_config(config)
else: else:
raise Exception("User does not have correct setup version.") raise Exception("User does not have correct setup version.")
@ -863,7 +894,7 @@ class InternalCommands:
raise Exception('Unsupported platform: ' + sys.platform) raise Exception('Unsupported platform: ' + sys.platform)
def get_generator_from_prompt(self): def get_generator_from_prompt(self):
return self.getGenerator() return self.getGenerator().cmakeName
def getGenerator(self): def getGenerator(self):
generators = self.get_generators() generators = self.get_generators()
@ -873,10 +904,14 @@ class InternalCommands:
# if user has specified a generator as an argument # if user has specified a generator as an argument
if self.generator_id: if self.generator_id:
return generators[int(self.generator_id)] return generators[int(self.generator_id)]
else:
raise Exception( conf = self.findGeneratorFromConfig()
'Generator not specified, use -g arg ' + if conf:
'(use `hm genlist` for a list of generators).') return conf
raise Exception(
'Generator not specified, use -g arg ' +
'(use `hm genlist` for a list of generators).')
def setup_generator_prompt(self, generators): def setup_generator_prompt(self, generators):
@ -1000,7 +1035,7 @@ class InternalCommands:
keys = generators.keys() keys = generators.keys()
keys.sort() keys.sort()
for k in keys: for k in keys:
print str(k) + ': ' + generators[k] print str(k) + ': ' + generators[k].cmakeName
def getMacPackageName(self): def getMacPackageName(self):
import commands import commands
@ -1056,10 +1091,7 @@ class CommandHandler:
self.ic.setup() self.ic.setup()
def configure(self): def configure(self):
target = '' self.ic.configureAll(self.build_targets)
if (len(self.build_targets) > 0):
target = self.build_targets[0]
self.ic.configure(target)
def build(self): def build(self):
self.ic.build(self.build_targets) self.ic.build(self.build_targets)