aboutsummaryrefslogtreecommitdiffstats
path: root/src/cg-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cg-base.c')
-rw-r--r--src/cg-base.c927
1 files changed, 0 insertions, 927 deletions
diff --git a/src/cg-base.c b/src/cg-base.c
deleted file mode 100644
index 9f77937..0000000
--- a/src/cg-base.c
+++ /dev/null
@@ -1,927 +0,0 @@
-/**
- * cg-tools -- Cooperative gamma-enabled tools
- * Copyright (C) 2016, 2018 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 "cg-base.h"
-
-#include <libclut.h>
-
-#include <alloca.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
-/**
- * The process's name
- */
-const char* argv0 = NULL;
-
-/**
- * The libcoopgamma context
- */
-libcoopgamma_context_t cg;
-
-/**
- * The names of the selected CRTC:s
- */
-char** crtcs = NULL;
-
-/**
- * Gamma ramp updates for each CRTC
- */
-filter_update_t* crtc_updates = NULL;
-
-/**
- * CRTC and monitor information about
- * each selected CRTC and connect monitor
- */
-libcoopgamma_crtc_info_t* crtc_info = NULL;
-
-/**
- * The number of selected CRTC:s
- */
-size_t crtcs_n = 0;
-
-/**
- * The number of filters
- */
-size_t filters_n = 0;
-
-
-/**
- * Contexts for asynchronous ramp updates
- */
-static libcoopgamma_async_context_t* asyncs = NULL;
-
-/**
- * The number of pending receives
- */
-static size_t pending_recvs = 0;
-
-/**
- * Whether message must be flushed
- */
-static int flush_pending = 0;
-
-
-
-/**
- * Data used to sort CRTC:s
- */
-struct crtc_sort_data
-{
- /**
- * The gamma ramp type
- */
- libcoopgamma_depth_t depth;
-
- /**
- * Should be 0
- */
- int __padding;
-
- /**
- * The size of the red gamma ramp
- */
- size_t red_size;
-
- /**
- * The size of the green gamma ramp
- */
- size_t green_size;
-
- /**
- * The size of the blue gamma ramp
- */
- size_t blue_size;
-
- /**
- * The index of the CRTC
- */
- size_t index;
-};
-
-
-
-/**
- * Compare two strings
- *
- * @param a Return -1 if this string is `NULL` or less than `b`
- * @param b Return +1 if this string is less than `a`
- * @return See `a` and `b`, 0 is returned if `a` and `b` are equal
- */
-static int nulstrcmp(const char *a, const char *b)
-{
- return (a == NULL) ? -1 : strcmp(a, b);
-}
-
-
-/**
- * Compare two instances of `crtc_sort_data`
- *
- * @param a_ Return -1 if this one is lower
- * @param b_ Return +1 if this one is higher
- * @return See `a_` and `b_`, only -1 or +1 can be returned
- */
-static int crtc_sort_data_cmp(const void* a_, const void* b_)
-{
- const struct crtc_sort_data* a = a_;
- const struct crtc_sort_data* b = b_;
- int cmp = memcmp(a, b, sizeof(*a) - sizeof(a->index));
- return cmp ? cmp : a->index < b->index ? -1 : +1;
-}
-
-
-/**
- * Make elements in `crtc_updates` slaves where appropriate
- *
- * @return Zero on success, -1 on error
- */
-int make_slaves(void)
-{
- struct crtc_sort_data* data;
- size_t i, j, n = 0, master = 0, master_i;
-
- data = alloca(filters_n * sizeof(*data));
- memset(data, 0, filters_n * sizeof(*data));
- for (i = 0; i < filters_n; i++)
- {
- if (!(crtc_info[crtc_updates[i].crtc].supported))
- continue;
-
- data[n].depth = crtc_updates[i].filter.depth;
- data[n].red_size = crtc_updates[i].filter.ramps.u8.red_size;
- data[n].green_size = crtc_updates[i].filter.ramps.u8.green_size;
- data[n].blue_size = crtc_updates[i].filter.ramps.u8.blue_size;
- data[n].index = i;
- n++;
- }
-
- qsort(data, n, sizeof(*data), crtc_sort_data_cmp);
- if (n == 0)
- return 0;
-
- master_i = data[0].index;
- for (i = 1; i < n; i++)
- if (memcmp(data + i, data + master, sizeof(*data) - sizeof(data->index)))
- {
- if (master + 1 < i)
- {
- crtc_updates[master_i].slaves = calloc(i - master, sizeof(size_t));
- if (crtc_updates[master_i].slaves == NULL)
- return -1;
- for (j = 1; master + j < i; j++)
- crtc_updates[master_i].slaves[j - 1] = data[master + j].index;
- }
- master = i;
- master_i = data[master].index;
- }
- else
- {
- libcoopgamma_ramps_destroy(&(crtc_updates[data[i].index].filter.ramps.u8));
- crtc_updates[data[i].index].master = 0;
- crtc_updates[data[i].index].filter.ramps.u8 = crtc_updates[master_i].filter.ramps.u8;
- }
-
- if (master + 1 < i)
- {
- crtc_updates[master_i].slaves = calloc(i - master, sizeof(size_t));
- if (crtc_updates[master_i].slaves == NULL)
- return -1;
- for (j = 1; master + j < i; j++)
- crtc_updates[master_i].slaves[j - 1] = data[master + j].index;
- }
-
- return 0;
-}
-
-
-/**
- * Update a filter and synchronise calls
- *
- * @param index The index of the CRTC
- * @param timeout The number of milliseconds a call to `poll` may block,
- * -1 if it may block forever
- * @return 1: Success, no pending synchronisations
- * 0: Success, with still pending synchronisations
- * -1: Error, `errno` set
- * -2: Error, `cg.error` set
- *
- * @throws EINTR Call to `poll` was interrupted by a signal
- * @throws EAGAIN Call to `poll` timed out
- */
-int update_filter(size_t index, int timeout)
-{
- filter_update_t* filter = crtc_updates + index;
-
- if (!(filter->synced) || filter->failed)
- abort();
-
- pending_recvs += 1;
-
- if (libcoopgamma_set_gamma_send(&(filter->filter), &cg, asyncs + index) < 0)
- switch (errno)
- {
- case EINTR:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- flush_pending = 1;
- break;
- default:
- return -1;
- }
-
- filter->synced = 0;
- return synchronise(timeout);
-}
-
-
-/**
- * Synchronised calls
- *
- * @param timeout The number of milliseconds a call to `poll` may block,
- * -1 if it may block forever
- * @return 1: Success, no pending synchronisations
- * 0: Success, with still pending synchronisations
- * -1: Error, `errno` set
- * -2: Error, `cg.error` set
- *
- * @throws EINTR Call to `poll` was interrupted by a signal
- * @throws EAGAIN Call to `poll` timed out
- */
-int synchronise(int timeout)
-{
- struct pollfd pollfd;
- size_t selected;
-
- pollfd.fd = cg.fd;
- pollfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
- if (flush_pending > 0)
- pollfd.events |= POLLOUT;
-
- pollfd.revents = 0;
- if (poll(&pollfd, (nfds_t)1, timeout) < 0)
- return -1;
-
- if (pollfd.revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
- {
- if (libcoopgamma_flush(&cg) < 0)
- goto sync;
- flush_pending = 0;
- }
-
- if ((timeout < 0) && (pending_recvs > 0))
- if (!(pollfd.revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)))
- {
- pollfd.revents = 0;
- if (poll(&pollfd, (nfds_t)1, -1) < 0)
- return -1;
- }
-
- sync:
- if (pollfd.revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLERR | POLLHUP | POLLNVAL))
- for (;;)
- {
- if (libcoopgamma_synchronise(&cg, asyncs, filters_n, &selected) < 0)
- {
- if (errno == 0)
- continue;
- else
- goto fail;
- }
- if (crtc_updates[selected].synced)
- continue;
- crtc_updates[selected].synced = 1;
- pending_recvs -= 1;
- if (libcoopgamma_set_gamma_recv(&cg, asyncs + selected) < 0)
- {
- if (cg.error.server_side)
- {
- crtc_updates[selected].error = cg.error;
- crtc_updates[selected].failed = 1;
- memset(&(cg.error), 0, sizeof(cg.error));
- }
- else
- goto cg_fail;
- }
- }
-
- return pending_recvs == 0;
- cg_fail:
- return -2;
- fail:
- switch (errno)
- {
- case EINTR:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- return pending_recvs == 0;
- default:
- return -1;
- }
-}
-
-
-/**
- * Initialise the process, specifically
- * reset the signal mask and signal handlers
- *
- * @return Zero on success, -1 on error
- */
-static int initialise_proc(void)
-{
- sigset_t sigmask;
- int sig;
-
- for (sig = 1; sig < _NSIG; sig++)
- if (signal(sig, SIG_DFL) == SIG_ERR)
- if (sig == SIGCHLD)
- return -1;
-
- if (sigemptyset(&sigmask) < 0)
- return -1;
- if (sigprocmask(SIG_SETMASK, &sigmask, NULL) < 0)
- return -1;
-
- return 0;
-}
-
-
-/**
- * Print, to stdout, a list of all
- * recognised adjustment methods
- *
- * @return Zero on success, -1 on error
- */
-static int list_methods(void)
-{
- char** list;
- size_t i;
-
- list = libcoopgamma_get_methods();
- if (list == NULL)
- return -1;
- for (i = 0; list[i]; i++)
- printf("%s\n", list[i]);
- free(list);
- if (fflush(stdout) < 0)
- return -1;
-
- return 0;
-}
-
-
-/**
- * Print, to stdout, a list of all CRTC:s
- *
- * A connection to the coopgamma server
- * must have been made
- *
- * @return Zero on success, -1 on error, -2
- * on libcoopgamma error
- */
-static int list_crtcs(void)
-{
- char** list;
- size_t i;
-
- list = libcoopgamma_get_crtcs_sync(&cg);
- if (list == NULL)
- return -2;
- for (i = 0; list[i]; i++)
- printf("%s\n", list[i]);
- free(list);
- if (fflush(stdout) < 0)
- return -1;
-
- return 0;
-}
-
-
-/**
- * Fill the list of CRTC information
- *
- * @return Zero on success, -1 on error, -2
- * on libcoopgamma error
- */
-static int get_crtc_info(void)
-{
- size_t i, unsynced = 0, selected;
- char* synced;
- int need_flush = 0;
- struct pollfd pollfd;
-
- synced = alloca(crtcs_n * sizeof(*synced));
- memset(synced, 0, crtcs_n * sizeof(*synced));
-
- i = 0;
- pollfd.fd = cg.fd;
- pollfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
-
- while ((unsynced > 0) || (i < crtcs_n))
- {
- wait:
- if (i < crtcs_n)
- pollfd.events |= POLLOUT;
- else
- pollfd.events &= ~POLLOUT;
-
- pollfd.revents = 0;
- if (poll(&pollfd, (nfds_t)1, -1) < 0)
- goto fail;
-
- if (pollfd.revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
- {
- if (need_flush && (libcoopgamma_flush(&cg) < 0))
- goto send_fail;
- need_flush = 0;
- for (; i < crtcs_n; i++)
- if (unsynced++, libcoopgamma_get_gamma_info_send(crtcs[i], &cg, asyncs + i) < 0)
- goto send_fail;
- goto send_done;
- send_fail:
- switch (errno)
- {
- case EINTR:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- i++;
- need_flush = 1;
- break;
- default:
- goto fail;
- }
- }
- send_done:
-
- if ((unsynced == 0) && (i == crtcs_n))
- break;
-
- if (pollfd.revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI))
- while (unsynced > 0)
- switch (libcoopgamma_synchronise(&cg, asyncs, i, &selected))
- {
- case 0:
- if (synced[selected])
- {
- libcoopgamma_skip_message(&cg);
- break;
- }
- synced[selected] = 1;
- unsynced -= 1;
- if (libcoopgamma_get_gamma_info_recv(crtc_info + selected, &cg, asyncs + selected) < 0)
- goto cg_fail;
- break;
- case -1:
- switch (errno)
- {
- case 0:
- break;
- case EINTR:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- goto wait;
- default:
- goto fail;
- }
- break;
- }
- }
-
- return 0;
- fail:
- return -1;
- cg_fail:
- return -2;
-}
-
-
-/**
- * -M METHOD
- * Select adjustment method. If METHOD is "?",
- * available methods will be printed to stdout.
- *
- * -S SITE
- * Select site (display server instance).
- *
- * -c CRTC
- * Select CRT controller. If CRTC is "?", CRTC:s
- * will be printed to stdout.
- *
- * This option can be used multiple times. If it
- * is not used at all, all CRTC:s will be selected.
- *
- * -p PRIORITY
- * Select the priority for the filter, this should
- * be a signed two's-complement integer. If
- * PRIORITY is "?", the default priority for the
- * program is printed to stdout.
- *
- * -R RULE
- * The rule of the filter, that is, the last part
- * of the class which is its identifier. If RULE
- * is "?" the default rule is printed to stdout,
- * if RULE is "??" the default class is printed
- * to stdout.
- *
- * @param argc The number of command line arguments
- * @param argv The command line arguments
- * @return 0 on success, 1 on error
- */
-int main(int argc, char* argv[])
-{
- int stage = 0;
- int dealloc_crtcs = 0;
- int rc = 0;
- char* method = NULL;
- char* site = NULL;
- size_t crtc_i = 0;
- int64_t priority = default_priority;
- char* prio = NULL;
- char* rule = NULL;
- char* class = default_class;
- char** classes = NULL;
- size_t classes_n = 0;
- int explicit_crtcs = 0;
- int have_crtc_q = 0;
- size_t i, filter_i;
-
- argv0 = *argv++, argc--;
-
- if (initialise_proc() < 0)
- goto fail;
-
- crtcs = alloca(argc * sizeof(*crtcs));
-
- for (; *argv; argv++, argc--)
- {
- char* args = *argv;
- char opt[3];
- if (!strcmp(args, "--"))
- {
- argv++, argc--;
- break;
- }
- opt[0] = *args++;
- opt[2] = '\0';
- if ((*opt != '-') && (*opt != '+'))
- break;
- while (*args)
- {
- char* arg;
- int at_end;
- opt[1] = *args++;
- arg = args;
- if ((at_end = !*arg))
- arg = argv[1];
- if (!strcmp(opt, "-M"))
- {
- if ((method != NULL) || ((method = arg) == NULL))
- usage();
- }
- else if (!strcmp(opt, "-S"))
- {
- if ((site != NULL) || ((site = arg) == NULL))
- usage();
- }
- else if (!strcmp(opt, "-c"))
- {
- if (arg == NULL)
- usage();
- crtcs[crtc_i++] = arg;
- explicit_crtcs = 1;
- if (!have_crtc_q && !strcmp(arg, "?"))
- have_crtc_q = 1;
- }
- else if (!strcmp(opt, "-p"))
- {
- if ((prio != NULL) || ((prio = arg) == NULL))
- usage();
- }
- else if (!strcmp(opt, "-R"))
- {
- if ((rule != NULL) || ((rule = arg) == NULL))
- usage();
- }
- else
- switch (handle_opt(opt, arg))
- {
- case 0:
- goto next_opt;
- case 1:
- break;
- default:
- goto fail;
- }
- argv += at_end;
- argc -= at_end;
- break;
- next_opt:;
- }
- }
-
- crtcs_n = crtc_i;
- crtcs[crtc_i] = NULL;
- if (!have_crtc_q && nulstrcmp(method, "?") &&
- nulstrcmp(rule, "?") && nulstrcmp(rule, "??") &&
- ((default_priority == NO_DEFAULT_PRIORITY) || nulstrcmp(prio, "?")))
- if (handle_args(argc, argv, prio) < 0)
- goto fail;
-
- if (default_priority != NO_DEFAULT_PRIORITY)
- {
- if (!nulstrcmp(prio, "?"))
- {
- printf("%" PRIi64 "\n", priority);
- return 0;
- }
- else if (prio != NULL)
- {
- char *end;
- errno = 0;
- priority = (int64_t)strtoll(prio, &end, 10);
- if (errno || *end || !*prio)
- usage();
- }
- }
-
- if (!nulstrcmp(rule, "??"))
- {
- size_t i;
- if (*class_suffixes == NULL)
- printf("%s\n", class);
- else
- for (i = 0; class_suffixes[i] != NULL; i++)
- printf("%s%s\n", class, class_suffixes[i]);
- return 0;
- }
- else if (!nulstrcmp(rule, "?"))
- {
- printf("%s\n", strstr(strstr(class, "::") + 2, "::") + 2);
- return 0;
- }
- else if (rule != NULL)
- {
- char* p = strstr(strstr(class, "::") + 2, "::") + 2;
- size_t n = (size_t)(p - class);
- class = alloca(strlen(rule) + n + (size_t)1);
- memcpy(class, default_class, n);
- strcpy(class + n, rule);
- if (strchr(class, '\n'))
- {
- fprintf(stderr, "%s: LF character is not allowed in the filter's class\n", argv0);
- goto custom_fail;
- }
- }
-
- if (!nulstrcmp(method, "?"))
- {
- if (list_methods() < 0)
- goto fail;
- return 0;
- }
-
- if (libcoopgamma_context_initialise(&cg) < 0)
- goto fail;
- stage++;
- if (libcoopgamma_connect(method, site, &cg) < 0)
- {
- fprintf(stderr, "%s: server failed to initialise\n", argv0);
- goto custom_fail;
- }
- stage++;
-
- if (have_crtc_q)
- switch (list_crtcs())
- {
- case 0:
- goto done;
- case -1:
- goto fail;
- default:
- goto cg_fail;
- }
-
- if (crtcs_n == 0)
- {
- crtcs = libcoopgamma_get_crtcs_sync(&cg);
- if (crtcs == NULL)
- goto cg_fail;
- dealloc_crtcs = 1;
- for (; crtcs[crtcs_n] != NULL; crtcs_n++);
- }
-
- if (crtcs_n == 0)
- {
- fprintf(stderr, "%s: no CRTC:s are available\n", argv0);
- goto custom_fail;
- }
-
- if (*class_suffixes == NULL)
- {
- classes = &class;
- classes_n = 1;
- }
- else
- {
- size_t len = strlen(class);
- while (class_suffixes[classes_n])
- classes_n++;
- classes = alloca(classes_n * sizeof(*classes));
- for (i = 0; i < classes_n; i++)
- {
- classes[i] = alloca(len + strlen(class_suffixes[i]) + sizeof(":"));
- stpcpy(stpcpy(stpcpy(classes[i], class), ":"), class_suffixes[i]);
- }
- }
- filters_n = classes_n * crtcs_n;
-
- crtc_info = alloca(crtcs_n * sizeof(*crtc_info));
- memset(crtc_info, 0, crtcs_n * sizeof(*crtc_info));
- for (crtc_i = 0; crtc_i < crtcs_n; crtc_i++)
- if (libcoopgamma_crtc_info_initialise(crtc_info + crtc_i) < 0)
- goto cg_fail;
-
- if (libcoopgamma_set_nonblocking(&cg, 1) < 0)
- goto fail;
-
- asyncs = alloca(filters_n * sizeof(*asyncs));
- memset(asyncs, 0, filters_n * sizeof(*asyncs));
- for (filter_i = 0; filter_i < filters_n; filter_i++)
- if (libcoopgamma_async_context_initialise(asyncs + filter_i) < 0)
- goto fail;
-
- switch (get_crtc_info())
- {
- case 0:
- break;
- case -1:
- goto fail;
- case -2:
- goto cg_fail;
- }
-
- for (crtc_i = 0; crtc_i < crtcs_n; crtc_i++)
- {
- if (explicit_crtcs && !(crtc_info[crtc_i].supported))
- fprintf(stderr, "%s: warning: gamma adjustments not supported on CRTC: %s\n",
- argv0, crtcs[crtc_i]);
- if (crtc_info[crtc_i].cooperative == 0)
- fprintf(stderr, "%s: warning: cooperative gamma server not running for CRTC: %s\n",
- argv0, crtcs[crtc_i]);
- }
-
- crtc_updates = alloca(filters_n * sizeof(*crtc_updates));
- memset(crtc_updates, 0, filters_n * sizeof(*crtc_updates));
- for (filter_i = i = 0; i < classes_n; i++)
- for (crtc_i = 0; crtc_i < crtcs_n; crtc_i++, filter_i++)
- {
- if (libcoopgamma_filter_initialise(&(crtc_updates[filter_i].filter)) < 0)
- goto fail;
- if (libcoopgamma_error_initialise(&(crtc_updates[filter_i].error)) < 0)
- goto fail;
- crtc_updates[filter_i].crtc = crtc_i;
- crtc_updates[filter_i].synced = 1;
- crtc_updates[filter_i].failed = 0;
- crtc_updates[filter_i].master = 1;
- crtc_updates[filter_i].slaves = NULL;
- crtc_updates[filter_i].filter.crtc = crtcs[crtc_i];
- crtc_updates[filter_i].filter.class = classes[i];
- crtc_updates[filter_i].filter.priority = priority;
- crtc_updates[filter_i].filter.depth = crtc_info[crtc_i].depth;
- crtc_updates[filter_i].filter.ramps.u8.red_size = crtc_info[crtc_i].red_size;
- crtc_updates[filter_i].filter.ramps.u8.green_size = crtc_info[crtc_i].green_size;
- crtc_updates[filter_i].filter.ramps.u8.blue_size = crtc_info[crtc_i].blue_size;
- switch (crtc_updates[filter_i].filter.depth)
- {
-#define X(CONST, MEMBER, MAX, TYPE)\
- case CONST:\
- libcoopgamma_ramps_initialise(&(crtc_updates[filter_i].filter.ramps.MEMBER));\
- libclut_start_over(&(crtc_updates[filter_i].filter.ramps.MEMBER), MAX, TYPE, 1, 1, 1);\
- break;
-LIST_DEPTHS
-#undef X
- default:
- fprintf(stderr, "%s: internal error: gamma ramp type is unrecognised: %i\n",
- argv0, crtc_updates[filter_i].filter.depth);
- goto custom_fail;
- }
- }
-
- switch (start())
- {
- case 0:
- break;
- case -1:
- goto fail;
- case -2:
- goto cg_fail;
- case -3:
- goto custom_fail;
- }
-
- for (filter_i = 0; filter_i < filters_n; filter_i++)
- if (crtc_updates[filter_i].failed)
- {
- const char* side = cg.error.server_side ? "server" : "client";
- const char* crtc = crtc_updates[filter_i].filter.crtc;
- if (cg.error.custom)
- {
- if ((cg.error.number != 0) && (cg.error.description != NULL))
- fprintf(stderr, "%s: %s-side error number %" PRIu64 " for CRTC %s: %s\n",
- argv0, side, cg.error.number, crtc, cg.error.description);
- else if (cg.error.number != 0)
- fprintf(stderr, "%s: %s-side error number %" PRIu64 " for CRTC %s\n",
- argv0, side, cg.error.number, crtc);
- else if (cg.error.description != NULL)
- fprintf(stderr, "%s: %s-side error for CRTC %s: %s\n", argv0, side, crtc, cg.error.description);
- }
- else if (cg.error.description != NULL)
- fprintf(stderr, "%s: %s-side error for CRTC %s: %s\n", argv0, side, crtc, cg.error.description);
- else
- fprintf(stderr, "%s: %s-side error for CRTC %s: %s\n", argv0, side, crtc, strerror(cg.error.number));
- }
-
- done:
- if (dealloc_crtcs)
- free(crtcs);
- if (crtc_info != NULL)
- for (crtc_i = 0; crtc_i < crtcs_n; crtc_i++)
- libcoopgamma_crtc_info_destroy(crtc_info + crtc_i);
- if (asyncs != NULL)
- for (filter_i = 0; filter_i < filters_n; filter_i++)
- libcoopgamma_async_context_destroy(asyncs + filter_i);
- if (stage >= 1)
- libcoopgamma_context_destroy(&cg, stage >= 2);
- if (crtc_updates != NULL)
- for (filter_i = 0; filter_i < filters_n; filter_i++)
- {
- if (crtc_updates[filter_i].master == 0)
- memset(&(crtc_updates[filter_i].filter.ramps.u8), 0, sizeof(crtc_updates[filter_i].filter.ramps.u8));
- crtc_updates[filter_i].filter.crtc = NULL;
- crtc_updates[filter_i].filter.class = NULL;
- libcoopgamma_filter_destroy(&(crtc_updates[filter_i].filter));
- libcoopgamma_error_destroy(&(crtc_updates[filter_i].error));
- free(crtc_updates[filter_i].slaves);
- }
- return rc;
-
- custom_fail:
- rc = 1;
- goto done;
-
- fail:
- rc = 1;
- if (errno)
- perror(argv0);
- goto done;
-
- cg_fail:
- rc = 1;
- {
- const char* side = cg.error.server_side ? "server" : "client";
- if (cg.error.custom)
- {
- if ((cg.error.number != 0) && (cg.error.description != NULL))
- fprintf(stderr, "%s: %s-side error number %" PRIu64 ": %s\n",
- argv0, side, cg.error.number, cg.error.description);
- else if (cg.error.number != 0)
- fprintf(stderr, "%s: %s-side error number %" PRIu64 "\n", argv0, side, cg.error.number);
- else if (cg.error.description != NULL)
- fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description);
- }
- else if (cg.error.description != NULL)
- fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description);
- else
- fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, strerror(cg.error.number));
- }
- goto done;
-}
-