diff options
Diffstat (limited to '')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/config-ini.c | 2 | ||||
-rw-r--r-- | src/gamma-drm.c | 5 | ||||
-rw-r--r-- | src/gamma-randr.c | 2 | ||||
-rw-r--r-- | src/gamma-vidmode.c | 2 | ||||
-rw-r--r-- | src/location-geoclue.c | 4 | ||||
-rw-r--r-- | src/redshift-gtk/statusicon.py | 71 | ||||
-rw-r--r-- | src/redshift.c | 78 | ||||
-rw-r--r-- | src/signals.c | 112 | ||||
-rw-r--r-- | src/signals.h | 38 |
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 */ |