diff options
author | Arturo Espinosa <unammx@src.gnome.org> | 1998-04-18 12:02:46 +0800 |
---|---|---|
committer | Arturo Espinosa <unammx@src.gnome.org> | 1998-04-18 12:02:46 +0800 |
commit | f1b08663ddff6432289ca4780bc823c96d471657 (patch) | |
tree | fed1c651f292c4855550302ef94808338b9fd0dc /calendar/alarm.c | |
parent | d79ee74dad39ee5210482aa90a7c6a7b2f0b7517 (diff) | |
download | gsoc2013-evolution-f1b08663ddff6432289ca4780bc823c96d471657.tar.gz 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.c | 145 |
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); +} + |