/* * Alarm handling for the GNOME Calendar. * * (C) 1998 the Free Software Foundation * * Author: Miguel de Icaza (miguel@kernel.org) */ #include #include #include #include #include #include #include "calobj.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; CalendarAlarm *alarm; } AlarmRecord; enum DebugAction { ALARM_ACTIVATED, ALARM_ADDED, ALARM_NOT_ADDED }; void debug_alarm (AlarmRecord* ar, enum DebugAction action); void calendar_notify (time_t time, CalendarAlarm *which, void *data); extern int debug_alarms; /* * SIGALRM handler. Notifies the callback about the alarm */ static void alarm_activate () { char c = 0; write (alarm_pipes [1], &c, 1); } /* * SIGUSR1 handler. Toggles debugging output */ static void toggle_debugging () { debug_alarms = !debug_alarms; } static void alarm_ready (void *closure, int fd, GdkInputCondition cond) { AlarmRecord *ar = head_alarm; time_t now = time (NULL); char c; if (read (alarm_pipes [0], &c, 1) != 1) return; if (ar == NULL){ g_warning ("Empty events. This should not happen\n"); return; } while (head_alarm){ if (debug_alarms) debug_alarm (ar, ALARM_ACTIVATED); (*ar->fn)(ar->activation_time, ar->alarm, ar->closure); alarms = g_list_remove (alarms, head_alarm); /* Schedule next alarm */ if (alarms){ AlarmRecord *next; head_alarm = alarms->data; next = head_alarm; if (next->activation_time > now){ struct itimerval itimer; itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = next->activation_time - now; itimer.it_value.tv_usec = 0; setitimer (ITIMER_REAL, &itimer, NULL); break; } else { g_free (ar); ar = next; } } else head_alarm = NULL; } g_free (ar); } static int alarm_compare_by_time (gconstpointer a, gconstpointer b) { const AlarmRecord *ara = a; const AlarmRecord *arb = b; time_t diff; diff = ara->activation_time - arb->activation_time; return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; } /** * alarm_add: * * Tries to schedule @alarm. * * Returns TRUE if the alarm was scheduled. */ gboolean alarm_add (CalendarAlarm *alarm, AlarmFunction fn, void *closure) { time_t now = time (NULL); AlarmRecord *ar; time_t alarm_time = alarm->trigger; ar = g_new0 (AlarmRecord, 1); ar->activation_time = alarm_time; ar->fn = fn; ar->closure = closure; ar->alarm = alarm; /* If it already expired, do not add it */ if (alarm_time < now) { if (debug_alarms) debug_alarm (ar, ALARM_NOT_ADDED); return FALSE; } 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; } if (debug_alarms) debug_alarm (ar, ALARM_ADDED); return TRUE; } int 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 1; } } return 0; } void alarm_init (void) { struct sigaction sa; struct sigaction debug_sa; int flags = 0; 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); /* Setup a signal handler to toggle debugging */ debug_sa.sa_handler = toggle_debugging; sigemptyset (&debug_sa.sa_mask); debug_sa.sa_flags = SA_RESTART; sigaction (SIGUSR1, &debug_sa, NULL); } void debug_alarm (AlarmRecord* ar, enum DebugAction action) { time_t now = time (NULL); iCalObject *ico = ar->closure; printf ("%s", ctime(&now)); switch (action) { case ALARM_ADDED: printf ("Added alarm for %s", ctime(&ar->activation_time)); break; case ALARM_NOT_ADDED: printf ("Alarm not added for %s", ctime(&ar->activation_time)); break; case ALARM_ACTIVATED: printf ("Activated alarm\n"); break; } if (ar->fn!=&calendar_notify) return; printf ("--- Summary: %s\n", ico->summary); switch (ar->alarm->type) { case ALARM_MAIL: printf ("--- Type: Mail\n"); break; case ALARM_PROGRAM: printf ("--- Type: Program\n"); break; case ALARM_DISPLAY: printf ("--- Type: Display\n"); break; case ALARM_AUDIO: printf ("--- Type: Audio\n"); break; } } /a>summaryrefslogtreecommitdiffstats
Commit message (Expand)AuthorAgeFilesLines
* Add NO_STAGE all over the place in preparation for the staging support (cat: ...bapt2013-09-211-0/+1
* - Remove MAKE_JOBS_SAFE variableak2013-08-151-1/+0
* Give my maintainership to Chris Petrikcs2013-07-291-1/+1
* Update to 9.2cs2013-06-273-4/+4
* Convert the 2 last USE_CMAKE to USES= cmakebapt2013-04-251-2/+1
* - Update to 9.1cs2013-04-183-25/+10
* Update to 9.0cs2013-03-293-4/+4
* Update to 8.8.1cs2013-03-253-5/+5
* - convert USE_CMAKE to USESmakc2013-03-231-1/+1
* - Update to 8.7cs2013-01-155-53/+10
* - Update to 8.6:cs2012-11-043-9/+6
* - Update to 8.5cs2012-09-212-4/+4
* Update to 8.4cs2012-06-082-3/+3
* Switch to OptionsNGcs2012-06-051-27/+60
* - Update to 8.3.2cs2012-05-313-57/+83
* In the rc.d scripts, change assignments to rcvar to use thedougb2012-01-142-2/+2
* Update to 7.8.2cs2011-11-192-3/+3
* Update to 7.8.1cs2011-11-102-3/+3
* Update to 7.7cs2011-10-072-3/+3
* - Add LDFLAGS to CONFIGURE_ENV and MAKE_ENV (as it was done with LDFLAGS)amdmi32011-09-241-3/+2
* Change maintainer address to my FreeBSD addresscs2011-09-151-1/+1
* I made a slightly incorrect suggestion about the pidfile optimization,dougb2011-08-251-1/+1
* - Updated to 7.6glarkin2011-08-254-10/+6
* - Added rc.d file for php-fcgi (Hiawatha FastCGI daemon)glarkin2011-08-244-7/+59
* - Updated to 7.5glarkin2011-07-072-3/+3
* - Updated to 7.4.1glarkin2011-04-233-23/+3
* - Added patch to circumvent integer overflow in Content-Length headerglarkin2011-03-182-0/+20
* - Updated to 7.4 (http://www.hiawatha-webserver.org/changelog) [1]glarkin2010-11-123-8/+8
* - Added the "largefile" option to be passed to the configure scriptglarkin2010-09-162-10/+28
* - Update to 7.3sahil2010-06-082-6/+7
* - Reset maintainer to ports@FreeBSD.orgsahil2010-06-051-1/+1
* - Update to 7.2 [1]sahil2010-05-273-21/+12
* - Update to 7.1sylvio2010-04-063-7/+7
* Begin the process of deprecating sysutils/rc_subr bydougb2010-03-271-1/+1
* Update to 7.0.tobez2010-03-162-8/+14
* - Update to 6.19wen2009-12-272-4/+4
* - Update to 6.18wen2009-11-162-4/+4
* - Update to 6.17amdmi32009-10-063-8/+9
* - Don't overwrite configuration files, or index.html.wxs2009-08-013-11/+32
* - Update to 6.15amdmi32009-07-083-5/+6
* - Update to 6.14.1.lippe2009-06-083-9/+9
* - Update to 6.13amdmi32009-05-312-4/+11
* - Update to 6.11jadawin2009-01-202-4/+4
* - Update to 6.10miwi2008-11-103-9/+9
* Update CONFIGURE_ARGS for how we pass CONFIGURE_TARGET to configure script.rafan2008-08-211-1/+0
* - Update to 6.7rafan2008-05-312-7/+12
* - Update to 6.3.araujo2008-02-174-37/+58
* - Update to 6.0pav2007-10-272-4/+4
* Update to 5.14lme2007-10-142-4/+4
* Update port: www/hiawathaedwin2007-09-093-7/+6
* - Set --mandir and --infodir in CONFIGURE_ARGS if the configure scriptrafan2007-07-231-1/+1
* - Update to 5.9rafan2007-06-173-6/+8
* - Update to 5.7miwi2007-03-082-4/+4
* - Update to 5.6rafan2007-02-173-18/+23
* - Update to 5.3itetcu2006-12-273-9/+13