From b55cad85dad5bd4bb81c92f6acaef7394b23d9b5 Mon Sep 17 00:00:00 2001
From: Frederic Culot <calcurse@culot.org>
Date: Mon, 20 Jul 2009 19:45:26 +0000
Subject: Beginning of work on implementing calcurse daemon.

---
 src/notify.c | 95 ++++++++++++++++++++++++++++++++++++++++++------------------
 src/notify.h | 37 ++++++++++++-----------
 src/utils.c  | 19 +++++++++++-
 src/utils.h  |  3 +-
 4 files changed, 107 insertions(+), 47 deletions(-)

(limited to 'src')

diff --git a/src/notify.c b/src/notify.c
index be2ce29..db80f75 100755
--- a/src/notify.c
+++ b/src/notify.c
@@ -1,4 +1,4 @@
-/*	$calcurse: notify.c,v 1.40 2009/07/12 17:55:14 culot Exp $	*/
+/*	$calcurse: notify.c,v 1.41 2009/07/20 19:45:26 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -57,12 +57,30 @@ static struct notify_app_s    notify_app;
 static pthread_attr_t         detached_thread_attr;
 static pthread_t              notify_t_main;
 
+/*
+ * Return the number of seconds before next appointment
+ * (0 if no upcoming appointment).
+ */
+int
+notify_time_left (void)
+{
+  struct tm *ntime;
+  time_t ntimer;
+  int left;  
+
+  ntimer = time (NULL);
+  ntime = localtime (&ntimer);
+  left = notify_app.time - ntimer;
+
+  return left > 0 ? left : 0;
+}
+
 /*
  * This is used to update the notify_app structure.
  * Note: the mutex associated with this structure must be locked by the
  * caller!
  */
-static void
+void
 notify_update_app (long start, char state, char *msg)
 {
   notify_free_app ();
@@ -148,6 +166,7 @@ notify_free_app (void)
 {
   if (notify_app.txt)
     mem_free (notify_app.txt);
+  notify_app.txt = 0;
 }
 
 /* Stop the notify-bar main thread. */
@@ -170,18 +189,30 @@ notify_reinit_bar (void)
 }
 
 /* Launch user defined command as a notification. */
-static void
-launch_cmd (char *cmd, char *shell)
+void
+notify_launch_cmd (void)
 {
   int pid;
 
+  if (notify_app.state & APOINT_NOTIFIED)
+    return;
+  
+  notify_app.state |= APOINT_NOTIFIED;
+    
   pid = fork ();
 
   if (pid < 0)
     ERROR_MSG (_("error while launching command: could not fork"));
-  else if (pid == 0)		/* Child: launch user defined command */
-    if (execlp (shell, shell, "-c", cmd, (char *)0) < 0)
-      ERROR_MSG (_("error while launching command"));
+  else if (pid == 0)
+    {
+      /* Child: launch user defined command */
+      if (execlp (nbar.shell, nbar.shell, "-c", nbar.cmd, (char *)0) < 0)
+        {
+          ERROR_MSG (_("error while launching command"));
+          _exit (1);
+        }
+      _exit (0);
+    }
 }
 
 /* 
@@ -193,8 +224,7 @@ notify_update_bar (void)
 {
   const int space = 3;
   int file_pos, date_pos, app_pos, txt_max_len, too_long = 0;
-  int time_left, hours_left, minutes_left;
-  int blinking;
+  int time_left, blinking;
   char buf[BUFSIZ];
 
   date_pos = space;
@@ -220,9 +250,11 @@ notify_update_bar (void)
 	  (void)strncpy (buf, notify_app.txt, txt_max_len - 3);
 	  buf[txt_max_len - 3] = '\0';
 	}
-      time_left = notify_app.time - notify.time_in_sec;
+      time_left = notify_time_left ();
       if (time_left > 0)
 	{
+          int hours_left, minutes_left;
+          
 	  hours_left = (time_left / HOURINSEC);
 	  minutes_left = (time_left - hours_left * HOURINSEC) / MININSEC;
 	  pthread_mutex_lock (&nbar.mutex);
@@ -243,11 +275,8 @@ notify_update_bar (void)
 	  if (blinking)
 	    wattroff (notify.win, A_BLINK);
 
-	  if (blinking && !(notify_app.state & APOINT_NOTIFIED))
-	    {
-	      notify_app.state |= APOINT_NOTIFIED;
-	      launch_cmd (nbar.cmd, nbar.shell);
-	    }
+	  if (blinking)
+            notify_launch_cmd ();
 	  pthread_mutex_unlock (&nbar.mutex);
 	}
       else
@@ -287,14 +316,13 @@ notify_main_thread (void *arg)
       ntimer = time (NULL);
       ntime = localtime (&ntimer);
       pthread_mutex_lock (&notify.mutex);
-      notify.time_in_sec = ntimer;
       pthread_mutex_lock (&nbar.mutex);
       strftime (notify.time, NOTIFY_FIELD_LENGTH, nbar.timefmt, ntime);
       strftime (notify.date, NOTIFY_FIELD_LENGTH, nbar.datefmt, ntime);
       pthread_mutex_unlock (&nbar.mutex);
       pthread_mutex_unlock (&notify.mutex);
       notify_update_bar ();
-      (void)sleep (thread_sleep);
+      psleep (thread_sleep);
       elapse += thread_sleep;
       if (elapse >= check_app)
 	{
@@ -309,24 +337,35 @@ notify_main_thread (void *arg)
   pthread_exit ((void *) 0);
 }
 
+/* Fill the given structure with information about next appointment. */
+unsigned
+notify_get_next (struct notify_app_s *a)
+{
+  time_t current_time;
+  
+  if (!a)
+    return 0;
+  
+  current_time = time (NULL);
+
+  a->time = current_time + DAYINSEC;
+  a->got_app = 0;
+  a->state = 0;
+  a->txt = (char *)0;
+  (void)recur_apoint_check_next (a, current_time, get_today ());
+  (void)apoint_check_next (a, current_time);
+
+  return 1;
+}
+
 /* Look for the next appointment within the next 24 hours. */
 /* ARGSUSED0 */
 static void *
 notify_thread_app (void *arg)
 {
   struct notify_app_s tmp_app;
-  time_t current_time;
-
-  current_time = time (NULL);
-
-  /* Use a temporary structure not to lock the mutex for a too
-   * long time while looking for next appointment. */
-  tmp_app.time = current_time + DAYINSEC;
-  tmp_app.got_app = 0;
-  tmp_app.txt = NULL;
-  tmp_app = *recur_apoint_check_next (&tmp_app, current_time, get_today ());
-  tmp_app = *apoint_check_next (&tmp_app, current_time);
 
+  (void)notify_get_next (&tmp_app);
   pthread_mutex_lock (&notify_app.mutex);
   if (tmp_app.got_app)
     {
diff --git a/src/notify.h b/src/notify.h
index 5b6ec4d..b066b97 100755
--- a/src/notify.h
+++ b/src/notify.h
@@ -1,9 +1,9 @@
-/*	$calcurse: notify.h,v 1.18 2009/07/05 20:33:22 culot Exp $	*/
+/*	$calcurse: notify.h,v 1.19 2009/07/20 19:45:26 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
  *
- * Copyright (c) 2004-2008 Frederic Culot <frederic@culot.org>
+ * Copyright (c) 2004-2009 Frederic Culot <frederic@culot.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,6 @@
 struct notify_vars_s
 {
   WINDOW *win;
-  long time_in_sec;
   char *apts_file;
   char time[NOTIFY_FIELD_LENGTH];
   char date[NOTIFY_FIELD_LENGTH];
@@ -64,19 +63,23 @@ struct notify_app_s
   pthread_mutex_t mutex;
 };
 
-int  notify_bar (void);
-void notify_init_vars (void);
-void notify_init_bar (void);
-void notify_free_app (void);
-void notify_start_main_thread (void);
-void notify_stop_main_thread (void);
-void notify_reinit_bar (void);
-void notify_update_bar (void);
-void notify_check_next_app (void);
-void notify_check_added (char *, long, char);
-void notify_check_repeated (recur_apoint_llist_node_t *);
-int  notify_same_item (long);
-int  notify_same_recur_item (recur_apoint_llist_node_t *);
-void notify_config_bar (void);
+int       notify_time_left (void);
+void      notify_update_app (long, char, char *);
+int       notify_bar (void);
+void      notify_init_vars (void);
+void      notify_init_bar (void);
+void      notify_free_app (void);
+void      notify_start_main_thread (void);
+void      notify_stop_main_thread (void);
+void      notify_reinit_bar (void);
+void      notify_launch_cmd (void);
+void      notify_update_bar (void);
+unsigned  notify_get_next (struct notify_app_s *);
+void      notify_check_next_app (void);
+void      notify_check_added (char *, long, char);
+void      notify_check_repeated (recur_apoint_llist_node_t *);
+int       notify_same_item (long);
+int       notify_same_recur_item (recur_apoint_llist_node_t *);
+void      notify_config_bar (void);
 
 #endif /* CALCURSE_NOTIFY_H */
diff --git a/src/utils.c b/src/utils.c
index e041bef..34cb142 100755
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,4 +1,4 @@
-/*	$calcurse: utils.c,v 1.76 2009/07/12 17:48:14 culot Exp $	*/
+/*	$calcurse: utils.c,v 1.77 2009/07/20 19:45:27 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -57,6 +57,7 @@
 #include "todo.h"
 #include "day.h"
 #include "keys.h"
+#include "dmon.h"
 #include "mem.h"
 
 /* General routine to exit calcurse properly. */
@@ -94,6 +95,8 @@ exit_calcurse (int status)
   mem_stats ();
   if (remove_lock)
     io_unset_lock ();
+
+  dmon_start (status);
   
   exit (status);
 }
@@ -938,3 +941,17 @@ file_close (FILE *f, const char *pos)
   ret = fclose (f);
   EXIT_IF (ret != 0, _("Error when closing file at %s"), pos);
 }
+
+/*
+ * Sleep the given number of seconds, but make it more 'precise' than sleep(3)
+ * (hence the 'p') in a way that even if a signal is caught during the sleep
+ * process, this function will return to sleep afterwards.
+ */
+void
+psleep (unsigned secs)
+{
+  unsigned unslept;
+
+  for (unslept = sleep (secs); unslept; unslept = sleep (unslept))
+    ;
+}
diff --git a/src/utils.h b/src/utils.h
index 59ce4c4..eae71a7 100755
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,4 +1,4 @@
-/*	$calcurse: utils.h,v 1.46 2009/07/12 16:22:02 culot Exp $	*/
+/*	$calcurse: utils.h,v 1.47 2009/07/20 19:45:27 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -156,5 +156,6 @@ void      erase_note (char **, erase_flag_e);
 int       parse_date (char *, int, int *, int *, int *);
 char     *str_toupper (char *);
 void      file_close (FILE *, const char *);
+void      psleep (unsigned);
 
 #endif /* CALCURSE_UTILS_H */
-- 
cgit v1.2.3-70-g09d2