diff options
Diffstat (limited to 'src/common.h')
-rw-r--r-- | src/common.h | 1690 |
1 files changed, 0 insertions, 1690 deletions
diff --git a/src/common.h b/src/common.h deleted file mode 100644 index d9a268d..0000000 --- a/src/common.h +++ /dev/null @@ -1,1690 +0,0 @@ -/*- - * redshift-ng - Automatically adjust display colour temperature according the Sun - * - * Copyright (c) 2009-2018 Jon Lund Steffensen <jonlst@gmail.com> - * Copyright (c) 2014-2016, 2025 Mattias Andrée <m@maandree.se> - * - * redshift-ng 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-ng 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-ng. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef WINDOWS -# if defined(__WIN32__) || defined(_WIN32) -# define WINDOWS -# endif -#endif - - -#include "arg.h" - -#include <sys/stat.h> -#include <sys/types.h> -#include <ctype.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <limits.h> -#include <locale.h> -#include <math.h> -#include <signal.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <time.h> -#include <unistd.h> -#ifdef _POSIX_TIMERS -# include <sys/time.h> -#endif -#ifdef WINDOWS -# include <windows.h> -# define localtime_r(T, TM) localtime_s((TM), (T)) -# define pause() millisleep(100U) -#else -# include <sys/file.h> -# include <poll.h> -# include <pwd.h> -# include <time.h> -#endif - -#include <libgamma.h> -#include <libgeome.h> -#include <libred.h> - - -#ifdef ENABLE_NLS -# include <libintl.h> -#else -# define gettext(s) s -#endif - -/** - * List for translation, and translate in place - * - * @param s:string-literal Translatable string - * @return :const char * Translation of `s` - */ -#define _(s) gettext(s) - -/** - * List for translation without translating in place - * - * @param s:string-literal Translatable string - * @return :string-literal `s` as is - */ -#define N_(s) s - - -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* broken in clang 19.1.7 */ -# pragma clang diagnostic ignored "-Wdisabled-macro-expansion" /* warns about system headers (also a stupid warning) */ -# pragma clang diagnostic ignored "-Wassign-enum" /* warns about bit field enums */ -# pragma clang diagnostic ignored "-Wpadded" /* only relevant for library headers */ -# pragma clang diagnostic ignored "-Wcomma" /* comma is useful in loop conditions */ -# pragma clang diagnostic ignored "-Wcovered-switch-default" /* stupid warning: not necessary true */ -#elif defined(__GNUC__) -# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" /* stupid warning */ -# pragma GCC diagnostic ignored "-Wpadded" /* only relevant for library headers */ -#endif - - -#if defined(__GNUC__) -# define GCC_ONLY(...) __VA_ARGS__ -#else -# define GCC_ONLY(...) -#endif - - -/** - * Truncate a value into a closed range - * - * @param LO The lower bound - * @param X The value to truncated - * @param UP The upper bound - * @return `X` truncated such that it is at least `LO` and at most `UP` - */ -#define CLAMP(LO, X, UP) (((LO) > (X)) ? (LO) : (((X) < (UP)) ? (X) : (UP))) - -/** - * Check whether a value is within a closed range - * - * @param LO The lower bound - * @param X The value to check - * @param UP The upper bound - * @return :int 1 if `X` is within [`LO`, `UP`], 0 otherwise - */ -#define WITHIN(LO, X, UP) ((LO) <= (X) && (X) <= (UP)) - -/** - * Check whether a value is within a bounded, open range - * - * @param LO The lower bound - * @param X The value to check - * @param UP The upper bound - * @return :int 1 if `X` is within (`LO`, `UP`), 0 otherwise - */ -#define BETWEEN(LO, X, UP) ((LO) < (X) && (X) < (UP)) - -/** - * Quiet not-a-number `double` - */ -#define FNAN ((double)NAN) /* because clang warns when implicitly promoted to double */ - -/** - * Get the number of elements in an array - * - * @param ARR The array, must not be a pointer - * @return :size_t The number of elements in `ARR` (constant - * expression, unless its size is dynamic) - */ -#define ELEMSOF(ARR) (sizeof(ARR) / (sizeof(*(ARR)))) - -/** - * Get the smallest of two numerical values - * - * @param A One of the values - * @param B The other value - * @return The smallest of `A` and `B` - */ -#define MIN(A, B) ((A) < (B) ? (A) : (B)) - -/** - * Get the largest of two numerical values - * - * @param A One of the values - * @param B The other value - * @return The largest of `A` and `B` - */ -#define MAX(A, B) ((A) > (B) ? (A) : (B)) - - -/** - * Symbol used to delimit paths in environment - * variables listing multiple paths - */ -#ifdef WINDOWS -# define PATH_DELIMITER ';' -#else -# define PATH_DELIMITER ':' -#endif - -/** - * The number of seconds in a day - */ -#define ONE_DAY ((time_t)(24L * 60L * 60L)) - - -/** - * Minimum valid latitude - */ -#define MIN_LATITUDE -90.0 - -/** - * Maximum valid latitude - */ -#define MAX_LATITUDE 90.0 - -/** - * Minimum valid longitude - */ -#define MIN_LONGITUDE -180.0 - -/** - * Maximum valid longitude - */ -#define MAX_LONGITUDE 180.0 - -/** - * Minimum allowed colour temperature - */ -#define MIN_TEMPERATURE ((unsigned long int)LIBRED_LOWEST_TEMPERATURE) - -/** - * Maximum allowed colour temperature - */ -#define MAX_TEMPERATURE ULONG_MAX - -/** - * Minimum allowed whitepoint brightness - */ -#define MIN_BRIGHTNESS 0.1 - -/** - * Maximum allowed whitepoint brightness - */ -#define MAX_BRIGHTNESS 1.0 - -/** - * Minimum allowed gamma - */ -#define MIN_GAMMA 0.1 - -/** - * Maximum allowed gamma - */ -#define MAX_GAMMA 10.0 - - -/** - * The colour temperature corresponding to no effect - */ -#define NEUTRAL_TEMPERATURE 6500UL - -/** - * The whitepoint brightness corresponding to - * full brightness (no effect) - */ -#define NEUTRAL_BRIGHTNESS 1.0 - -/** - * The gamma corresponding to no effect (linear output level curve) - */ -#define NEUTRAL_GAMMA 1.0 - - -/** - * Default daytime colour temperature - */ -#define DEFAULT_DAY_TEMPERATURE 6500UL - -/** - * Default night colour temperature - */ -#define DEFAULT_NIGHT_TEMPERATURE 4500UL - -/** - * Default daytime whitepoint brightness level - */ -#define DEFAULT_DAY_BRIGHTNESS NEUTRAL_BRIGHTNESS - -/** - * Default night whitepoint brightness level - */ -#define DEFAULT_NIGHT_BRIGHTNESS NEUTRAL_BRIGHTNESS - -/** - * Default daytime gamma value - */ -#define DEFAULT_DAY_GAMMA NEUTRAL_GAMMA - -/** - * Default night gamma value - */ -#define DEFAULT_NIGHT_GAMMA NEUTRAL_GAMMA - -/** - * The solar elevation, in degrees, that marks the - * threshold to daytime - */ -#define DEFAULT_HIGH_ELEVATION 3.0 - -/** - * The solar elevation, in degrees, that marks the - * threshold to night - */ -#define DEFAULT_LOW_ELEVATION LIBRED_SOLAR_ELEVATION_CIVIL_DUSK_DAWN - - -/** - * Initialiser for `struct colour_setting` - * - * Sets all values to their neutral values (no effects applied) - */ -#define COLOUR_SETTING_NEUTRAL\ - ((struct colour_setting){\ - NEUTRAL_TEMPERATURE,\ - NEUTRAL_BRIGHTNESS,\ - {NEUTRAL_GAMMA, NEUTRAL_GAMMA, NEUTRAL_GAMMA}\ - }) - - -/** - * State of an adjustment method - * - * Each method has their own definition of this structure - */ -typedef struct gamma_state GAMMA_STATE; - -/** - * State of a location provider - * - * Each provider has their own definition of this structure - */ -typedef struct location_state LOCATION_STATE; - - -/** - * The time of the day: day, night, or twilight - */ -enum period { - /** - * None applied - */ - PERIOD_NONE, - - /** - * Full daytime - */ - PERIOD_DAYTIME, - - /** - * Full nighttime - */ - PERIOD_NIGHT, - - /** - * Transitioning between day and night - * (either direction) (twilight) - */ - PERIOD_TRANSITION -}; - - -/** - * The mode the program is running in - */ -enum program_mode { - /** - * Run in foreground continually update temperature - */ - PROGRAM_MODE_CONTINUAL, - - /** - * Update temperature once then exit - */ - PROGRAM_MODE_ONE_SHOT, - - /** - * Update temperature once and reset when killed - */ - PROGRAM_MODE_UNTIL_DEATH, - - /** - * Print setting and exit - */ - PROGRAM_MODE_PRINT, - - /** - * Remove effects and exit - */ - PROGRAM_MODE_RESET -}; - - -/** - * By what the effects of the application change - */ -enum scheme_type { - /** - * Effects are dependent on the Sun's elevation - */ - SOLAR_SCHEME, - - /** - * Effects are dependent on the wall clock time - */ - CLOCK_SCHEME, - - /** - * Effects do not change - */ - STATIC_SCHEME -}; - -/** - * Scheme has not been specified - */ -#define UNSPECIFIED_SCHEME STATIC_SCHEME - - -/** - * The sources where an setting was been loaded from - * - * Higher valued sources have higher priority - * - * This is a bitmask `enum` - */ -enum setting_source { - /** - * No setting loaded, default value set - */ - SETTING_DEFAULT = 0x00, - - /** - * Setting loaded from configuration file - */ - SETTING_CONFIGFILE = 0x01, - - /** - * Setting loaded from command line arguments - */ - SETTING_CMDLINE = 0x02 -}; - - -/** - * SIGUSR2 signal values as bitmask values - */ -enum signals { - /** - * Block SIGUSR2 until all signals have been processed - */ - SIGNAL_ORDER_BARRIER = 1 << 0, - - /** - * Disable the effects of redshift - */ - SIGNAL_DISABLE = 1 << 1, - - /** - * Enable the effects of redshift - */ - SIGNAL_ENABLE = 1 << 2, - - /** - * Reload the configuration file - * - * Settings from the command line will be overriden - */ - SIGNAL_RELOAD = 1 << 3, - - /** - * Execute into the currently installed version of redshift - */ - SIGNAL_REEXEC = 1 << 4, - - /** - * Set the "fade" setting to off - */ - SIGNAL_USE_FADE_OFF = 1 << 5, - - /** - * Set the "fade" setting to on - */ - SIGNAL_USE_FADE_ON = 1 << 6, - - /** - * Set the "preserve-gamma" setting to off - */ - SIGNAL_PRESERVE_GAMMA_OFF = 1 << 7, - - /** - * Set the "preserve-gamma" setting to on - */ - SIGNAL_PRESERVE_GAMMA_ON = 1 << 8, - - /** - * Exit the process without removing the its effects - * - * If the used adjustment method does not support - * leaving the effects, they will be removed - */ - SIGNAL_EXIT_WITHOUT_RESET = 1 << 9, - - /** - * Do not terminate redshift the standard output - * and standard error are closed - */ - SIGNAL_IGNORE_SIGPIPE = 1 << 10, - - /** - * Enable verbose mode - */ - SIGNAL_VERBOSE_ON = 1 << 11, - - /** - * Disable verbose mode - * - * Ignore if started in verbose mode (-v option) - */ - SIGNAL_VERBOSE_OFF = 1 << 12 -}; - - -/** - * Specification for a path that consists of a two parts: - * the first being defined by the environment, and the - * seocnd being a static string - */ -struct env_path { - /** - * Whether the environment variable referenced by `.prefix` - * should be split at each colon (:) into multiple paths to - * test - * - * On Windows semicolon (;) is used instead of colon - */ - int multidir_env; - - /** - * Environment variable to use as the first part of the path - * - * `NULL` if the user's home directory should be used - * - * The empty string if `.suffix` should be used as is - */ - const char *prefix_env; - - /** - * The second part of the path - */ - const char *suffix; -}; - - -/** - * Geographical location, using GPS coordinates - */ -struct location { - /** - * Degrees north of the equator - */ - double latitude; - - /** - * Degrees east of the prime meridian - */ - double longitude; -}; - - -/** - * Colour setting to apply - */ -struct colour_setting { - /** - * Colour temperature, in Kelvin - */ - unsigned long int temperature; - - /** - * Whitepoint brightness level - */ - double brightness; - - /** - * Gamma correct, for the each RGB channel - * in the order: red, green, and blue - */ - double gamma[3]; -}; - - -/** - * Linked list of time periods for `CLOCK_SCHEME` - */ -struct time_period { - /** - * The number of seconds after midnight the period starts - */ - time_t start; - - /** - * 1 if at daytime at the the time `.start`, - * 0 if at nighttime at the the time `.start` - */ - double day_level; - - /** - * `.next->day_level - .day_level` dividied by - * the duration of the period, in seconds - * - * `.day_level` is added to the number of seconds - * elapsed since `.start` multiplied by this number - * to get the dayness level at that time - */ - double diff_over_duration; - - /** - * The following time period - */ - const struct time_period *next; -}; - - -/** - * Dayness level scheme - */ -union scheme { - /** - * The scheme type - * - * If `STATIC_SCHEME`, the union contains no scheme data - */ - enum scheme_type type; - - /** - * Used if `.type == SOLAR_SCHEME` - */ - struct solar_scheme { - /** - * `SOLAR_SCHEME` - */ - enum scheme_type type; - - /** - * The lowest solar elevation of daytime - */ - double high; - - /** - * The highest solar elevation of nighttime - */ - double low; - - /** - * `.high - .low` - */ - double range; - } elevation; - - /** - * Used if `.type == CLOCK_SCHEME` - */ - struct clock_scheme { - /** - * `CLOCK_SCHEME` - */ - enum scheme_type type; - - /** - * Circularly linked list of time periods - * - * The application will update this to always - * point to the current time period - */ - const struct time_period *periods; - - /** - * The memory allocation for the nodes in `.periods` - */ - struct time_period periods_array[4]; - } time; -}; - - -struct config_ini_setting { - struct config_ini_setting *next; - char *name; - char *value; -}; - - -struct config_ini_section { - struct config_ini_section *next; - char *name; - struct config_ini_setting *settings; -}; - - -struct config_ini_state { - struct config_ini_section *sections; -}; - - -/** - * `int` valued setting (used for booleans) with setting source - */ -struct setting_i { - enum setting_source source; /**< Setting source */ - int value; /**< Setting value */ -}; - -/** - * `unsigned long int` valued setting with setting source - */ -struct setting_lu { - enum setting_source source; /**< Setting source */ - unsigned long int value; /**< Setting value */ -}; - -/** - * `double` valued setting with setting source - */ -struct setting_f { - enum setting_source source; /**< Setting source */ - double value; /**< Setting value */ -}; - -/** - * `double[3]` valued setting with setting source - */ -struct setting_f3 { - enum setting_source source; /**< Setting source */ - double value[3]; /**< Setting values */ -}; - -/** - * `time_t` valued setting with setting source - */ -struct setting_time { - enum setting_source source; /**< Setting source */ - time_t value; /**< Setting value */ -}; - -/** - * `char *` valued setting with setting source - */ -struct setting_str { - enum setting_source source; /**< Setting source */ - char *value; /**< Setting value */ -}; - -/** - * Intermediate settings representation of colour settings - * (for a non-transitional period) with settings sources - * used for determining whether settings from the configuration - * file (which is parsed after the command line) applied or are - * specified multiple times in the configuration file - */ -struct setting_colour { - /** - * Colour temperature, in Kelvin - * - * Set by the "-t" and "-o" options and the "temperature" - * ("temp") settings, optionally suffixed "-day" if - * a daytime setting or "-night" if a nighttime setting - */ - struct setting_lu temperature; - - /** - * Whitepoint brightness level, as a [0, 1] value - * - * Set by the "-b" option and the "brightness" settings, - * optionally suffixed "-day" if a daytime setting or - * "-night" if a nighttime setting - */ - struct setting_f brightness; - - /** - * Gamma values, in the order red, green, blue - * - * Set by the "-g" option and the "gamma" settings, - * optionally suffixed "-day" if a daytime setting or - * "-night" if a nighttime setting - */ - struct setting_f3 gamma; -}; - -/** - * Intermediate settings representation with settings sources - * used for determining whether settings from the configuration - * file (which is parsed after the command line) applied or - * are specified multiple times in the configuration file - * - * Settings without a source can only be specified in the - * command line - */ -struct settings { - /** - * The path to the configuration, `NULL` if unspecified - * (search default paths) - * - * This represents the "-c" option - */ - const char *config_file; - - /** - * Scheme type to use as according the the command line - * options, `UNSPECIFIED_SCHEME` if not unspecified - */ - enum scheme_type scheme_type; - - /** - * Whether the program should, if ran in one-shot mode, - * pause after applying the effect and reset them when - * killed - * - * This represents the "-d" option - */ - int until_death; - - /** - * The path to the hook file or hook directory, `NULL` - * if unspecified (search default paths) - * - * This represents the "hook" setting and "-H" option - */ - struct setting_str hook_file; - - /** - * Whether the program should preserve preapplied - * colour calibrations - * - * This represents the "preserve-gamma" setting and - * "-P" (off) and "+P" (on) options - */ - struct setting_i preserve_gamma; - - /** - * Whether smooth transitions shall be applied when - * a large change in colour settings occurs - * - * This represents the "fade" setting (or the deprecated - * alias "transition") and "-r" (off) and "+r" (on) options - */ - struct setting_i use_fade; - - /** - * Whether the program should start in disabled mode - * - * This represents the "start-disabled" setting and - * "-D" (off) and "+D" (on) options - */ - struct setting_i disabled; - - /** - * The colour settings to apply at daytime - */ - struct setting_colour day; - - /** - * The colour settings to apply at nighttime - */ - struct setting_colour night; - - /** - * The lowest solar elevation, in degrees, at daytime, - * when using solar scheme - * - * This represents the "elevation-high" setting and the - * left value of the -e option - */ - struct setting_f elevation_high; - - /** - * The highest solar elevation, in degrees, at nighttime, - * when using solar scheme - * - * This represents the "elevation-low" setting - * - * This represents the "elevation-low" setting and the - * right value of the -e option - */ - struct setting_f elevation_low; - - /** - * The wall-clock time that marks the end of nighttime, - * when using clock scheme - * - * This represents the left value of the "dawn-time" setting - */ - struct setting_time dawn_start; /* TODO no cmdline option */ - - /** - * The wall-clock time that marks the start of daytime, - * when using clock scheme - * - * This represents the right value of the "dawn-time" setting - */ - struct setting_time dawn_end; /* TODO no cmdline option */ - - /** - * The wall-clock time that marks the end of daytime, - * when using clock scheme - * - * This represents the left value of the "dusk-time" setting - */ - struct setting_time dusk_start; /* TODO no cmdline option */ - - /** - * The wall-clock time that marks the start of nighttime, - * when using clock scheme - * - * This represents the right value of the "dusk-time" setting - */ - struct setting_time dusk_end; /* TODO no cmdline option */ - - /* Selected gamma method */ - const struct gamma_method *method; - /* Arguments for gamma method */ - char *method_args; - - /* Selected location provider */ - const struct location_provider *provider; - /* Arguments for location provider */ - char *provider_args; - - struct config_ini_state config; -}; - - -/** - * Adjustment method information and interface - */ -struct gamma_method { - /** - * The name of the adjustment method - */ - const char *name; - - /** - * 1 if the method should be tried if none is explicitly chosen, - * 0 otherwise - */ - int autostart; - - /** - * 1 if the method automatically resets the adjustments when disconnected, - * 0 otherwise - */ - int autoreset; - - /** - * Check if the adjustment method is available in the used backend - * - * @return 1 if the adjustment method is available, 0 otherwise - */ - int (*is_available)(void); - - /** - * Create an initialised state object - * - * @param state_out Output parameter for the state object - * @return 0 on success, -1 on failure - * - * `*state_out` is set (potentially to `NULL`) on failure - */ - int (*create)(GAMMA_STATE **state_out); - - /** - * Configure the adjustment method - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ - int (*set_option)(GAMMA_STATE *state, const char *key, const char *value); - - /** - * Print help on options for the adjustment method - */ - void (*print_help)(void); - - /** - * Finalise option-dependent initialisation and connections - * - * @param state State object for the adjustment method - * @return 0 on success, -1 on failure - */ - int (*start)(GAMMA_STATE *state); - - /** - * Apply colour settings - * - * @param state State object for the adjustment method - * @param settings The colour settings to apply - * @param preserve Whether currently applied adjustments (assumed - * to be colour calibration) shall remain applied - * @return 0 on success, -1 on failure - */ - int (*apply)(GAMMA_STATE *state, const struct colour_setting *setting, int preserve); - - /** - * Restore the adjustments to the `.state` before start was called - * - * @param state State object for the adjustment method - */ - void (*restore)(GAMMA_STATE *state); - - /** - * Close connections and deallocate all state resources - * - * @param state The state to terminate - * - * The pointer `state` will become invalid - */ - void (*free)(GAMMA_STATE *state); -}; - -/** - * Initialiser for `struct gamma_method` - * - * @param NAME:const char * Value for `.name` - * @param AUTOSTART:int Value for `.autostart` - * @param AUTORESET:int Value for `.autoreset` - * @param PREFIX:identifier The text, sans terminal underscore (_), prefixed to the - * names of each function implementing the adjustment method - */ -#define GAMMA_METHOD_INIT(NAME, AUTOSTART, AUTORESET, PREFIX)\ - {\ - .name = (NAME),\ - .autostart = (AUTOSTART),\ - .autoreset = (AUTORESET),\ - .is_available = &PREFIX##_is_available,\ - .create = &PREFIX##_create,\ - .set_option = &PREFIX##_set_option,\ - .print_help = &PREFIX##_print_help,\ - .start = &PREFIX##_start,\ - .free = &PREFIX##_free,\ - .restore = &PREFIX##_restore,\ - .apply = &PREFIX##_apply\ - } - - -/** - * Location provider information and interface - */ -struct location_provider { - /** - * The name of the location provider - */ - const char *name; - - /** - * Create an initialised state object - * - * @param state_out Output parameter for the state object - * @return 0 on success, -1 on failure - * - * `*state_out` is set (potentially to `NULL`) on failure - */ - int (*create)(LOCATION_STATE **state_out); - - /** - * Configure the location provider - * - * @param state State object for the location provider - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ - int (*set_option)(LOCATION_STATE *state, const char *key, const char *value); - - /** - * Print help on options for the location provider - */ - void (*print_help)(void); - - /** - * Finalise option-dependent initialisation and connections - * - * @param state State object for the location provider - * @return 0 on success, -1 on failure - */ - int (*start)(LOCATION_STATE *state); - - /** - * Get the file descriptor used by the location provider - * - * The application may use it for detecting when there - * is data available for `.handle` to act upon - * - * @param state State object for the location provider - * @return The file descriptor used by location provider, -1 if none - */ - int (*get_fd)(LOCATION_STATE *state); - - /** - * Get the current location - * - * This function shall only be caused if `.get_fd` returns -1 - * or the file descriptor it returns has data available on it - * as indicated by input polling, otherwise `*location` and - * `*available` will not be set - * - * @param state State object for the location provider - * @param location_out Output parameter for the current location - * @param available_out Output parameter for whether the location provider - * is currently available - * @return 0 on success, -1 on unrecoverable failure - */ - int (*fetch)(LOCATION_STATE *state, struct location *location, int *available); - - /** - * Close connections and deallocate all state resources - * - * @param state The state to terminate - * - * The pointer `state` will become invalid - */ - void (*free)(LOCATION_STATE *state); -}; - -/** - * Initialiser for `struct location_provider` - * - * @param NAME:const char * Value for `.name` - * @param PREFIX:identifier The text, sans terminal underscore (_), prefixed to the - * names of each function implementing the location provider - */ -#define LOCATION_PROVIDER_INIT(NAME, PREFIX)\ - {\ - .name = (NAME),\ - .create = &PREFIX##_create,\ - .set_option = &PREFIX##_set_option,\ - .print_help = &PREFIX##_print_help,\ - .start = &PREFIX##_start,\ - .get_fd = &PREFIX##_get_fd,\ - .fetch = &PREFIX##_fetch,\ - .free = &PREFIX##_free\ - } - - -/** - * `NULL` terminated list of adjustment methods - */ -extern const struct gamma_method *gamma_methods[]; - -/** - * `NULL` terminated list of location providers - */ -extern const struct location_provider *location_providers[]; - -/** - * Set to 1 once the process has received a signal to terminate - */ -extern volatile sig_atomic_t exiting; - -/** - * Set to 1 once the process has received a signal to remove its effect - */ -extern volatile sig_atomic_t disable; - -/** - * Bitwise or OR of received SIGUSR2 signal values - */ -extern volatile enum signals signals; - -/** - * The colour settings applied at daytime - */ -extern struct colour_setting day_settings; - -/** - * The colour settings applied at nighttime - */ -extern struct colour_setting night_settings; - -/** - * The colour settings applied at nighttime - */ -extern union scheme scheme; - -/** - * The mode the application is running in - */ -extern enum program_mode mode; - -/** - * Whether initially applied adjustments (assumed - * to be colour calibration) shall remain applied - */ -extern int preserve_gamma; - -/** - * Whether smooth transitions shall be applied when - * a large change in colour settings occurs - */ -extern int use_fade; - -/** - * Whether the application is in verbose mode - */ -extern int verbose; - -/** - * The path to the hook file or hook directory, `NULL` - * if unspecified (search default paths) - */ -extern char *hook_file; - - -/* backend-direct.c */ - -/** - * Create an initialised state object for direct gamma adjustments - * - * @param state_out Output parameter for the state object - * @param method libgamma constant for the adjustment method - * @param method_name redshift's name for the adjustment method - * @return 0 on success, -1 on failure - * - * `*state_out` is set (potentially to `NULL`) on failure - */ -int direct_create(GAMMA_STATE **state_out, int method, const char *method_name); - -/** - * Print help on options for the adjustment method using direct gamma adjustments - * - * @param method libgamma constant for the adjustment method - */ -void direct_print_help(int method); - -/** - * Configure the adjustment method using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ -int direct_set_option(GAMMA_STATE *state, const char *key, const char *value); - -/** - * Select site to apply adjustments to using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ -int direct_set_site(GAMMA_STATE *state, const char *key, const char *value); - -/** - * Select partitions to apply adjustments to using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ -int direct_set_partitions(GAMMA_STATE *state, const char *key, const char *value); - -/** - * Select CRTCs to apply adjustments to using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ -int direct_set_crtcs(GAMMA_STATE *state, const char *key, const char *value); - -/** - * Select EDIDs of outputs to apply adjustments to using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param key Option to configure - * @param value Option value to set - * @return 0 on success, -1 on failure - */ -int direct_set_edids(GAMMA_STATE *state, const char *key, const char *value); - -/** - * Finalise option-dependent initialisation and connections - * for direct gamma adjustments - * - * @param state State object for the adjustment method - * @return 0 on success, -1 on failure - */ -int direct_start(GAMMA_STATE *state); - -/** - * Apply colour settings using direct gamma adjustments - * - * @param state State object for the adjustment method - * @param settings The colour settings to apply - * @param preserve Whether currently applied adjustments (assumed - * to be colour calibration) shall remain applied - * @return 0 on success, -1 on failure - */ -int direct_apply(GAMMA_STATE *state, const struct colour_setting *setting, int preserve); - -/** - * Restore the adjustments to the `.state` before start was called - * using direct gamma adjustments - * - * @param state State object for the adjustment method - */ -void direct_restore(GAMMA_STATE *state); - -/** - * Close connections and deallocate all state resources - * for direct gamma adjustments - * - * @param state The state to terminate - * - * The pointer `state` will become invalid - */ -void direct_free(GAMMA_STATE *state); - - -/* colour.c */ - -/** - * Interpolate between two colour settings - * - * @param a The first colour setting, used wholly when `t` is 0 - * @param b The second colour setting, used wholly when `t` is 1 - * @param t The degree to which `second` second be applied - * @param result Output parameter for `(1 - t) * a + t * b` - */ -void interpolate_colour_settings(const struct colour_setting *a, const struct colour_setting *b, - double t, struct colour_setting *result); - -/** - * Check whether the differences between two colours settings - * are large enough to warrant fading between the two - * - * @param a The first colour setting - * @param b The second colour setting - * @return 1 if the difference between `a` and `b` is large, 0 otherwise - */ -GCC_ONLY(__attribute__((__pure__))) -int colour_setting_diff_is_major(const struct colour_setting *a, const struct colour_setting *b); - -#define LIST_RAMPS_STOP_VALUE_TYPES(X, D)\ - X(u8, ramps8, uint8_t, UINT8_MAX, 8) D \ - X(u16, ramps16, uint16_t, UINT16_MAX, 16) D\ - X(u32, ramps32, uint32_t, UINT32_MAX, 32) D\ - X(u64, ramps64, uint64_t, UINT64_MAX, 64) D\ - X(float, rampsf, float, 1, -1) D\ - X(double, rampsd, double, 1, -2) - -#define X(SUFFIX, RAMPS, TYPE, MAX, DEPTH)\ - /** - * Fill the gamma ramps - * - * @param gamma_r The gamma ramp for the red channel - * @param gamma_g The gamma ramp for the green channel - * @param gamma_b The gamma ramp for the blue channel - * @param saved_r Saved gamma ramp with calibrations for - * the red channel to preserve, or `NULL` - * @param saved_g Saved gamma ramp with calibrations for - * the green channel to preserve, or `NULL` - * @param saved_b Saved gamma ramp with calibrations for - * the blue channel to preserve, or `NULL` - * @param size_r The number of stops in `gamma_r` - * @param size_g The number of stops in `gamma_g` - * @param size_b The number of stops in `gamma_b` - * @param settings The colour settings to apply (temperature, brightness, gamma) - */\ - void fill_ramps_##SUFFIX(TYPE *gamma_r, TYPE *gamma_g, TYPE *gamma_b,\ - const TYPE *saved_r, const TYPE *saved_g, const TYPE *saved_b,\ - size_t size_r, size_t size_g, size_t size_b,\ - const struct colour_setting *setting) -LIST_RAMPS_STOP_VALUE_TYPES(X, ;); -#undef X - - -/* config-ini.c */ - -/** - * Load the configuration file - * - * @param state Output parameter for the configurations - * @param path The path to the configuration file, or `NULL` if the - * application should look for it in the default paths - * @param pathbuf_out Output parameter for the memory allocated for the - * return value - * @return The path to the loaded configuration file, `NULL` if none - */ -const char *config_ini_init(struct config_ini_state *state, const char *path, char **pathbuf_out); - -/** - * Deallocate the settings loaded - * from the configurations file - * - * @param state The configurations - */ -void config_ini_free(struct config_ini_state *state); - -/** - * Get a section from the configuration file - * - * @param state The configurations - * @param name The name of the section - * @return The section; `NULL` if missing - */ -GCC_ONLY(__attribute__((__pure__))) -struct config_ini_section *config_ini_get_section(struct config_ini_state *state, const char *name); - - -/* config.c */ - -/** - * Load settings - * - * @param settings Output parameter for the settings - * @param argc Number of command line arguments - * @param argv `NULL` terminated list of command line arguments, - * including argument zero - */ -void load_settings(struct settings *settings, int argc, char *argv[]); - - -/* gamma.c */ - -/** - * Get and configure adjustment method - * - * @param settings The loaded application settings, will be updated - * to point `settings->method` to the adjustment method - * @param method_state_out Output parameter for the state of the adjustment method - * - * The function will print an error message and exit the - * process if no adjustment method is available - */ -void acquire_adjustment_method(struct settings *settings, GAMMA_STATE **method_state_out); - - -/* location.c */ - -/** - * Get the current location from the location provider - * - * @param provider The location provider functions - * @param state The location provider state - * @param timeout The number of milliseconds to wait, -1 for indefinitely - * @param location_out Output parameter for the location, in GPS coordinates - * @return 1 if `*location_out` was updated, - * 0 if the timeout was reached, - * -1 on error - */ -int get_location(const struct location_provider *provider, LOCATION_STATE *state, int timeout, struct location *location_out); - -/** - * Get and configure location provider - * - * @param settings The loaded application settings, will be updated - * to point `settings->provider` to the location provider - * @param location_state_out Output parameter for the state of the location provider - * - * The function will print an error message and exit the - * process if no location provider is available - */ -void acquire_location_provider(struct settings *settings, LOCATION_STATE **location_state_out); - -/** - * Check whether location is valid - * - * If the message is invalid, and error message is printed - * - * @param location The location to check - * @return 1 if the location is valid, 0 otherwise - */ -int location_is_valid(const struct location *location); - -/** - * Print the current location to standard output - * - * @param location The current location - */ -void print_location(const struct location *location); - - -/* hooks.c */ - -/** - * Run hooks with a signal that the period changed - * - * @param prev_period The previous period - * @param period The new current period - */ -void run_period_change_hooks(enum period prev_period, enum period period); - - -/* signals.c */ - -/** - * Install signal handlers for the process - */ -void install_signal_handlers(void); - -/** - * Install signal handlers for forcefully terminating - * the process - * - * This is useful if slave thread is blocked - * - * SIGINT, SIGTERM, and SIGQUIT are set to at the - * first arrival arm a SIGARLM timer with a short - * expiration time, and on the second arrival - * immediately terminate the process. SIGARLM is - * set to immediately terminate the process. - */ -#ifndef WINDOWS -void install_forceful_exit_signal_handlers(void); -#endif - - -/* util.c */ - -/** - * Remove trailing whitespace - * - * @param s The string to trim, will be truncated - * @param end The current end of `s`; will be looked up if `NULL` - * @return `s` - */ -char *rtrim(char *s, char *end); - -/** - * Remove leading whitespace - * - * @param s The string to trim (will not be modified) - * @return `s` with an offset - */ -GCC_ONLY(__attribute__((__warn_unused_result__, __pure__))) -char *ltrim(char *s); - -/** - * Get the user's home directory - * - * This function looks up the user's home directory - * once and caches the result, later calls to this - * function will use the cached result - * - * @return The user's home directory; the empty string if not found - */ -const char *get_home(void); - -/** - * Search for a file and open it for reading - * - * @param path_spec Specification for the path to try - * @param path_out Output parameter for the found file - * @param pathbuf_out Output parameter for the memory allocation for `*path_out`; - * shall be free(3)d by the caller - * @return `FILE` object for the reading the file; `NULL` if not found - */ -FILE *try_path_fopen(const struct env_path *path_spec, const char **path_out, char **pathbuf_out); - -/** - * Search for a directory and open it for reading - * - * @param path_spec Specification for the path to try - * @param path_out Output parameter for the found directory - * @param pathbuf_out Output parameter for the memory allocation for `*path_out`; - * shall be free(3)d by the caller - * @return `DIR` object for the reading the directory; `NULL` if not found - */ -DIR *try_path_opendir(const struct env_path *path_spec, const char **path_out, char **pathbuf_out); - -#ifndef WINDOWS -/** - * Create a pipe(7) where both ends have `O_CLOEXEC`, - * the read-end will also have `O_NONBLOCK` applied - * - * @param pipefds Output parameter for the pipe's file descriptors: - * 0) reading file descriptor, and - * 1) writing file descriptor - */ -void pipe_rdnonblock(int pipefds[2]); -#endif - -/** - * Wrapper for calloc(3) that prints and error message - * and terminates the process on failure - * - * @param n Number of elements to allocate memory for - * @param m The size, in bytes, of each element - * @return Pointer to zero-initialised storage of at least `n*m` bytes, with default alignment - */ -GCC_ONLY(__attribute__((__warn_unused_result__, __malloc__, __alloc_size__(1, 2), __returns_nonnull__))) -void *ecalloc(size_t n, size_t m); - -/** - * Wrapper for malloc(3) that prints and error message - * and terminates the process on failure - * - * @param n Number of bytes to allocate - * @return Pointer to uninitialised storage of at least `n` bytes, with default alignment - */ -GCC_ONLY(__attribute__((__warn_unused_result__, __malloc__, __alloc_size__(1), __returns_nonnull__))) -void *emalloc(size_t n); - -/** - * Wrapper for realloc(3) that prints and error message - * and terminates the process on failure - * - * @param ptr Pointer to reallocate - * @param n Despired allocation size in bytes - * @return Replacement pointer for `ptr`, pointing to storage of at least `n` bytes, - * any byte that could be copied from `ptr` is copied over, and additional - * memory is uninitialised - */ -GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__, __alloc_size__(2)))) -void *erealloc(void *ptr, size_t n); - -/** - * Wrapper for strdup(3) that prints and error message - * and terminates the process on failure - * - * @param s String to copy - * @return Copy of `s` - */ -GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__, __malloc__, __assume_aligned__(1), __nonnull__))) -char *estrdup(const char *s); - -/** - * Print a message, prefixed with the process name (followed by ": "), - * to standard error - * - * @param fmt Message text format string, see fprintf(3) - * @param args Message text arguments - */ -GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 0)))) -void vweprintf(const char *fmt, va_list args); - -/** - * Print a message, prefixed with the process name (followed by ": "), - * to standard error - * - * @param fmt Message text format string, see fprintf(3) - * @param ... Message text arguments - */ -GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2)))) -void weprintf(const char *fmt, ...); - -/** - * Print a message, prefixed with the process name (followed by ": "), - * to standard error and terminate the process with exit value - * indicating error - * - * @param fmt Message text format string, see fprintf(3) - * @param ... Message text arguments - */ -GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2), __noreturn__))) -void eprintf(const char *fmt, ...); - - -extern const struct gamma_method dummy_gamma_method; -#ifdef ENABLE_COOPGAMMA -extern const struct gamma_method coopgamma_gamma_method; -#endif -extern const struct gamma_method randr_gamma_method; -extern const struct gamma_method vidmode_gamma_method; -extern const struct gamma_method drm_gamma_method; -extern const struct gamma_method quartz_gamma_method; -extern const struct gamma_method wingdi_gamma_method; - -extern const struct location_provider manual_location_provider; -#ifdef ENABLE_GEOCLUE2 -extern const struct location_provider geoclue2_location_provider; -#endif -#ifdef ENABLE_CORELOCATION -extern const struct location_provider corelocation_location_provider; -#endif -#ifndef WINDOWS -extern const struct location_provider geofile_location_provider; -extern const struct location_provider timezone_location_provider; -#endif - - -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif -static inline int -exact_eq(double a, double b) -{ - return a == b; -} -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif |