aboutsummaryrefslogtreecommitdiffstats
path: root/src/redshift.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/redshift.c')
-rw-r--r--src/redshift.c701
1 files changed, 516 insertions, 185 deletions
diff --git a/src/redshift.c b/src/redshift.c
index 9c3f404..18cc2c5 100644
--- a/src/redshift.c
+++ b/src/redshift.c
@@ -28,28 +28,51 @@
#include <time.h>
#include <math.h>
#include <locale.h>
-#include <sys/signal.h>
+#include <errno.h>
-#include <libintl.h>
-#define _(s) gettext(s)
+#ifdef HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#endif
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
+
+#include "redshift.h"
#include "solar.h"
+#include "systemtime.h"
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MAX(x,y) ((x) > (y) ? (x) : (y))
-#if !(defined(ENABLE_RANDR) || defined(ENABLE_VIDMODE))
-# error "At least one of RANDR or VidMode must be enabled."
+#if !(defined(ENABLE_RANDR) || \
+ defined(ENABLE_VIDMODE) || \
+ defined(ENABLE_WINGDI))
+# error "At least one of RANDR, VidMode or WinGDI must be enabled."
#endif
#ifdef ENABLE_RANDR
-# include "randr.h"
+# include "gamma-randr.h"
#endif
#ifdef ENABLE_VIDMODE
-# include "vidmode.h"
+# include "gamma-vidmode.h"
+#endif
+
+#ifdef ENABLE_WINGDI
+# include "gamma-w32gdi.h"
+#endif
+
+
+#include "location-manual.h"
+
+#ifdef ENABLE_GNOME_CLOCK
+# include "location-gnome-clock.h"
#endif
@@ -61,9 +84,94 @@ typedef union {
#ifdef ENABLE_VIDMODE
vidmode_state_t vidmode;
#endif
+#ifdef ENABLE_WINGDI
+ w32gdi_state_t w32gdi;
+#endif
} gamma_state_t;
+/* Gamma adjustment method structs */
+static const gamma_method_t gamma_methods[] = {
+#ifdef ENABLE_RANDR
+ {
+ "randr",
+ (gamma_method_init_func *)randr_init,
+ (gamma_method_start_func *)randr_start,
+ (gamma_method_free_func *)randr_free,
+ (gamma_method_print_help_func *)randr_print_help,
+ (gamma_method_set_option_func *)randr_set_option,
+ (gamma_method_restore_func *)randr_restore,
+ (gamma_method_set_temperature_func *)randr_set_temperature
+ },
+#endif
+#ifdef ENABLE_VIDMODE
+ {
+ "vidmode",
+ (gamma_method_init_func *)vidmode_init,
+ (gamma_method_start_func *)vidmode_start,
+ (gamma_method_free_func *)vidmode_free,
+ (gamma_method_print_help_func *)vidmode_print_help,
+ (gamma_method_set_option_func *)vidmode_set_option,
+ (gamma_method_restore_func *)vidmode_restore,
+ (gamma_method_set_temperature_func *)vidmode_set_temperature
+ },
+#endif
+#ifdef ENABLE_WINGDI
+ {
+ "wingdi",
+ (gamma_method_init_func *)w32gdi_init,
+ (gamma_method_start_func *)w32gdi_start,
+ (gamma_method_free_func *)w32gdi_free,
+ (gamma_method_print_help_func *)w32gdi_print_help,
+ (gamma_method_set_option_func *)w32gdi_set_option,
+ (gamma_method_restore_func *)w32gdi_restore,
+ (gamma_method_set_temperature_func *)w32gdi_set_temperature
+ },
+#endif
+ { NULL }
+};
+
+
+/* Union of state data for location providers */
+typedef union {
+ location_manual_state_t manual;
+#ifdef ENABLE_GNOME_CLOCK
+ location_gnome_clock_state_t gnome_clock;
+#endif
+} location_state_t;
+
+
+/* Location provider method structs */
+static const location_provider_t location_providers[] = {
+#ifdef ENABLE_GNOME_CLOCK
+ {
+ "gnome-clock",
+ (location_provider_init_func *)location_gnome_clock_init,
+ (location_provider_start_func *)location_gnome_clock_start,
+ (location_provider_free_func *)location_gnome_clock_free,
+ (location_provider_print_help_func *)
+ location_gnome_clock_print_help,
+ (location_provider_set_option_func *)
+ location_gnome_clock_set_option,
+ (location_provider_get_location_func *)
+ location_gnome_clock_get_location
+ },
+#endif
+ {
+ "manual",
+ (location_provider_init_func *)location_manual_init,
+ (location_provider_start_func *)location_manual_start,
+ (location_provider_free_func *)location_manual_free,
+ (location_provider_print_help_func *)
+ location_manual_print_help,
+ (location_provider_set_option_func *)
+ location_manual_set_option,
+ (location_provider_get_location_func *)
+ location_manual_get_location
+ },
+ { NULL }
+};
+
/* Bounds for parameters. */
#define MIN_LAT -90.0
#define MAX_LAT 90.0
@@ -79,6 +187,9 @@ typedef union {
#define DEFAULT_NIGHT_TEMP 3700
#define DEFAULT_GAMMA 1.0
+/* The color temperature when no adjustment is applied. */
+#define NEUTRAL_TEMP 6500
+
/* Angular elevation of the sun at which the color temperature
transition period starts and ends (in degress).
Transition during twilight, and while the sun is lower than
@@ -86,6 +197,15 @@ typedef union {
#define TRANSITION_LOW SOLAR_CIVIL_TWILIGHT_ELEV
#define TRANSITION_HIGH 3.0
+/* Program modes. */
+typedef enum {
+ PROGRAM_MODE_CONTINUAL,
+ PROGRAM_MODE_ONE_SHOT,
+ PROGRAM_MODE_RESET
+} program_mode_t;
+
+
+#ifdef HAVE_SYS_SIGNAL_H
static volatile sig_atomic_t exiting = 0;
static volatile sig_atomic_t disable = 0;
@@ -104,61 +224,12 @@ sigdisable(int signo)
disable = 1;
}
+#else /* ! HAVE_SYS_SIGNAL_H */
-/* Restore saved gamma ramps with the appropriate adjustment method. */
-static void
-gamma_state_restore(gamma_state_t *state, int use_randr)
-{
- switch (use_randr) {
-#ifdef ENABLE_VIDMODE
- case 0:
- vidmode_restore(&state->vidmode);
- break;
-#endif
-#ifdef ENABLE_RANDR
- case 1:
- randr_restore(&state->randr);
- break;
-#endif
- }
-}
+static int exiting = 0;
+static int disable = 0;
-/* Free the state associated with the appropriate adjustment method. */
-static void
-gamma_state_free(gamma_state_t *state, int use_randr)
-{
- switch (use_randr) {
-#ifdef ENABLE_VIDMODE
- case 0:
- vidmode_free(&state->vidmode);
- break;
-#endif
-#ifdef ENABLE_RANDR
- case 1:
- randr_free(&state->randr);
- break;
-#endif
- }
-}
-
-/* Set temperature with the appropriate adjustment method. */
-static int
-gamma_state_set_temperature(gamma_state_t *state, int use_randr,
- int temp, float gamma[3])
-{
- switch (use_randr) {
-#ifdef ENABLE_VIDMODE
- case 0:
- return vidmode_set_temperature(&state->vidmode, temp, gamma);
-#endif
-#ifdef ENABLE_RANDR
- case 1:
- return randr_set_temperature(&state->randr, temp, gamma);
-#endif
- }
-
- return -1;
-}
+#endif /* ! HAVE_SYS_SIGNAL_H */
/* Calculate color temperature for the specified solar elevation. */
@@ -212,21 +283,170 @@ print_help(const char *program_name)
fputs("\n", stdout);
/* TRANSLATORS: help output 4
+ `list' must not be translated
no-wrap */
fputs(_(" -g R:G:B\tAdditional gamma correction to apply\n"
" -l LAT:LON\tYour current location\n"
- " -m METHOD\tMethod to use to set color temperature"
- " (randr or vidmode)\n"
+ " -l PROVIDER\tSelect provider for automatic"
+ " location updates\n"
+ " \t\t(Type `list' to see available providers)\n"
+ " -m METHOD\tMethod to use to set color temperature\n"
+ " \t\t(Type `list' to see available methods)\n"
" -o\t\tOne shot mode (do not continously adjust"
" color temperature)\n"
- " -r\t\tDisable initial temperature transition\n"
- " -s SCREEN\tX screen to apply adjustments to\n"
+ " -x\t\tReset mode (remove adjustment from screen)\n"
+ " -r\t\tDisable temperature transitions\n"
" -t DAY:NIGHT\tColor temperature to set at daytime/night\n"),
stdout);
fputs("\n", stdout);
/* TRANSLATORS: help output 5 */
- printf("Please report bugs to <%s>\n", PACKAGE_BUGREPORT);
+ printf(_("Default values:\n\n"
+ " Daytime temperature: %uK\n"
+ " Night temperature: %uK\n"),
+ DEFAULT_DAY_TEMP, DEFAULT_NIGHT_TEMP);
+
+ fputs("\n", stdout);
+
+ /* TRANSLATORS: help output 6 */
+ printf(_("Please report bugs to <%s>\n"), PACKAGE_BUGREPORT);
+}
+
+static void
+print_method_list()
+{
+ fputs(_("Available adjustment methods:\n"), stdout);
+ for (int i = 0; gamma_methods[i].name != NULL; i++) {
+ printf(" %s\n", gamma_methods[i].name);
+ }
+
+ fputs("\n", stdout);
+ fputs(_("Specify colon-separated options with"
+ " `-m METHOD:OPTIONS'.\n"), stdout);
+ /* TRANSLATORS: `help' must not be translated. */
+ fputs(_("Try `-m METHOD:help' for help.\n"), stdout);
+}
+
+static void
+print_provider_list()
+{
+ fputs(_("Available location providers:\n"), stdout);
+ for (int i = 0; location_providers[i].name != NULL; i++) {
+ printf(" %s\n", location_providers[i].name);
+ }
+
+ fputs("\n", stdout);
+ fputs(_("Specify colon-separated options with"
+ "`-l PROVIDER:OPTIONS'.\n"), stdout);
+ /* TRANSLATORS: `help' must not be translated. */
+ fputs(_("Try `-l PROVIDER:help' for help.\n"), stdout);
+}
+
+
+static int
+provider_try_start(const location_provider_t *provider,
+ location_state_t *state, char *args)
+{
+ int r;
+
+ r = provider->init(state);
+ if (r < 0) {
+ fprintf(stderr, _("Initialization of %s failed.\n"),
+ provider->name);
+ return -1;
+ }
+
+ /* Set provider options. */
+ while (args != NULL) {
+ char *next_arg = strchr(args, ':');
+ if (next_arg != NULL) *(next_arg++) = '\0';
+
+ char *key = NULL;
+ char *value = strchr(args, '=');
+ if (value != NULL) {
+ key = args;
+ *(value++) = '\0';
+ } else {
+ value = args;
+ }
+
+ r = provider->set_option(state, key, value);
+ if (r < 0) {
+ provider->free(state);
+ fprintf(stderr, _("Failed to set %s option.\n"),
+ provider->name);
+ /* TRANSLATORS: `help' must not be translated. */
+ fprintf(stderr, _("Try `-l %s:help' for more"
+ " information.\n"), provider->name);
+ return -1;
+ }
+
+ args = next_arg;
+ }
+
+ /* Start provider. */
+ r = provider->start(state);
+ if (r < 0) {
+ provider->free(state);
+ fprintf(stderr, _("Failed to start provider %s.\n"),
+ provider->name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+method_try_start(const gamma_method_t *method,
+ gamma_state_t *state, char *args)
+{
+ int r;
+
+ r = method->init(state);
+ if (r < 0) {
+ fprintf(stderr, _("Initialization of %s failed.\n"),
+ method->name);
+ return -1;
+ }
+
+ /* Set method options. */
+ while (args != NULL) {
+ char *next_arg = strchr(args, ':');
+ if (next_arg != NULL) *(next_arg++) = '\0';
+
+ char *key = NULL;
+ char *value = strchr(args, '=');
+ if (value != NULL) {
+ key = args;
+ *(value++) = '\0';
+ } else {
+ value = args;
+ }
+
+ r = method->set_option(state, key, value);
+ if (r < 0) {
+ method->free(state);
+ fprintf(stderr, _("Failed to set %s option.\n"),
+ method->name);
+ /* TRANSLATORS: `help' must not be translated. */
+ fprintf(stderr, _("Try -m %s:help' for more"
+ " information.\n"), method->name);
+ return -1;
+ }
+
+ args = next_arg;
+ }
+
+ /* Start method. */
+ r = method->start(state);
+ if (r < 0) {
+ method->free(state);
+ fprintf(stderr, _("Failed to start adjustment method %s.\n"),
+ method->name);
+ return -1;
+ }
+
+ return 0;
}
@@ -235,32 +455,35 @@ main(int argc, char *argv[])
{
int r;
+#ifdef ENABLE_NLS
/* Init locale */
setlocale(LC_CTYPE, "");
setlocale(LC_MESSAGES, "");
-#ifdef ENABLE_NLS
/* Internationalisation */
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
#endif
/* Initialize to defaults */
- float lat = NAN;
- float lon = NAN;
int temp_day = DEFAULT_DAY_TEMP;
int temp_night = DEFAULT_NIGHT_TEMP;
float gamma[3] = { DEFAULT_GAMMA, DEFAULT_GAMMA, DEFAULT_GAMMA };
- int use_randr = -1;
- int screen_num = -1;
+
+ const gamma_method_t *method = NULL;
+ char *method_args = NULL;
+
+ const location_provider_t *provider = NULL;
+ char *provider_args = NULL;
+
int transition = 1;
- int one_shot = 0;
+ program_mode_t mode = PROGRAM_MODE_CONTINUAL;
int verbose = 0;
char *s;
/* Parse arguments. */
int opt;
- while ((opt = getopt(argc, argv, "g:hl:m:ors:t:v")) != -1) {
+ while ((opt = getopt(argc, argv, "g:hl:m:ort:vx")) != -1) {
switch (opt) {
case 'g':
s = strchr(optarg, ':');
@@ -292,56 +515,101 @@ main(int argc, char *argv[])
exit(EXIT_SUCCESS);
break;
case 'l':
- s = strchr(optarg, ':');
- if (s == NULL) {
- fputs(_("Malformed location argument.\n"),
- stderr);
- fputs(_("Try `-h' for more information.\n"),
- stderr);
+ /* Print list of providers if argument is `list' */
+ if (strcasecmp(optarg, "list") == 0) {
+ print_provider_list();
+ exit(EXIT_SUCCESS);
+ }
+
+ char *provider_name = NULL;
+
+ /* Don't save the result of strtof(); we simply want
+ to know if optarg can be parsed as a float. */
+ errno = 0;
+ char *end;
+ strtof(optarg, &end);
+ if (errno == 0 && *end == ':') {
+ /* Use instead as arguments to `manual'. */
+ provider_name = "manual";
+ provider_args = optarg;
+ } else {
+ /* Split off provider arguments. */
+ s = strchr(optarg, ':');
+ if (s != NULL) {
+ *(s++) = '\0';
+ provider_args = s;
+ }
+
+ provider_name = optarg;
+ }
+
+ /* Lookup argument in location provider table */
+ for (int i = 0; location_providers[i].name != NULL;
+ i++) {
+ const location_provider_t *p =
+ &location_providers[i];
+ if (strcasecmp(provider_name, p->name) == 0) {
+ provider = p;
+ }
+ }
+
+ if (provider == NULL) {
+ fprintf(stderr, _("Unknown location provider"
+ " `%s'.\n"), provider_name);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Print provider help if arg is `help'. */
+ if (provider_args != NULL &&
+ strcasecmp(provider_args, "help") == 0) {
+ provider->print_help(stdout);
exit(EXIT_FAILURE);
}
- *(s++) = '\0';
- lat = atof(optarg);
- lon = atof(s);
break;
case 'm':
- if (strcmp(optarg, "randr") == 0 ||
- strcmp(optarg, "RANDR") == 0) {
-#ifdef ENABLE_RANDR
- use_randr = 1;
-#else
- fputs(_("RANDR method was not"
- " enabled at compile time.\n"),
- stderr);
- exit(EXIT_FAILURE);
-#endif
- } else if (strcmp(optarg, "vidmode") == 0 ||
- strcmp(optarg, "VidMode") == 0) {
-#ifdef ENABLE_VIDMODE
- use_randr = 0;
-#else
- fputs(_("VidMode method was not"
- " enabled at compile time.\n"),
- stderr);
- exit(EXIT_FAILURE);
-#endif
- } else {
+ /* Print list of methods if argument is `list' */
+ if (strcasecmp(optarg, "list") == 0) {
+ print_method_list();
+ exit(EXIT_SUCCESS);
+ }
+
+ /* Split off method arguments. */
+ s = strchr(optarg, ':');
+ if (s != NULL) {
+ *(s++) = '\0';
+ method_args = s;
+ }
+
+ /* Lookup argument in gamma methods table */
+ for (int i = 0; gamma_methods[i].name != NULL; i++) {
+ const gamma_method_t *m =
+ &gamma_methods[i];
+ if (strcasecmp(optarg, m->name) == 0) {
+ method = m;
+ }
+ }
+
+ if (method == NULL) {
/* TRANSLATORS: This refers to the method
used to adjust colors e.g VidMode */
fprintf(stderr, _("Unknown method `%s'.\n"),
optarg);
exit(EXIT_FAILURE);
}
+
+ /* Print method help if arg is `help'. */
+ if (method_args != NULL &&
+ strcasecmp(method_args, "help") == 0) {
+ method->print_help(stdout);
+ exit(EXIT_FAILURE);
+ }
break;
case 'o':
- one_shot = 1;
+ mode = PROGRAM_MODE_ONE_SHOT;
break;
case 'r':
transition = 0;
break;
- case 's':
- screen_num = atoi(optarg);
- break;
case 't':
s = strchr(optarg, ':');
if (s == NULL) {
@@ -358,6 +626,9 @@ main(int argc, char *argv[])
case 'v':
verbose = 1;
break;
+ case 'x':
+ mode = PROGRAM_MODE_RESET;
+ break;
case '?':
fputs(_("Try `-h' for more information.\n"), stderr);
exit(EXIT_FAILURE);
@@ -365,34 +636,81 @@ main(int argc, char *argv[])
}
}
- /* Latitude and longitude must be set */
- if (isnan(lat) || isnan(lon)) {
- fputs(_("Latitude and longitude must be set.\n"), stderr);
- fputs(_("Try `-h' for more information.\n"), stderr);
- exit(EXIT_FAILURE);
- }
+ /* Initialize location provider. If provider is NULL
+ try all providers until one that works is found. */
+ location_state_t location_state;
+
+ /* Location is not needed for reset mode. */
+ if (mode != PROGRAM_MODE_RESET) {
+ if (provider != NULL) {
+ /* Use provider specified on command line. */
+ r = provider_try_start(provider, &location_state,
+ provider_args);
+ if (r < 0) exit(EXIT_FAILURE);
+ } else {
+ /* Try all providers, use the first that works. */
+ for (int i = 0;
+ location_providers[i].name != NULL; i++) {
+ const location_provider_t *p =
+ &location_providers[i];
+ r = provider_try_start(p, &location_state,
+ NULL);
+ if (r < 0) {
+ fputs(_("Trying other provider...\n"),
+ stderr);
+ continue;
+ }
- if (verbose) {
- /* TRANSLATORS: Append degree symbols if possible. */
- printf(_("Location: %f, %f\n"), lat, lon);
- }
+ provider = p;
+ break;
+ }
- /* Latitude */
- if (lat < MIN_LAT || lat > MAX_LAT) {
- /* TRANSLATORS: Append degree symbols if possible. */
- fprintf(stderr,
- _("Latitude must be between %.1f and %.1f.\n"),
- MIN_LAT, MAX_LAT);
- exit(EXIT_FAILURE);
+ /* Failure if no providers were successful at this
+ point. */
+ if (provider == NULL) {
+ fputs(_("No more location providers"
+ " to try.\n"), stderr);
+ exit(EXIT_FAILURE);
+ }
+ }
}
- /* Longitude */
- if (lon < MIN_LON || lon > MAX_LON) {
- /* TRANSLATORS: Append degree symbols if possible. */
- fprintf(stderr,
- _("Longitude must be between %.1f and %.1f.\n"),
- MIN_LON, MAX_LON);
- exit(EXIT_FAILURE);
+ float lat = NAN;
+ float lon = NAN;
+
+ if (mode != PROGRAM_MODE_RESET) {
+ /* Get current location. */
+ r = provider->get_location(&location_state, &lat, &lon);
+ if (r < 0) {
+ fputs(_("Unable to get location from provider.\n"),
+ stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ provider->free(&location_state);
+
+ if (verbose) {
+ /* TRANSLATORS: Append degree symbols if possible. */
+ printf(_("Location: %f, %f\n"), lat, lon);
+ }
+
+ /* Latitude */
+ if (lat < MIN_LAT || lat > MAX_LAT) {
+ /* TRANSLATORS: Append degree symbols if possible. */
+ fprintf(stderr,
+ _("Latitude must be between %.1f and %.1f.\n"),
+ MIN_LAT, MAX_LAT);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Longitude */
+ if (lon < MIN_LON || lon > MAX_LON) {
+ /* TRANSLATORS: Append degree symbols if possible. */
+ fprintf(stderr,
+ _("Longitude must be between"
+ " %.1f and %.1f.\n"), MIN_LON, MAX_LON);
+ exit(EXIT_FAILURE);
+ }
}
/* Color temperature at daytime */
@@ -426,47 +744,44 @@ main(int argc, char *argv[])
gamma[0], gamma[1], gamma[2]);
}
- /* Initialize gamma adjustment method. If use_randr is negative
+ /* Initialize gamma adjustment method. If method is NULL
try all methods until one that works is found. */
gamma_state_t state;
-#ifdef ENABLE_RANDR
- if (use_randr < 0 || use_randr == 1) {
- /* Initialize RANDR state */
- r = randr_init(&state.randr, screen_num);
- if (r < 0) {
- fputs(_("Initialization of RANDR failed.\n"), stderr);
- if (use_randr < 0) {
+
+ if (method != NULL) {
+ /* Use method specified on command line. */
+ r = method_try_start(method, &state, method_args);
+ if (r < 0) exit(EXIT_FAILURE);
+ } else {
+ /* Try all methods, use the first that works. */
+ for (int i = 0; gamma_methods[i].name != NULL; i++) {
+ const gamma_method_t *m = &gamma_methods[i];
+ r = method_try_start(m, &state, NULL);
+ if (r < 0) {
fputs(_("Trying other method...\n"), stderr);
- } else {
- exit(EXIT_FAILURE);
+ continue;
}
- } else {
- use_randr = 1;
+
+ method = m;
+ break;
}
- }
-#endif
-#ifdef ENABLE_VIDMODE
- if (use_randr < 0 || use_randr == 0) {
- /* Initialize VidMode state */
- r = vidmode_init(&state.vidmode, screen_num);
- if (r < 0) {
- fputs(_("Initialization of VidMode failed.\n"),
- stderr);
+ /* Failure if no methods were successful at this point. */
+ if (method == NULL) {
+ fputs(_("No more methods to try.\n"), stderr);
exit(EXIT_FAILURE);
- } else {
- use_randr = 0;
}
}
-#endif
- if (one_shot) {
+ switch (mode) {
+ case PROGRAM_MODE_ONE_SHOT:
+ {
/* Current angular elevation of the sun */
- struct timespec now;
- r = clock_gettime(CLOCK_REALTIME, &now);
+ double now;
+ r = systemtime_get_time(&now);
if (r < 0) {
- perror("clock_gettime");
- gamma_state_free(&state, use_randr);
+ fputs(_("Unable to read system time.\n"), stderr);
+ method->free(&state);
exit(EXIT_FAILURE);
}
@@ -484,16 +799,29 @@ main(int argc, char *argv[])
if (verbose) printf(_("Color temperature: %uK\n"), temp);
/* Adjust temperature */
- r = gamma_state_set_temperature(&state, use_randr,
- temp, gamma);
+ r = method->set_temperature(&state, temp, gamma);
if (r < 0) {
fputs(_("Temperature adjustment failed.\n"), stderr);
- gamma_state_free(&state, use_randr);
+ method->free(&state);
exit(EXIT_FAILURE);
}
- } else {
+ }
+ break;
+ case PROGRAM_MODE_RESET:
+ {
+ /* Reset screen */
+ r = method->set_temperature(&state, NEUTRAL_TEMP, gamma);
+ if (r < 0) {
+ fputs(_("Temperature adjustment failed.\n"), stderr);
+ method->free(&state);
+ exit(EXIT_FAILURE);
+ }
+ }
+ break;
+ case PROGRAM_MODE_CONTINUAL:
+ {
/* Transition state */
- struct timespec short_trans_end;
+ double short_trans_end = 0;
int short_trans = 0;
int short_trans_done = 0;
@@ -507,6 +835,7 @@ main(int argc, char *argv[])
will be exactly 6500K. */
float adjustment_alpha = 0.0;
+#ifdef HAVE_SYS_SIGNAL_H
struct sigaction sigact;
sigset_t sigset;
sigemptyset(&sigset);
@@ -523,6 +852,7 @@ main(int argc, char *argv[])
sigact.sa_mask = sigset;
sigact.sa_flags = 0;
sigaction(SIGUSR1, &sigact, NULL);
+#endif /* HAVE_SYS_SIGNAL_H */
/* Continously adjust color temperature */
int done = 0;
@@ -568,22 +898,20 @@ main(int argc, char *argv[])
}
/* Read timestamp */
- struct timespec now;
- r = clock_gettime(CLOCK_REALTIME, &now);
+ double now;
+ r = systemtime_get_time(&now);
if (r < 0) {
- perror("clock_gettime");
- gamma_state_free(&state, use_randr);
+ fputs(_("Unable to read system time.\n"),
+ stderr);
+ method->free(&state);
exit(EXIT_FAILURE);
}
/* Set up a new transition */
if (short_trans_create) {
if (transition) {
- memcpy(&short_trans_end, &now,
- sizeof(struct timespec));
- short_trans_end.tv_sec +=
- short_trans_len;
-
+ short_trans_end = now;
+ short_trans_end += short_trans_len;
short_trans = 1;
short_trans_create = 0;
} else {
@@ -600,11 +928,8 @@ main(int argc, char *argv[])
/* Ongoing short transition */
if (short_trans) {
- double start = now.tv_sec +
- now.tv_nsec / 1000000000.0;
- double end = short_trans_end.tv_sec +
- short_trans_end.tv_nsec /
- 1000000000.0;
+ double start = now;
+ double end = short_trans_end;
if (start > end) {
/* Transisiton done */
@@ -629,7 +954,7 @@ main(int argc, char *argv[])
if (short_trans_done) {
if (disabled) {
/* Restore saved gamma ramps */
- gamma_state_restore(&state, use_randr);
+ method->restore(&state);
}
short_trans_done = 0;
}
@@ -648,28 +973,34 @@ main(int argc, char *argv[])
/* Adjust temperature */
if (!disabled || short_trans) {
- r = gamma_state_set_temperature(&state,
- use_randr,
- temp, gamma);
+ r = method->set_temperature(&state,
+ temp, gamma);
if (r < 0) {
fputs(_("Temperature adjustment"
" failed.\n"), stderr);
- gamma_state_free(&state, use_randr);
+ method->free(&state);
exit(EXIT_FAILURE);
}
}
/* Sleep for a while */
+#ifndef _WIN32
if (short_trans) usleep(100000);
else usleep(5000000);
+#else /* ! _WIN32 */
+ if (short_trans) Sleep(100);
+ else Sleep(5000);
+#endif /* ! _WIN32 */
}
/* Restore saved gamma ramps */
- gamma_state_restore(&state, use_randr);
+ method->restore(&state);
+ }
+ break;
}
/* Clean up gamma adjustment state */
- gamma_state_free(&state, use_randr);
+ method->free(&state);
return EXIT_SUCCESS;
}