Beginning of work on implementing calcurse daemon.

This commit is contained in:
Frederic Culot 2009-07-20 19:45:26 +00:00
parent c20463c47d
commit b55cad85da
5 changed files with 121 additions and 47 deletions

View File

@ -1,3 +1,17 @@
2009-07-20 Frederic Culot <frederic@culot.org>
* src/utils.c (psleep): new function
* configure.ac: check for some headers added
* src/notify.c (notify_time_left, notify_launch_cmd)
(notify_get_next): new functions
* src/Makefile.am
* src/dmon.[ch]: new files to implement calcurse daemon
* src/utils.c (psleep): new function
2009-07-19 Frederic Culot <frederic@culot.org>
* src/mem.c (dbg_free): no need to double check for null pointer

View File

@ -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)
{

View File

@ -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 */

View File

@ -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))
;
}

View File

@ -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 */