aboutsummaryrefslogtreecommitdiffstats
path: root/src/servers
diff options
context:
space:
mode:
Diffstat (limited to 'src/servers')
-rw-r--r--src/servers/coopgamma.c558
-rw-r--r--src/servers/coopgamma.h101
-rw-r--r--src/servers/crtc.c325
-rw-r--r--src/servers/crtc.h100
-rw-r--r--src/servers/gamma.c398
-rw-r--r--src/servers/gamma.h85
-rw-r--r--src/servers/kernel.c384
-rw-r--r--src/servers/kernel.h85
-rw-r--r--src/servers/master.c394
-rw-r--r--src/servers/master.h36
10 files changed, 0 insertions, 2466 deletions
diff --git a/src/servers/coopgamma.c b/src/servers/coopgamma.c
deleted file mode 100644
index 6e544be..0000000
--- a/src/servers/coopgamma.c
+++ /dev/null
@@ -1,558 +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 "coopgamma.h"
-#include "gamma.h"
-#include "../state.h"
-#include "../communication.h"
-#include "../util.h"
-#include "../types/output.h"
-
-#include <libclut.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
-/**
- * Apply a filter on top of another filter
- *
- * @param dest The output for the resulting ramp-trio, must be initialised
- * @param application The red, green and blue ramps, as one single raw array,
- * of the filter that should be applied
- * @param depth -1: `float` stops
- * -2: `double` stops
- * Other: the number of bits of each (integral) stop
- * @param base The CLUT on top of which the new filter should be applied,
- * this can be the same pointer as `dest`
- */
-static void apply_filter(union gamma_ramps* restrict dest, void* restrict application,
- int depth, union gamma_ramps* restrict base)
-{
- union gamma_ramps app;
- size_t bytedepth;
- size_t red_width, green_width, blue_width;
-
- if (depth == -1)
- bytedepth = sizeof(float);
- else if (depth == -2)
- bytedepth = sizeof(double);
- else
- bytedepth = (size_t)depth / 8;
-
- red_width = (app.u8.red_size = base->u8.red_size) * bytedepth;
- green_width = (app.u8.green_size = base->u8.green_size) * bytedepth;
- blue_width = (app.u8.blue_size = base->u8.blue_size) * bytedepth;
-
- app.u8.red = application;
- app.u8.green = app.u8.red + red_width;
- app.u8.blue = app.u8.green + green_width;
-
- if (dest != base)
- {
- memcpy(dest->u8.red, base->u8.red, red_width);
- memcpy(dest->u8.green, base->u8.green, green_width);
- memcpy(dest->u8.blue, base->u8.blue, blue_width);
- }
-
- switch (depth)
- {
- case 8:
- libclut_apply(&(dest->u8), UINT8_MAX, uint8_t, &(app.u8), UINT8_MAX, uint8_t, 1, 1, 1);
- break;
- case 16:
- libclut_apply(&(dest->u16), UINT16_MAX, uint16_t, &(app.u16), UINT16_MAX, uint16_t, 1, 1, 1);
- break;
- case 32:
- libclut_apply(&(dest->u32), UINT32_MAX, uint32_t, &(app.u32), UINT32_MAX, uint32_t, 1, 1, 1);
- break;
- case 64:
- libclut_apply(&(dest->u64), UINT64_MAX, uint64_t, &(app.u64), UINT64_MAX, uint64_t, 1, 1, 1);
- break;
- case -1:
- libclut_apply(&(dest->f), 1.0f, float, &(app.d), 1.0f, float, 1, 1, 1);
- break;
- case -2:
- libclut_apply(&(dest->d), (double)1, double, &(app.f), (double)1, double, 1, 1, 1);
- break;
- default:
- abort();
- }
-}
-
-
-
-/**
- * Remove a filter from an output
- *
- * @param out The output
- * @param filter The filter
- * @return The index of the filter, `out->table_size` if not found
- */
-static ssize_t remove_filter(struct output* restrict out, struct filter* restrict filter)
-{
- size_t i, n = out->table_size;
-
- for (i = 0; i < n; i++)
- if (!strcmp(filter->class, out->table_filters[i].class))
- break;
-
- if (i == out->table_size)
- {
- fprintf(stderr, "%s: ignoring attempt to removing non-existing filter on CRTC %s: %s\n",
- argv0, out->name, filter->class);
- return (ssize_t)(out->table_size);
- }
-
- filter_destroy(out->table_filters + i);
- libgamma_gamma_ramps8_destroy(&(out->table_sums[i].u8));
-
- n = n - i - 1;
- memmove(out->table_filters + i, out->table_filters + i + 1, n * sizeof(*(out->table_filters)));
- memmove(out->table_sums + i, out->table_sums + i + 1, n * sizeof(*(out->table_sums)));
- out->table_size--;
-
- return (ssize_t)i;
-}
-
-
-/**
- * Add a filter to an output
- *
- * @param out The output
- * @param filter The filter
- * @return The index given to the filter, -1 on error
- */
-static ssize_t add_filter(struct output* restrict out, struct filter* restrict filter)
-{
- size_t i, n = out->table_size;
- int r = -1;
-
- /* Remove? */
- if (filter->lifespan == LIFESPAN_REMOVE)
- return remove_filter(out, filter);
-
- /* Update? */
- for (i = 0; i < n; i++)
- if (!strcmp(filter->class, out->table_filters[i].class))
- break;
- if (i != n)
- {
- filter_destroy(out->table_filters + i);
- out->table_filters[i] = *filter;
- filter->class = NULL;
- filter->ramps = NULL;
- return (ssize_t)i;
- }
-
- /* Add! */
- for (i = 0; i < n; i++)
- if (filter->priority > out->table_filters[i].priority)
- break;
-
- if (n == out->table_alloc)
- {
- void* new;
-
- new = realloc(out->table_filters, (n + 10) * sizeof(*(out->table_filters)));
- if (new == NULL)
- return -1;
- out->table_filters = new;
-
- new = realloc(out->table_sums, (n + 10) * sizeof(*(out->table_sums)));
- if (new == NULL)
- return -1;
- out->table_sums = new;
-
- out->table_alloc += 10;
- }
-
- memmove(out->table_filters + i + 1, out->table_filters + i, (n - i) * sizeof(*(out->table_filters)));
- memmove(out->table_sums + i + 1, out->table_sums + i, (n - i) * sizeof(*(out->table_sums)));
- out->table_size++;
-
- out->table_filters[i] = *filter;
- filter->class = NULL;
- filter->ramps = NULL;
-
- COPY_RAMP_SIZES(&(out->table_sums[i].u8), out);
- switch (out->depth)
- {
- case 8: r = libgamma_gamma_ramps8_initialise(&(out->table_sums[i].u8)); break;
- case 16: r = libgamma_gamma_ramps16_initialise(&(out->table_sums[i].u16)); break;
- case 32: r = libgamma_gamma_ramps32_initialise(&(out->table_sums[i].u32)); break;
- case 64: r = libgamma_gamma_ramps64_initialise(&(out->table_sums[i].u64)); break;
- case -1: r = libgamma_gamma_rampsf_initialise(&(out->table_sums[i].f)); break;
- case -2: r = libgamma_gamma_rampsd_initialise(&(out->table_sums[i].d)); break;
- default:
- abort();
- }
- if (r < 0)
- return -1;
-
- return (ssize_t)i;
-}
-
-
-/**
- * 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++)
- {
- if (j != k)
- {
- output->table_filters[j] = output->table_filters[k];
- output->table_sums[j] = output->table_sums[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;
- }
- }
- 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, n,
- "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) && (start < end))
- memcpy(buf + n, output->table_sums[end - 1].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;
- if (flush_filters(output, (size_t)r))
- goto fail;
-
- free(filter.class);
- free(filter.ramps);
- 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;
-}
-
diff --git a/src/servers/coopgamma.h b/src/servers/coopgamma.h
deleted file mode 100644
index 5a9f7d9..0000000
--- a/src/servers/coopgamma.h
+++ /dev/null
@@ -1,101 +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/>.
- */
-#ifndef SERVERS_COOPGAMMA_H
-#define SERVERS_COOPGAMMA_H
-
-
-#include "../types/output.h"
-
-#include <stddef.h>
-
-
-
-#ifndef GCC_ONLY
-# if defined(__GNUC__) && !defined(__clang__)
-# define GCC_ONLY(...) __VA_ARGS__
-# else
-# define GCC_ONLY(...) /* nothing */
-# endif
-#endif
-
-
-
-/**
- * Handle a closed connection
- *
- * @param client The file descriptor for the client
- * @return Zero on success, -1 on error
- */
-int connection_closed(int client);
-
-/**
- * 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
- */
-GCC_ONLY(__attribute__((nonnull(2))))
-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);
-
-/**
- * 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
- */
-GCC_ONLY(__attribute__((nonnull(2))))
-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);
-
-
-/**
- * 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
- */
-GCC_ONLY(__attribute__((nonnull)))
-int flush_filters(struct output* restrict output, size_t first_updated);
-
-
-/**
- * Preserve current gamma ramps at priority 0 for all outputs
- *
- * @return Zero on success, -1 on error
- */
-int preserve_gamma(void);
-
-
-#endif
-
diff --git a/src/servers/crtc.c b/src/servers/crtc.c
deleted file mode 100644
index ca10940..0000000
--- a/src/servers/crtc.c
+++ /dev/null
@@ -1,325 +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 "crtc.h"
-#include "gamma.h"
-#include "coopgamma.h"
-#include "../state.h"
-#include "../communication.h"
-#include "../util.h"
-
-#include <errno.h>
-#include <string.h>
-
-
-
-/**
- * Handle a ‘Command: enumerate-crtcs’ message
- *
- * @param conn The index of the connection
- * @param message_id The value of the ‘Message ID’ header
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-int handle_enumerate_crtcs(size_t conn, const char* restrict message_id)
-{
- size_t i, n = 0, len;
- char* restrict buf;
-
- for (i = 0; i < outputs_n; i++)
- n += strlen(outputs[i].name) + 1;
-
- MAKE_MESSAGE(&buf, &n, n,
- "Command: crtc-enumeration\n"
- "In response to: %s\n"
- "Length: %zu\n"
- "\n",
- message_id, n);
-
- for (i = 0; i < outputs_n; i++)
- {
- len = strlen(outputs[i].name);
- memcpy(buf + n, outputs[i].name, len);
- buf[n + len] = '\n';
- n += len + 1;
- }
-
- return send_message(conn, buf, n);
-}
-
-
-/**
- * Get the name of a CRTC
- *
- * @param info Information about the CRTC
- * @param crtc libgamma's state for the CRTC
- * @return The name of the CRTC, `NULL` on error
- */
-char* get_crtc_name(const libgamma_crtc_information_t* restrict info,
- const libgamma_crtc_state_t* restrict crtc)
-{
- if ((info->edid_error == 0) && (info->edid != NULL))
- return libgamma_behex_edid(info->edid, info->edid_length);
- else if ((info->connector_name_error == 0) && (info->connector_name != NULL))
- {
- char* name = malloc(3 * sizeof(size_t) + strlen(info->connector_name) + 2);
- if (name != NULL)
- sprintf(name, "%zu.%s", crtc->partition->partition, info->connector_name);
- return name;
- }
- else
- {
- char* name = malloc(2 * 3 * sizeof(size_t) + 2);
- if (name != NULL)
- sprintf(name, "%zu.%zu", crtc->partition->partition, crtc->crtc);
- return name;
- }
-}
-
-
-/**
- * Initialise the site
- *
- * @return Zero on success, -1 on error
- */
-int initialise_site(void)
-{
- char* restrict sitename_dup = NULL;
- int gerror, saved_errno;
-
- if ((sitename != NULL) && !(sitename_dup = memdup(sitename, strlen(sitename) + 1)))
- goto fail;
- if ((gerror = libgamma_site_initialise(&site, method, sitename_dup)))
- goto fail_libgamma;
-
- return 0;
- fail_libgamma:
- sitename_dup = NULL;
- libgamma_perror(argv0, gerror);
- errno = 0;
- fail:
- saved_errno = errno;
- free(sitename_dup);
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * Get partitions and CRTC:s
- *
- * @return Zero on success, -1 on error
- */
-int initialise_crtcs(void)
-{
- size_t i, j, n, n0;
- int gerror;
-
- /* Get partitions */
- outputs_n = 0;
- if (site.partitions_available)
- if (!(partitions = calloc(site.partitions_available, sizeof(*partitions))))
- goto fail;
- for (i = 0; i < site.partitions_available; i++)
- {
- if ((gerror = libgamma_partition_initialise(partitions + i, &site, i)))
- goto fail_libgamma;
- outputs_n += partitions[i].crtcs_available;
- }
-
- /* Get CRTC:s */
- if (outputs_n)
- if (!(crtcs = calloc(outputs_n, sizeof(*crtcs))))
- goto fail;
- for (i = 0, j = n = 0; i < site.partitions_available; i++)
- for (n0 = n, n += partitions[i].crtcs_available; j < n; j++)
- if ((gerror = libgamma_crtc_initialise(crtcs + j, partitions + i, j - n0)))
- goto fail_libgamma;
-
- return 0;
-
- fail_libgamma:
- libgamma_perror(argv0, gerror);
- errno = 0;
- fail:
- return -1;
-}
-
-
-/**
- * Merge the new state with an old state
- *
- * @param old_outputs The old `outputs`
- * @param old_outputs_n The old `outputs_n`
- * @return Zero on success, -1 on error
- */
-int merge_state(struct output* restrict old_outputs, size_t old_outputs_n)
-{
- struct output* restrict new_outputs = NULL;
- size_t new_outputs_n;
- size_t i, j;
-
- /* How many outputs does the system now have? */
- i = j = new_outputs_n = 0;
- while ((i < old_outputs_n) && (j < outputs_n))
- {
- int cmp = strcmp(old_outputs[i].name, outputs[j].name);
- if (cmp <= 0)
- new_outputs_n++;
- i += cmp >= 0;
- j += cmp <= 0;
- }
- new_outputs_n += outputs_n - j;
-
- /* Allocate output state array */
- if (new_outputs_n > 0)
- {
- new_outputs = calloc(new_outputs_n, sizeof(*new_outputs));
- if (new_outputs == NULL)
- return -1;
- }
-
- /* Merge output states */
- i = j = new_outputs_n = 0;
- while ((i < old_outputs_n) && (j < outputs_n))
- {
- int is_same = 0, cmp = strcmp(old_outputs[i].name, outputs[j].name);
- if (cmp == 0)
- is_same = (old_outputs[i].depth == outputs[j].depth &&
- old_outputs[i].red_size == outputs[j].red_size &&
- old_outputs[i].green_size == outputs[j].green_size &&
- old_outputs[i].blue_size == outputs[j].blue_size);
- if (is_same)
- {
- new_outputs[new_outputs_n] = old_outputs[i];
- new_outputs[new_outputs_n].crtc = outputs[j].crtc;
- memset(old_outputs + i, 0, sizeof(*old_outputs));
- outputs[j].crtc = NULL;
- output_destroy(outputs + j);
- new_outputs_n++;
- }
- else if (cmp <= 0)
- new_outputs[new_outputs_n++] = outputs[j];
- i += cmp >= 0;
- j += cmp <= 0;
- }
- while (j < outputs_n)
- new_outputs[new_outputs_n++] = outputs[j++];
-
- /* Commit merge */
- free(outputs);
- outputs = new_outputs;
- outputs_n = new_outputs_n;
-
- return 0;
-}
-
-
-
-/**
- * Disconnect from the site
- *
- * @return Zero on success, -1 on error
- */
-int disconnect(void)
-{
- size_t i;
-
- if (!connected)
- return 0;
- connected = 0;
-
- for (i = 0; i < outputs_n; i++)
- {
- outputs[i].crtc = NULL;
- libgamma_crtc_destroy(crtcs + i);
- }
- free(crtcs), crtcs = NULL;
- for (i = 0; i < site.partitions_available; i++)
- libgamma_partition_destroy(partitions + i);
- free(partitions), partitions = NULL;
- libgamma_site_destroy(&site);
- memset(&site, 0, sizeof(site));
-
- return 0;
-}
-
-
-/**
- * Reconnect to the site
- *
- * @return Zero on success, -1 on error
- */
-int reconnect(void)
-{
- struct output* restrict old_outputs;
- size_t i, old_outputs_n;
- int saved_errno;
-
- if (connected)
- return 0;
- connected = 1;
-
- /* Remember old state */
- old_outputs = outputs, outputs = NULL;
- old_outputs_n = outputs_n, outputs_n = 0;
-
- /* Get site */
- if (initialise_site() < 0)
- goto fail;
-
- /* Get partitions and CRTC:s */
- if (initialise_crtcs() < 0)
- goto fail;
-
- /* Get CRTC information */
- if (outputs_n && !(outputs = calloc(outputs_n, sizeof(*outputs))))
- goto fail;
- if (initialise_gamma_info() < 0)
- goto fail;
-
- /* Sort outputs */
- qsort(outputs, outputs_n, sizeof(*outputs), output_cmp_by_name);
-
- /* Load current gamma ramps */
- store_gamma();
-
- /* Preserve current gamma ramps at priority=0 if -p */
- if (preserve && (preserve_gamma() < 0))
- goto fail;
-
- /* Merge state */
- if (merge_state(old_outputs, old_outputs_n) < 0)
- goto fail;
- for (i = 0; i < old_outputs_n; i++)
- output_destroy(old_outputs + i);
- free(old_outputs), old_outputs = NULL, old_outputs_n = 0;
-
- /* Reapply gamma ramps */
- reapply_gamma();
-
- return 0;
-
- fail:
- saved_errno = errno;
- for (i = 0; i < old_outputs_n; i++)
- output_destroy(old_outputs + i);
- free(old_outputs);
- errno = saved_errno;
- return -1;
-}
-
diff --git a/src/servers/crtc.h b/src/servers/crtc.h
deleted file mode 100644
index 68239d4..0000000
--- a/src/servers/crtc.h
+++ /dev/null
@@ -1,100 +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/>.
- */
-#ifndef SERVERS_CRTC_H
-#define SERVERS_CRTC_H
-
-
-#include "../types/output.h"
-
-#include <libgamma.h>
-
-
-
-#ifndef GCC_ONLY
-# if defined(__GNUC__) && !defined(__clang__)
-# define GCC_ONLY(...) __VA_ARGS__
-# else
-# define GCC_ONLY(...) /* nothing */
-# endif
-#endif
-
-
-
-/**
- * Handle a ‘Command: enumerate-crtcs’ message
- *
- * @param conn The index of the connection
- * @param message_id The value of the ‘Message ID’ header
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-GCC_ONLY(__attribute__((nonnull)))
-int handle_enumerate_crtcs(size_t conn, const char* restrict message_id);
-
-/**
- * Get the name of a CRTC
- *
- * @param info Information about the CRTC
- * @param crtc libgamma's state for the CRTC
- * @return The name of the CRTC, `NULL` on error
- */
-GCC_ONLY(__attribute__((nonnull)))
-char* get_crtc_name(const libgamma_crtc_information_t* restrict info,
- const libgamma_crtc_state_t* restrict crtc);
-
-/**
- * Initialise the site
- *
- * @return Zero on success, -1 on error
- */
-int initialise_site(void);
-
-/**
- * Get partitions and CRTC:s
- *
- * @return Zero on success, -1 on error
- */
-int initialise_crtcs(void);
-
-/**
- * Merge the new state with an old state
- *
- * @param old_outputs The old `outputs`
- * @param old_outputs_n The old `outputs_n`
- * @return Zero on success, -1 on error
- */
-int merge_state(struct output* restrict old_outputs, size_t old_outputs_n);
-
-
-/**
- * Disconnect from the site
- *
- * @return Zero on success, -1 on error
- */
-int disconnect(void);
-
-/**
- * Reconnect to the site
- *
- * @return Zero on success, -1 on error
- */
-int reconnect(void);
-
-
-#endif
-
diff --git a/src/servers/gamma.c b/src/servers/gamma.c
deleted file mode 100644
index 17105d4..0000000
--- a/src/servers/gamma.c
+++ /dev/null
@@ -1,398 +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 "gamma.h"
-#include "crtc.h"
-#include "../state.h"
-#include "../communication.h"
-#include "../util.h"
-
-#include <errno.h>
-#include <string.h>
-
-
-
-#if defined(__clang__)
-# pragma GCC diagnostic ignored "-Wswitch-enum"
-#endif
-
-
-
-/**
- * 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
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-int handle_get_gamma_info(size_t conn, const char* restrict message_id, const char* restrict crtc)
-{
- struct output* restrict output;
- char* restrict buf;
- char depth[3];
- const char* supported;
- const char* colourspace;
- char gamut[8 * sizeof("White x: 1023")];
- size_t n;
-
- if (crtc == NULL) return send_error("protocol error: 'CRTC' header omitted");
-
- output = output_find_by_name(crtc, outputs, outputs_n);
- if (output == NULL)
- return send_error("selected CRTC does not exist");
-
- switch (output->depth)
- {
- case -2: strcpy(depth, "d"); break;
- case -1: strcpy(depth, "f"); break;
- default:
- sprintf(depth, "%i", output->depth);
- break;
- }
-
- switch (output->supported)
- {
- case LIBGAMMA_YES: supported = "yes"; break;
- case LIBGAMMA_NO: supported = "no"; break;
- default: supported = "maybe"; break;
- }
-
- switch (output->colourspace)
- {
- case COLOURSPACE_SRGB_SANS_GAMUT:
- case COLOURSPACE_SRGB: colourspace = "Colour space: sRGB\n"; break;
- case COLOURSPACE_RGB_SANS_GAMUT:
- case COLOURSPACE_RGB: colourspace = "Colour space: RGB\n"; break;
- case COLOURSPACE_NON_RGB: colourspace = "Colour space: non-RGB\n"; break;
- case COLOURSPACE_GREY: colourspace = "Colour space: grey\n"; break;
- default: colourspace = ""; break;
- }
-
- switch (output->colourspace)
- {
- case COLOURSPACE_SRGB:
- case COLOURSPACE_RGB:
- sprintf(gamut,
- "Red x: %u\n"
- "Red y: %u\n"
- "Green x: %u\n"
- "Green y: %u\n"
- "Blue x: %u\n"
- "Blue y: %u\n"
- "White x: %u\n"
- "White y: %u\n",
- output->red_x, output->red_y, output->green_x, output->green_y,
- output->blue_x, output->blue_y, output->white_x, output->white_y);
- break;
- default:
- *gamut = '\0';
- break;
- }
-
- MAKE_MESSAGE(&buf, &n, 0,
- "In response to: %s\n"
- "Cooperative: yes\n" /* In mds: say ‘no’, mds-coopgamma changes to ‘yes’.” */
- "Depth: %s\n"
- "Red size: %zu\n"
- "Green size: %zu\n"
- "Blue size: %zu\n"
- "Gamma support: %s\n"
- "%s%s"
- "\n",
- message_id, depth, output->red_size, output->green_size,
- output->blue_size, supported, gamut, colourspace);
-
- return send_message(conn, buf, n);
-}
-
-
-/**
- * Set the gamma ramps on an output
- *
- * @param output The output
- * @param ramps The gamma ramps
- */
-void set_gamma(const struct output* restrict output, const union gamma_ramps* restrict ramps)
-{
- int r = 0;
-
- if (!connected)
- return;
-
- switch (output->depth)
- {
- case 8: r = libgamma_crtc_set_gamma_ramps8(output->crtc, ramps->u8); break;
- case 16: r = libgamma_crtc_set_gamma_ramps16(output->crtc, ramps->u16); break;
- case 32: r = libgamma_crtc_set_gamma_ramps32(output->crtc, ramps->u32); break;
- case 64: r = libgamma_crtc_set_gamma_ramps64(output->crtc, ramps->u64); break;
- case -1: r = libgamma_crtc_set_gamma_rampsf(output->crtc, ramps->f); break;
- case -2: r = libgamma_crtc_set_gamma_rampsd(output->crtc, ramps->d); break;
- default:
- abort();
- }
- if (r)
- libgamma_perror(argv0, r); /* Not fatal */
-}
-
-
-/**
- * Parse the EDID of a monitor
- *
- * @param output The output
- * @param edid The EDID in binary format
- * @param n The length of the EDID
- */
-static void parse_edid(struct output* restrict output, const unsigned char* restrict edid, size_t n)
-{
- size_t i;
- int analogue;
- unsigned sum;
-
- output->red_x = output->green_x = output->blue_x = output->white_x = 0;
- output->red_y = output->green_y = output->blue_y = output->white_y = 0;
- output->colourspace = COLOURSPACE_UNKNOWN;
-
- if ((edid == NULL) || (n < 128))
- return;
- for (i = 0, sum = 0; i < 128; i++)
- sum += (unsigned)edid[i];
- if ((sum & 0xFF) != 0)
- return;
- if ((edid[0] != 0) || (edid[7] != 0))
- return;
- for (i = 1; i < 7; i++)
- if (edid[i] != 0xFF)
- return;
-
- analogue = !(edid[20] & 0x80);
- if (!analogue)
- output->colourspace = COLOURSPACE_RGB;
- else
- switch ((edid[24] >> 3) & 3)
- {
- case 0: output->colourspace = COLOURSPACE_GREY; break;
- case 1: output->colourspace = COLOURSPACE_RGB; break;
- case 2: output->colourspace = COLOURSPACE_NON_RGB; break;
- default: output->colourspace = COLOURSPACE_UNKNOWN; break;
- }
-
- if (output->colourspace != COLOURSPACE_RGB)
- return;
-
- if (edid[24] & 4)
- output->colourspace = COLOURSPACE_SRGB;
-
- output->red_x = (edid[25] >> 6) & 3;
- output->red_y = (edid[25] >> 4) & 3;
- output->green_x = (edid[25] >> 2) & 3;
- output->green_y = (edid[25] >> 0) & 3;
- output->blue_x = (edid[26] >> 6) & 3;
- output->blue_y = (edid[26] >> 4) & 3;
- output->white_x = (edid[26] >> 2) & 3;
- output->white_y = (edid[26] >> 0) & 3;
-
- output->red_x |= ((unsigned)(edid[27])) << 2;
- output->red_y |= ((unsigned)(edid[28])) << 2;
- output->green_x |= ((unsigned)(edid[29])) << 2;
- output->green_y |= ((unsigned)(edid[30])) << 2;
- output->blue_x |= ((unsigned)(edid[31])) << 2;
- output->blue_y |= ((unsigned)(edid[32])) << 2;
- output->white_x |= ((unsigned)(edid[33])) << 2;
- output->white_y |= ((unsigned)(edid[34])) << 2;
-
- if ((output->red_x == output->red_y) &&
- (output->red_x == output->green_x) &&
- (output->red_x == output->green_y) &&
- (output->red_x == output->blue_x) &&
- (output->red_x == output->blue_y) &&
- (output->red_x == output->white_x) &&
- (output->red_x == output->white_y))
- {
- if (output->colourspace == COLOURSPACE_SRGB)
- output->colourspace = COLOURSPACE_SRGB_SANS_GAMUT;
- else
- output->colourspace = COLOURSPACE_RGB_SANS_GAMUT;
- }
-}
-
-
-/**
- * Store all current gamma ramps
- *
- * @return Zero on success, -1 on error
- */
-int initialise_gamma_info(void)
-{
- libgamma_crtc_information_t info;
- int saved_errno;
- size_t i;
-
- for (i = 0; i < outputs_n; i++)
- {
- libgamma_get_crtc_information(&info, crtcs + i,
- LIBGAMMA_CRTC_INFO_EDID |
- LIBGAMMA_CRTC_INFO_MACRO_RAMP |
- LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT |
- LIBGAMMA_CRTC_INFO_CONNECTOR_NAME);
- outputs[i].depth = info.gamma_depth_error ? 0 : info.gamma_depth;
- outputs[i].red_size = info.gamma_size_error ? 0 : info.red_gamma_size;
- outputs[i].green_size = info.gamma_size_error ? 0 : info.green_gamma_size;
- outputs[i].blue_size = info.gamma_size_error ? 0 : info.blue_gamma_size;
- outputs[i].supported = info.gamma_support_error ? 0 : info.gamma_support;
- if (info.gamma_support_error == LIBGAMMA_CRTC_INFO_NOT_SUPPORTED)
- outputs[i].supported = LIBGAMMA_MAYBE;
- if (outputs[i].depth == 0 || outputs[i].red_size == 0 ||
- outputs[i].green_size == 0 || outputs[i].blue_size == 0)
- outputs[i].supported = 0;
- parse_edid(outputs + i, info.edid_error ? NULL : info.edid, info.edid_error ? 0 : info.edid_length);
- outputs[i].name = get_crtc_name(&info, crtcs + i);
- saved_errno = errno;
- outputs[i].name_is_edid = ((info.edid_error == 0) && (info.edid != NULL));
- outputs[i].crtc = crtcs + i;
- libgamma_crtc_information_destroy(&info);
- outputs[i].ramps_size = outputs[i].red_size + outputs[i].green_size + outputs[i].blue_size;
- switch (outputs[i].depth)
- {
- default:
- outputs[i].depth = 64;
- /* Fall through */
- case 8:
- case 16:
- case 32:
- case 64: outputs[i].ramps_size *= (size_t)(outputs[i].depth / 8); break;
- case -2: outputs[i].ramps_size *= sizeof(double); break;
- case -1: outputs[i].ramps_size *= sizeof(float); break;
- }
- errno = saved_errno;
- if (outputs[i].name == NULL)
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * Store all current gamma ramps
- */
-void store_gamma(void)
-{
- int gerror;
- size_t i;
-
-#define LOAD_RAMPS(SUFFIX, MEMBER) \
- do \
- { \
- libgamma_gamma_ramps##SUFFIX##_initialise(&(outputs[i].saved_ramps.MEMBER)); \
- gerror = libgamma_crtc_get_gamma_ramps##SUFFIX(outputs[i].crtc, &(outputs[i].saved_ramps.MEMBER)); \
- if (gerror) \
- { \
- libgamma_perror(argv0, gerror); \
- outputs[i].supported = LIBGAMMA_NO; \
- libgamma_gamma_ramps##SUFFIX##_destroy(&(outputs[i].saved_ramps.MEMBER)); \
- memset(&(outputs[i].saved_ramps.MEMBER), 0, sizeof(outputs[i].saved_ramps.MEMBER)); \
- } \
- } \
- while (0)
-
- for (i = 0; i < outputs_n; i++)
- {
- if (outputs[i].supported == LIBGAMMA_NO)
- continue;
-
- outputs[i].saved_ramps.u8.red_size = outputs[i].red_size;
- outputs[i].saved_ramps.u8.green_size = outputs[i].green_size;
- outputs[i].saved_ramps.u8.blue_size = outputs[i].blue_size;
-
- switch (outputs[i].depth)
- {
- case 64: LOAD_RAMPS(64, u64); break;
- case 32: LOAD_RAMPS(32, u32); break;
- case 16: LOAD_RAMPS(16, u16); break;
- case 8: LOAD_RAMPS( 8, u8); break;
- case -2: LOAD_RAMPS(d, d); break;
- case -1: LOAD_RAMPS(f, f); break;
- default: /* impossible */ break;
- }
- }
-}
-
-
-/**
- * Restore all gamma ramps
- */
-void restore_gamma(void)
-{
- size_t i;
- int gerror;
-
-#define RESTORE_RAMPS(SUFFIX, MEMBER) \
- do \
- if (outputs[i].saved_ramps.MEMBER.red != NULL) \
- { \
- gerror = libgamma_crtc_set_gamma_ramps##SUFFIX(outputs[i].crtc, outputs[i].saved_ramps.MEMBER); \
- if (gerror) \
- libgamma_perror(argv0, gerror); \
- } \
- while (0)
-
- for (i = 0; i < outputs_n; i++)
- {
- if (outputs[i].supported == LIBGAMMA_NO)
- continue;
- if (outputs[i].saved_ramps.u8.red == NULL)
- continue;
-
- switch (outputs[i].depth)
- {
- case 64: RESTORE_RAMPS(64, u64); break;
- case 32: RESTORE_RAMPS(32, u32); break;
- case 16: RESTORE_RAMPS(16, u16); break;
- case 8: RESTORE_RAMPS( 8, u8); break;
- case -2: RESTORE_RAMPS(d, d); break;
- case -1: RESTORE_RAMPS(f, f); break;
- default: /* impossible */ break;
- }
- }
-}
-
-
-/**
- * Reapplu all gamma ramps
- */
-void reapply_gamma(void)
-{
- union gamma_ramps plain;
- size_t i;
-
- /* Reapply gamma ramps */
- for (i = 0; i < outputs_n; i++)
- {
- struct output* output = outputs + i;
- if (output->table_size > 0)
- set_gamma(output, output->table_sums + output->table_size - 1);
- else
- {
- make_plain_ramps(&plain, output);
- set_gamma(output, &plain);
- libgamma_gamma_ramps8_destroy(&(plain.u8));
- }
- }
-}
-
diff --git a/src/servers/gamma.h b/src/servers/gamma.h
deleted file mode 100644
index ac269e0..0000000
--- a/src/servers/gamma.h
+++ /dev/null
@@ -1,85 +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/>.
- */
-#ifndef SERVERS_GAMMA_H
-#define SERVERS_GAMMA_H
-
-
-#include "../types/output.h"
-
-#include <stddef.h>
-
-
-
-#ifndef GCC_ONLY
-# if defined(__GNUC__) && !defined(__clang__)
-# define GCC_ONLY(...) __VA_ARGS__
-# else
-# define GCC_ONLY(...) /* nothing */
-# endif
-#endif
-
-
-
-/**
- * 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
- * @return Zero on success (even if ignored), -1 on error,
- * 1 if connection closed
- */
-GCC_ONLY(__attribute__((nonnull(2))))
-int handle_get_gamma_info(size_t conn, const char* restrict message_id, const char* restrict crtc);
-
-/**
- * Set the gamma ramps on an output
- *
- * @param output The output
- * @param ramps The gamma ramps
- */
-GCC_ONLY(__attribute__((nonnull)))
-void set_gamma(const struct output* restrict output, const union gamma_ramps* restrict ramps);
-
-
-/**
- * Store all current gamma ramps
- *
- * @return Zero on success, -1 on error
- */
-int initialise_gamma_info(void);
-
-/**
- * Store all current gamma ramps
- */
-void store_gamma(void);
-
-/**
- * Restore all gamma ramps
- */
-void restore_gamma(void);
-
-
-/**
- * Reapplu all gamma ramps
- */
-void reapply_gamma(void);
-
-
-#endif
-
diff --git a/src/servers/kernel.c b/src/servers/kernel.c
deleted file mode 100644
index 1600d0a..0000000
--- a/src/servers/kernel.c
+++ /dev/null
@@ -1,384 +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 "kernel.h"
-#include "../state.h"
-#include "../util.h"
-
-#include <libgamma.h>
-
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-/**
- * Get the pathname of the runtime file
- *
- * @param suffix The suffix for the file
- * @return The pathname of the file, `NULL` on error
- */
-GCC_ONLY(__attribute__((malloc, nonnull)))
-static char* get_pathname(const char* restrict suffix)
-{
- const char* restrict rundir = getenv("XDG_RUNTIME_DIR");
- const char* restrict username = "";
- char* name = NULL;
- char* p;
- char* restrict rc;
- struct passwd* restrict pw;
- size_t n;
- int saved_errno;
-
- if (sitename)
- {
- name = memdup(sitename, strlen(sitename) + 1);
- if (name == NULL)
- goto fail;
- }
- else if ((name = libgamma_method_default_site(method)))
- {
- name = memdup(name, strlen(name) + 1);
- if (name == NULL)
- goto fail;
- }
-
- if (name != NULL)
- switch (method)
- {
- case LIBGAMMA_METHOD_X_RANDR:
- case LIBGAMMA_METHOD_X_VIDMODE:
- if ((p = strrchr(name, ':')))
- if ((p = strchr(p, '.')))
- *p = '\0';
- break;
- default:
- break;
- }
-
- if (!rundir || !*rundir)
- rundir = "/tmp";
-
- if ((pw = getpwuid(getuid())))
- username = pw->pw_name ? pw->pw_name : "";
-
- n = sizeof("/.coopgammad/~/.") + 3 * sizeof(int);
- n += strlen(rundir) + strlen(username) + ((name != NULL) ? strlen(name) : 0) + strlen(suffix);
- if (!(rc = malloc(n)))
- goto fail;
- sprintf(rc, "%s/.coopgammad/~%s/%i%s%s%s",
- rundir, username, method, name ? "." : "", name ? name : "", suffix);
- free(name);
- return rc;
-
- fail:
- saved_errno = errno;
- free(name);
- errno = saved_errno;
- return NULL;
-}
-
-
-/**
- * Get the pathname of the socket
- *
- * @return The pathname of the socket, `NULL` on error
- */
-char* get_socket_pathname(void)
-{
- return get_pathname(".socket");
-}
-
-
-/**
- * Get the pathname of the PID file
- *
- * @return The pathname of the PID file, `NULL` on error
- */
-char* get_pidfile_pathname(void)
-{
- return get_pathname(".pid");
-}
-
-
-/**
- * Get the pathname of the state file
- *
- * @return The pathname of the state file, `NULL` on error
- */
-char* get_state_pathname(void)
-{
- return get_pathname(".state");
-}
-
-
-/**
- * Check whether a PID file is outdated
- *
- * @param pidpath The PID file
- * @param token An environment variable (including both key and value)
- * that must exist in the process if it is a coopgammad process
- * @return -1: An error occurred
- * 0: The service is already running
- * 1: The PID file is outdated
- */
-GCC_ONLY(__attribute__((nonnull)))
-static int is_pidfile_reusable(const char* restrict pidpath, const char* restrict token)
-{
- /* PORTERS: /proc/$PID/environ is Linux specific */
-
- char temp[sizeof("/proc//environ") + 3 * sizeof(long long int)];
- int fd = -1, saved_errno, tries = 0;
- char* content = NULL;
- char* p;
- pid_t pid = 0;
- size_t n;
-#if defined(HAVE_LINUX_PROCFS)
- char* end;
-#else
- (void) token;
-#endif
-
- /* Get PID */
- retry:
- fd = open(pidpath, O_RDONLY);
- if (fd < 0)
- return -1;
- content = nread(fd, &n);
- if (content == NULL)
- goto fail;
- close(fd), fd = -1;
-
- if (n == 0)
- {
- if (++tries > 1)
- goto bad;
- msleep(100); /* 1 tenth of a second */
- goto retry;
- }
-
- if (('0' > content[0]) || (content[0] > '9'))
- goto bad;
- if ((content[0] == '0') && ('0' <= content[1]) && (content[1] <= '9'))
- goto bad;
- for (p = content; *p; p++)
- if (('0' <= *p) && (*p <= '9'))
- pid = pid * 10 + (*p & 15);
- else
- break;
- if (*p++ != '\n')
- goto bad;
- if (*p)
- goto bad;
- if ((size_t)(p - content) != n)
- goto bad;
- sprintf(temp, "%llu\n", (unsigned long long)pid);
- if (strcmp(content, temp))
- goto bad;
- free(content);
-
- /* Validate PID */
-#if defined(HAVE_LINUX_PROCFS)
- sprintf(temp, "/proc/%llu/environ", (unsigned long long)pid);
- fd = open(temp, O_RDONLY);
- if (fd < 0)
- return ((errno == ENOENT) || (errno == EACCES)) ? 1 : -1;
- content = nread(fd, &n);
- if (content == NULL)
- goto fail;
- close(fd), fd = -1;
-
- for (end = (p = content) + n; p != end; p = strchr(p, '\0') + 1)
- if (!strcmp(p, token))
- return free(content), 0;
- free(content);
-#else
- if ((kill(pid, 0) == 0) || (errno == EINVAL))
- return 0;
-#endif
-
- return 1;
- bad:
- fprintf(stderr, "%s: pid file contains invalid content: %s\n", argv0, pidpath);
- errno = 0;
- return -1;
- fail:
- saved_errno = errno;
- free(content);
- if (fd >= 0)
- close(fd);
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * Create PID file
- *
- * @param pidpath The pathname of the PID file
- * @return Zero on success, -1 on error,
- * -2 if the service is already running
- */
-int create_pidfile(char* pidpath)
-{
- int fd = -1, r, saved_errno;
- char* p;
- char* restrict token = NULL;
-
- /* Create token used to validate the service. */
- token = malloc(sizeof("COOPGAMMAD_PIDFILE_TOKEN=") + strlen(pidpath));
- if (token == NULL)
- return -1;
- sprintf(token, "COOPGAMMAD_PIDFILE_TOKEN=%s", pidpath);
-#if !defined(USE_VALGRIND)
- if (putenv(token))
- goto putenv_fail;
- /* `token` must not be free! */
-#else
- {
- static char static_token[sizeof("COOPGAMMAD_PIDFILE_TOKEN=") + PATH_MAX];
- if (strlen(pidpath) > PATH_MAX)
- abort();
- strcpy(static_token, token);
- if (putenv(static_token))
- goto fail;
- }
-#endif
-
- /* Create PID file's directory. */
- for (p = pidpath; *p == '/'; p++);
- while ((p = strchr(p, '/')))
- {
- *p = '\0';
- if (mkdir(pidpath, 0755) < 0)
- if (errno != EEXIST)
- {
- *p = '/';
- goto fail;
- }
- *p++ = '/';
- }
-
- /* Create PID file. */
- retry:
- fd = open(pidpath, O_CREAT | O_EXCL | O_WRONLY, 0644);
- if (fd < 0)
- {
- if (errno == EINTR)
- goto retry;
- if (errno != EEXIST)
- return -1;
- r = is_pidfile_reusable(pidpath, token);
- if (r > 0)
- {
- unlink(pidpath);
- goto retry;
- }
- else if (r < 0)
- goto fail;
- fprintf(stderr, "%s: service is already running\n", argv0);
- errno = 0;
- return -2;
- }
-
- /* Write PID to PID file. */
- if (dprintf(fd, "%llu\n", (unsigned long long)getpid()) < 0)
- goto fail;
-
- /* Done */
-#if defined(USE_VALGRIND)
- free(token);
-#endif
- if (close(fd) < 0)
- if (errno != EINTR)
- return -1;
- return 0;
-#if !defined(USE_VALGRIND)
- putenv_fail:
- saved_errno = errno;
- free(token);
- errno = saved_errno;
-#endif
- fail:
- saved_errno = errno;
-#if defined(USE_VALGRIND)
- free(token);
-#endif
- if (fd >= 0)
- {
- close(fd);
- unlink(pidpath);
- }
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * Create socket and start listening
- *
- * @param socketpath The pathname of the socket
- * @return Zero on success, -1 on error
- */
-int create_socket(const char* socketpath)
-{
- struct sockaddr_un address;
-
- address.sun_family = AF_UNIX;
- if (strlen(socketpath) >= sizeof(address.sun_path))
- {
- errno = ENAMETOOLONG;
- return -1;
- }
- strcpy(address.sun_path, socketpath);
- unlink(socketpath);
- if ((socketfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- return -1;
- if (fchmod(socketfd, S_IRWXU) < 0)
- return -1;
- if (bind(socketfd, (struct sockaddr*)(&address), (socklen_t)sizeof(address)) < 0)
- return -1;
- if (listen(socketfd, SOMAXCONN) < 0)
- return -1;
-
- return 0;
-}
-
-
-/**
- * Close and unlink the socket
- *
- * @param socketpath The pathname of the socket
- */
-void close_socket(const char* socketpath)
-{
- if (socketfd >= 0)
- {
- shutdown(socketfd, SHUT_RDWR);
- close(socketfd);
- unlink(socketpath);
- }
-}
-
diff --git a/src/servers/kernel.h b/src/servers/kernel.h
deleted file mode 100644
index 494e150..0000000
--- a/src/servers/kernel.h
+++ /dev/null
@@ -1,85 +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/>.
- */
-#ifndef SERVERS_KERNEL_H
-#define SERVERS_KERNEL_H
-
-
-#ifndef GCC_ONLY
-# if defined(__GNUC__) && !defined(__clang__)
-# define GCC_ONLY(...) __VA_ARGS__
-# else
-# define GCC_ONLY(...) /* nothing */
-# endif
-#endif
-
-
-
-/**
- * Get the pathname of the socket
- *
- * @return The pathname of the socket, `NULL` on error
- */
-GCC_ONLY(__attribute__((malloc)))
-char* get_socket_pathname(void);
-
-/**
- * Get the pathname of the PID file
- *
- * @return The pathname of the PID file, `NULL` on error
- */
-GCC_ONLY(__attribute__((malloc)))
-char* get_pidfile_pathname(void);
-
-/**
- * Get the pathname of the state file
- *
- * @return The pathname of the state file, `NULL` on error
- */
-GCC_ONLY(__attribute__((malloc)))
-char* get_state_pathname(void);
-
-/**
- * Create PID file
- *
- * @param pidpath The pathname of the PID file
- * @return Zero on success, -1 on error,
- * -2 if the service is already running
- */
-GCC_ONLY(__attribute__((nonnull)))
-int create_pidfile(char* pidpath);
-
-/**
- * Create socket and start listening
- *
- * @param socketpath The pathname of the socket
- * @return Zero on success, -1 on error
- */
-GCC_ONLY(__attribute__((nonnull)))
-int create_socket(const char* socketpath);
-
-/**
- * Close and unlink the socket
- *
- * @param socketpath The pathname of the socket
- */
-GCC_ONLY(__attribute__((nonnull)))
-void close_socket(const char* socketpath);
-
-
-#endif
-
diff --git a/src/servers/master.c b/src/servers/master.c
deleted file mode 100644
index 01b9bb5..0000000
--- a/src/servers/master.c
+++ /dev/null
@@ -1,394 +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 "master.h"
-#include "crtc.h"
-#include "gamma.h"
-#include "coopgamma.h"
-#include "../util.h"
-#include "../communication.h"
-#include "../state.h"
-
-#include <sys/socket.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-/**
- * All poll(3p) events that are not for writing
- */
-#define NON_WR_POLL_EVENTS (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLERR | POLLHUP | POLLNVAL)
-
-
-/**
- * Extract headers from an inbound message and pass
- * them on to appropriate message handling function
- *
- * @param conn The index of the connection
- * @param msg The inbound message
- * @return 1: The connection as closed
- * 0: Successful
- * -1: Failure
- */
-static int dispatch_message(size_t conn, struct message* restrict msg)
-{
- size_t i;
- int r = 0;
- const char* header;
- const char* value;
- const char* command = NULL;
- const char* crtc = NULL;
- const char* coalesce = NULL;
- const char* high_priority = NULL;
- const char* low_priority = NULL;
- const char* priority = NULL;
- const char* class = NULL;
- const char* lifespan = NULL;
- const char* message_id = NULL;
-
- for (i = 0; i < msg->header_count; i++)
- {
- value = strstr((header = msg->headers[i]), ": ") + 2;
- if (strstr(header, "Command: ") == header) command = value;
- else if (strstr(header, "CRTC: ") == header) crtc = value;
- else if (strstr(header, "Coalesce: ") == header) coalesce = value;
- else if (strstr(header, "High priority: ") == header) high_priority = value;
- else if (strstr(header, "Low priority: ") == header) low_priority = value;
- else if (strstr(header, "Priority: ") == header) priority = value;
- else if (strstr(header, "Class: ") == header) class = value;
- else if (strstr(header, "Lifespan: ") == header) lifespan = value;
- else if (strstr(header, "Message ID: ") == header) message_id = value;
- else if (strstr(header, "Length: ") == header) ;/* Handled transparently */
- else
- fprintf(stderr, "%s: ignoring unrecognised header: %s\n", argv0, header);
- }
-
- if (command == NULL)
- fprintf(stderr, "%s: ignoring message without Command header\n", argv0);
- else if (message_id == NULL)
- fprintf(stderr, "%s: ignoring message without Message ID header\n", argv0);
- else if (!strcmp(command, "enumerate-crtcs"))
- {
- if (crtc || coalesce || high_priority || low_priority || priority || class || lifespan)
- fprintf(stderr, "%s: ignoring superfluous headers in Command: enumerate-crtcs message\n", argv0);
- r = handle_enumerate_crtcs(conn, message_id);
- }
- else if (!strcmp(command, "get-gamma-info"))
- {
- if (coalesce || high_priority || low_priority || priority || class || lifespan)
- fprintf(stderr, "%s: ignoring superfluous headers in Command: get-gamma-info message\n", argv0);
- r = handle_get_gamma_info(conn, message_id, crtc);
- }
- else if (!strcmp(command, "get-gamma"))
- {
- if (priority || class || lifespan)
- fprintf(stderr, "%s: ignoring superfluous headers in Command: get-gamma message\n", argv0);
- r = handle_get_gamma(conn, message_id, crtc, coalesce, high_priority, low_priority);
- }
- else if (!strcmp(command, "set-gamma"))
- {
- if (coalesce || high_priority || low_priority)
- fprintf(stderr, "%s: ignoring superfluous headers in Command: set-gamma message\n", argv0);
- r = handle_set_gamma(conn, message_id, crtc, priority, class, lifespan);
- }
- else
- fprintf(stderr, "%s: ignoring unrecognised command: Command: %s\n", argv0, command);
-
- return r;
-}
-
-
-/**
- * Sets the file descriptor set that includes
- * the server socket and all connections
- *
- * The file descriptor will be ordered as in
- * the array `connections`, `socketfd` will
- * be last.
- *
- * @param fds Reference parameter for the array of file descriptors
- * @param fdn Output parameter for the number of file descriptors
- * @param fds_alloc Reference parameter for the allocation size of `fds`, in elements
- * @return Zero on success, -1 on error
- */
-static int update_fdset(struct pollfd** restrict fds, nfds_t* restrict fdn, nfds_t* restrict fds_alloc)
-{
- size_t i;
- nfds_t j = 0;
-
- if (connections_used + 1 > *fds_alloc)
- {
- void* new = realloc(*fds, (connections_used + 1) * sizeof(**fds));
- if (new == NULL)
- return -1;
- *fds = new;
- *fds_alloc = connections_used + 1;
- }
-
- for (i = 0; i < connections_used; i++)
- if (connections[i] >= 0)
- {
- (*fds)[j].fd = connections[i];
- (*fds)[j].events = NON_WR_POLL_EVENTS;
- j++;
- }
-
- (*fds)[j].fd = socketfd;
- (*fds)[j].events = NON_WR_POLL_EVENTS;
- j++;
-
- *fdn = j;
- return 0;
-}
-
-
-/**
- * Handle event on the server socket
- *
- * @return 1: New connection accepted
- * 0: Successful
- * -1: Failure
- */
-static int handle_server(void)
-{
- int fd, flags, saved_errno;
-
- fd = accept(socketfd, NULL, NULL);
- if (fd < 0)
- switch (errno)
- {
- case EINTR:
- return 0;
- case ECONNABORTED:
- case EINVAL:
- terminate = 1;
- return 0;
- default:
- return -1;
- }
-
- flags = fcntl(fd, F_GETFL);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
- goto fail;
-
- if (connections_ptr == connections_alloc)
- {
- void* new;
-
- new = realloc(connections, (connections_alloc + 10) * sizeof(*connections));
- if (new == NULL)
- goto fail;
- connections = new;
- connections[connections_ptr] = fd;
-
- new = realloc(outbound, (connections_alloc + 10) * sizeof(*outbound));
- if (new == NULL)
- goto fail;
- outbound = new;
- ring_initialise(outbound + connections_ptr);
-
- new = realloc(inbound, (connections_alloc + 10) * sizeof(*inbound));
- if (new == NULL)
- goto fail;
- inbound = new;
- connections_alloc += 10;
- if (message_initialise(inbound + connections_ptr))
- goto fail;
- }
- else
- {
- connections[connections_ptr] = fd;
- ring_initialise(outbound + connections_ptr);
- if (message_initialise(inbound + connections_ptr))
- goto fail;
- }
-
- connections_ptr++;
- while ((connections_ptr < connections_used) && (connections[connections_ptr] >= 0))
- connections_ptr++;
- if (connections_used < connections_ptr)
- connections_used = connections_ptr;
-
- return 1;
- fail:
- saved_errno = errno;
- shutdown(fd, SHUT_RDWR);
- close(fd);
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * Handle event on a connection to a client
- *
- * @param conn The index of the connection
- * @return 1: The connection as closed
- * 0: Successful
- * -1: Failure
- */
-static int handle_connection(size_t conn)
-{
- struct message* restrict msg = inbound + conn;
- int r, fd = connections[conn];
-
- again:
- switch (message_read(msg, fd))
- {
- default:
- break;
- case -1:
- switch (errno)
- {
- case EINTR:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- return 0;
- default:
- return -1;
- case ECONNRESET:;
- /* Fall throught to `case -2` in outer switch */
- }
- case -2:
- shutdown(fd, SHUT_RDWR);
- close(fd);
- connections[conn] = -1;
- if (conn < connections_ptr)
- connections_ptr = conn;
- while ((connections_used > 0) && (connections[connections_used - 1] < 0))
- connections_used -= 1;
- message_destroy(msg);
- ring_destroy(outbound + conn);
- if (connection_closed(fd) < 0)
- return -1;
- return 1;
- }
-
- if ((r = dispatch_message(conn, msg)))
- return r;
-
- goto again;
-}
-
-
-
-/**
- * Disconnect all clients
- */
-void disconnect_all(void)
-{
- size_t i;
- for (i = 0; i < connections_used; i++)
- if (connections[i] >= 0)
- {
- shutdown(connections[i], SHUT_RDWR);
- close(connections[i]);
- }
-}
-
-
-/**
- * The program's main loop
- *
- * @return Zero on success, -1 on error
- */
-int main_loop(void)
-{
- struct pollfd* fds = NULL;
- nfds_t i, fdn = 0, fds_alloc = 0;
- int r, update, saved_errno;
- size_t j;
-
- if (update_fdset(&fds, &fdn, &fds_alloc) < 0)
- goto fail;
-
- while (!reexec && !terminate)
- {
- if (connection)
- {
- if ((connection == 1 ? disconnect() : reconnect()) < 0)
- {
- connection = 0;
- goto fail;
- }
- connection = 0;
- }
-
- for (j = 0, i = 0; j < connections_used; j++)
- if (connections[j] >= 0)
- {
- fds[i].revents = 0;
- if (ring_have_more(outbound + j))
- fds[(size_t)i++ + j].events |= POLLOUT;
- else
- fds[(size_t)i++ + j].events &= ~POLLOUT;
- }
- fds[i].revents = 0;
-
- if (poll(fds, fdn, -1) < 0)
- {
- if (errno == EAGAIN)
- perror(argv0);
- else if (errno != EINTR)
- goto fail;
- }
-
- update = 0;
- for (i = 0; i < fdn; i++)
- {
- int do_read = fds[i].revents & NON_WR_POLL_EVENTS;
- int do_write = fds[i].revents & POLLOUT;
- int fd = fds[i].fd;
- if (!do_read && !do_write)
- continue;
-
- if (fd == socketfd)
- r = handle_server();
- else
- {
- for (j = 0; connections[j] != fd; j++);
- r = do_read ? handle_connection(j) : 0;
- }
-
- if ((r >= 0) && do_write)
- r |= continue_send(j);
- if (r < 0)
- goto fail;
- update |= (r > 0);
- }
- if (update)
- if (update_fdset(&fds, &fdn, &fds_alloc) < 0)
- goto fail;
- }
-
- free(fds);
- return 0;
- fail:
- saved_errno = errno;
- free(fds);
- errno = saved_errno;
- return -1;
-}
-
diff --git a/src/servers/master.h b/src/servers/master.h
deleted file mode 100644
index d7ef6e5..0000000
--- a/src/servers/master.h
+++ /dev/null
@@ -1,36 +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/>.
- */
-#ifndef SERVERS_MASTER_H
-#define SERVERS_MASTER_H
-
-
-/**
- * Disconnect all clients
- */
-void disconnect_all(void);
-
-/**
- * The program's main loop
- *
- * @return Zero on success, -1 on error
- */
-int main_loop(void);
-
-
-#endif
-