aboutsummaryrefslogtreecommitdiffstats
path: root/libcoopgamma_set_gamma_send.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcoopgamma_set_gamma_send.c')
-rw-r--r--libcoopgamma_set_gamma_send.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/libcoopgamma_set_gamma_send.c b/libcoopgamma_set_gamma_send.c
new file mode 100644
index 0000000..d6daf91
--- /dev/null
+++ b/libcoopgamma_set_gamma_send.c
@@ -0,0 +1,85 @@
+/* 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;
+}