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;  } | 
