aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/alarm.c
diff options
context:
space:
mode:
authorArturo Espinosa <unammx@src.gnome.org>1998-04-18 12:02:46 +0800
committerArturo Espinosa <unammx@src.gnome.org>1998-04-18 12:02:46 +0800
commitf1b08663ddff6432289ca4780bc823c96d471657 (patch)
treefed1c651f292c4855550302ef94808338b9fd0dc /calendar/alarm.c
parentd79ee74dad39ee5210482aa90a7c6a7b2f0b7517 (diff)
downloadgsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.gz
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.bz2
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.lz
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.xz
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.zst
gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.zip
Yes.
Yes. It works. It loads, it saves, it does all that stuff. It works, even if federico complains that we did not test close. Repetition, alarms, all that stuff you all guys love. It it is there. We did minimal testing, but we know you will happilly commit a fix if you find a problem, right? Ok, we are off to a party now. Miguel svn path=/trunk/; revision=155
Diffstat (limited to 'calendar/alarm.c')
-rw-r--r--calendar/alarm.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/calendar/alarm.c b/calendar/alarm.c
new file mode 100644
index 0000000000..bb5c4c1b8d
--- /dev/null
+++ b/calendar/alarm.c
@@ -0,0 +1,145 @@
+/*
+ * Alarm handling for the GNOME Calendar.
+ *
+ * (C) 1998 the Free Software Foundation
+ *
+ * Author: Miguel de Icaza (miguel@kernel.org)
+ */
+#include <config.h>
+#include <time.h>
+#include <gnome.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include "alarm.h"
+
+/* The pipes used to notify about an alarm */
+int alarm_pipes [2];
+
+/* The list of pending alarms */
+static GList *alarms;
+
+static void *head_alarm;
+
+typedef struct {
+ time_t activation_time;
+ AlarmFunction fn;
+ void *closure;
+} AlarmRecord;
+
+/*
+ * SIGALRM handler. Notifies the callback about the alarm
+ */
+static void
+alarm_activate ()
+{
+ char c = 0;
+
+ printf ("ALARMA!\n");
+ write (alarm_pipes [1], &c, 1);
+}
+
+static void
+alarm_ready (void *closure, int fd, GdkInputCondition cond)
+{
+ AlarmRecord *ar = head_alarm;
+ char c;
+
+ if (read (alarm_pipes [0], &c, 1) != 1)
+ return;
+
+ if (ar == NULL){
+ g_warning ("Empty events. This should not happen\n");
+ return;
+ }
+ (*ar->fn)(ar->activation_time, ar->closure);
+ alarms = g_list_remove (alarms, head_alarm);
+ if (alarms)
+ head_alarm = alarms->data;
+ else
+ head_alarm = NULL;
+ g_free (ar);
+}
+
+static int
+alarm_compare_by_time (gpointer a, gpointer b)
+{
+ AlarmRecord *ara = a;
+ AlarmRecord *arb = b;
+ time_t diff;
+
+ diff = ara->activation_time - arb->activation_time;
+ return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
+}
+
+void
+alarm_add (time_t alarm_time, AlarmFunction fn, void *closure)
+{
+ time_t now = time (NULL);
+ AlarmRecord *ar;
+
+ /* If it already expired, do not add it */
+ if (alarm_time < now)
+ return;
+
+ ar = g_new0 (AlarmRecord, 1);
+ ar->activation_time = alarm_time;
+ ar->fn = fn;
+ ar->closure = closure;
+
+ alarms = g_list_insert_sorted (alarms, ar, alarm_compare_by_time);
+
+ /* If first alarm is not the previous first alarm, reschedule SIGALRM */
+ if (head_alarm != alarms->data){
+ struct itimerval itimer;
+ int v;
+
+ /* Set the timer to disable upon activation */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ itimer.it_value.tv_sec = alarm_time - now;
+ itimer.it_value.tv_usec = 0;
+ v = setitimer (ITIMER_REAL, &itimer, NULL);
+ head_alarm = alarms->data;
+ }
+}
+
+void
+alarm_kill (void *closure_key)
+{
+ GList *p;
+
+ for (p = alarms; p; p = p->next){
+ AlarmRecord *ar = p->data;
+
+ if (ar->closure == closure_key){
+ alarms = g_list_remove (alarms, p->data);
+ if (alarms)
+ head_alarm = alarms->data;
+ else
+ head_alarm = NULL;
+ return;
+ }
+ }
+}
+
+void
+alarm_init (void)
+{
+ struct sigaction sa;
+ int flags;
+
+ pipe (alarm_pipes);
+
+ /* set non blocking mode */
+ fcntl (alarm_pipes [0], F_GETFL, &flags);
+ fcntl (alarm_pipes [0], F_SETFL, flags | O_NONBLOCK);
+ gdk_input_add (alarm_pipes [0], GDK_INPUT_READ, alarm_ready, 0);
+
+ /* Setup the signal handler */
+ sa.sa_handler = alarm_activate;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction (SIGALRM, &sa, NULL);
+}
+