From 42a2a579628d4aa8153775cdcd894b8b5c80e7da Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 6 Feb 2025 20:08:50 +0100 Subject: m + libradharc for client-side protocol implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libradharc.h | 796 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 796 insertions(+) create mode 100644 libradharc.h (limited to 'libradharc.h') diff --git a/libradharc.h b/libradharc.h new file mode 100644 index 0000000..ee00b09 --- /dev/null +++ b/libradharc.h @@ -0,0 +1,796 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBRADHARC_H +#define LIBRADHARC_H + +#include +#include +#include +#include +#include +#include + + +enum libradharc_property { + LIBRADHARC_PROPERTY_FADE_IN, + LIBRADHARC_PROPERTY_FADE_OUT, + LIBRADHARC_PROPERTY_HIGH_TEMPERATURE, + LIBRADHARC_PROPERTY_LOW_TEMPERATURE, + LIBRADHARC_PROPERTY_HIGH_ELEVATION, + LIBRADHARC_PROPERTY_LOW_ELEVATION, + LIBRADHARC_PROPERTY_LOCATION, + LIBRADHARC_PROPERTY_OPERATION_MODE, + LIBRADHARC_PROPERTY_TEMPERATURE, + LIBRADHARC_PROPERTY_PRIORITY, + LIBRADHARC_PROPERTY_VENDOR_OPTION, + LIBRADHARC_PROPERTY_STATUS +}; + +enum libradharc_request_type { + LIBRADHARC_REQUEST_GET, + LIBRADHARC_REQUEST_SET, + LIBRADHARC_REQUEST_UNSET, + LIBRADHARC_REQUEST_SIGNAL +}; + +/** + * How radharc determines which colour temperature to apply + */ +enum libradharc_operation_mode { + /** + * A specific colour temperature has been selected + */ + LIBRADHARC_OPERATION_STATIC, + + /** + * A colour temperature range has been selected + * along with a range of solar elevations and the + * user's location. The temperature is changed + * gradually by mapping to current solar elevation's + * position in the range of solar elevations + * (clips to the range's boundaries) to a colour + * temperature, in corresponding position, the + * colour temperature range. + */ + LIBRADHARC_OPERATION_BY_SOLAR_ELEVATION +}; + +/** + * Request response type + */ +enum libradharc_response_type { + /** + * The made request was invalid + */ + LIBRADHARC_RESPONSE_INVALID_REQUEST, + + /** + * Value sent with the request was unsupported + */ + LIBRADHARC_RESPONSE_UNSUPPORTED, + + /** + * Action performed + */ + LIBRADHARC_RESPONSE_ACK, + + /** + * No action to perform + */ + LIBRADHARC_RESPONSE_ACK_NOOP, + + /** + * The requested property is not set + */ + LIBRADHARC_RESPONSE_UNSET, + + /** + * The requested property is set to the true boolean value + */ + LIBRADHARC_RESPONSE_YES, + + /** + * The requested property is set to the false boolean value + */ + LIBRADHARC_RESPONSE_NO, + + /** + * A server-side error was encountered + */ + LIBRADHARC_RESPONSE_ERROR_STRING, + + /** + * The requested property is set, and has a string value + */ + LIBRADHARC_RESPONSE_SET_STRING, + + /** + * The requested property is set, and has a time duration + */ + LIBRADHARC_RESPONSE_SET_TIME, + + /** + * The requested property is set, and has a real value + */ + LIBRADHARC_RESPONSE_SET_REAL, + + /** + * The requested property is set, and has two real values + * + * For the geographical location, this would be the the + * latitude as the first value, and a the longitude as + * the second value + */ + LIBRADHARC_RESPONSE_SET_REAL_PAIR, + + /** + * The requested property is set, and has a signed + * 64-bit integer value + */ + LIBRADHARC_RESPONSE_SET_SIGNED64, + + /** + * The requested property is set, and has a named value + */ + LIBRADHARC_RESPONSE_SET_ENUM +}; + +/** + * Response from radharc + */ +struct libradharc_response { + /** + * Response from radharc or indicate of + * type used for the response + */ + enum libradharc_response_type type; + + /** + * Value send back by radharc + * + * Only set if `.type` has one of the values + * listed the union member fields. The following + * values of `.type` do not have an associated + * value: + * - `LIBRADHARC_RESPONSE_INVALID_REQUEST` + * - `LIBRADHARC_RESPONSE_UNSUPPORTED` + * - `LIBRADHARC_RESPONSE_ACK` + * - `LIBRADHARC_RESPONSE_ACK_NOOP` + * - `LIBRADHARC_RESPONSE_UNSET` + * - `LIBRADHARC_RESPONSE_YES` + * - `LIBRADHARC_RESPONSE_NO` + */ + union { + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_STRING` or + * `LIBRADHARC_RESPONSE_ERROR_STRING` + */ + const char *string; + + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_TIME` + */ + struct timespec time; + + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_REAL` + */ + double real; + + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_REAL_PAIR` + */ + double real_pair[2]; + + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_SIGNED64` + */ + int64_t signed64; + + /** + * Use if `.type` is `LIBRADHARC_RESPONSE_SET_ENUM`, + * and the response is for a get-request for radharc's + * operation mode + */ + enum libradharc_operation_mode operation_mode; + } value; +}; + + +/** + * Parse a response from radharc + * + * All requests generate a response, which are sent in order + * + * @param msg The received message + * @param msglen The length of the message + * @param response_out Output parameter for the prased message + * @return 0 on success, -1 on failure + * + * @throws EINVAL `msglen` is 0 + * @throws EINVAL `msg` is `NULL` + * @throws EINVAL `response_out` is `NULL` + * @throws EBADMSG The received message is invalid + */ +int libradharc_parse_response(const void *msg, size_t msglen, struct libradharc_response *response_out); + + +size_t libradharc_format_request__n__(void *buffer, enum libradharc_request_type type, int what, size_t n, ...); + +inline size_t +libradharc_format_request__0__(void *buffer, enum libradharc_request_type type, int what) +{ + return libradharc_format_request__n__(buffer, type, what, 0); +} + +inline size_t +libradharc_format_request__1__(void *buffer, enum libradharc_request_type type, int what, + const void *value1, size_t size1) +{ + return libradharc_format_request__n__(buffer, type, what, 1, value1, size1); +} + +inline size_t +libradharc_format_request__2__(void *buffer, enum libradharc_request_type type, int what, + const void *value1, size_t size1, + const void *value2, size_t size2) +{ + return libradharc_format_request__n__(buffer, type, what, 2, value1, size1, value2, size2); +} + +inline size_t +libradharc_format_request__3__(void *buffer, enum libradharc_request_type type, int what, + const void *value1, size_t size1, + const void *value2, size_t size2, + const void *value3, size_t size3) +{ + return libradharc_format_request__n__(buffer, type, what, 3, value1, size1, value2, size2, value3, size3); +} + +inline size_t +libradharc_format_get_request__0__(void *buffer, enum libradharc_property property) +{ + return libradharc_format_request__0__(buffer, LIBRADHARC_REQUEST_GET, (int)property); +} + +inline size_t +libradharc_format_get_request__s__(void *buffer, enum libradharc_property property, const char *arg1) +{ + if (!arg1) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__1__(buffer, LIBRADHARC_REQUEST_GET, (int)property, arg1, strlen(arg1) + 1U); +} + +inline size_t +libradharc_format_set_request__64i__(void *buffer, enum libradharc_property property, int64_t arg1) +{ + return libradharc_format_request__1__(buffer, LIBRADHARC_REQUEST_SET, (int)property, &arg1, sizeof(arg1)); +} + +inline size_t +libradharc_format_set_request__i__(void *buffer, enum libradharc_property property, int arg1) +{ + return libradharc_format_request__1__(buffer, LIBRADHARC_REQUEST_SET, (int)property, &arg1, sizeof(arg1)); +} + +inline size_t +libradharc_format_set_request__r__(void *buffer, enum libradharc_property property, double arg1) +{ + return libradharc_format_request__1__(buffer, LIBRADHARC_REQUEST_SET, (int)property, &arg1, sizeof(arg1)); +} + +inline size_t +libradharc_format_set_request__rt__(void *buffer, enum libradharc_property property, double arg1, const struct timespec *arg2) +{ + if (!arg2 || arg2->tv_sec < 0 || arg2->tv_nsec < 0 || arg2->tv_nsec >= 1000000000L) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__3__(buffer, LIBRADHARC_REQUEST_SET, property, + &arg1, sizeof(arg1), + &arg2->tv_sec, sizeof(arg2->tv_sec), + &arg2->tv_nsec, sizeof(arg2->tv_nsec)); +} + +inline size_t +libradharc_format_set_request__rr__(void *buffer, enum libradharc_property property, double arg1, double arg2) +{ + return libradharc_format_request__2__(buffer, LIBRADHARC_REQUEST_SET, (int)property, + &arg1, sizeof(arg1), &arg2, sizeof(arg2)); +} + +inline size_t +libradharc_format_set_request__s__(void *buffer, enum libradharc_property property, const char *arg1) +{ + if (!arg1) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__1__(buffer, LIBRADHARC_REQUEST_SET, (int)property, + arg1, strlen(arg1) + 1U); +} + +inline size_t +libradharc_format_set_request__ss__(void *buffer, enum libradharc_property property, const char *arg1, const char *arg2) +{ + if (!arg1 || !arg2) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__2__(buffer, LIBRADHARC_REQUEST_SET, (int)property, + arg1, strlen(arg1) + 1U, arg2, strlen(arg2) + 1U); +} + +inline size_t +libradharc_format_set_request__t__(void *buffer, enum libradharc_property property, const struct timespec *arg1) +{ + if (!arg1 || arg1->tv_sec < 0 || arg1->tv_nsec < 0 || arg1->tv_nsec >= 1000000000L) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__2__(buffer, LIBRADHARC_REQUEST_SET, (int)property, + &arg1->tv_sec, sizeof(arg1->tv_sec), + &arg1->tv_nsec, sizeof(arg1->tv_nsec)); +} + +inline size_t +libradharc_format_unset_request__0__(void *buffer, enum libradharc_property property) +{ + return libradharc_format_request__0__(buffer, LIBRADHARC_REQUEST_UNSET, (int)property); +} + +inline size_t +libradharc_format_signal_request__0__(void *buffer, int signal) +{ + return libradharc_format_request__0__(buffer, LIBRADHARC_REQUEST_SIGNAL, signal); +} + +inline size_t +libradharc_format_signal_request__t__(void *buffer, int signal, const struct timespec *arg1) +{ + if (!arg1 || arg1->tv_sec < 0 || arg1->tv_nsec < 0 || arg1->tv_nsec >= 1000000000L) { + errno = EINVAL; + return 0; + } + return libradharc_format_request__2__(buffer, LIBRADHARC_REQUEST_SIGNAL, signal, + &arg1->tv_sec, sizeof(arg1->tv_sec), + &arg1->tv_nsec, sizeof(arg1->tv_nsec)); +} + + +inline size_t +libradharc_format_set_request__rnt__(void *buffer, enum libradharc_property property, double arg1, const struct timespec *arg2) +{ + if (arg2) + return libradharc_format_set_request__rt__(buffer, property, arg1, arg2); + else + return libradharc_format_set_request__r__(buffer, property, arg1); +} + +inline size_t +libradharc_format_set_request__sns__(void *buffer, enum libradharc_property property, const char *arg1, const char *arg2) +{ + if (arg2) + return libradharc_format_set_request__ss__(buffer, property, arg1, arg2); + else + return libradharc_format_set_request__s__(buffer, property, arg1); +} + +inline size_t +libradharc_format_signal_request__nt__(void *buffer, int signal, const struct timespec *arg1) +{ + if (arg1) + return libradharc_format_signal_request__t__(buffer, signal, arg1); + else + return libradharc_format_signal_request__0__(buffer, signal); +} + + +/** + * Format a message that instructs radharc to reconfigure + * its effect fade-in time + * + * It is unspecified how this effects any ongoing fade-in + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param duration The new fade duration + * @return The size of the message, 0 on failure + * + * @throws EINVAL `duration` is `NULL` + * @throws EINVAL `duration->tv_nsec` is invalid + * @throws EINVAL `duration->tv_sec` is negative + */ +inline size_t +libradharc_format_set_fade_in(void *buffer, const struct timespec *duration) +{ return libradharc_format_set_request__t__(buffer, LIBRADHARC_PROPERTY_FADE_IN, duration); } + +/** + * Format a message that instructs radharc to send back + * its currently configured effect fade-in time + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_fade_in(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_FADE_IN); } + + +/** + * Format a message that instructs radharc to reconfigure + * its effect fade-out time + * + * It is unspecified how this effects any ongoing fade-out + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param duration The new fade duration + * @return The size of the message, 0 on failure + * + * @throws EINVAL `duration` is `NULL` + * @throws EINVAL `duration->tv_nsec` is invalid + * @throws EINVAL `duration->tv_sec` is negative + */ +inline size_t +libradharc_format_set_fade_out(void *buffer, const struct timespec *duration) +{ return libradharc_format_set_request__t__(buffer, LIBRADHARC_PROPERTY_FADE_OUT, duration); } + +/** + * Format a message that instructs radharc to send back + * its currently configured effect fade-out time + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_fade_out(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_FADE_OUT); } + + +/** + * Format a message that instructs radharc to configure + * the colour temperature that shall be applied + * when the Sun's elevation at least at the configured + * upper threshold of twilight, that at daytime after + * daybreak + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param temperature The colour temperature, in Kelvins, must be at least 1000 + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_high_temperature(void *buffer, double temperature) +{ return libradharc_format_set_request__r__(buffer, LIBRADHARC_PROPERTY_HIGH_TEMPERATURE, temperature); } + +/** + * Format a message that instructs radharc to send back + * its configured colour temperature that shall be applied + * when the Sun's elevation at least at the configured + * upper threshold of twilight, that at daytime after + * daybreak + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_high_temperature(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_HIGH_TEMPERATURE); } + + +/** + * Format a message that instructs radharc to configure + * the colour temperature that shall be applied + * when the Sun's elevation at most at the configured + * lower threshold of twilight, that at nighttime after + * nightfall + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param temperature The colour temperature, in Kelvins, must be at least 1000 + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_low_temperature(void *buffer, double temperature) +{ return libradharc_format_set_request__r__(buffer, LIBRADHARC_PROPERTY_LOW_TEMPERATURE, temperature); } + +/** + * Format a message that instructs radharc to send back + * its configured colour temperature that shall be applied + * when the Sun's elevation at most at the configured + * lower threshold of twilight, that at nighttime after + * nightfall + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_low_temperature(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_LOW_TEMPERATURE); } + + +/** + * Format a message that instructs radharc to configure + * the upper theshold of twilight, that is, the solar + * elevation that marks the end of daybreak and the + * beginning of nightfall + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param degrees The solar elevation, in degrees + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_high_elevation(void *buffer, double degrees) +{ return libradharc_format_set_request__r__(buffer, LIBRADHARC_PROPERTY_HIGH_ELEVATION, degrees); } + +/** + * Format a message that instructs radharc to send back + * its configured upper theshold of twilight, that is, + * the solar elevation that marks the end of daybreak + * and the beginning of nightfall + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_high_elevation(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_HIGH_ELEVATION); } + + +/** + * Format a message that instructs radharc to configure + * the lower theshold of twilight, that is, the solar + * elevation that marks the end of nightfall and the + * beginning of daybreak + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param degrees The solar elevation, in degrees + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_low_elevation(void *buffer, double degrees) +{ return libradharc_format_set_request__r__(buffer, LIBRADHARC_PROPERTY_LOW_ELEVATION, degrees); } + +/** + * Format a message that instructs radharc to send back + * its configured lower theshold of twilight, that is, + * the solar elevation that marks the end of nightfall + * and the beginning of daybreak + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_low_elevation(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_LOW_ELEVATION); } + + +/** + * Format a message that instructs radharc to reconfigured + * the geographical location + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param latitude The new latitude, in degrees north of the equator according to GPS + * @param longitude The new longitude, in degrees east of the prime meridian according to GPS + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_location(void *buffer, double latitude, double longitude) +{ return libradharc_format_set_request__rr__(buffer, LIBRADHARC_PROPERTY_LOCATION, latitude, longitude); } + +/** + * Format a message that instructs radharc to send back + * its currently configured geographical location + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_location(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_LOCATION); } + +/** + * Format a message that instructs radharc remove its + * currently configured geolocation, causing it to + * freeze at the current temperature, until modified + * or a new location is set, unless another operation + * mode that doesn't need the user's location is being + * used + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_unset_location(void *buffer) +{ return libradharc_format_unset_request__0__(buffer, LIBRADHARC_PROPERTY_LOCATION); } + + +/** + * Format a message that instructs radharc to use another + * operation mode + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param mode The new operation mode + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_operation_mode(void *buffer, enum libradharc_operation_mode mode) +{ return libradharc_format_set_request__i__(buffer, LIBRADHARC_PROPERTY_OPERATION_MODE, (int)mode); } + +/** + * Format a message that instructs radharc to send back + * its currently configured operation mode + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_operation_mode(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_OPERATION_MODE); } + + +/** + * Format a message that instructs radharc to apply + * a specific colour temperature + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param temperature The temperature to apply, in Kelvins, must be at least 1000 + * @param transition_duration The transition time, or `NULL` to use the configured fade time + * (it's implementation specific how it is defined) + * @return The size of the message, 0 on failure + * + * Implementations of radharc need not implement support for + * smooth temperature transitions, so `transition_duration` + * may be ignored + */ +inline size_t +libradharc_format_set_temperature(void *buffer, double temperature, const struct timespec *transition_duration) +{ return libradharc_format_set_request__rnt__(buffer, LIBRADHARC_PROPERTY_TEMPERATURE, temperature, transition_duration); } + +/** + * Format a message that instructs radharc to send back + * its currently applied temperature + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_temperature(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_TEMPERATURE); } + + +/** + * Format a message that instructs radharc to reconfigure + * its effect priority + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param priority The new priority + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_set_priority(void *buffer, int64_t priority) +{ return libradharc_format_set_request__64i__(buffer, LIBRADHARC_PROPERTY_PRIORITY, priority); } + +/** + * Format a message that instructs radharc to send back + * its currently configured effect priority + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_priority(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_PRIORITY); } + + +/** + * Format a message that instructs radharc to apply + * or modify an implemenation specific setting + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param option The name of the option + * @param value The value for the option, or `NULL` if there is none + * @return The size of the message, 0 on failure + * + * @throws EINVAL `option` is `NULL` + */ +inline size_t +libradharc_format_set_vendor_option(void *buffer, const char *option, const char *value) +{ return libradharc_format_set_request__sns__(buffer, LIBRADHARC_PROPERTY_VENDOR_OPTION, option, value); } + +/** + * Format a message that instructs radharc to send + * back the value of a implemenation specific setting + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param option The name of the option + * @return The size of the message, 0 on failure + * + * @throws EINVAL `option` is `NULL` + */ +inline size_t +libradharc_format_get_vendor_option(void *buffer, const char *option) +{ return libradharc_format_get_request__s__(buffer, LIBRADHARC_PROPERTY_VENDOR_OPTION, option); } + + +/** + * Format a message that instructs radharc to send back + * its current status + * + * radharc will respond with an with a single-line string, + * but it's content is implementation defined + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_get_status(void *buffer) +{ return libradharc_format_get_request__0__(buffer, LIBRADHARC_PROPERTY_STATUS); } + + +/** + * Format a message that instructs radharc to fade out its + * effect and terminate + * + * Sending this message is equivalent to sending SIGINT once, + * except the transition duration can be overridden ad hoc, + * or twice if `transition_duration` is `{0, 0}` + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param transition_duration The transition time, or `NULL` to use the configured fade out time + * @return The size of the message, 0 on failure + * + * @throws EINVAL `transition_duration->tv_nsec` is invalid + * @throws EINVAL `transition_duration->tv_sec` is negative + */ +inline size_t +libradharc_format_smooth_terminate(void *buffer, const struct timespec *transition_duration) +{ return libradharc_format_signal_request__nt__(buffer, SIGINT, transition_duration); } + +/** + * Format a message that instructs radharc to, once any + * current transition has take place, terminate without + * restoring the colour temperature + * + * Sending this message is equivalent to sending SIGHUP + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @return The size of the message, 0 on failure + */ +inline size_t +libradharc_format_freeze_terminate(void *buffer) +{ return libradharc_format_signal_request__0__(buffer, SIGHUP); } + +/** + * Format a message that instructs radharc to disable itself + * + * Sending this message is equivalent to sending SIGUSR1, + * except the transition duration can be overridden ad hoc + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param transition_duration The transition time, or `NULL` to use the configured fade out time + * @return The size of the message, 0 on failure + * + * @throws EINVAL `transition_duration->tv_nsec` is invalid + * @throws EINVAL `transition_duration->tv_sec` is negative + */ +inline size_t +libradharc_format_disable(void *buffer, const struct timespec *transition_duration) +{ return libradharc_format_signal_request__nt__(buffer, SIGUSR1, transition_duration); } + +/** + * Format a message that instructs radharc to enable itself + * + * Sending this message is equivalent to sending SIGUSR2, + * except the transition duration can be overridden ad hoc + * + * @param buffer Output buffer for the message, or `NULL` to measure the required size + * @param transition_duration The transition time, or `NULL` to use the configured fade in time + * @return The size of the message, 0 on failure + * + * @throws EINVAL `transition_duration->tv_nsec` is invalid + * @throws EINVAL `transition_duration->tv_sec` is negative + */ +inline size_t +libradharc_format_enable(void *buffer, const struct timespec *transition_duration) +{ return libradharc_format_signal_request__nt__(buffer, SIGUSR2, transition_duration); } + +#endif -- cgit v1.2.3-70-g09d2