aboutsummaryrefslogtreecommitdiff
path: root/src/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service.c')
-rw-r--r--src/service.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/service.c b/src/service.c
index e8d4764..1123c51 100644
--- a/src/service.c
+++ b/src/service.c
@@ -107,6 +107,7 @@ struct _IndicatorDatetimeServicePrivate
guint header_timer;
guint timezone_timer;
+ guint alarm_timer;
/* Which year/month to show in the calendar,
and which day should get the cursor.
@@ -376,6 +377,96 @@ start_header_timer (IndicatorDatetimeService * self)
g_date_time_unref (now);
}
+/***
+****
+***/
+
+static void start_alarm_timer (IndicatorDatetimeService * self);
+
+static gboolean
+datetimes_have_the_same_minute (GDateTime * a, GDateTime * b)
+{
+ int ay, am, ad;
+ int by, bm, bd;
+
+ g_date_time_get_ymd (a, &ay, &am, &ad);
+ g_date_time_get_ymd (b, &by, &bm, &bd);
+
+ return (ay == by) &&
+ (am == bm) &&
+ (ad == ad) &&
+ (g_date_time_get_hour (a) == g_date_time_get_hour (b)) &&
+ (g_date_time_get_minute (a) == g_date_time_get_minute (b));
+}
+
+/* This is called on the minute, every minute.
+ We check for alarms that start at the current time.
+ If we find any, we dispatch the URL associated with them. */
+static void
+dispatch_alarm_urls (IndicatorDatetimeService * self)
+{
+ GDateTime * now = indicator_datetime_service_get_localtime (self);
+ GSList * l;
+
+ for (l=self->priv->upcoming_appointments; l!=NULL; l=l->next)
+ {
+ const struct IndicatorDatetimeAppt * appt = l->data;
+
+ if ((appt->has_alarms) &&
+ (appt->url != NULL) &&
+ (g_str_has_prefix (appt->url, "alarm:///")) &&
+ (datetimes_have_the_same_minute (now, appt->begin)))
+ {
+ gchar * str = g_date_time_format (appt->begin, "%F %H:%M");
+ g_debug ("at %s, dispatching url \"%s\" for appointment \"%s\"", str, appt->url, appt->summary);
+ url_dispatch_send (appt->url, NULL, NULL);
+ g_free (str);
+ }
+ }
+
+ g_date_time_unref (now);
+}
+
+static gboolean
+on_alarm_timer (gpointer self)
+{
+ dispatch_alarm_urls (self);
+
+ /* Restarting the timer to recalculate the interval. This helps us to hit
+ our marks despite clock skew, suspend+resume, leap seconds, etc */
+ start_alarm_timer (self);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+start_alarm_timer (IndicatorDatetimeService * self)
+{
+ priv_t * p;
+ GDateTime * now;
+ guint interval_msec;
+
+ p = self->priv;
+
+ indicator_clear_timer (&p->alarm_timer);
+
+ now = indicator_datetime_service_get_localtime (self);
+ interval_msec = calculate_milliseconds_until_next_minute (now);
+ interval_msec += 50; /* add a small margin to ensure the callback
+ fires /after/ next is reached */
+
+ p->alarm_timer = g_timeout_add_full (G_PRIORITY_HIGH,
+ interval_msec,
+ on_alarm_timer,
+ self,
+ NULL);
+
+ g_date_time_unref (now);
+}
+
+/***
+****
+***/
+
/**
* General purpose handler for rebuilding sections and restarting their timers
* when time jumps for whatever reason:
@@ -1782,6 +1873,7 @@ my_dispose (GObject * o)
indicator_clear_timer (&p->rebuild_id);
indicator_clear_timer (&p->timezone_timer);
indicator_clear_timer (&p->header_timer);
+ indicator_clear_timer (&p->alarm_timer);
if (p->settings != NULL)
{
@@ -1948,6 +2040,8 @@ indicator_datetime_service_init (IndicatorDatetimeService * self)
on_local_time_jumped (self);
+ start_alarm_timer (self);
+
for (i=0; i<N_PROFILES; ++i)
create_menu (self, i);