diff options
Diffstat (limited to 'src/redshift.c')
-rw-r--r-- | src/redshift.c | 206 |
1 files changed, 64 insertions, 142 deletions
diff --git a/src/redshift.c b/src/redshift.c index 9a44b0b..04c6c77 100644 --- a/src/redshift.c +++ b/src/redshift.c @@ -24,7 +24,7 @@ #ifndef WINDOWS # include <poll.h> #else -#define POLLIN 0 +# define POLLIN 0 struct pollfd { int fd; short events; @@ -42,16 +42,6 @@ int poll(struct pollfd *fds, int nfds, int timeout) { abort(); } #define FADE_LENGTH 40 -/* Names of periods of day */ -static const char *period_names[] = { - /* TRANSLATORS: Name printed when period of day is unknown */ - N_("None"), - N_("Daytime"), - N_("Night"), - N_("Transition") -}; - - #if defined(__GNUC__) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wfloat-equal" @@ -88,7 +78,11 @@ millisleep(unsigned int msecs) } -/* Return number of seconds since midnight from timestamp. */ +/** + * Get the number of seconds since midnight + * + * @return The number of seconds since midnight + */ static time_t get_time_since_midnight(void) { @@ -101,61 +95,30 @@ get_time_since_midnight(void) return t; } -/* Print verbose description of the given period. */ + +/** + * Print the current period of the day + * + * @param period The current period of the day + * @param day_level The current dayness level + */ static void print_period(enum period period, double day_level) { + static const char *period_names[] = { + /* TRANSLATORS: Name printed when period of day is unknown */ + [PERIOD_NONE] = N_("None"), + [PERIOD_DAYTIME] = N_("Daytime"), + [PERIOD_NIGHT] = N_("Night"), + [PERIOD_TRANSITION] = N_("Transition") + }; + if (period == PERIOD_TRANSITION) printf(_("Period: %s (%.2f%% day)\n"), gettext(period_names[period]), day_level * 100); else printf(_("Period: %s\n"), gettext(period_names[period])); } -/* Print location */ -static void -print_location(const struct location *location) -{ - /* TRANSLATORS: Abbreviation for `north' */ - const char *north = _("N"); - /* TRANSLATORS: Abbreviation for `south' */ - const char *south = _("S"); - /* TRANSLATORS: Abbreviation for `east' */ - const char *east = _("E"); - /* TRANSLATORS: Abbreviation for `west' */ - const char *west = _("W"); - - /* TRANSLATORS: Append degree symbols after %f if possible. - The string following each number is an abreviation for - north, source, east or west (N, S, E, W). */ - printf(_("Location: %.2f %s, %.2f %s\n"), - fabs(location->latitude), location->latitude >= 0.0 ? north : south, - fabs(location->longitude), location->longitude >= 0.0 ? east : west); -} - -/* Interpolate colour setting structs given alpha. */ -static void -interpolate_colour_settings(const struct colour_setting *first, const struct colour_setting *second, - double alpha, struct colour_setting *result) -{ - int i; - alpha = CLAMP(0.0, alpha, 1.0); - result->temperature = (1.0 - alpha) * first->temperature + alpha * second->temperature; - result->brightness = (1.0 - alpha) * first->brightness + alpha * second->brightness; - for (i = 0; i < 3; i++) - result->gamma[i] = (1.0 - alpha) * first->gamma[i] + alpha * second->gamma[i]; -} - -/* Return 1 if colour settings have major differences, otherwise 0. - Used to determine if a fade should be applied in continual mode. */ -static int -colour_setting_diff_is_major(const struct colour_setting *first, const struct colour_setting *second) -{ - return MAX(first->temperature, second->temperature) - MIN(first->temperature, second->temperature) > 25UL || - fabs(first->brightness - second->brightness) > 0.1 || - fabs(first->gamma[0] - second->gamma[0]) > 0.1 || - fabs(first->gamma[1] - second->gamma[1]) > 0.1 || - fabs(first->gamma[2] - second->gamma[2]) > 0.1; -} /** * Get the current period of day and the colour settings @@ -165,11 +128,10 @@ colour_setting_diff_is_major(const struct colour_setting *first, const struct co * @param colour_out Output parameter for the colour settings * @param period_out Output parameter for the period of the day * @param day_level_out Output parameter for the dayness level - * @param verbose Whether the application is running in verbose mode */ static void get_colour_settings(const struct location *location, struct colour_setting *colour_out, - enum period *period_out, double *day_level_out, int verbose) + enum period *period_out, double *day_level_out) { time_t time_offset; double t, elevation; @@ -220,34 +182,21 @@ get_colour_settings(const struct location *location, struct colour_setting *colo } -/* Check whether location is valid. - Prints error message on stderr and returns 0 if invalid, otherwise - returns 1. */ -static int -location_is_valid(const struct location *location) -{ - if (!WITHIN(MIN_LATITUDE, location->latitude, MAX_LATITUDE)) { - /* TRANSLATORS: Append degree symbols if possible. */ - weprintf(_("Latitude must be between %.1f and %.1f."), MIN_LATITUDE, MAX_LATITUDE); - return 0; - } - if (!WITHIN(MIN_LONGITUDE, location->longitude, MAX_LONGITUDE)) { - /* TRANSLATORS: Append degree symbols if possible. */ - weprintf(_("Longitude must be between %.1f and %.1f."), MIN_LONGITUDE, MAX_LONGITUDE); - return 0; - } - return 1; -} - -/* Easing function for fade. - See https://github.com/mietek/ease-tween */ +/** + * Easing function used for fade effect + * + * See https://github.com/mietek/ease-tween + * + * @param t Raw fade progress + * @return Fade progress to apply + */ +GCC_ONLY(__attribute__((__const__))) static double ease_fade(double t) { if (t <= 0) return 0; if (t >= 1) return 1; - return 1.0042954579734844 * exp( - -6.4041738958415664 * exp(-7.2908241330981340 * t)); + return 1.0042954579734844 * exp(-6.4041738958415664 * exp(-7.2908241330981340 * t)); } @@ -258,7 +207,7 @@ ease_fade(double t) static void run_continual_mode(const struct location_provider *provider, LOCATION_STATE *location_state, const struct gamma_method *method, GAMMA_STATE *method_state, int use_fade, - int preserve_gamma, int verbose) + int preserve_gamma) { int done = 0; int prev_disabled = 1; @@ -274,13 +223,13 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc int fade_time = 0; /* Save previous parameters so we can avoid printing status updates if - the values did not change. */ + * the values did not change. */ enum period prev_period = PERIOD_NONE; install_signal_handlers(); /* Previous target colour setting and current actual colour setting. - Actual colour setting takes into account the current colour fade. */ + * Actual colour setting takes into account the current colour fade. */ prev_target_interp = COLOUR_SETTING_NEUTRAL; interp = COLOUR_SETTING_NEUTRAL; @@ -289,7 +238,6 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc if (scheme.type == SOLAR_SCHEME) { weprintf(_("Waiting for initial location to become available...")); - /* Get initial location from provider */ if (get_location(provider, location_state, -1, &loc) < 0) eprintf(_("Unable to get location from provider.")); @@ -320,7 +268,7 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc /* Check to see if exit signal was caught */ if (exiting) { if (done) - break; /* On second signal stop the ongoing fade. */ + break; /* On second signal stop the ongoing fade */ done = 1; disabled = 1; exiting = 0; @@ -332,7 +280,7 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc prev_disabled = disabled; - get_colour_settings(&loc, &target_interp, &period, &day_level, verbose); + get_colour_settings(&loc, &target_interp, &period, &day_level); if (disabled) { period = PERIOD_NONE; @@ -343,9 +291,9 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc period = PERIOD_NONE; /* Print period if it changed during this update, - or if we are in the transition period. In transition we - print the progress, so we always print it in - that case. */ + * or if we are in the transition period. In transition we + * print the progress, so we always print it in + * that case. */ if (verbose && (period != prev_period || period == PERIOD_TRANSITION)) print_period(period, day_level); @@ -353,8 +301,7 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc if (period != prev_period) run_period_change_hooks(prev_period, period); - /* Start fade if the parameter differences are too big to apply - instantly. */ + /* Start fade if the parameter differences are too big to apply instantly */ if (use_fade && colour_setting_diff_is_major(&target_interp, fade_length ? &prev_target_interp : &interp)) { fade_length = FADE_LENGTH; fade_time = 0; @@ -388,17 +335,17 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc } /* Adjust temperature */ - if (method->set_temperature(method_state, &interp, preserve_gamma) < 0) + if (method->apply(method_state, &interp, preserve_gamma) < 0) eprintf(_("Temperature adjustment failed.")); /* Save period and target colour setting as previous */ prev_period = period; prev_target_interp = target_interp; - /* Sleep length depends on whether a fade is ongoing. */ + /* Sleep length depends on whether a fade is ongoing */ delay = fade_length ? SLEEP_DURATION_SHORT : SLEEP_DURATION; - /* Update location. */ + /* Update location */ loc_fd = scheme.type == SOLAR_SCHEME ? provider->get_fd(location_state) : -1; if (loc_fd >= 0) { @@ -406,7 +353,7 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc struct location new_loc; int r, new_available; - /* Provider is dynamic. */ + /* Provider is dynamic */ pollfds[0].fd = loc_fd; pollfds[0].events = POLLIN; r = poll(pollfds, 1, delay); @@ -421,8 +368,8 @@ run_continual_mode(const struct location_provider *provider, LOCATION_STATE *loc continue; } - /* Get new location and availability information. */ - if (provider->handle(location_state, &new_loc, &new_available) < 0) + /* Get new location and availability information */ + if (provider->fetch(location_state, &new_loc, &new_available) < 0) eprintf(_("Unable to get location from provider.")); if (!new_available && new_available != location_available) { @@ -456,8 +403,8 @@ int main(int argc, char *argv[]) { struct settings settings; - GAMMA_STATE *method_state; - LOCATION_STATE *location_state; + GAMMA_STATE *method_state = NULL; + LOCATION_STATE *location_state = NULL; struct location loc = {NAN, NAN}; double day_level; enum period period; @@ -473,30 +420,19 @@ main(int argc, char *argv[]) #endif load_settings(&settings, argc, argv); - - /* Initialize location provider if needed. If provider is NULL - try all providers until one that works is found. */ - - /* Location is not needed for reset mode and manual mode. */ - if (settings.scheme_type == SOLAR_SCHEME) + if (scheme.type == SOLAR_SCHEME) acquire_location_provider(&settings, &location_state); - - /* Initialize gamma adjustment method. If method is NULL - try all methods until one that works is found. */ - - /* Gamma adjustment not needed for print mode */ - if (settings.mode != PROGRAM_MODE_PRINT) + if (mode != PROGRAM_MODE_PRINT) acquire_adjustment_method(&settings, &method_state); - config_ini_free(&settings.config); - switch (settings.mode) { + switch (mode) { case PROGRAM_MODE_ONE_SHOT: case PROGRAM_MODE_PRINT: - if (settings.scheme_type == SOLAR_SCHEME) { + case PROGRAM_MODE_RESET: + if (scheme.type == SOLAR_SCHEME) { weprintf(_("Waiting for current location to become available...")); - /* Wait for location provider. */ if (get_location(settings.provider, location_state, -1, &loc) < 0) eprintf(_("Unable to get location from provider.")); @@ -506,25 +442,23 @@ main(int argc, char *argv[]) print_location(&loc); } - get_colour_settings(&loc, &colour, &period, &day_level, settings.verbose); + get_colour_settings(&loc, &colour, &period, &day_level); - if (settings.verbose || settings.mode == PROGRAM_MODE_PRINT) { - if (settings.scheme_type != STATIC_SCHEME) + if (verbose || mode == PROGRAM_MODE_PRINT) { + if (scheme.type != STATIC_SCHEME) print_period(period, day_level); printf(_("Color temperature: %luK\n"), colour.temperature); printf(_("Brightness: %.2f\n"), colour.brightness); + if (mode == PROGRAM_MODE_PRINT) + break; } - if (settings.mode == PROGRAM_MODE_PRINT) - break; - - apply: - if (settings.method->set_temperature(method_state, &colour, settings.preserve_gamma.value) < 0) + if (settings.method->apply(method_state, &colour, settings.preserve_gamma.value) < 0) eprintf(_("Temperature adjustment failed.")); #ifndef WINDOWS /* In Quartz (OSX) the gamma adjustments will automatically revert when - * the process exits. Therefore, we have to loop until CTRL-C is received. */ + * the process exits. Therefore, we have to loop until Ctrl+C is received. */ if (!strcmp(settings.method->name, "quartz")) { weprintf(_("Press ctrl-c to stop...")); while (!exiting) @@ -533,27 +467,15 @@ main(int argc, char *argv[]) #endif break; - case PROGRAM_MODE_MANUAL: - /* TODO interpolate for current time if a value range has been specified */ - colour = day_settings; - if (settings.verbose) - printf(_("Color temperature: %luK\n"), colour.temperature); - goto apply; - - case PROGRAM_MODE_RESET: - colour = COLOUR_SETTING_NEUTRAL; - settings.preserve_gamma.value = 0; - goto apply; - case PROGRAM_MODE_CONTINUAL: run_continual_mode(settings.provider, location_state, settings.method, method_state, - settings.use_fade.value, settings.preserve_gamma.value, settings.verbose); + settings.use_fade.value, settings.preserve_gamma.value); break; } - if (settings.mode != PROGRAM_MODE_PRINT) + if (method_state) settings.method->free(method_state); - if (scheme.type == SOLAR_SCHEME) + if (location_state) settings.provider->free(location_state); return 0; } |