aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/config-ini.c2
-rw-r--r--src/gamma-drm.c5
-rw-r--r--src/gamma-randr.c2
-rw-r--r--src/gamma-vidmode.c2
-rw-r--r--src/location-geoclue.c4
-rw-r--r--src/redshift-gtk/statusicon.py71
-rw-r--r--src/redshift.c78
-rw-r--r--src/signals.c112
-rw-r--r--src/signals.h38
10 files changed, 208 insertions, 107 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c7a5444..318fc2c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ bin_PROGRAMS = redshift
redshift_SOURCES = \
redshift.c redshift.h \
+ signals.c signals.h \
colorramp.c colorramp.h \
config-ini.c config-ini.h \
location-manual.c location-manual.h \
diff --git a/src/config-ini.c b/src/config-ini.c
index 65751dd..749512a 100644
--- a/src/config-ini.c
+++ b/src/config-ini.c
@@ -226,7 +226,7 @@ config_ini_init(config_ini_state_t *state, const char *filepath)
config_ini_free(state);
return -1;
}
-
+
/* Insert into section list. */
setting->name = NULL;
setting->value = NULL;
diff --git a/src/gamma-drm.c b/src/gamma-drm.c
index d15f3f6..c2ac4bd 100644
--- a/src/gamma-drm.c
+++ b/src/gamma-drm.c
@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
-#include <alloca.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -60,7 +59,7 @@ drm_start(drm_state_t *state)
{
/* Acquire access to a graphics card. */
long maxlen = strlen(DRM_DIR_NAME) + strlen(DRM_DEV_NAME) + 10;
- char *pathname = alloca(maxlen * sizeof(char));
+ char pathname[maxlen];
sprintf(pathname, DRM_DEV_NAME, DRM_DIR_NAME, state->card_num);
@@ -69,6 +68,8 @@ drm_start(drm_state_t *state)
/* TODO check if access permissions, normally root or
membership of the video group is required. */
perror("open");
+ fprintf(stderr, _("Failed to open DRM device: %s\n"),
+ pathname);
return -1;
}
diff --git a/src/gamma-randr.c b/src/gamma-randr.c
index 0594332..6fa2bc6 100644
--- a/src/gamma-randr.c
+++ b/src/gamma-randr.c
@@ -306,7 +306,7 @@ randr_set_temperature_for_crtc(randr_state_t *state, int crtc_num,
const color_setting_t *setting)
{
xcb_generic_error_t *error;
-
+
if (crtc_num >= state->crtc_count || crtc_num < 0) {
fprintf(stderr, _("CRTC %d does not exist. "),
state->crtc_num);
diff --git a/src/gamma-vidmode.c b/src/gamma-vidmode.c
index 254d065..c9682d2 100644
--- a/src/gamma-vidmode.c
+++ b/src/gamma-vidmode.c
@@ -167,7 +167,7 @@ vidmode_restore(vidmode_state_t *state)
if (!r) {
fprintf(stderr, _("X request failed: %s\n"),
"XF86VidModeSetGammaRamp");
- }
+ }
}
int
diff --git a/src/location-geoclue.c b/src/location-geoclue.c
index 851a75b..e24c2d2 100644
--- a/src/location-geoclue.c
+++ b/src/location-geoclue.c
@@ -50,7 +50,7 @@ location_geoclue_init(location_geoclue_state_t *state)
state->position = NULL;
state->provider = NULL;
state->provider_path = NULL;
-
+
return 0;
}
@@ -200,7 +200,7 @@ location_geoclue_get_location(location_geoclue_state_t *state,
g_error_free(error);
return -1;
}
-
+
if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
fprintf(stdout, _("According to the geoclue provider"
diff --git a/src/redshift-gtk/statusicon.py b/src/redshift-gtk/statusicon.py
index b766175..9d9835d 100644
--- a/src/redshift-gtk/statusicon.py
+++ b/src/redshift-gtk/statusicon.py
@@ -29,11 +29,15 @@ import signal
import re
import gettext
+import gi
+gi.require_version('Gtk', '3.0')
+
from gi.repository import Gtk, GLib, GObject
try:
+ gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator
-except ImportError:
+except (ImportError, ValueError):
appindicator = None
from . import defs
@@ -139,9 +143,13 @@ class RedshiftController(GObject.GObject):
if inhibit != self._inhibited:
self._child_toggle_inhibit()
+ def _child_signal(self, sg):
+ """Send signal to child process."""
+ os.kill(self._process[0], sg)
+
def _child_toggle_inhibit(self):
'''Sends a request to the child process to toggle state'''
- os.kill(self._process[0], signal.SIGUSR1)
+ self._child_signal(signal.SIGUSR1)
def _child_cb(self, pid, status, data=None):
'''Called when the child process exists'''
@@ -159,13 +167,12 @@ class RedshiftController(GObject.GObject):
report_errors = False
try:
GLib.spawn_check_exit_status(status)
- Gtk.main_quit()
except GLib.GError:
- report_errors = True
-
- if report_errors:
self.emit('error-occured', self._errors)
+ GLib.spawn_close_pid(self._process[0])
+ Gtk.main_quit()
+
def _child_key_change_cb(self, key, value):
'''Called when the child process reports a change of internal state'''
@@ -223,14 +230,13 @@ class RedshiftController(GObject.GObject):
return True
- def termwait(self):
- '''Send SIGINT and wait for the child process to quit'''
- try:
- os.kill(self._process[0], signal.SIGINT)
- os.waitpid(self._process[0], 0)
- except ProcessLookupError:
- # Process has apparently already disappeared
- pass
+ def terminate_child(self):
+ """Send SIGINT to child process."""
+ self._child_signal(signal.SIGINT)
+
+ def kill_child(self):
+ """Send SIGKILL to child process."""
+ self._child_signal(signal.SIGKILL)
class RedshiftStatusIcon(object):
@@ -468,15 +474,23 @@ class RedshiftStatusIcon(object):
def change_temperature(self, temperature):
'''Change interface to new temperature'''
self.temperature_label.set_markup('<b>{}:</b> {}K'.format(_('Color temperature'), temperature))
+ self.update_tooltip_text()
def change_period(self, period):
'''Change interface to new period'''
self.period_label.set_markup('<b>{}:</b> {}'.format(_('Period'), period))
+ self.update_tooltip_text()
def change_location(self, location):
'''Change interface to new location'''
self.location_label.set_markup('<b>{}:</b> {}, {}'.format(_('Location'), *location))
+ def update_tooltip_text(self):
+ '''Update text of tooltip status icon '''
+ if not appindicator:
+ self.status_icon.set_tooltip_text('{}: {}K, {}: {}'.format(
+ _('Color temperature'), self._controller.temperature,
+ _('Period'), self._controller.period))
def autostart_cb(self, widget, data=None):
'''Callback when a request to toggle autostart is made'''
@@ -486,35 +500,36 @@ class RedshiftStatusIcon(object):
'''Callback when a request to quit the application is made'''
if not appindicator:
self.status_icon.set_visible(False)
- Gtk.main_quit()
+ self._controller.terminate_child()
return False
-def sigterm_handler(data=None):
- sys.exit(0)
-
-
def run():
utils.setproctitle('redshift-gtk')
- # Install TERM signal handler
- GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGTERM,
- sigterm_handler, None)
- GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT,
- sigterm_handler, None)
-
# Internationalisation
gettext.bindtextdomain('redshift', defs.LOCALEDIR)
gettext.textdomain('redshift')
# Create redshift child process controller
c = RedshiftController(sys.argv[1:])
+
+ def terminate_child(data=None):
+ c.terminate_child()
+ return False
+
+ # Install signal handlers
+ GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGTERM,
+ terminate_child, None)
+ GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT,
+ terminate_child, None)
+
try:
# Create status icon
s = RedshiftStatusIcon(c)
# Run main loop
Gtk.main()
- finally:
- # Always make sure that the child process is closed
- c.termwait()
+ except:
+ c.kill_child()
+ raise
diff --git a/src/redshift.c b/src/redshift.c
index defd0a1..bf741bb 100644
--- a/src/redshift.c
+++ b/src/redshift.c
@@ -48,6 +48,7 @@
#include "solar.h"
#include "systemtime.h"
#include "hooks.h"
+#include "signals.h"
/* pause() is not defined on windows platform but is not needed either.
Use a noop macro instead. */
@@ -319,32 +320,6 @@ static const char *period_names[] = {
N_("Transition")
};
-#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
-
-static volatile sig_atomic_t exiting = 0;
-static volatile sig_atomic_t disable = 0;
-
-/* Signal handler for exit signals */
-static void
-sigexit(int signo)
-{
- exiting = 1;
-}
-
-/* Signal handler for disable signal */
-static void
-sigdisable(int signo)
-{
- disable = 1;
-}
-
-#else /* ! HAVE_SIGNAL_H || __WIN32__ */
-
-static int exiting = 0;
-static int disable = 0;
-
-#endif /* ! HAVE_SIGNAL_H || __WIN32__ */
-
/* Determine which period we are currently in. */
static period_t
@@ -817,52 +792,11 @@ run_continual_mode(const location_t *loc,
will be exactly 6500K. */
double adjustment_alpha = 1.0;
-#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
- struct sigaction sigact;
- sigset_t sigset;
- sigemptyset(&sigset);
-
- /* Install signal handler for INT and TERM signals */
- sigact.sa_handler = sigexit;
- sigact.sa_mask = sigset;
- sigact.sa_flags = 0;
-
- r = sigaction(SIGINT, &sigact, NULL);
+ r = signals_install_handlers();
if (r < 0) {
- perror("sigaction");
- return -1;
+ return r;
}
- r = sigaction(SIGTERM, &sigact, NULL);
- if (r < 0) {
- perror("sigaction");
- return -1;
- }
-
- /* Install signal handler for USR1 signal */
- sigact.sa_handler = sigdisable;
- sigact.sa_mask = sigset;
- sigact.sa_flags = 0;
-
- r = sigaction(SIGUSR1, &sigact, NULL);
- if (r < 0) {
- perror("sigaction");
- return -1;
- }
-
- /* 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");
- return -1;
- }
-#endif /* HAVE_SIGNAL_H && ! __WIN32__ */
-
if (verbose) {
printf(_("Status: %s\n"), _("Enabled"));
}
@@ -1447,9 +1381,9 @@ main(int argc, char *argv[])
stderr);
exit(EXIT_FAILURE);
}
-
+
provider->free(&location_state);
-
+
if (verbose) {
print_location(&loc);
@@ -1470,7 +1404,7 @@ main(int argc, char *argv[])
MIN_LAT, MAX_LAT);
exit(EXIT_FAILURE);
}
-
+
/* Longitude */
if (loc.lon < MIN_LON || loc.lon > MAX_LON) {
/* TRANSLATORS: Append degree symbols if possible. */
diff --git a/src/signals.c b/src/signals.c
new file mode 100644
index 0000000..cee5ece
--- /dev/null
+++ b/src/signals.c
@@ -0,0 +1,112 @@
+/* signals.c -- Signal processing source
+ 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) 2009-2015 Jon Lund Steffensen <jonlst@gmail.com>
+ Copyright (c) 2015 Mattias Andrée <maandree@member.fsf.org>
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
+# include <signal.h>
+#endif
+
+#include "signals.h"
+
+
+#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
+
+volatile sig_atomic_t exiting = 0;
+volatile sig_atomic_t disable = 0;
+
+
+/* Signal handler for exit signals */
+static void
+sigexit(int signo)
+{
+ exiting = 1;
+}
+
+/* Signal handler for disable signal */
+static void
+sigdisable(int signo)
+{
+ disable = 1;
+}
+
+#else /* ! HAVE_SIGNAL_H || __WIN32__ */
+
+int disable = 0;
+int exiting = 0;
+
+#endif /* ! HAVE_SIGNAL_H || __WIN32__ */
+
+
+int
+signals_install_handlers(void)
+{
+#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
+ struct sigaction sigact;
+ sigset_t sigset;
+ int r;
+ sigemptyset(&sigset);
+
+ /* Install signal handler for INT and TERM signals */
+ sigact.sa_handler = sigexit;
+ sigact.sa_mask = sigset;
+ sigact.sa_flags = 0;
+
+ r = sigaction(SIGINT, &sigact, NULL);
+ if (r < 0) {
+ perror("sigaction");
+ return -1;
+ }
+
+ r = sigaction(SIGTERM, &sigact, NULL);
+ if (r < 0) {
+ perror("sigaction");
+ return -1;
+ }
+
+ /* Install signal handler for USR1 signal */
+ sigact.sa_handler = sigdisable;
+ sigact.sa_mask = sigset;
+ sigact.sa_flags = 0;
+
+ r = sigaction(SIGUSR1, &sigact, NULL);
+ if (r < 0) {
+ perror("sigaction");
+ return -1;
+ }
+
+ /* 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");
+ return -1;
+ }
+#endif /* HAVE_SIGNAL_H && ! __WIN32__ */
+
+ return 0;
+}
diff --git a/src/signals.h b/src/signals.h
new file mode 100644
index 0000000..7a1d22e
--- /dev/null
+++ b/src/signals.h
@@ -0,0 +1,38 @@
+/* signals.h -- Signal processing header
+ 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) 2009-2015 Jon Lund Steffensen <jonlst@gmail.com>
+ Copyright (c) 2015 Mattias Andrée <maandree@member.fsf.org>
+*/
+#ifndef REDSHIFT_SIGNALS_H
+#define REDSHIFT_SIGNALS_H
+
+
+#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
+
+extern volatile sig_atomic_t exiting;
+extern volatile sig_atomic_t disable;
+
+#else /* ! HAVE_SIGNAL_H || __WIN32__ */
+extern int exiting;
+extern int disable;
+#endif /* ! HAVE_SIGNAL_H || __WIN32__ */
+
+
+int signals_install_handlers(void);
+
+
+#endif /* REDSHIFT_SIGNALS_H */