/* See LICENSE file for copyright and license details. */ #include "common.h" /** * Apply, update, or remove a gamma ramp adjustment, send request part * * Cannot be used before connecting to the server * * @param filter The filter to apply, update, or remove, gamma ramp meta-data must match the CRTC's * @param ctx The state of the library, must be connected * @param async Information about the request, that is needed to * identify and parse the response, is stored here * @return Zero on success, -1 on error */ int libcoopgamma_set_gamma_send(const libcoopgamma_filter_t *restrict filter, libcoopgamma_context_t *restrict ctx, libcoopgamma_async_context_t *restrict async) { const void *payload = NULL; const char *lifespan; char priority[sizeof("Priority: \n") + 3 * sizeof(int64_t)] = {'\0'}; char length [sizeof("Length: \n") + 3 * sizeof(size_t) ] = {'\0'}; size_t payload_size = 0, stopwidth = 0; #if defined(__GNUC__) && !defined(__clang__) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wnonnull-compare" #endif if (!filter || !filter->crtc || strchr(filter->crtc, '\n') || !filter->class || strchr(filter->class, '\n')) { errno = EINVAL; goto fail; } #if defined(__GNUC__) && !defined(__clang__) # pragma GCC diagnostic pop #endif switch (filter->lifespan) { case LIBCOOPGAMMA_REMOVE: lifespan = "remove"; break; case LIBCOOPGAMMA_UNTIL_DEATH: lifespan = "until-death"; break; case LIBCOOPGAMMA_UNTIL_REMOVAL: lifespan = "until-removal"; break; default: errno = EINVAL; goto fail; } if (filter->lifespan != LIBCOOPGAMMA_REMOVE) { switch (filter->depth) { case LIBCOOPGAMMA_FLOAT: stopwidth = sizeof(float); break; case LIBCOOPGAMMA_DOUBLE: stopwidth = sizeof(double); break; default: INTEGRAL_DEPTHS if (filter->depth <= 0 || (filter->depth & 7)) { errno = EINVAL; goto fail; } stopwidth = (size_t)(filter->depth / 8); break; } payload_size = filter->ramps.u8.red_size; payload_size += filter->ramps.u8.green_size; payload_size += filter->ramps.u8.blue_size; payload_size *= stopwidth; payload = filter->ramps.u8.red; sprintf(priority, "Priority: %" PRIi64 "\n", filter->priority); sprintf(length, "Length: %zu\n", payload_size); } async->message_id = ctx->message_id; SEND_MESSAGE(ctx, payload, payload_size, "Command: set-gamma\n" "Message ID: %" PRIu32 "\n" "CRTC: %s\n" "Class: %s\n" "Lifespan: %s\n" "%s" "%s" "\n", ctx->message_id, filter->crtc, filter->class, lifespan, priority, length); return 0; fail: copy_errno(ctx); return -1; }