diff options
-rw-r--r-- | src/filter.c | 86 | ||||
-rw-r--r-- | src/filter.h | 21 | ||||
-rw-r--r-- | src/gammad.c | 2 | ||||
-rw-r--r-- | src/output.c | 207 | ||||
-rw-r--r-- | src/output.h | 52 | ||||
-rw-r--r-- | src/ramps.c | 96 | ||||
-rw-r--r-- | src/ramps.h | 24 | ||||
-rw-r--r-- | src/util.h | 39 |
8 files changed, 471 insertions, 56 deletions
diff --git a/src/filter.c b/src/filter.c index fe239f1..80e3ed1 100644 --- a/src/filter.c +++ b/src/filter.c @@ -15,9 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#define _GNU_SOURCE #include "filter.h" +#include "util.h" +#include <stdlib.h> #include <string.h> @@ -26,68 +27,68 @@ * Free all resources allocated to a filter. * The allocation of `filter` itself is not freed. * - * @param filter The filter. + * @param this The filter */ -void filter_destroy(struct filter* filter) +void filter_destroy(struct filter* this) { - free(filter->crtc); - free(filter->class); - free(filter->ramps); + free(this->crtc); + free(this->class); + free(this->ramps); } /** - * Marshal a filter. + * Marshal a filter * - * @param filter The filter. - * @param buf Output buffer for the marshalled filter. + * @param this The filter + * @param buf Output buffer for the marshalled filter, * `NULL` just measure how large the buffers - * needs to be. - * @param ramps_size The byte-size of `filter->ramps` + * needs to be + * @param ramps_size The byte-size of `this->ramps` * @return The number of marshalled byte */ -size_t filter_marshal(const struct filter* filter, char* buf, size_t ramps_size) +size_t filter_marshal(const struct filter* this, char* buf, size_t ramps_size) { size_t off = 0, n; char nonnulls = 0; if (buf != NULL) { - if (filter->crtc != NULL) nonnulls |= 1; - if (filter->class != NULL) nonnulls |= 2; - if (filter->ramps != NULL) nonnulls |= 4; + if (this->crtc != NULL) nonnulls |= 1; + if (this->class != NULL) nonnulls |= 2; + if (this->ramps != NULL) nonnulls |= 4; *(buf + off) = nonnulls; } off += 1; if (buf != NULL) - *(int64_t*)(buf + off) = filter->priority; + *(int64_t*)(buf + off) = this->priority; off += sizeof(int64_t); if (buf != NULL) - *(enum lifespan*)(buf + off) = filter->lifespan; + *(enum lifespan*)(buf + off) = this->lifespan; off += sizeof(enum lifespan); - if (filter->crtc != NULL) + if (this->crtc != NULL) { - n = strlen(filter->crtc) + 1; + n = strlen(this->crtc) + 1; if (buf != NULL) - memcpy(buf + off, filter->crtc, n); + memcpy(buf + off, this->crtc, n); off += n; } - if (filter->class != NULL) + if (this->class != NULL) { - n = strlen(filter->class) + 1; + n = strlen(this->class) + 1; if (buf != NULL) - memcpy(buf + off, filter->class, n); + memcpy(buf + off, this->class, n); off += n; } - if (filter->ramps != NULL) + if (this->ramps != NULL) { if (buf != NULL) - memcpy(buf + off, filter->ramps, ramps_size); + memcpy(buf + off, this->ramps, ramps_size); off += n; } @@ -96,14 +97,14 @@ size_t filter_marshal(const struct filter* filter, char* buf, size_t ramps_size) /** - * Unmarshal a filter. + * Unmarshal a filter * - * @param filter Output for the filter, `NULL` to skip unmarshalling + * @param this Output for the filter * @param buf Buffer with the marshalled filter - * @param ramps_size The byte-size of `filter->ramps` + * @param ramps_size The byte-size of `this->ramps` * @return The number of unmarshalled bytes, 0 on error */ -size_t filter_unmarshal(struct filter* filter, const char* buf, size_t ramps_size) +size_t filter_unmarshal(struct filter* this, const char* buf, size_t ramps_size) { size_t off = 0, n; char nonnulls = 0; @@ -111,25 +112,20 @@ size_t filter_unmarshal(struct filter* filter, const char* buf, size_t ramps_siz nonnulls = *(buf + off); off += 1; - if (filter != NULL) - { - filter->crtc = NULL; - filter->class = NULL; - filter->ramps = NULL; - } + this->crtc = NULL; + this->class = NULL; + this->ramps = NULL; - if (filter != NULL) - filter->priority = *(int64_t*)(buf + off); + this->priority = *(int64_t*)(buf + off); off += sizeof(int64_t); - if (filter != NULL) - filter->lifespan = *(enum lifespan*)(buf + off); + this->lifespan = *(enum lifespan*)(buf + off); off += sizeof(enum lifespan); if (nonnulls & 1) { n = strlen(buf + off) + 1; - if ((filter != NULL) && (!(filter->crtc = memdup(buf + off, n)))) + if (!(this->crtc = memdup(buf + off, n))) goto fail; off += n; } @@ -137,14 +133,14 @@ size_t filter_unmarshal(struct filter* filter, const char* buf, size_t ramps_siz if (nonnulls & 2) { n = strlen(buf + off) + 1; - if ((filter != NULL) && (!(filter->class = memdup(buf + off, n)))) + if (!(this->class = memdup(buf + off, n))) goto fail; off += n; } if (nonnulls & 4) { - if ((filter != NULL) && (!(filter->ramps = memdup(buf + off, ramps_size)))) + if (!(this->ramps = memdup(buf + off, ramps_size))) goto fail; off += n; } @@ -152,9 +148,9 @@ size_t filter_unmarshal(struct filter* filter, const char* buf, size_t ramps_siz return off; fail: - free(filter->crtc); - free(filter->class); - free(filter->ramps); + free(this->crtc); + free(this->class); + free(this->ramps); return 0; } diff --git a/src/filter.h b/src/filter.h index 5b46371..d53650c 100644 --- a/src/filter.h +++ b/src/filter.h @@ -92,29 +92,30 @@ struct filter * Free all resources allocated to a filter. * The allocation of `filter` itself is not freed. * - * @param filter The filter. + * @param this The filter */ -void filter_destroy(struct filter* filter); +void filter_destroy(struct filter* this); /** - * Marshal a filter. + * Marshal a filter * - * @param filter The filter. - * @param buf Output buffer for the marshalled filter. + * @param this The filter + * @param buf Output buffer for the marshalled filter, * `NULL` just measure how large the buffers - * needs to be. + * needs to be * @param ramps_size The byte-size of `filter->ramps` * @return The number of marshalled byte */ -size_t filter_marshal(const struct filter* filter, char* buf, size_t ramps_size); +size_t filter_marshal(const struct filter* this, char* buf, size_t ramps_size); /** - * Unmarshal a filter. + * Unmarshal a filter * - * @param filter Output for the filter, `NULL` to skip unmarshalling + * @param this Output for the filter, `.red_size`, `.green_size`, + * and `.blue_size` must already be set * @param buf Buffer with the marshalled filter * @param ramps_size The byte-size of `filter->ramps` * @return The number of unmarshalled bytes, 0 on error */ -size_t filter_unmarshal(struct filter* filter, const char* buf, size_t ramps_size); +size_t filter_unmarshal(struct filter* this, const char* buf, size_t ramps_size); diff --git a/src/gammad.c b/src/gammad.c index c04ba5d..fca9079 100644 --- a/src/gammad.c +++ b/src/gammad.c @@ -194,7 +194,6 @@ int main(int argc, char** argv) gerror = libgamma_crtc_set_gamma_ramps##SUFFIX(outputs[i].crtc, outputs[i].saved_ramps.MEMBER); \ if (gerror) \ libgamma_perror(argv0, gerror); \ - libgamma_gamma_ramps##SUFFIX##_destroy(&(outputs[i].saved_ramps.MEMBER)); \ } \ while (0) if (crtcs != NULL) @@ -224,6 +223,7 @@ int main(int argc, char** argv) default: break; /* impossible */ } + output_destroy(outputs + i); libgamma_crtc_destroy(crtcs + i); } free(crtcs); diff --git a/src/output.c b/src/output.c new file mode 100644 index 0000000..48a51a8 --- /dev/null +++ b/src/output.c @@ -0,0 +1,207 @@ +/** + * gammad -- Cooperative gamma server + * Copyright (C) 2016 Mattias Andrée (maandree@kth.se) + * + * This library 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 library 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 library. If not, see <http://www.gnu.org/licenses/>. + */ +#include "output.h" +#include "util.h" + +#include <stdlib.h> +#include <string.h> + + + +/** + * Free all resources allocated to an output. + * The allocation of `output` itself is not freed. + * + * @param this The output + */ +void output_destroy(struct output* this) +{ + size_t i; + + if (this->supported != LIBGAMMA_NO) + switch (this->depth) + { + case 8: + libgamma_gamma_ramps8_destroy(&(this->saved_ramps.u8)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_ramps8_destroy(&(this->table_sums[i].u8)); + break; + case 16: + libgamma_gamma_ramps16_destroy(&(this->saved_ramps.u16)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_ramps16_destroy(&(this->table_sums[i].u16)); + break; + case 32: + libgamma_gamma_ramps32_destroy(&(this->saved_ramps.u32)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_ramps32_destroy(&(this->table_sums[i].u32)); + break; + case 64: + libgamma_gamma_ramps64_destroy(&(this->saved_ramps.u64)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_ramps64_destroy(&(this->table_sums[i].u64)); + break; + case -1: + libgamma_gamma_rampsf_destroy(&(this->saved_ramps.f)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_rampsf_destroy(&(this->table_sums[i].f)); + break; + case -2: + libgamma_gamma_rampsd_destroy(&(this->saved_ramps.d)); + for (i = 0; i < this->table_size; i++) + libgamma_gamma_rampsd_destroy(&(this->table_sums[i].d)); + break; + default: + break; /* impossible */ + } + + for (i = 0; i < this->table_size; i++) + filter_destroy(this->table_filters + i); + + free(this->table_filters); + free(this->table_sums); + free(this->name); +} + + +/** + * Marshal an output + * + * @param this The output + * @param buf Output buffer for the marshalled output, + * `NULL` just measure how large the buffers + * needs to be + * @return The number of marshalled byte + */ +size_t output_marshal(const struct output* this, char* buf) +{ + size_t off = 0, i, n; + + if (buf != NULL) + *(signed*)(buf + off) = this->depth; + off += sizeof(signed); + + if (buf != NULL) + *(size_t*)(buf + off) = this->red_size; + off += sizeof(size_t); + + if (buf != NULL) + *(size_t*)(buf + off) = this->green_size; + off += sizeof(size_t); + + if (buf != NULL) + *(size_t*)(buf + off) = this->blue_size; + off += sizeof(size_t); + + if (buf != NULL) + *(size_t*)(buf + off) = this->ramps_size; + off += sizeof(size_t); + + if (buf != NULL) + *(enum libgamma_decision*)(buf + off) = this->supported; + off += sizeof(enum libgamma_decision); + + n = strlen(this->name) + 1; + if (buf != NULL) + memcpy(buf + off, this->name, n); + off += n; + + off += gamma_ramps_marshal(&(this->saved_ramps), buf ? buf + off : NULL, this->ramps_size); + + if (buf != NULL) + *(size_t*)(buf + off) = this->table_size; + off += sizeof(size_t); + + for (i = 0; i < this->table_size; i++) + { + off += filter_marshal(this->table_filters + i, buf ? buf + off : NULL, this->ramps_size); + off += gamma_ramps_marshal(this->table_sums + i, buf ? buf + off : NULL, this->ramps_size); + } + + return off; +} + + +/** + * Unmarshal an output + * + * @param this Output for the output + * @param buf Buffer with the marshalled output + * @return The number of unmarshalled bytes, 0 on error + */ +size_t output_unmarshal(struct output* this, const char* buf) +{ + size_t off = 0, i, n; + + this->crtc = NULL; + this->name = NULL; + + this->depth = *(signed*)(buf + off); + off += sizeof(signed); + + this->red_size = *(size_t*)(buf + off); + off += sizeof(size_t); + + this->green_size = *(size_t*)(buf + off); + off += sizeof(size_t); + + this->blue_size = *(size_t*)(buf + off); + off += sizeof(size_t); + + this->ramps_size = *(size_t*)(buf + off); + off += sizeof(size_t); + + this->supported = *(enum libgamma_decision*)(buf + off); + off += sizeof(enum libgamma_decision); + + n = strlen(buf + off) + 1; + this->name = memdup(buf + off, n); + if (this->name == NULL) + return 0; + + off += n = gamma_ramps_unmarshal(&(this->saved_ramps), buf, this->ramps_size); + COPY_RAMP_SIZES(&(this->saved_ramps.u8), this); + if (n == 0) + return 0; + + this->table_size = this->table_alloc = *(size_t*)(buf + off); + off += sizeof(size_t); + if (this->table_size > 0) + { + this->table_filters = calloc(this->table_size, sizeof(*(this->table_filters))); + if (this->table_filters == NULL) + return 0; + this->table_sums = calloc(this->table_size, sizeof(*(this->table_sums))); + if (this->table_sums == NULL) + return 0; + } + + for (i = 0; i < this->table_size; i++) + { + off += n = filter_unmarshal(this->table_filters + i, buf + off, this->ramps_size); + if (n == 0) + return 0; + COPY_RAMP_SIZES(&(this->table_sums[i].u8), this); + off += n = gamma_ramps_unmarshal(this->table_sums + i, buf + off, this->ramps_size); + if (n == 0) + return 0; + } + + return off; +} + diff --git a/src/output.h b/src/output.h index d3b39ec..b27059f 100644 --- a/src/output.h +++ b/src/output.h @@ -20,6 +20,23 @@ #include <libgamma.h> #include "ramps.h" +#include "filter.h" + + + +/** + * Copy the ramp sizes + * + * This macro supports both `struct output` + * and `struct gamma_ramps` + * + * @param dest The destination + * @param src The source + */ +#define COPY_RAMP_SIZES(dest, src) \ + ((dest)->red_size = (src)->red_size, \ + (dest)->green_size = (src)->green_size, \ + (dest)->blue_size = (src)->blue_size) @@ -85,5 +102,40 @@ struct output * Saved gamma ramps */ union gamma_ramps saved_ramps; + + struct filter* table_filters; + union gamma_ramps* table_sums; + size_t table_alloc; + size_t table_size; }; + + +/** + * Free all resources allocated to an output. + * The allocation of `output` itself is not freed. + * + * @param this The output + */ +void output_destroy(struct output* this); + +/** + * Marshal an output + * + * @param this The output + * @param buf Output buffer for the marshalled output, + * `NULL` just measure how large the buffers + * needs to be + * @return The number of marshalled byte + */ +size_t output_marshal(const struct output* this, char* buf); + +/** + * Unmarshal an output + * + * @param this Output for the output + * @param buf Buffer with the marshalled output + * @return The number of unmarshalled bytes, 0 on error + */ +size_t output_unmarshal(struct output* this, const char* buf); + diff --git a/src/ramps.c b/src/ramps.c new file mode 100644 index 0000000..2c24b52 --- /dev/null +++ b/src/ramps.c @@ -0,0 +1,96 @@ +/** + * gammad -- Cooperative gamma server + * Copyright (C) 2016 Mattias Andrée (maandree@kth.se) + * + * This library 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 library 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 library. If not, see <http://www.gnu.org/licenses/>. + */ +#include "ramps.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + + + +/** + * The name of the process + */ +extern char* argv0; + + + +/** + * Marshal a ramp trio + * + * @param this The ramps + * @param buf Output buffer for the marshalled ramps, + * `NULL` just measure how large the buffers + * needs to be + * @param ramps_size The byte-size of ramps + * @return The number of marshalled byte + */ +size_t gamma_ramps_marshal(const union gamma_ramps* this, char* buf, size_t ramps_size) +{ + if (buf != NULL) + memcpy(buf, this->u8.red, ramps_size); + return ramps_size; +} + + +/** + * Unmarshal a ramp trio + * + * @param this Output for the ramps, `.red_size`, `.green_size`, + * and `.blue_size` must already be set + * @param buf Buffer with the marshalled ramps + * @param ramps_size The byte-size of ramps + * @return The number of unmarshalled bytes, 0 on error + */ +size_t gamma_ramps_unmarshal(union gamma_ramps* this, const char* buf, size_t ramps_size) +{ + size_t depth = ramps_size / (this->u8.red_size + this->u8.green_size + this->u8.blue_size); + int r = 0; + switch (depth) + { + case 1: + r = libgamma_gamma_ramps8_initialise(&(this->u8)); + break; + case 2: + r = libgamma_gamma_ramps16_initialise(&(this->u16)); + break; + case 4: + r = libgamma_gamma_ramps32_initialise(&(this->u32)); + break; + case 8: + r = libgamma_gamma_ramps64_initialise(&(this->u64)); + break; + default: + if (depth == sizeof(float)) + r = libgamma_gamma_rampsf_initialise(&(this->f)); + else if (depth == sizeof(double)) + r = libgamma_gamma_rampsd_initialise(&(this->d)); + else + abort(); + break; + } + if (r) + { + libgamma_perror(argv0, r); + errno = 0; + return 0; + } + memcpy(this->u8.red, buf, ramps_size); + return ramps_size; +} + diff --git a/src/ramps.h b/src/ramps.h index 0f1462c..7aa08fd 100644 --- a/src/ramps.h +++ b/src/ramps.h @@ -56,3 +56,27 @@ union gamma_ramps libgamma_gamma_rampsd_t d; }; + + +/** + * Marshal a ramp trio + * + * @param this The ramps + * @param buf Output buffer for the marshalled ramps, + * `NULL` just measure how large the buffers + * needs to be + * @param ramps_size The byte-size of ramps + * @return The number of marshalled byte + */ +size_t gamma_ramps_marshal(const union gamma_ramps* this, char* buf, size_t ramps_size); + +/** + * Unmarshal a ramp trio + * + * @param this Output for the ramps + * @param buf Buffer with the marshalled ramps + * @param ramps_size The byte-size of ramps + * @return The number of unmarshalled bytes, 0 on error + */ +size_t gamma_ramps_unmarshal(union gamma_ramps* this, const char* buf, size_t ramps_size); + diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..4f9cbde --- /dev/null +++ b/src/util.h @@ -0,0 +1,39 @@ +/** + * gammad -- Cooperative gamma server + * Copyright (C) 2016 Mattias Andrée (maandree@kth.se) + * + * This library 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 library 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 library. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <string.h> + + + +/** + * Duplicate a memory segment + * + * @param src The memory segment, must not be `NULL` + * @param n The size of the memory segment, must not be zero + * @return The duplicate of the memory segment, + * `NULL` on error + */ +static inline void* memdup(const void* src, size_t n) +{ + void* dest = malloc(n); + if (dest == NULL) + return NULL; + memcpy(dest, src, n); + return dest; +} + |