Merge branch 'hooks-dir'
This commit is contained in:
+19
@@ -148,6 +148,25 @@ location\-provider=manual
|
||||
lat=55.7
|
||||
lon=12.6
|
||||
.fi
|
||||
.SH HOOKS
|
||||
Executable files (e.g. scripts) placed in `~/.config/redshift/hooks'
|
||||
will be run when a certain event happens. The first parameter to the
|
||||
script indicates the event and further parameters may indicate
|
||||
more details about the event. The event `period-changed' is indicated
|
||||
when the period changes (`night', `daytime', `transition'). The second
|
||||
parameter is the old period and the third is the new period. The event
|
||||
is also signaled when Redshift starts up with the old period set to
|
||||
`none'.
|
||||
|
||||
A simple script to handle these events can be written like this:
|
||||
.IP
|
||||
.nf
|
||||
#!/bin/sh
|
||||
case \fB$1\fR in
|
||||
\fBperiod-changed\fR)
|
||||
exec notify-send "Redshift" "Period changed to \fB$3\fR"
|
||||
esac
|
||||
.fi
|
||||
.SH AUTHOR
|
||||
.B redshift
|
||||
was written by Jon Lund Steffensen <jonlst@gmail.com>.
|
||||
|
||||
@@ -15,6 +15,7 @@ redshift_SOURCES = \
|
||||
location-manual.c location-manual.h \
|
||||
solar.c solar.h \
|
||||
systemtime.c systemtime.h \
|
||||
hooks.c hooks.h \
|
||||
gamma-dummy.c gamma-dummy.h
|
||||
|
||||
EXTRA_redshift_SOURCES = \
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/* hooks.c -- Hooks triggered by events
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2014 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "hooks.h"
|
||||
#include "redshift.h"
|
||||
|
||||
#define MAX_HOOK_PATH 4096
|
||||
|
||||
|
||||
/* Names of periods supplied to scripts. */
|
||||
static const char *period_names[] = {
|
||||
"none",
|
||||
"daytime",
|
||||
"night",
|
||||
"transition"
|
||||
};
|
||||
|
||||
|
||||
/* Try to open the directory containing hooks. HP is a string
|
||||
of MAX_HOOK_PATH length that will be filled with the path
|
||||
of the returned directory. */
|
||||
static DIR *
|
||||
open_hooks_dir(char *hp)
|
||||
{
|
||||
char *env;
|
||||
|
||||
if ((env = getenv("XDG_CONFIG_HOME")) != NULL &&
|
||||
env[0] != '\0') {
|
||||
snprintf(hp, MAX_HOOK_PATH, "%s/redshift/hooks", env);
|
||||
return opendir(hp);
|
||||
}
|
||||
|
||||
if ((env = getenv("HOME")) != NULL &&
|
||||
env[0] != '\0') {
|
||||
snprintf(hp, MAX_HOOK_PATH, "%s/.config/redshift/hooks", env);
|
||||
return opendir(hp);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
struct passwd *pwd = getpwuid(getuid());
|
||||
snprintf(hp, MAX_HOOK_PATH, "%s/.config/redshift/hooks", pwd->pw_dir);
|
||||
return opendir(hp);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Run hooks with a signal that the period changed. */
|
||||
void
|
||||
hooks_signal_period_change(period_t prev_period, period_t period)
|
||||
{
|
||||
char hooksdir_path[MAX_HOOK_PATH];
|
||||
DIR *hooks_dir = open_hooks_dir(hooksdir_path);
|
||||
if (hooks_dir == NULL) return;
|
||||
|
||||
struct dirent* ent;
|
||||
while ((ent = readdir(hooks_dir)) != NULL) {
|
||||
/* Skip hidden and special files (., ..) */
|
||||
if (ent->d_name[0] == '\0' || ent->d_name[0] == '.') continue;
|
||||
|
||||
char *hook_name = ent->d_name;
|
||||
char hook_path[MAX_HOOK_PATH];
|
||||
snprintf(hook_path, sizeof(hook_path), "%s/%s",
|
||||
hooksdir_path, hook_name);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Fork and exec the hook. We close stdout
|
||||
so the hook cannot interfere with the normal
|
||||
output. */
|
||||
pid_t pid = fork();
|
||||
if (pid == (pid_t)-1) {
|
||||
perror("fork");
|
||||
continue;
|
||||
} else if (pid == 0) { /* Child */
|
||||
close(STDOUT_FILENO);
|
||||
|
||||
int r = execl(hook_path, hook_name,
|
||||
"period-changed",
|
||||
period_names[prev_period],
|
||||
period_names[period], NULL);
|
||||
if (r < 0 && errno != EACCES) perror("execl");
|
||||
|
||||
/* Only reached on error */
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/* hooks.h -- Hooks triggered by events
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2014 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef REDSHIFT_HOOKS_H
|
||||
#define REDSHIFT_HOOKS_H
|
||||
|
||||
#include "redshift.h"
|
||||
|
||||
void hooks_signal_period_change(period_t prev_period,
|
||||
period_t period);
|
||||
|
||||
|
||||
#endif /* ! REDSHIFT_HOOKS_H */
|
||||
+19
-8
@@ -47,6 +47,7 @@
|
||||
#include "config-ini.h"
|
||||
#include "solar.h"
|
||||
#include "systemtime.h"
|
||||
#include "hooks.h"
|
||||
|
||||
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
@@ -296,14 +297,6 @@ typedef enum {
|
||||
PROGRAM_MODE_MANUAL
|
||||
} program_mode_t;
|
||||
|
||||
/* Periods of day. */
|
||||
typedef enum {
|
||||
PERIOD_NONE = 0,
|
||||
PERIOD_DAYTIME,
|
||||
PERIOD_NIGHT,
|
||||
PERIOD_TRANSITION
|
||||
} period_t;
|
||||
|
||||
/* Names of periods of day */
|
||||
static const char *period_names[] = {
|
||||
/* TRANSLATORS: Name printed when period of day is unknown */
|
||||
@@ -1445,6 +1438,18 @@ main(int argc, char *argv[])
|
||||
perror("sigaction");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ignore CHLD signal. This causes child processes
|
||||
(hooks) to be reaped automatically. */
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigact.sa_mask = sigset;
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
r = sigaction(SIGCHLD, &sigact, NULL);
|
||||
if (r < 0) {
|
||||
perror("sigaction");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif /* HAVE_SIGNAL_H && ! __WIN32__ */
|
||||
|
||||
if (verbose) {
|
||||
@@ -1540,6 +1545,12 @@ main(int argc, char *argv[])
|
||||
print_period(period, transition);
|
||||
}
|
||||
|
||||
/* Activate hooks if period changed */
|
||||
if (period != prev_period) {
|
||||
hooks_signal_period_change(prev_period,
|
||||
period);
|
||||
}
|
||||
|
||||
/* Ongoing short transition */
|
||||
if (short_trans_delta) {
|
||||
/* Calculate alpha */
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* Periods of day. */
|
||||
typedef enum {
|
||||
PERIOD_NONE = 0,
|
||||
PERIOD_DAYTIME,
|
||||
PERIOD_NIGHT,
|
||||
PERIOD_TRANSITION
|
||||
} period_t;
|
||||
|
||||
|
||||
/* Color setting */
|
||||
typedef struct {
|
||||
int temperature;
|
||||
|
||||
Reference in New Issue
Block a user