diff options
| author | Remko Tronçon <git@el-tramo.be> | 2009-11-24 18:09:37 (GMT) |
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2009-11-24 18:09:37 (GMT) |
| commit | c7fb528f0d80f9d96a2d84444352386d5d4288dc (patch) | |
| tree | bc52f4729e948c5021ab322e6ad739f315d41140 | |
| parent | ea951bec1c4b84b739a9f435e0d17dbb99e4d724 (diff) | |
| download | swift-c7fb528f0d80f9d96a2d84444352386d5d4288dc.zip swift-c7fb528f0d80f9d96a2d84444352386d5d4288dc.tar.bz2 | |
Added SwifTools/Idle module.
| -rw-r--r-- | SConstruct | 29 | ||||
| -rw-r--r-- | SwifTools/Idle/ActualIdleDetector.cpp | 29 | ||||
| -rw-r--r-- | SwifTools/Idle/ActualIdleDetector.h | 25 | ||||
| -rw-r--r-- | SwifTools/Idle/DummyIdleQuerier.h | 14 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleDetector.cpp | 8 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleDetector.h | 24 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleQuerier.cpp | 8 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleQuerier.h | 10 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleQuerierTest/.gitignore | 1 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleQuerierTest/IdleQuerierTest.cpp | 16 | ||||
| -rw-r--r-- | SwifTools/Idle/IdleQuerierTest/SConscript | 11 | ||||
| -rw-r--r-- | SwifTools/Idle/PlatformIdleQuerier.cpp | 26 | ||||
| -rw-r--r-- | SwifTools/Idle/PlatformIdleQuerier.h | 18 | ||||
| -rw-r--r-- | SwifTools/Idle/UnitTest/ActualIdleDetectorTest.cpp | 164 | ||||
| -rw-r--r-- | SwifTools/Idle/UnitTest/SConscript | 5 | ||||
| -rw-r--r-- | SwifTools/Idle/XSSIdleQuerier.cpp | 36 | ||||
| -rw-r--r-- | SwifTools/Idle/XSSIdleQuerier.h | 22 | ||||
| -rw-r--r-- | SwifTools/SConscript | 30 |
18 files changed, 464 insertions, 12 deletions
@@ -1,233 +1,248 @@ import sys, os sys.path.append(Dir("BuildTools/SCons").abspath) ################################################################################ # Build variables ################################################################################ vars = Variables("config.py") vars.Add('ccflags', "Extra C(++) compiler flags") vars.Add('linkflags', "Extra linker flags") vars.Add(EnumVariable("test", "Compile and run tests", "none", ["none", "all", "unit", "system"])) vars.Add(BoolVariable("optimize", "Compile with optimizations turned on", "no")) vars.Add(BoolVariable("debug", "Compile with debug information", "yes" if os.name != "nt" else "no")) vars.Add(BoolVariable("warnings", "Compile with warnings turned on", - "yes" if os.name != "nt" else "no")) + "yes" if os.name != "nt" else "no")) if os.name != "nt" : - vars.Add(BoolVariable("coverage", "Compile with coverage information", "no")) + vars.Add(BoolVariable("coverage", "Compile with coverage information", "no")) if os.name == "posix" : - vars.Add(BoolVariable("valgrind", "Run tests with valgrind", "no")) + vars.Add(BoolVariable("valgrind", "Run tests with valgrind", "no")) if os.name == "mac" : - vars.Add(BoolVariable("universal", "Create universal binaries", "no")) + vars.Add(BoolVariable("universal", "Create universal binaries", "no")) if os.name == "nt" : - vars.Add(PathVariable("vcredist", "MSVC redistributable dir", "", PathVariable.PathAccept)) + vars.Add(PathVariable("vcredist", "MSVC redistributable dir", "", PathVariable.PathAccept)) if os.name == "nt" : - vars.Add(PackageVariable("bonjour", "Bonjour SDK location", "yes")) + vars.Add(PackageVariable("bonjour", "Bonjour SDK location", "yes")) vars.Add(PackageVariable("openssl", "OpenSSL location", "yes")) vars.Add(PathVariable("qt", "Qt location", "", PathVariable.PathAccept)) ################################################################################ # Set up default build & configure environment ################################################################################ env = Environment(CPPPATH = "#", ENV = {'PATH' : os.environ['PATH']}, variables = vars) Help(vars.GenerateHelpText(env)) env.Alias("dist", ["."]) # Default custom tools env.Tool("Test", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("WriteVal", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("BuildVersion", toolpath = ["#/BuildTools/SCons/Tools"]) if env["PLATFORM"] == "darwin" : env.Tool("Nib", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("AppBundle", toolpath = ["#/BuildTools/SCons/Tools"]) if env["PLATFORM"] == "win32" : env.Tool("WindowsBundle", toolpath = ["#/BuildTools/SCons/Tools"]) # Default compiler flags env["CCFLAGS"] = env.get("ccflags", []) env["LINKFLAGS"] = env.get("linkflags", []) if env["optimize"] : env.Append(CCFLAGS = "-O2") if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["GL"]) env.Append(LINKFLAGS = ["/INCREMENTAL:NO", "/LTCG"]) if env["debug"] : if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/Zi", "/MDd"]) env.Append(LINKFLAGS = ["/DEBUG"]) else : env.Append(CCFLAGS = "-g") elif env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/MD"]) if env.get("universal", 0) : assert(env["PLATFORM"] == "darwin") env.Append(CCFLAGS = [ "-isysroot", "/Developer/SDKs/MacOSX10.4u.sdk", "-arch", "i386", "-arch", "ppc"]) env.Append(LINKFLAGS = [ "-mmacosx-version-min=10.4", "-Wl", "-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk", "-arch", "i386", "-arch", "ppc"]) if env["warnings"] : if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/Wall"]) else : env.Append(CCFLAGS = ["-W", "-Wall"]) #env.Append(CCFLAGS = ["-W", "-Wall", "-Wredundant-decls", "-pedantic", "-Wno-long-long", "-Woverloaded-virtual", "-Wundef", "-Wfloat-equal", "-Wold-style-cast"]) if env.get("coverage", 0) : assert(env["PLATFORM"] != "win32") env.Append(CCFLAGS = ["-fprofile-arcs", "-ftest-coverage"]) env.Append(LINKFLAGS = ["-fprofile-arcs", "-ftest-coverage"]) if env["PLATFORM"] == "win32" : env.Append(LIBS = ["dnsapi", "ws2_32", "wsock32"]) env.Append(CCFLAGS = ["/EHsc", "/nologo"]) env["LINKCOM"] = [env["LINKCOM"], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1'] env["SHLINKCOM"] = [env["SHLINKCOM"], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2'] if env["PLATFORM"] == "darwin" : env.Append(FRAMEWORKS = "AppKit") # Testing env["TEST_TYPE"] = env["test"] env.Alias("check", ".") if "check" in ARGUMENTS or "check" in COMMAND_LINE_TARGETS : env["TEST_TYPE"] = "unit" env["TEST"] = (env["TEST_TYPE"] != "none") or env.GetOption("clean") if env.get("valgrind", 0) : - env["TEST_RUNNER"] = "valgrind --suppressions=QA/valgrind.supp -q --leak-check=full --track-origins=yes " + env["TEST_RUNNER"] = "valgrind --suppressions=QA/valgrind.supp -q --leak-check=full --track-origins=yes " # Packaging if ARGUMENTS.get("SWIFT_INSTALLDIR", "") : env["SWIFT_INSTALLDIR"] = Dir(ARGUMENTS["SWIFT_INSTALLDIR"]).abspath conf_env = env.Clone() Export("env") Export("conf_env") ################################################################################ # Extend the default build environment (not affecting the configure env) # # Keeping both environments separated mostly because of SCons Issue 2391, # although it doesn't hurt to separate them (e.g. not have pretty printed # strings in config.log) ################################################################################ #if env["PLATFORM"] == "win32" : # env["MSVC_BATCH"] = 1 # Pretty output def colorize(command, target, color) : colors = { "red": "31", "green": "32", "yellow": "33", "blue": "34" } prefix = "" suffix = "" if sys.stdout.isatty() and env["PLATFORM"] != "win32": prefix = "\033[0;" + colors[color] + ";140m" suffix = "\033[0m" return " " + prefix + command + suffix + " " + target if int(ARGUMENTS.get("V", 0)) == 0: env["CCCOMSTR"] = colorize("CC", "$TARGET", "green") env["CXXCOMSTR"] = colorize("CXX", "$TARGET", "green") env["LINKCOMSTR"] = colorize("LINK", "$TARGET", "red") env["ARCOMSTR"] = colorize("AR", "$TARGET", "red") env["RANLIBCOMSTR"] = colorize("RANLIB", "$TARGET", "red") env["QT4_RCCCOMSTR"] = colorize("RCC", "$TARGET", "blue") env["QT4_UICCOMSTR"] = colorize("UIC", "$TARGET", "blue") env["QT4_MOCFROMHCOMSTR"] = colorize("MOC", "$TARGET", "blue") env["QT4_MOCFROMCXXCOMSTR"] = colorize("MOC", "$TARGET", "blue") env["GENCOMSTR"] = colorize("GEN", "$TARGET", "blue") env["RCCOMSTR"] = colorize("RC", "$TARGET", "blue") env["BUNDLECOMSTR"] = colorize("BUNDLE", "$TARGET", "blue") env["NIBCOMSTR"] = colorize("NIB", "$TARGET", "blue") env["NSISCOMSTR"] = colorize("NSIS", "$TARGET", "blue") env["TESTCOMSTR"] = colorize("TEST", "$SOURCE", "yellow") #Progress(colorize("DEP", "$TARGET", "red") ################################################################################ # Platform configuration ################################################################################ conf = Configure(conf_env) if conf.CheckLib("z") : env.Append(LIBS = "z") env["ZLIB_FLAGS"] = "" else : SConscript("3rdParty/ZLib/SConscript") if conf.CheckLib("dl") : env.Append(LIBS = ["dl"]) if conf.CheckLib("c") : env.Append(LIBS = ["c"]) if conf.CheckLib("resolv") : env.Append(LIBS = ["resolv"]) # Expat if conf.CheckCHeader("expat.h") and conf.CheckLib("expat") : env["HAVE_EXPAT"] = 1 env["EXPAT_FLAGS"] = { "LIBS": ["expat"] } conf.Finish() +# Xss +env["HAVE_XSS"] = 0 +if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" : + xss_flags = { + "LIBPATH": ["/usr/X11R6/lib"], + "LIBS": ["X11", "Xss"] + } + xss_env = conf_env.Clone() + xss_env.MergeFlags(xss_flags) + conf = Configure(xss_env) + if conf.CheckFunc("XScreenSaverQueryExtension") : + env["HAVE_XSS"] = 1 + env["XSS_FLAGS"] = xss_flags + conf.Finish() + # LibXML conf = Configure(conf_env) if conf.CheckCHeader("libxml/parser.h") and conf.CheckLib("xml2") : env["HAVE_LIBXML"] = 1 env["LIBXML_FLAGS"] = { "LIBS": ["xml2"] } conf.Finish() if not env.get("HAVE_LIBXML", 0) : libxml_env = conf_env.Clone() libxml_env.Append(CPPPATH = ["/usr/include/libxml2"]) conf = Configure(libxml_env) if conf.CheckCHeader("libxml/parser.h") and conf.CheckLib("xml2") : env["HAVE_LIBXML"] = 1 env["LIBXML_FLAGS"] = { "CPPPATH": ["/usr/include/libxml2"], "LIBS": ["xml2"] } conf.Finish() # Bundled expat bundledExpat = False if not env.get("HAVE_EXPAT", 0) : print "Expat or LibXML not found. Using bundled Expat" SConscript("3rdParty/Expat/SConscript") env["HAVE_EXPAT"] = 1 bundledExpat = True # Qt if env["qt"] : env["QTDIR"] = env["qt"] # OpenSSL openssl_env = conf_env.Clone() use_openssl = bool(env["openssl"]) openssl_prefix = env["openssl"] if isinstance(env["openssl"], str) else "" openssl_flags = {} if openssl_prefix : openssl_flags = { "CPPPATH": [os.path.join(openssl_prefix, "include")] } if env["PLATFORM"] == "win32" : openssl_flags["LIBPATH"] = [os.path.join(openssl_prefix, "lib", "VC")] env["OPENSSL_DIR"] = openssl_prefix else : openssl_flags["LIBPATH"] = [os.path.join(openssl_prefix, "lib")] openssl_env.MergeFlags(openssl_flags) openssl_conf = Configure(openssl_env) if use_openssl and openssl_conf.CheckCHeader("openssl/ssl.h") : env["HAVE_OPENSSL"] = 1 env["OPENSSL_FLAGS"] = openssl_flags if env["PLATFORM"] == "win32" : env["OPENSSL_FLAGS"]["LIBS"] = ["libeay32MT", "ssleay32MT"] diff --git a/SwifTools/Idle/ActualIdleDetector.cpp b/SwifTools/Idle/ActualIdleDetector.cpp new file mode 100644 index 0000000..2e3f307 --- /dev/null +++ b/SwifTools/Idle/ActualIdleDetector.cpp @@ -0,0 +1,29 @@ +#include "SwifTools/Idle/ActualIdleDetector.h" + +#include <boost/bind.hpp> + +#include "SwifTools/Idle/IdleQuerier.h" +#include "Swiften/Network/Timer.h" +#include "Swiften/Network/TimerFactory.h" + +namespace Swift { + +ActualIdleDetector::ActualIdleDetector(IdleQuerier* querier, TimerFactory* timerFactory, int refreshRateSeconds) : querier(querier), isIdle(false) { + timer = timerFactory->createTimer(refreshRateSeconds*1000); + timer->onTick.connect(boost::bind(&ActualIdleDetector::handleTimerTick, this)); + timer->start(); +} + +ActualIdleDetector::~ActualIdleDetector() { + timer->stop(); +} + +void ActualIdleDetector::handleTimerTick() { + bool idle = (querier->getIdleTimeSeconds() >= getIdleTimeSeconds()); + if (idle != isIdle) { + isIdle = idle; + onIdleChanged(isIdle); + } +} + +} diff --git a/SwifTools/Idle/ActualIdleDetector.h b/SwifTools/Idle/ActualIdleDetector.h new file mode 100644 index 0000000..48428bb --- /dev/null +++ b/SwifTools/Idle/ActualIdleDetector.h @@ -0,0 +1,25 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +#include "SwifTools/Idle/IdleDetector.h" + +namespace Swift { + class IdleQuerier; + class TimerFactory; + class Timer; + + class ActualIdleDetector : public IdleDetector, public boost::bsignals::trackable { + public: + ActualIdleDetector(IdleQuerier*, TimerFactory*, int refreshRateSeconds); + ~ActualIdleDetector(); + + private: + void handleTimerTick(); + + private: + IdleQuerier* querier; + bool isIdle; + boost::shared_ptr<Timer> timer; + }; +} diff --git a/SwifTools/Idle/DummyIdleQuerier.h b/SwifTools/Idle/DummyIdleQuerier.h new file mode 100644 index 0000000..b8ba776 --- /dev/null +++ b/SwifTools/Idle/DummyIdleQuerier.h @@ -0,0 +1,14 @@ +#pragma once + +#include "SwifTools/Idle/IdleQuerier.h" + +namespace Swift { + class DummyIdleQuerier : public IdleQuerier { + public: + DummyIdleQuerier() {} + + virtual int getIdleTimeSeconds() { + return 0; + } + }; +} diff --git a/SwifTools/Idle/IdleDetector.cpp b/SwifTools/Idle/IdleDetector.cpp new file mode 100644 index 0000000..42559cd --- /dev/null +++ b/SwifTools/Idle/IdleDetector.cpp @@ -0,0 +1,8 @@ +#include "SwifTools/Idle/IdleDetector.h" + +namespace Swift { + +IdleDetector::~IdleDetector() { +} + +} diff --git a/SwifTools/Idle/IdleDetector.h b/SwifTools/Idle/IdleDetector.h new file mode 100644 index 0000000..1fb3d69 --- /dev/null +++ b/SwifTools/Idle/IdleDetector.h @@ -0,0 +1,24 @@ +#pragma once + +#include <boost/signals.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + class IdleDetector { + public: + virtual ~IdleDetector(); + + void setIdleTimeSeconds(int time) { + idleTimeSeconds = time; + } + + int getIdleTimeSeconds() const { + return idleTimeSeconds; + } + + boost::signal<void (bool /* isIdle */)> onIdleChanged; + + private: + int idleTimeSeconds; + }; +} diff --git a/SwifTools/Idle/IdleQuerier.cpp b/SwifTools/Idle/IdleQuerier.cpp new file mode 100644 index 0000000..0974aba --- /dev/null +++ b/SwifTools/Idle/IdleQuerier.cpp @@ -0,0 +1,8 @@ +#include "SwifTools/Idle/IdleQuerier.h" + +namespace Swift { + +IdleQuerier::~IdleQuerier() { +} + +} diff --git a/SwifTools/Idle/IdleQuerier.h b/SwifTools/Idle/IdleQuerier.h new file mode 100644 index 0000000..71f201e --- /dev/null +++ b/SwifTools/Idle/IdleQuerier.h @@ -0,0 +1,10 @@ +#pragma once + +namespace Swift { + class IdleQuerier { + public: + virtual ~IdleQuerier(); + + virtual int getIdleTimeSeconds() = 0; + }; +} diff --git a/SwifTools/Idle/IdleQuerierTest/.gitignore b/SwifTools/Idle/IdleQuerierTest/.gitignore new file mode 100644 index 0000000..6c63ee9 --- /dev/null +++ b/SwifTools/Idle/IdleQuerierTest/.gitignore @@ -0,0 +1 @@ +IdleQuerierTest diff --git a/SwifTools/Idle/IdleQuerierTest/IdleQuerierTest.cpp b/SwifTools/Idle/IdleQuerierTest/IdleQuerierTest.cpp new file mode 100644 index 0000000..94f7e2b --- /dev/null +++ b/SwifTools/Idle/IdleQuerierTest/IdleQuerierTest.cpp @@ -0,0 +1,16 @@ +#include <iostream> + +#include "SwifTools/Idle/PlatformIdleQuerier.h" +#include "Swiften/Base/sleep.h" + +using namespace Swift; + +int main() { + PlatformIdleQuerier querier; + while (true) { + std::cout << "Idle time: " << querier.getIdleTimeSeconds() << std::endl; + Swift::sleep(1000); + } + + return 0; +} diff --git a/SwifTools/Idle/IdleQuerierTest/SConscript b/SwifTools/Idle/IdleQuerierTest/SConscript new file mode 100644 index 0000000..d45aeea --- /dev/null +++ b/SwifTools/Idle/IdleQuerierTest/SConscript @@ -0,0 +1,11 @@ +Import("env") + +if env["TEST"] : + myenv = env.Clone() + myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["BOOST_FLAGS"]) + myenv.MergeFlags(myenv.get("XSS_FLAGS", {})) + myenv.Append(LIBPATH = ["/usr/X11R6/lib"]) + myenv.Append(LIBS = ["X11", "Xss"]) + tester = myenv.Program("IdleQuerierTest", ["IdleQuerierTest.cpp"]) diff --git a/SwifTools/Idle/PlatformIdleQuerier.cpp b/SwifTools/Idle/PlatformIdleQuerier.cpp new file mode 100644 index 0000000..76a3f7d --- /dev/null +++ b/SwifTools/Idle/PlatformIdleQuerier.cpp @@ -0,0 +1,26 @@ +#include "SwifTools/Idle/PlatformIdleQuerier.h" + +#if defined(HAVE_XSS) +#include "SwifTools/Idle/XSSIdleQuerier.h" +#else +#include "SwifTools/Idle/DummyIdleQuerier.h" +#endif + +#include <cassert> +#include <iostream> + +namespace Swift { + +PlatformIdleQuerier::PlatformIdleQuerier() : querier(NULL) { +#if defined(HAVE_XSS) + querier = new XSSIdleQuerier(); +#else + querier = new DummyIdleQuerier(); +#endif +} + +PlatformIdleQuerier::~PlatformIdleQuerier() { + delete querier; +} + +} diff --git a/SwifTools/Idle/PlatformIdleQuerier.h b/SwifTools/Idle/PlatformIdleQuerier.h new file mode 100644 index 0000000..e567b0e --- /dev/null +++ b/SwifTools/Idle/PlatformIdleQuerier.h @@ -0,0 +1,18 @@ +#pragma once + +#include "SwifTools/Idle/IdleQuerier.h" + +namespace Swift { + class PlatformIdleQuerier : public IdleQuerier { + public: + PlatformIdleQuerier(); + ~PlatformIdleQuerier(); + + virtual int getIdleTimeSeconds() { + return querier->getIdleTimeSeconds(); + } + + private: + IdleQuerier* querier; + }; +} diff --git a/SwifTools/Idle/UnitTest/ActualIdleDetectorTest.cpp b/SwifTools/Idle/UnitTest/ActualIdleDetectorTest.cpp new file mode 100644 index 0000000..99a7099 --- /dev/null +++ b/SwifTools/Idle/UnitTest/ActualIdleDetectorTest.cpp @@ -0,0 +1,164 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/bind.hpp> + +#include "SwifTools/Idle/ActualIdleDetector.h" +#include "SwifTools/Idle/IdleQuerier.h" +#include "Swiften/Base/foreach.h" +#include "Swiften/Network/TimerFactory.h" +#include "Swiften/Network/Timer.h" + +using namespace Swift; + +class ActualIdleDetectorTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ActualIdleDetectorTest); + CPPUNIT_TEST(testDestructor); + CPPUNIT_TEST(testHandleTick_Idle); + CPPUNIT_TEST(testHandleTick_Idle_AlreadyIdle); + CPPUNIT_TEST(testHandleTick_NotIdle); + CPPUNIT_TEST(testHandleTick_NotIdle_AlreadyNotIdle); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + querier = new MockIdleQuerier(); + timerFactory = new MockTimerFactory(); + idleEvents.clear(); + } + + void tearDown() { + delete timerFactory; + delete querier; + } + + void testDestructor() { + ActualIdleDetector* testling = createDetector(); + testling->setIdleTimeSeconds(15); + delete testling; + + querier->idleTime = 15; + timerFactory->updateTime(15000); + + CPPUNIT_ASSERT_EQUAL(0U, idleEvents.size()); + } + + void testHandleTick_Idle() { + std::auto_ptr<ActualIdleDetector> testling(createDetector()); + testling->setIdleTimeSeconds(15); + querier->idleTime = 15; + + timerFactory->updateTime(15000); + + CPPUNIT_ASSERT_EQUAL(1U, idleEvents.size()); + CPPUNIT_ASSERT(idleEvents[0]); + } + + void testHandleTick_Idle_AlreadyIdle() { + std::auto_ptr<ActualIdleDetector> testling(createDetector()); + testling->setIdleTimeSeconds(15); + querier->idleTime = 15; + timerFactory->updateTime(15000); + + querier->idleTime = 30; + timerFactory->updateTime(30000); + + CPPUNIT_ASSERT_EQUAL(1U, idleEvents.size()); + CPPUNIT_ASSERT(idleEvents[0]); + } + + void testHandleTick_NotIdle() { + std::auto_ptr<ActualIdleDetector> testling(createDetector()); + testling->setIdleTimeSeconds(15); + querier->idleTime = 15; + timerFactory->updateTime(15000); + + querier->idleTime = 5; + timerFactory->updateTime(30000); + + CPPUNIT_ASSERT_EQUAL(2U, idleEvents.size()); + CPPUNIT_ASSERT(idleEvents[0]); + CPPUNIT_ASSERT(!idleEvents[1]); + } + + void testHandleTick_NotIdle_AlreadyNotIdle() { + std::auto_ptr<ActualIdleDetector> testling(createDetector()); + testling->setIdleTimeSeconds(15); + querier->idleTime = 5; + + timerFactory->updateTime(15000); + + CPPUNIT_ASSERT_EQUAL(0U, idleEvents.size()); + } + + private: + ActualIdleDetector* createDetector() { + ActualIdleDetector* detector = new ActualIdleDetector(querier, timerFactory, 10); + detector->onIdleChanged.connect(boost::bind(&ActualIdleDetectorTest::handleIdle, this, _1)); + return detector; + } + + void handleIdle(bool b) { + idleEvents.push_back(b); + } + + private: + struct MockIdleQuerier : public IdleQuerier { + MockIdleQuerier() : idleTime(0) {} + virtual int getIdleTimeSeconds() { return idleTime; } + int idleTime; + }; + + struct MockTimer : public Timer { + MockTimer(int interval) : interval(interval), running(false), lastTime(0) {} + + virtual void start() { + running = true; + } + + virtual void stop() { + running = false; + } + + virtual void updateTime(int currentTime) { + if (lastTime == currentTime) { + return; + } + if (running) { + int time = lastTime; + while (time <= currentTime) { + onTick(); + time += interval; + } + } + lastTime = currentTime; + } + + int interval; + bool running; + int lastTime; + }; + + struct MockTimerFactory : public TimerFactory { + MockTimerFactory() {} + + void updateTime(int milliseconds) { + foreach(boost::shared_ptr<MockTimer> timer, timers) { + timer->updateTime(milliseconds); + } + } + + boost::shared_ptr<Timer> createTimer(int milliseconds) { + boost::shared_ptr<MockTimer> timer(new MockTimer(milliseconds)); + timers.push_back(timer); + return timer; + } + + std::vector<boost::shared_ptr<MockTimer> > timers; + }; + + MockIdleQuerier* querier; + MockTimerFactory* timerFactory; + std::vector<bool> idleEvents; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ActualIdleDetectorTest); diff --git a/SwifTools/Idle/UnitTest/SConscript b/SwifTools/Idle/UnitTest/SConscript new file mode 100644 index 0000000..f193349 --- /dev/null +++ b/SwifTools/Idle/UnitTest/SConscript @@ -0,0 +1,5 @@ +Import("env") + +env.Append(UNITTEST_SOURCES = [ + File("ActualIdleDetectorTest.cpp") + ]) diff --git a/SwifTools/Idle/XSSIdleQuerier.cpp b/SwifTools/Idle/XSSIdleQuerier.cpp new file mode 100644 index 0000000..2259620 --- /dev/null +++ b/SwifTools/Idle/XSSIdleQuerier.cpp @@ -0,0 +1,36 @@ +#include "SwifTools/Idle/XSSIdleQuerier.h" + +#include <cassert> +#include <iostream> + +namespace Swift { + +XSSIdleQuerier::XSSIdleQuerier() : display(NULL), info(NULL) { + display = XOpenDisplay(NULL); + assert(display); + rootWindow = DefaultRootWindow(display); + int event, error; + available = XScreenSaverQueryExtension(display, &event, &error); + if (available) { + info = XScreenSaverAllocInfo(); + } + else { + std::cerr << "Warning: XScreenSaver extension not found. Idle time detection will not work." << std::endl; + } +} + +XSSIdleQuerier::~XSSIdleQuerier() { + XFree(info); +} + +int XSSIdleQuerier::getIdleTimeSeconds() { + if (available) { + XScreenSaverQueryInfo(display, rootWindow, info); + return info->idle / 1000; + } + else { + return 0; + } +} + +} diff --git a/SwifTools/Idle/XSSIdleQuerier.h b/SwifTools/Idle/XSSIdleQuerier.h new file mode 100644 index 0000000..476784d --- /dev/null +++ b/SwifTools/Idle/XSSIdleQuerier.h @@ -0,0 +1,22 @@ +#pragma once + +#include <X11/Xlib.h> +#include <X11/extensions/scrnsaver.h> + +#include "SwifTools/Idle/IdleQuerier.h" + +namespace Swift { + class XSSIdleQuerier : public IdleQuerier { + public: + XSSIdleQuerier(); + ~XSSIdleQuerier(); + + virtual int getIdleTimeSeconds(); + + private: + Display* display; + Window rootWindow; + bool available; + XScreenSaverInfo* info; + }; +} diff --git a/SwifTools/SConscript b/SwifTools/SConscript index 2caff5f..cff2c6b 100644 --- a/SwifTools/SConscript +++ b/SwifTools/SConscript @@ -1,15 +1,35 @@ Import("env") env["SWIFTOOLS_FLAGS"] = { "LIBPATH": [Dir(".")], "LIBS": ["SwifTools"] } myenv = env.Clone() - myenv.MergeFlags(myenv["BOOST_FLAGS"]) -myenv.StaticLibrary("SwifTools", [ - "Linkify.cpp" - ]) -SConscript(dirs = ["UnitTest"]) +sources = [ + "Idle/IdleDetector.cpp", + "Idle/ActualIdleDetector.cpp", + "Idle/IdleQuerier.cpp", + "Idle/PlatformIdleQuerier.cpp", + "Linkify.cpp", + ] + +if myenv["PLATFORM"] == "win32" : + pass +elif myenv["PLATFORM"] == "darwin" : + pass +elif myenv["HAVE_XSS"] : + myenv.Append(CPPDEFINES = ["HAVE_XSS"]) + sources += ["Idle/XSSIdleQuerier.cpp"] +else : + sources += ["Idle/DummyIdleQuerier.cpp"] + +myenv.StaticLibrary("SwifTools", sources) + +SConscript(dirs = [ + "Idle/IdleQuerierTest", + "Idle/UnitTest", + "UnitTest" + ]) |
Swift