diff options
Diffstat (limited to 'SwifTools/Idle')
-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 |
16 files changed, 417 insertions, 0 deletions
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; + }; +} |