aboutsummaryrefslogtreecommitdiffstats
path: root/src/coopgamma-server/server.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-07-17 19:11:36 +0200
committerMattias Andrée <maandree@kth.se>2016-07-17 19:11:36 +0200
commitd2c052cb9374b6420aa65e50d32e6f864f45ec53 (patch)
tree842a8dde54ac2f53ca711808aae38be7e5daa4a6 /src/coopgamma-server/server.c
parentContinued refactoring (diff)
downloadcoopgammad-d2c052cb9374b6420aa65e50d32e6f864f45ec53.tar.gz
coopgammad-d2c052cb9374b6420aa65e50d32e6f864f45ec53.tar.bz2
coopgammad-d2c052cb9374b6420aa65e50d32e6f864f45ec53.tar.xz
More refactoring
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/coopgamma-server/server.c')
-rw-r--r--src/coopgamma-server/server.c374
1 files changed, 0 insertions, 374 deletions
diff --git a/src/coopgamma-server/server.c b/src/coopgamma-server/server.c
deleted file mode 100644
index e0a5188..0000000
--- a/src/coopgamma-server/server.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/**
- * coopgammad -- Cooperative gamma server
- * Copyright (C) 2016 Mattias Andrée (maandree@kth.se)
- *
- * This program 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.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include "server.h"
-#include "chaining.h"
-#include "../state.h"
-#include "../communication.h"
-#include "../util.h"
-#include "../gamma-server/server.h"
-
-#include <libclut.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
-/**
- * Handle a closed connection
- *
- * @param client The file descriptor for the client
- * @return Zero on success, -1 on error
- */
-int connection_closed(int client)
-{
- size_t i, j, k;
- int remove;
-
- for (i = 0; i < outputs_n; i++)
- {
- struct output* output = outputs + i;
- ssize_t updated = -1;
- for (j = k = 0; j < output->table_size; j += !remove, k++)
- {
- remove = output->table_filters[j].client == client;
- remove = remove && (output->table_filters[j].lifespan == LIFESPAN_UNTIL_DEATH);
- if (remove)
- {
- filter_destroy(output->table_filters + j);
- libgamma_gamma_ramps8_destroy(&(output->table_sums[j].u8));
- output->table_size -= 1;
- if (updated == -1)
- updated = (ssize_t)j;
- }
- output->table_filters[j] = output->table_filters[k];
- output->table_sums[j] = output->table_sums[k];
- }
- if (updated >= 0)
- if (flush_filters(output, (size_t)updated) < 0)
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * Handle a ‘Command: get-gamma’ message
- *
- * @param conn The index of the connection
- * @param message_id The value of the ‘Message ID’ header
- * @param crtc The value of the ‘CRTC’ header
- * @param coalesce The value of the ‘Coalesce’ header
- * @param high_priority The value of the ‘High priority’ header
- * @param low_priority The value of the ‘Low priority’ header
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-int handle_get_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc,
- const char* restrict coalesce, const char* restrict high_priority,
- const char* restrict low_priority)
-{
- struct output* restrict output;
- int64_t high, low;
- int coal;
- char* restrict buf;
- size_t start, end, len, n, i;
- char depth[3];
- char tables[sizeof("Tables: \n") + 3 * sizeof(size_t)];
-
- if (crtc == NULL) return send_error("protocol error: 'CRTC' header omitted");
- if (coalesce == NULL) return send_error("protocol error: 'Coalesce' header omitted");
- if (high_priority == NULL) return send_error("protocol error: 'High priority' header omitted");
- if (low_priority == NULL) return send_error("protocol error: 'Low priority' header omitted");
-
- high = (int64_t)atoll(high_priority);
- low = (int64_t)atoll(low_priority);
-
- if (!strcmp(coalesce, "yes"))
- coal = 1;
- else if (!strcmp(coalesce, "no"))
- coal = 0;
- else
- return send_error("protocol error: recognised value for 'Coalesce' header");
-
- output = output_find_by_name(crtc, outputs, outputs_n);
- if (output == NULL)
- return send_error("selected CRTC does not exist");
- else if (output->supported == LIBGAMMA_NO)
- return send_error("selected CRTC does not support gamma adjustments");
-
- for (start = 0; start < output->table_size; start++)
- if (output->table_filters[start].priority <= high)
- break;
-
- for (end = output->table_size; end > 0; end--)
- if (output->table_filters[end - 1].priority >= low)
- break;
-
- switch (output->depth)
- {
- case -2: strcpy(depth, "d"); break;
- case -1: strcpy(depth, "f"); break;
- default:
- sprintf(depth, "%i", output->depth);
- break;
- }
-
- if (coal)
- {
- *tables = '\0';
- n = output->ramps_size;
- }
- else
- {
- sprintf(tables, "Tables: %zu\n", end - start);
- n = (sizeof(int64_t) + output->ramps_size) * (end - start);
- for (i = start; i < end; i++)
- n += strlen(output->table_filters[i].class) + 1;
- }
-
- MAKE_MESSAGE(&buf, &n, 0,
- "In response to: %s\n"
- "Depth: %s\n"
- "Red size: %zu\n"
- "Green size: %zu\n"
- "Blue size: %zu\n"
- "%s"
- "Length: %zu\n"
- "\n",
- message_id, depth, output->red_size, output->green_size,
- output->blue_size, tables, n);
-
- if (coal)
- {
- if (start == 0)
- memcpy(buf + n, output->table_sums[end].u8.red, output->ramps_size);
- else
- {
- union gamma_ramps ramps;
- if (make_plain_ramps(&ramps, output))
- {
- int saved_errno = errno;
- free(buf);
- errno = saved_errno;
- return -1;
- }
- for (i = start; i < end; i++)
- apply_filter(&ramps, output->table_filters[i].ramps, output->depth, &ramps);
- memcpy(buf + n, ramps.u8.red, output->ramps_size);
- libgamma_gamma_ramps8_destroy(&(ramps.u8));
- }
- n += output->ramps_size;
- }
- else
- for (i = start; i < end; i++)
- {
-#if defined(__clang__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-align"
-#endif
- *(int64_t*)(buf + n) = output->table_filters[i].priority;
-#if defined(__clang__)
-# pragma GCC diagnostic pop
-#endif
- n += sizeof(int64_t);
- len = strlen(output->table_filters[i].class) + 1;
- memcpy(buf + n, output->table_filters[i].class, len);
- n += len;
- memcpy(buf + n, output->table_filters[i].ramps, output->ramps_size);
- n += output->ramps_size;
- }
-
- return send_message(conn, buf, n);
-}
-
-
-/**
- * Handle a ‘Command: set-gamma’ message
- *
- * @param conn The index of the connection
- * @param message_id The value of the ‘Message ID’ header
- * @param crtc The value of the ‘CRTC’ header
- * @param priority The value of the ‘Priority’ header
- * @param class The value of the ‘Class’ header
- * @param lifespan The value of the ‘Lifespan’ header
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-int handle_set_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc,
- const char* restrict priority, const char* restrict class, const char* restrict lifespan)
-{
- struct message* restrict msg = inbound + conn;
- struct output* restrict output = NULL;
- struct filter filter;
- char* restrict p;
- char* restrict q;
- int saved_errno;
- ssize_t r;
-
- if (crtc == NULL) return send_error("protocol error: 'CRTC' header omitted");
- if (class == NULL) return send_error("protocol error: 'Class' header omitted");
- if (lifespan == NULL) return send_error("protocol error: 'Lifespan' header omitted");
-
- filter.client = connections[conn];
- filter.priority = priority == NULL ? 0 : (int64_t)atoll(priority);
- filter.ramps = NULL;
-
- output = output_find_by_name(crtc, outputs, outputs_n);
- if (output == NULL)
- return send_error("CRTC does not exists");
-
- p = strstr(class, "::");
- if ((p == NULL) || (p == class))
- return send_error("protocol error: malformatted value for 'Class' header");
- q = strstr(p + 2, "::");
- if ((q == NULL) || (q == p))
- return send_error("protocol error: malformatted value for 'Class' header");
-
- if (!strcmp(lifespan, "until-removal"))
- filter.lifespan = LIFESPAN_UNTIL_REMOVAL;
- else if (!strcmp(lifespan, "until-death"))
- filter.lifespan = LIFESPAN_UNTIL_DEATH;
- else if (!strcmp(lifespan, "remove"))
- filter.lifespan = LIFESPAN_REMOVE;
- else
- return send_error("protocol error: recognised value for 'Lifespan' header");
-
- if (filter.lifespan == LIFESPAN_REMOVE)
- {
- if (msg->payload_size)
- fprintf(stderr, "%s: ignoring superfluous payload on Command: set-gamma message with "
- "Lifespan: remove\n", argv0);
- if (priority != NULL)
- fprintf(stderr, "%s: ignoring superfluous Priority header on Command: set-gamma message with "
- "Lifespan: remove\n", argv0);
- }
- else if (msg->payload_size != output->ramps_size)
- return send_error("invalid payload: size of message payload does matched the expectancy");
- else if (priority == NULL)
- return send_error("protocol error: 'Priority' header omitted");
-
- filter.class = memdup(class, strlen(class) + 1);
- if (filter.class == NULL)
- goto fail;
-
- if (filter.lifespan != LIFESPAN_REMOVE)
- {
- filter.ramps = memdup(msg->payload, msg->payload_size);
- if (filter.ramps == NULL)
- goto fail;
- }
-
- if ((r = add_filter(output, &filter)) < 0)
- goto fail;
- filter.class = NULL;
- filter.ramps = NULL;
- if (flush_filters(output, (size_t)r))
- goto fail;
-
- return send_errno(0);
-
- fail:
- saved_errno = errno;
- send_errno(saved_errno);
- free(filter.class);
- free(filter.ramps);
- errno = saved_errno;
- return -1;
-}
-
-
-
-/**
- * Recalculate the resulting gamma and
- * update push the new gamma ramps to the CRTC
- *
- * @param output The output
- * @param first_updated The index of the first added or removed filter
- * @return Zero on success, -1 on error
- */
-int flush_filters(struct output* restrict output, size_t first_updated)
-{
- union gamma_ramps plain;
- union gamma_ramps* last;
- size_t i;
-
- if (first_updated == 0)
- {
- if (make_plain_ramps(&plain, output) < 0)
- return -1;
- last = &plain;
- }
- else
- last = output->table_sums + (first_updated - 1);
-
- for (i = first_updated; i < output->table_size; i++)
- {
- apply_filter(output->table_sums + i, output->table_filters[i].ramps, output->depth, last);
- last = output->table_sums + i;
- }
-
- set_gamma(output, last);
-
- if (first_updated == 0)
- libgamma_gamma_ramps8_destroy(&(plain.u8));
-
- return 0;
-}
-
-
-
-/**
- * Preserve current gamma ramps at priority 0 for all outputs
- *
- * @return Zero on success, -1 on error
- */
-int preserve_gamma(void)
-{
- size_t i;
-
- for (i = 0; i < outputs_n; i++)
- {
- struct filter filter = {
- .client = -1,
- .priority = 0,
- .class = NULL,
- .lifespan = LIFESPAN_UNTIL_REMOVAL,
- .ramps = NULL
- };
- outputs[i].table_filters = calloc(4, sizeof(*(outputs[i].table_filters)));
- outputs[i].table_sums = calloc(4, sizeof(*(outputs[i].table_sums)));
- outputs[i].table_alloc = 4;
- outputs[i].table_size = 1;
- filter.class = memdup(PKGNAME "::" COMMAND "::preserved", sizeof(PKGNAME "::" COMMAND "::preserved"));
- if (filter.class == NULL)
- return -1;
- filter.ramps = memdup(outputs[i].saved_ramps.u8.red, outputs[i].ramps_size);
- if (filter.ramps == NULL)
- return -1;
- outputs[i].table_filters[0] = filter;
- COPY_RAMP_SIZES(&(outputs[i].table_sums[0].u8), outputs + i);
- if (!gamma_ramps_unmarshal(outputs[i].table_sums, outputs[i].saved_ramps.u8.red, outputs[i].ramps_size))
- return -1;
- }
-
- return 0;
-}
-