summaryrefslogtreecommitdiff
path: root/src/timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/timer.cpp')
-rw-r--r--src/timer.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/timer.cpp b/src/timer.cpp
index 4f7c2a3..d01a8e7 100644
--- a/src/timer.cpp
+++ b/src/timer.cpp
@@ -27,6 +27,136 @@
#include <core/screen.h>
#include "privatescreen.h"
+CompTimeoutSource::CompTimeoutSource () :
+ Glib::Source ()
+{
+ struct timespec ts;
+
+ clock_gettime (CLOCK_MONOTONIC, &ts);
+
+ mLastTimeout = ts;
+
+ set_priority (G_PRIORITY_HIGH);
+ attach (screen->priv->ctx);
+ connect (sigc::mem_fun <bool, CompTimeoutSource> (this, &CompTimeoutSource::callback));
+}
+
+CompTimeoutSource::~CompTimeoutSource ()
+{
+}
+
+sigc::connection
+CompTimeoutSource::connect (const sigc::slot <bool> &slot)
+{
+ return connect_generic (slot);
+}
+
+Glib::RefPtr <CompTimeoutSource>
+CompTimeoutSource::create ()
+{
+ return Glib::RefPtr <CompTimeoutSource> (new CompTimeoutSource ());
+}
+
+#define COMPIZ_TIMEOUT_WAIT 15
+
+bool
+CompTimeoutSource::prepare (int &timeout)
+{
+ struct timespec ts;
+
+ clock_gettime (CLOCK_MONOTONIC, &ts);
+
+ /* Determine time to wait */
+
+ if (screen->priv->timers.empty ())
+ {
+ /* This kind of sucks, but we have to do it, considering
+ * that glib provides us no safe way to remove the source -
+ * thankfully we shouldn't ever be hitting this case since
+ * we create the source after we start pingTimer
+ * and that doesn't stop until compiz does
+ */
+
+ timeout = COMPIZ_TIMEOUT_WAIT;
+ return true;
+ }
+
+ if (screen->priv->timers.front ()->mMinLeft > 0)
+ {
+ std::list<CompTimer *>::iterator it = screen->priv->timers.begin ();
+
+ CompTimer *t = (*it);
+ timeout = t->mMaxLeft;
+ while (it != screen->priv->timers.end ())
+ {
+ t = (*it);
+ if (t->mMinLeft >= timeout)
+ break;
+ if (t->mMaxLeft < timeout)
+ timeout = t->mMaxLeft;
+ it++;
+ }
+
+ mLastTimeout = ts;
+ return false;
+ }
+ else
+ {
+ mLastTimeout = ts;
+ timeout = 0;
+ return true;
+ }
+}
+
+bool
+CompTimeoutSource::check ()
+{
+ struct timespec ts;
+ int timeDiff;
+
+ clock_gettime (CLOCK_MONOTONIC, &ts);
+ timeDiff = TIMESPECDIFF (&ts, &mLastTimeout);
+
+ if (timeDiff < 0)
+ timeDiff = 0;
+
+ foreach (CompTimer *t, screen->priv->timers)
+ {
+ t->mMinLeft -= timeDiff;
+ t->mMaxLeft -= timeDiff;
+ }
+
+ return screen->priv->timers.front ()->mMinLeft <= 0;
+}
+
+bool
+CompTimeoutSource::dispatch (sigc::slot_base *slot)
+{
+ (*static_cast <sigc::slot <bool> *> (slot)) ();
+
+ return true;
+}
+
+bool
+CompTimeoutSource::callback ()
+{
+ while (screen->priv->timers.begin () != screen->priv->timers.end () &&
+ screen->priv->timers.front ()->mMinLeft <= 0)
+ {
+ CompTimer *t = screen->priv->timers.front ();
+ screen->priv->timers.pop_front ();
+
+ t->mActive = false;
+ if (t->mCallBack ())
+ {
+ screen->priv->addTimer (t);
+ t->mActive = true;
+ }
+ }
+
+ return !screen->priv->timers.empty ();
+}
+
CompTimer::CompTimer () :
mActive (false),
mMinTime (0),