2015-11-28 13:08:54 +00:00
|
|
|
/* See LICENSE file for copyright and license details. */
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2016-02-25 12:14:36 +00:00
|
|
|
#include <signal.h>
|
2016-05-13 15:13:23 +00:00
|
|
|
#ifdef NOTIFY
|
2015-11-28 13:08:54 +00:00
|
|
|
#include <libnotify/notify.h>
|
2016-05-13 15:13:23 +00:00
|
|
|
#endif /* NOTIFY */
|
2015-11-28 13:08:54 +00:00
|
|
|
|
|
|
|
#include "arg.h"
|
|
|
|
|
|
|
|
char *argv0;
|
|
|
|
|
|
|
|
/* macros */
|
2016-07-11 10:47:18 +00:00
|
|
|
#define LEN(a) (sizeof(a) / sizeof(a[0]))
|
|
|
|
|
2015-11-28 13:08:54 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
unsigned int tmr;
|
|
|
|
char *cmt;
|
2016-02-02 15:07:13 +00:00
|
|
|
} Timers;
|
2015-11-28 13:08:54 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2016-10-25 18:23:05 +00:00
|
|
|
volatile static sig_atomic_t display, suspend;
|
2016-02-25 12:14:36 +00:00
|
|
|
|
2015-11-28 13:08:54 +00:00
|
|
|
/* function declarations */
|
|
|
|
static void die(const char *errstr, ...);
|
2016-07-11 11:36:15 +00:00
|
|
|
static void spawn(char *cmd, char *cmt);
|
2016-07-11 09:32:47 +00:00
|
|
|
static void notify_send(char *cmt);
|
2016-10-25 18:23:05 +00:00
|
|
|
static void display_time(int timecount);
|
|
|
|
static void toggle_display(int sigint);
|
|
|
|
static void toggle_suspend(int sigint);
|
2015-11-28 13:08:54 +00:00
|
|
|
static void usage(void);
|
|
|
|
|
|
|
|
/* functions implementations */
|
|
|
|
void
|
|
|
|
die(const char *errstr, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, errstr);
|
|
|
|
vfprintf(stderr, errstr, ap);
|
|
|
|
va_end(ap);
|
2016-07-11 11:36:15 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spawn(char *cmd, char *cmt)
|
|
|
|
{
|
|
|
|
if (fork() == 0) {
|
|
|
|
setsid();
|
|
|
|
execlp(cmd, cmd, "spt", cmt, NULL);
|
|
|
|
die("spt: execlp %s\n", cmd);
|
|
|
|
perror(" failed");
|
|
|
|
exit(0);
|
|
|
|
}
|
2015-11-28 13:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
notify_send(char *cmt)
|
|
|
|
{
|
2016-05-13 15:13:23 +00:00
|
|
|
#ifdef NOTIFY
|
2016-07-11 09:32:47 +00:00
|
|
|
notify_init("spt");
|
|
|
|
NotifyNotification *n = notify_notification_new("spt", cmt, \
|
|
|
|
"dialog-information");
|
|
|
|
notify_notification_show(n, NULL);
|
|
|
|
g_object_unref(G_OBJECT(n));
|
|
|
|
notify_uninit();
|
|
|
|
#else
|
2016-07-11 10:47:18 +00:00
|
|
|
if (strcmp(notifycmd, "")) /* TODO: call function in config.h */
|
2016-07-11 11:36:15 +00:00
|
|
|
spawn(notifycmd, cmt);
|
2016-07-11 09:32:47 +00:00
|
|
|
#endif /* NOTIFY */
|
2015-11-28 13:08:54 +00:00
|
|
|
|
|
|
|
if (strcmp(notifyext, "")) /* extra commands to use */
|
2016-07-11 11:36:15 +00:00
|
|
|
spawn(notifyext, NULL);
|
2015-11-28 13:08:54 +00:00
|
|
|
}
|
|
|
|
|
2016-02-25 12:14:36 +00:00
|
|
|
void
|
2016-10-25 18:23:05 +00:00
|
|
|
display_time(int timecount)
|
2016-02-25 12:14:36 +00:00
|
|
|
{
|
2016-07-11 11:36:15 +00:00
|
|
|
char buf[17];
|
2016-02-25 12:14:36 +00:00
|
|
|
|
2016-07-11 11:36:15 +00:00
|
|
|
snprintf(buf, 17, "Remaining: %02d:%02d\n",
|
2016-10-25 18:23:05 +00:00
|
|
|
timecount / 60,
|
|
|
|
timecount % 60);
|
2016-02-25 12:14:36 +00:00
|
|
|
|
2016-07-11 11:36:15 +00:00
|
|
|
notify_send(buf);
|
2016-10-25 18:23:05 +00:00
|
|
|
display = 0;
|
2016-02-25 12:14:36 +00:00
|
|
|
}
|
|
|
|
|
2016-07-12 08:51:26 +00:00
|
|
|
void
|
2016-10-25 18:23:05 +00:00
|
|
|
toggle_display(int sigint)
|
|
|
|
{
|
|
|
|
display = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
toggle_suspend(int sigint)
|
|
|
|
{
|
2016-10-19 22:24:09 +00:00
|
|
|
suspend ^= 1;
|
2016-07-12 08:51:26 +00:00
|
|
|
}
|
|
|
|
|
2015-11-28 13:08:54 +00:00
|
|
|
void
|
|
|
|
usage(void)
|
|
|
|
{
|
|
|
|
die("usage: %s [-e notifyext] [-n notifycmd] [-v]\n", argv0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
2016-10-22 18:06:23 +00:00
|
|
|
struct sigaction sa;
|
|
|
|
sigset_t emptymask;
|
2016-10-25 18:23:05 +00:00
|
|
|
int i, timecount;
|
2016-07-12 08:51:26 +00:00
|
|
|
|
2015-11-28 13:08:54 +00:00
|
|
|
ARGBEGIN {
|
|
|
|
case 'e':
|
|
|
|
notifyext = EARGF(usage());
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
notifycmd = EARGF(usage());
|
|
|
|
break;
|
|
|
|
case 'v':
|
2016-10-28 16:43:20 +00:00
|
|
|
die("spt " VERSION " © 2015-2016 spt engineers, "
|
2015-11-28 13:08:54 +00:00
|
|
|
"see LICENSE for details\n");
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
break;
|
|
|
|
} ARGEND;
|
|
|
|
|
2016-10-22 18:06:23 +00:00
|
|
|
/* add SIGUSR1 handler: remaining_time */
|
2016-10-25 18:23:05 +00:00
|
|
|
sa.sa_handler = toggle_display;
|
2016-10-22 18:06:23 +00:00
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
|
|
|
|
if (sigaction(SIGUSR1, &sa, NULL) == -1)
|
|
|
|
die("cannot associate SIGUSR1 to handler\n");
|
|
|
|
|
|
|
|
/* add SIGUSR2 handler: toggle */
|
2016-10-25 18:23:05 +00:00
|
|
|
sa.sa_handler = toggle_suspend;
|
2016-10-22 18:06:23 +00:00
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
|
|
|
|
if (sigaction(SIGUSR2, &sa, NULL) == -1)
|
|
|
|
die("cannot associate SIGUSR2 to handler\n");
|
2016-02-25 12:14:36 +00:00
|
|
|
|
2016-09-06 13:36:05 +00:00
|
|
|
for (i = 0; ; i = (i + 1) % LEN(timers)) {
|
|
|
|
notify_send(timers[i].cmt);
|
2016-10-19 22:24:09 +00:00
|
|
|
timecount = 0;
|
2016-10-25 18:23:05 +00:00
|
|
|
while (timecount < timers[i].tmr) {
|
|
|
|
if (display)
|
|
|
|
display_time(timecount);
|
|
|
|
|
2016-10-19 22:24:09 +00:00
|
|
|
if (suspend)
|
2016-10-22 18:06:23 +00:00
|
|
|
sigsuspend(&emptymask);
|
2016-10-19 22:24:09 +00:00
|
|
|
else {
|
|
|
|
sleep(1);
|
|
|
|
timecount++;
|
|
|
|
}
|
2016-10-25 18:23:05 +00:00
|
|
|
}
|
2016-09-06 13:36:05 +00:00
|
|
|
}
|
2015-11-28 13:08:54 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|