diff options
author | Jon Lund Steffensen <jonlst@gmail.com> | 2014-12-30 22:27:54 -0500 |
---|---|---|
committer | Jon Lund Steffensen <jonlst@gmail.com> | 2015-01-04 16:32:47 -0500 |
commit | f9c2a1568c308ec69970662a8f5ceb8726e8d8cc (patch) | |
tree | a1d33dfaead79f4e94cdbb9330cfa51588deb97f /src | |
parent | Add location_t type with lat/lon fields (diff) | |
download | redshift-ng-f9c2a1568c308ec69970662a8f5ceb8726e8d8cc.tar.gz redshift-ng-f9c2a1568c308ec69970662a8f5ceb8726e8d8cc.tar.bz2 redshift-ng-f9c2a1568c308ec69970662a8f5ceb8726e8d8cc.tar.xz |
redshift: Move continual loop mode to separate function
Diffstat (limited to 'src')
-rw-r--r-- | src/redshift.c | 463 |
1 files changed, 241 insertions, 222 deletions
diff --git a/src/redshift.c b/src/redshift.c index 3d22064..10f00d5 100644 --- a/src/redshift.c +++ b/src/redshift.c @@ -774,6 +774,243 @@ find_location_provider(const char *name) } +/* Run continual mode loop + This is the main loop of the continual mode which keeps track of the + current time and continuously updates the screen to the appropriate + color temperature. */ +static int +run_continual_mode(const location_t *loc, + const color_setting_t *day, + const color_setting_t *night, + const gamma_method_t *method, + gamma_state_t *state, + int transition, int verbose) +{ + int r; + + /* Make an initial transition from 6500K */ + int short_trans_delta = -1; + int short_trans_len = 10; + + /* Amount of adjustment to apply. At zero the color + temperature will be exactly as calculated, and at one it + 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); + 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__ */ + + if (verbose) { + printf(_("Status: %s\n"), _("Enabled")); + } + + /* Save previous colors so we can avoid + printing status updates if the values + did not change. */ + period_t prev_period = PERIOD_NONE; + color_setting_t prev_interp = + { -1, { NAN, NAN, NAN }, NAN }; + + /* Continuously adjust color temperature */ + int done = 0; + int disabled = 0; + while (1) { + /* Check to see if disable signal was caught */ + if (disable) { + short_trans_len = 2; + if (!disabled) { + /* Transition to disabled state */ + short_trans_delta = 1; + } else { + /* Transition back to enabled */ + short_trans_delta = -1; + } + disabled = !disabled; + disable = 0; + + if (verbose) { + printf(_("Status: %s\n"), disabled ? + _("Disabled") : _("Enabled")); + } + } + + /* Check to see if exit signal was caught */ + if (exiting) { + if (done) { + /* On second signal stop the ongoing + transition */ + short_trans_delta = 0; + adjustment_alpha = 0.0; + } else { + if (!disabled) { + /* Make a short transition + back to 6500K */ + short_trans_delta = 1; + short_trans_len = 2; + } + + done = 1; + } + exiting = 0; + } + + /* Read timestamp */ + double now; + r = systemtime_get_time(&now); + if (r < 0) { + fputs(_("Unable to read system time.\n"), stderr); + return -1; + } + + /* Skip over transition if transitions are disabled */ + int set_adjustments = 0; + if (!transition) { + if (short_trans_delta) { + adjustment_alpha = short_trans_delta < 0 ? + 0.0 : 1.0; + short_trans_delta = 0; + set_adjustments = 1; + } + } + + /* Current angular elevation of the sun */ + double elevation = solar_elevation(now, loc->lat, + loc->lon); + + /* Use elevation of sun to set color temperature */ + color_setting_t interp; + interpolate_color_settings(elevation, day, night, &interp); + + /* Print period if it changed during this update, + or if we are in transition. In transition we + print the progress, so we always print it in + that case. */ + period_t period = get_period(elevation); + if (verbose && (period != prev_period || + period == PERIOD_TRANSITION)) { + double transition = + get_transition_progress(elevation); + 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 */ + adjustment_alpha += short_trans_delta * 0.1 / + (float)short_trans_len; + + /* Stop transition when done */ + if (adjustment_alpha <= 0.0 || + adjustment_alpha >= 1.0) { + short_trans_delta = 0; + } + + /* Clamp alpha value */ + adjustment_alpha = + MAX(0.0, MIN(adjustment_alpha, 1.0)); + } + + /* Interpolate between 6500K and calculated + temperature */ + interp.temperature = adjustment_alpha*6500 + + (1.0-adjustment_alpha)*interp.temperature; + + interp.brightness = adjustment_alpha*1.0 + + (1.0-adjustment_alpha)*interp.brightness; + + /* Quit loop when done */ + if (done && !short_trans_delta) break; + + if (verbose) { + if (interp.temperature != + prev_interp.temperature) { + printf(_("Color temperature: %uK\n"), + interp.temperature); + } + if (interp.brightness != + prev_interp.brightness) { + printf(_("Brightness: %.2f\n"), + interp.brightness); + } + } + + /* Adjust temperature */ + if (!disabled || short_trans_delta || set_adjustments) { + r = method->set_temperature(&state, &interp); + if (r < 0) { + fputs(_("Temperature adjustment" + " failed.\n"), stderr); + return -1; + } + } + + /* Save temperature as previous */ + prev_period = period; + memcpy(&prev_interp, &interp, + sizeof(color_setting_t)); + + /* Sleep for 5 seconds or 0.1 second. */ + if (short_trans_delta) { + systemtime_msleep(SLEEP_DURATION_SHORT); + } else { + systemtime_msleep(SLEEP_DURATION); + } + } + + /* Restore saved gamma ramps */ + method->restore(&state); + + return 0; +} + int main(int argc, char *argv[]) { @@ -1426,228 +1663,10 @@ main(int argc, char *argv[]) break; case PROGRAM_MODE_CONTINUAL: { - /* Make an initial transition from 6500K */ - int short_trans_delta = -1; - int short_trans_len = 10; - - /* Amount of adjustment to apply. At zero the color - temperature will be exactly as calculated, and at one it - 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); - if (r < 0) { - perror("sigaction"); - exit(EXIT_FAILURE); - } - - r = sigaction(SIGTERM, &sigact, NULL); - if (r < 0) { - perror("sigaction"); - exit(EXIT_FAILURE); - } - - /* 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"); - 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) { - printf(_("Status: %s\n"), _("Enabled")); - } - - /* Save previous colors so we can avoid - printing status updates if the values - did not change. */ - period_t prev_period = PERIOD_NONE; - color_setting_t prev_interp = - { -1, { NAN, NAN, NAN }, NAN }; - - /* Continuously adjust color temperature */ - int done = 0; - int disabled = 0; - while (1) { - /* Check to see if disable signal was caught */ - if (disable) { - short_trans_len = 2; - if (!disabled) { - /* Transition to disabled state */ - short_trans_delta = 1; - } else { - /* Transition back to enabled */ - short_trans_delta = -1; - } - disabled = !disabled; - disable = 0; - - if (verbose) { - printf(_("Status: %s\n"), disabled ? - _("Disabled") : _("Enabled")); - } - } - - /* Check to see if exit signal was caught */ - if (exiting) { - if (done) { - /* On second signal stop the - ongoing transition */ - short_trans_delta = 0; - adjustment_alpha = 0.0; - } else { - if (!disabled) { - /* Make a short transition - back to 6500K */ - short_trans_delta = 1; - short_trans_len = 2; - } - - done = 1; - } - exiting = 0; - } - - /* Read timestamp */ - double now; - r = systemtime_get_time(&now); - if (r < 0) { - fputs(_("Unable to read system time.\n"), - stderr); - method->free(&state); - exit(EXIT_FAILURE); - } - - /* Skip over transition if transitions are disabled */ - int set_adjustments = 0; - if (!transition) { - if (short_trans_delta) { - adjustment_alpha = short_trans_delta < 0 ? 0.0 : 1.0; - short_trans_delta = 0; - set_adjustments = 1; - } - } - - /* Current angular elevation of the sun */ - double elevation = - solar_elevation(now, loc.lat, loc.lon); - - /* Use elevation of sun to set color temperature */ - color_setting_t interp; - interpolate_color_settings(elevation, &day, &night, &interp); - - /* Print period if it changed during this update, - or if we are in transition. In transition we - print the progress, so we always print it in - that case. */ - period_t period = get_period(elevation); - if (verbose && (period != prev_period || - period == PERIOD_TRANSITION)) { - double transition = - get_transition_progress(elevation); - 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 */ - adjustment_alpha += short_trans_delta * 0.1 / - (float)short_trans_len; - - /* Stop transition when done */ - if (adjustment_alpha <= 0.0 || - adjustment_alpha >= 1.0) { - short_trans_delta = 0; - } - - /* Clamp alpha value */ - adjustment_alpha = - MAX(0.0, MIN(adjustment_alpha, 1.0)); - } - - /* Interpolate between 6500K and calculated - temperature */ - interp.temperature = adjustment_alpha*6500 + - (1.0-adjustment_alpha)*interp.temperature; - - interp.brightness = adjustment_alpha*1.0 + - (1.0-adjustment_alpha)*interp.brightness; - - /* Quit loop when done */ - if (done && !short_trans_delta) break; - - if (verbose) { - if (interp.temperature != - prev_interp.temperature) { - printf(_("Color temperature: %uK\n"), - interp.temperature); - } - if (interp.brightness != - prev_interp.brightness) { - printf(_("Brightness: %.2f\n"), - interp.brightness); - } - } - - /* Adjust temperature */ - if (!disabled || short_trans_delta || set_adjustments) { - r = method->set_temperature(&state, &interp); - if (r < 0) { - fputs(_("Temperature adjustment" - " failed.\n"), stderr); - method->free(&state); - exit(EXIT_FAILURE); - } - } - - /* Save temperature as previous */ - prev_period = period; - memcpy(&prev_interp, &interp, - sizeof(color_setting_t)); - - /* Sleep for 5 seconds or 0.1 second. */ - if (short_trans_delta) { - systemtime_msleep(SLEEP_DURATION_SHORT); - } else { - systemtime_msleep(SLEEP_DURATION); - } - } - - /* Restore saved gamma ramps */ - method->restore(&state); + r = run_continual_mode(&loc, &day, &night, + method, &state, + transition, verbose); + if (r < 0) exit(EXIT_FAILURE); } break; } |