aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2019-10-22 18:59:27 +0200
committerMattias Andrée <maandree@kth.se>2019-10-22 18:59:27 +0200
commitbf4020471356938b9181a33984f511ffdd7ff25b (patch)
tree7f9a9abd1ae51318cd435f0ed7471be5f33b478c /src
parentList radharc's priority (diff)
downloadlibcoopgamma-bf4020471356938b9181a33984f511ffdd7ff25b.tar.gz
libcoopgamma-bf4020471356938b9181a33984f511ffdd7ff25b.tar.bz2
libcoopgamma-bf4020471356938b9181a33984f511ffdd7ff25b.tar.xz
Change license, change style, clean up, flat file hier, clean valgrind output in test
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--libcoopgamma.h (renamed from src/libcoopgamma.h)1237
-rw-r--r--src/libcoopgamma.c2620
-rw-r--r--src/test.c273
3 files changed, 596 insertions, 3534 deletions
diff --git a/src/libcoopgamma.h b/libcoopgamma.h
index 723d5a3..5f5e800 100644
--- a/src/libcoopgamma.h
+++ b/libcoopgamma.h
@@ -1,40 +1,21 @@
-/**
- * libcoopgamma -- Library for interfacing with cooperative gamma servers
- * 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/>.
- */
+/* See LICENSE file for copyright and license details. */
#ifndef LIBCOOPGAMMA_H
#define LIBCOOPGAMMA_H
-
-
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
-
#if defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdocumentation"
#endif
#if defined(__GNUC__) && !defined(__clang__)
-# define LIBCOOPGAMMA_GCC_ONLY(...) __VA_ARGS__
+# define LIBCOOPGAMMA_GCC_ONLY(...) __VA_ARGS__
#else
-# define LIBCOOPGAMMA_GCC_ONLY(...) /* ignore */
+# define LIBCOOPGAMMA_GCC_ONLY(...) /* ignore */
#endif
@@ -171,30 +152,29 @@
* Values used to indicate the support
* for gamma adjustments
*/
-typedef enum libcoopgamma_support
-{
- /**
- * Gamma adjustments are not supported
- *
- * This value will always be 0
- */
- LIBCOOPGAMMA_NO = 0,
-
- /**
- * Don't know whether gamma
- * adjustments are supported
- *
- * This value will always be 1
- */
- LIBCOOPGAMMA_MAYBE = 1,
-
- /**
- * Gamma adjustments are supported
- *
- * This value will always be 2
- */
- LIBCOOPGAMMA_YES = 2
-
+typedef enum libcoopgamma_support {
+ /**
+ * Gamma adjustments are not supported
+ *
+ * This value will always be 0
+ */
+ LIBCOOPGAMMA_NO = 0,
+
+ /**
+ * Don't know whether gamma
+ * adjustments are supported
+ *
+ * This value will always be 1
+ */
+ LIBCOOPGAMMA_MAYBE = 1,
+
+ /**
+ * Gamma adjustments are supported
+ *
+ * This value will always be 2
+ */
+ LIBCOOPGAMMA_YES = 2
+
} libcoopgamma_support_t;
@@ -206,38 +186,37 @@ typedef enum libcoopgamma_support
* of bits for integral types, and
* negative for floating-point types
*/
-typedef enum libcoopgamma_depth
-{
- /**
- * `uint8_t`
- */
- LIBCOOPGAMMA_UINT8 = 8,
-
- /**
- * `uint16_t`
- */
- LIBCOOPGAMMA_UINT16 = 16,
-
- /**
- * `uint32_t`
- */
- LIBCOOPGAMMA_UINT32 = 32,
-
- /**
- * `uint64_t`
- */
- LIBCOOPGAMMA_UINT64 = 64,
-
- /**
- * `float`
- */
- LIBCOOPGAMMA_FLOAT = -1,
-
- /**
- * `double`
- */
- LIBCOOPGAMMA_DOUBLE = -2
-
+typedef enum libcoopgamma_depth {
+ /**
+ * `uint8_t`
+ */
+ LIBCOOPGAMMA_UINT8 = 8,
+
+ /**
+ * `uint16_t`
+ */
+ LIBCOOPGAMMA_UINT16 = 16,
+
+ /**
+ * `uint32_t`
+ */
+ LIBCOOPGAMMA_UINT32 = 32,
+
+ /**
+ * `uint64_t`
+ */
+ LIBCOOPGAMMA_UINT64 = 64,
+
+ /**
+ * `float`
+ */
+ LIBCOOPGAMMA_FLOAT = -1,
+
+ /**
+ * `double`
+ */
+ LIBCOOPGAMMA_DOUBLE = -2
+
} libcoopgamma_depth_t;
@@ -245,63 +224,61 @@ typedef enum libcoopgamma_depth
* Values used to tell when a filter
* should be removed
*/
-typedef enum libcoopgamma_lifespan
-{
- /**
- * Remove the filter now
- *
- * This value will always be 0
- */
- LIBCOOPGAMMA_REMOVE = 0,
-
- /**
- * Remove the filter when disconnecting
- * from the coopgamma server
- */
- LIBCOOPGAMMA_UNTIL_DEATH = 1,
-
- /**
- * Only remove the filter when it
- * is explicitly requested
- */
- LIBCOOPGAMMA_UNTIL_REMOVAL = 2
-
+typedef enum libcoopgamma_lifespan {
+ /**
+ * Remove the filter now
+ *
+ * This value will always be 0
+ */
+ LIBCOOPGAMMA_REMOVE = 0,
+
+ /**
+ * Remove the filter when disconnecting
+ * from the coopgamma server
+ */
+ LIBCOOPGAMMA_UNTIL_DEATH = 1,
+
+ /**
+ * Only remove the filter when it
+ * is explicitly requested
+ */
+ LIBCOOPGAMMA_UNTIL_REMOVAL = 2
+
} libcoopgamma_lifespan_t;
/**
* Colourspaces
*/
-typedef enum libcoopgamma_colourspace
-{
- /**
- * The colourspace is unknown
- *
- * This value will always be 0
- */
- LIBCOOPGAMMA_UNKNOWN = 0,
-
- /**
- * sRGB (Standard RGB)
- */
- LIBCOOPGAMMA_SRGB = 1,
-
- /**
- * RGB other than sRGB
- */
- LIBCOOPGAMMA_RGB = 2,
-
- /**
- * Non-RGB multicolour
- */
- LIBCOOPGAMMA_NON_RGB = 3,
-
- /**
- * Monochrome, greyscale, or some
- * other singlecolour scale
- */
- LIBCOOPGAMMA_GREY = 4
-
+typedef enum libcoopgamma_colourspace {
+ /**
+ * The colourspace is unknown
+ *
+ * This value will always be 0
+ */
+ LIBCOOPGAMMA_UNKNOWN = 0,
+
+ /**
+ * sRGB (Standard RGB)
+ */
+ LIBCOOPGAMMA_SRGB = 1,
+
+ /**
+ * RGB other than sRGB
+ */
+ LIBCOOPGAMMA_RGB = 2,
+
+ /**
+ * Non-RGB multicolour
+ */
+ LIBCOOPGAMMA_NON_RGB = 3,
+
+ /**
+ * Monochrome, greyscale, or some
+ * other singlecolour scale
+ */
+ LIBCOOPGAMMA_GREY = 4
+
} libcoopgamma_colourspace_t;
@@ -311,39 +288,38 @@ typedef enum libcoopgamma_colourspace
* @param suffix:identifier The end of the name of the `struct`
* @param type:scalar-type The datatype of the stops
*/
-#define LIBCOOPGAMMA_RAMPS__(suffix, type) \
-typedef struct libcoopgamma_ramps##suffix \
-{ \
- /**
- * The number of stops in the red ramp
- */ \
- size_t red_size; \
- \
- /**
- * The number of stops in the green ramp
- */ \
- size_t green_size; \
- \
- /**
- * The number of stops in the blue ramp
- */ \
- size_t blue_size; \
- \
- /**
- * The red ramp
- */ \
- type* red; \
- \
- /**
- * The green ramp
- */ \
- type* green; \
- \
- /**
- * The blue ramp
- */ \
- type* blue; \
- \
+#define LIBCOOPGAMMA_RAMPS__(suffix, type)\
+typedef struct libcoopgamma_ramps##suffix {\
+ /**
+ * The number of stops in the red ramp
+ */\
+ size_t red_size;\
+ \
+ /**
+ * The number of stops in the green ramp
+ */\
+ size_t green_size;\
+ \
+ /**
+ * The number of stops in the blue ramp
+ */\
+ size_t blue_size;\
+ \
+ /**
+ * The red ramp
+ */\
+ type *red;\
+ \
+ /**
+ * The green ramp
+ */\
+ type *green;\
+ \
+ /**
+ * The blue ramp
+ */\
+ type *blue;\
+ \
} libcoopgamma_ramps##suffix##_t
/**
@@ -392,38 +368,37 @@ LIBCOOPGAMMA_RAMPS__(d, double);
/**
* Union with all ramp types.
*/
-typedef union libcoopgamma_ramps
-{
- /**
- * 8-bit version
- */
- libcoopgamma_ramps8_t u8;
-
- /**
- * 16-bit version
- */
- libcoopgamma_ramps16_t u16;
-
- /**
- * 32-bit version
- */
- libcoopgamma_ramps32_t u32;
-
- /**
- * 64-bit version
- */
- libcoopgamma_ramps64_t u64;
-
- /**
- * Single precision floating-point version
- */
- libcoopgamma_rampsf_t f;
-
- /**
- * Double precision floating-point version
- */
- libcoopgamma_rampsd_t d;
-
+typedef union libcoopgamma_ramps {
+ /**
+ * 8-bit version
+ */
+ libcoopgamma_ramps8_t u8;
+
+ /**
+ * 16-bit version
+ */
+ libcoopgamma_ramps16_t u16;
+
+ /**
+ * 32-bit version
+ */
+ libcoopgamma_ramps32_t u32;
+
+ /**
+ * 64-bit version
+ */
+ libcoopgamma_ramps64_t u64;
+
+ /**
+ * Single precision floating-point version
+ */
+ libcoopgamma_rampsf_t f;
+
+ /**
+ * Double precision floating-point version
+ */
+ libcoopgamma_rampsd_t d;
+
} libcoopgamma_ramps_t;
@@ -431,153 +406,151 @@ typedef union libcoopgamma_ramps
* Data set to the coopgamma server to apply,
* update, or remove a filter.
*/
-typedef struct libcoopgamma_filter
-{
- /**
- * The priority of the filter, higher priority
- * is applied first. The gamma correction should
- * have priority 0.
- */
- int64_t priority;
-
- /**
- * The CRTC for which this filter shall be applied
- */
- char* crtc;
-
- /**
- * Identifier for the filter
- *
- * The syntax must be "${PACKAGE_NAME}::${COMMAND_NAME}::${RULE}"
- */
- char* class;
-
- /**
- * When shall the filter be removed?
- *
- * If this member's value is `LIBCOOPGAMMA_REMOVE`,
- * only `.crtc` and `.class` need also be defined
- */
- libcoopgamma_lifespan_t lifespan;
-
- /**
- * The data type and bit-depth of the ramp stops
- */
- libcoopgamma_depth_t depth;
-
- /**
- * The gamma ramp adjustments of the filter
- */
- libcoopgamma_ramps_t ramps;
-
+typedef struct libcoopgamma_filter {
+ /**
+ * The priority of the filter, higher priority
+ * is applied first. The gamma correction should
+ * have priority 0.
+ */
+ int64_t priority;
+
+ /**
+ * The CRTC for which this filter shall be applied
+ */
+ char *crtc;
+
+ /**
+ * Identifier for the filter
+ *
+ * The syntax must be "${PACKAGE_NAME}::${COMMAND_NAME}::${RULE}"
+ */
+ char *class;
+
+ /**
+ * When shall the filter be removed?
+ *
+ * If this member's value is `LIBCOOPGAMMA_REMOVE`,
+ * only `.crtc` and `.class` need also be defined
+ */
+ libcoopgamma_lifespan_t lifespan;
+
+ /**
+ * The data type and bit-depth of the ramp stops
+ */
+ libcoopgamma_depth_t depth;
+
+ /**
+ * The gamma ramp adjustments of the filter
+ */
+ libcoopgamma_ramps_t ramps;
+
} libcoopgamma_filter_t;
/**
* Gamma ramp meta information for a CRTC
*/
-typedef struct libcoopgamma_crtc_info
-{
- /**
- * Is cooperative gamma server running?
- */
- int cooperative;
-
- /**
- * The data type and bit-depth of the ramp stops
- */
- libcoopgamma_depth_t depth;
-
- /**
- * Is gamma adjustments supported on the CRTC?
- * If not, `.depth`, `.red_size`, `.green_size`,
- * and `.blue_size` are undefined
- */
- libcoopgamma_support_t supported;
-
+typedef struct libcoopgamma_crtc_info {
+ /**
+ * Is cooperative gamma server running?
+ */
+ int cooperative;
+
+ /**
+ * The data type and bit-depth of the ramp stops
+ */
+ libcoopgamma_depth_t depth;
+
+ /**
+ * Is gamma adjustments supported on the CRTC?
+ * If not, `.depth`, `.red_size`, `.green_size`,
+ * and `.blue_size` are undefined
+ */
+ libcoopgamma_support_t supported;
+
#if INT_MAX != LONG_MAX
- int padding__;
+ int padding__;
#endif
-
- /**
- * The number of stops in the red ramp
- */
- size_t red_size;
-
- /**
- * The number of stops in the green ramp
- */
- size_t green_size;
-
- /**
- * The number of stops in the blue ramp
- */
- size_t blue_size;
-
- /**
- * The monitor's colourspace
- */
- libcoopgamma_colourspace_t colourspace;
-
- /**
- * Whether `.red_x`, `.red_y`, `.green_x`,
- * `.green_y`, `.blue_x`, `.blue_y`,
- * `.white_x`, and `.white_y` are set.
- *
- * If this is true, but the colourspace
- * is not RGB (or sRGB), there is something
- * wrong. Please also check the colourspace.
- */
- int have_gamut;
-
- /**
- * The x-value (CIE xyY) of the monitor's
- * red colour, multiplied by 1024
- */
- unsigned red_x;
-
- /**
- * The y-value (CIE xyY) of the monitor's
- * red colour, multiplied by 1024
- */
- unsigned red_y;
-
- /**
- * The x-value (CIE xyY) of the monitor's
- * green colour, multiplied by 1024
- */
- unsigned green_x;
-
- /**
- * The y-value (CIE xyY) of the monitor's
- * green colour, multiplied by 1024
- */
- unsigned green_y;
-
- /**
- * The x-value (CIE xyY) of the monitor's
- * blue colour, multiplied by 1024
- */
- unsigned blue_x;
-
- /**
- * The y-value (CIE xyY) of the monitor's
- * blue colour, multiplied by 1024
- */
- unsigned blue_y;
-
- /**
- * The x-value (CIE xyY) of the monitor's
- * default white point, multiplied by 1024
- */
- unsigned white_x;
-
- /**
- * The y-value (CIE xyY) of the monitor's
- * default white point, multiplied by 1024
- */
- unsigned white_y;
-
+
+ /**
+ * The number of stops in the red ramp
+ */
+ size_t red_size;
+
+ /**
+ * The number of stops in the green ramp
+ */
+ size_t green_size;
+
+ /**
+ * The number of stops in the blue ramp
+ */
+ size_t blue_size;
+
+ /**
+ * The monitor's colourspace
+ */
+ libcoopgamma_colourspace_t colourspace;
+
+ /**
+ * Whether `.red_x`, `.red_y`, `.green_x`,
+ * `.green_y`, `.blue_x`, `.blue_y`,
+ * `.white_x`, and `.white_y` are set.
+ *
+ * If this is true, but the colourspace
+ * is not RGB (or sRGB), there is something
+ * wrong. Please also check the colourspace.
+ */
+ int have_gamut;
+
+ /**
+ * The x-value (CIE xyY) of the monitor's
+ * red colour, multiplied by 1024
+ */
+ unsigned red_x;
+
+ /**
+ * The y-value (CIE xyY) of the monitor's
+ * red colour, multiplied by 1024
+ */
+ unsigned red_y;
+
+ /**
+ * The x-value (CIE xyY) of the monitor's
+ * green colour, multiplied by 1024
+ */
+ unsigned green_x;
+
+ /**
+ * The y-value (CIE xyY) of the monitor's
+ * green colour, multiplied by 1024
+ */
+ unsigned green_y;
+
+ /**
+ * The x-value (CIE xyY) of the monitor's
+ * blue colour, multiplied by 1024
+ */
+ unsigned blue_x;
+
+ /**
+ * The y-value (CIE xyY) of the monitor's
+ * blue colour, multiplied by 1024
+ */
+ unsigned blue_y;
+
+ /**
+ * The x-value (CIE xyY) of the monitor's
+ * default white point, multiplied by 1024
+ */
+ unsigned white_x;
+
+ /**
+ * The y-value (CIE xyY) of the monitor's
+ * default white point, multiplied by 1024
+ */
+ unsigned white_y;
+
} libcoopgamma_crtc_info_t;
@@ -586,36 +559,35 @@ typedef struct libcoopgamma_crtc_info
* when requestng the current filter
* table
*/
-typedef struct libcoopgamma_filter_query
-{
- /**
- * Do no return filters with higher
- * priority than this value
- */
- int64_t high_priority;
-
- /**
- * Do no return filters with lower
- * priority than this value
- */
- int64_t low_priority;
-
- /**
- * The CRTC for which the the current
- * filters shall returned
- */
- char* crtc;
-
- /**
- * Whether to coalesce all filters
- * into one gamma ramp triplet
- */
- int coalesce;
-
+typedef struct libcoopgamma_filter_query {
+ /**
+ * Do no return filters with higher
+ * priority than this value
+ */
+ int64_t high_priority;
+
+ /**
+ * Do no return filters with lower
+ * priority than this value
+ */
+ int64_t low_priority;
+
+ /**
+ * The CRTC for which the the current
+ * filters shall returned
+ */
+ char *crtc;
+
+ /**
+ * Whether to coalesce all filters
+ * into one gamma ramp triplet
+ */
+ int coalesce;
+
#if INT_MAX != LONG_MAX
- int padding__;
+ int padding__;
#endif
-
+
} libcoopgamma_filter_query_t;
@@ -624,23 +596,22 @@ typedef struct libcoopgamma_filter_query
* which only contains the information returned
* in response to "Command: get-gamma"
*/
-typedef struct libcoopgamma_queried_filter
-{
- /**
- * The filter's priority
- */
- int64_t priority;
-
- /**
- * The filter's class
- */
- char* class;
-
- /**
- * The gamma ramp adjustments of the filter
- */
- libcoopgamma_ramps_t ramps;
-
+typedef struct libcoopgamma_queried_filter {
+ /**
+ * The filter's priority
+ */
+ int64_t priority;
+
+ /**
+ * The filter's class
+ */
+ char *class;
+
+ /**
+ * The gamma ramp adjustments of the filter
+ */
+ libcoopgamma_ramps_t ramps;
+
} libcoopgamma_queried_filter_t;
@@ -649,82 +620,80 @@ typedef struct libcoopgamma_queried_filter
* list of applied filters and meta-information
* that was necessary for decoding the response
*/
-typedef struct libcoopgamma_filter_table
-{
- /**
- * The number of stops in the red ramp
- */
- size_t red_size;
-
- /**
- * The number of stops in the green ramp
- */
- size_t green_size;
-
- /**
- * The number of stops in the blue ramp
- */
- size_t blue_size;
-
- /**
- * The number of filters
- */
- size_t filter_count;
-
- /**
- * The filters, should be ordered by priority
- * in descending order, lest there is something
- * wrong with the coopgamma server
- *
- * If filter coalition was requested, there will
- * be exactly one filter (`.filter_count == 1`)
- * and `.filters->class == NULL` and
- * `.filters->priority` is undefined.
- */
- libcoopgamma_queried_filter_t* filters;
-
- /**
- * The data type and bit-depth of the ramp stops
- */
- libcoopgamma_depth_t depth;
-
+typedef struct libcoopgamma_filter_table {
+ /**
+ * The number of stops in the red ramp
+ */
+ size_t red_size;
+
+ /**
+ * The number of stops in the green ramp
+ */
+ size_t green_size;
+
+ /**
+ * The number of stops in the blue ramp
+ */
+ size_t blue_size;
+
+ /**
+ * The number of filters
+ */
+ size_t filter_count;
+
+ /**
+ * The filters, should be ordered by priority
+ * in descending order, lest there is something
+ * wrong with the coopgamma server
+ *
+ * If filter coalition was requested, there will
+ * be exactly one filter (`.filter_count == 1`)
+ * and `.filters->class == NULL` and
+ * `.filters->priority` is undefined.
+ */
+ libcoopgamma_queried_filter_t *filters;
+
+ /**
+ * The data type and bit-depth of the ramp stops
+ */
+ libcoopgamma_depth_t depth;
+
#if INT_MAX != LONG_MAX
- int padding__;
+ int padding__;
#endif
-
+
} libcoopgamma_filter_table_t;
/**
* Error message from coopgamma server
*/
-typedef struct libcoopgamma_error
-{
- /**
- * Error code
- *
- * If `.custom` is false, 0 indicates
- * success, otherwise, 0 indicates that
- * no error code has been assigned
- */
- uint64_t number;
-
- /**
- * Is this a custom error?
- */
- int custom;
-
- /**
- * Did the error occur on the server-side?
- */
- int server_side;
-
- /**
- * Error message, can be `NULL` if
- * `.custom` is false
- */
- char* description;
-
+typedef struct libcoopgamma_error {
+ /**
+ * Error code
+ *
+ * If `.custom` is false, 0 indicates
+ * success, otherwise, 0 indicates that
+ * no error code has been assigned
+ */
+ uint64_t number;
+
+ /**
+ * Is this a custom error?
+ */
+ int custom;
+
+ /**
+ * Did the error occur on the server-side?
+ */
+ int server_side;
+
+ /**
+ * Error message, can be `NULL` if
+ * `.custom` is false
+ */
+ char *description;
+
} libcoopgamma_error_t;
@@ -735,103 +704,102 @@ typedef struct libcoopgamma_error
* create one instance per thread that uses
* this structure
*/
-typedef struct libcoopgamma_context
-{
- /**
- * The error of the last failed function call
- *
- * This member is undefined after successful function call
- */
- libcoopgamma_error_t error;
-
- /**
- * File descriptor for the socket
- */
- int fd;
-
- /* The members below are internal. */
-
- /**
- * Whether `libcoopgamma_synchronise` have
- * read the empty end-of-headers line
- */
- int have_all_headers;
-
- /**
- * Whether `libcoopgamma_synchronise` is reading
- * a corrupt but recoverable message
- */
- int bad_message;
-
- /**
- * Is communication blocking?
- */
- int blocking;
-
- /**
- * Message ID of the next message
- */
- uint32_t message_id;
-
- /**
- * The ID of outbound message to which the inbound
- * message being read by `libcoopgamma_synchronise`
- * is a response
- */
- uint32_t in_response_to;
-
- /**
- * Buffer with the outbound message
- */
- char* outbound;
-
- /**
- * The write head for `outbound`
- */
- size_t outbound_head;
-
- /**
- * The read head for `outbound`
- */
- size_t outbound_tail;
-
- /**
- * The allocation size of `outbound`
- */
- size_t outbound_size;
-
- /**
- * Buffer with the inbound message
- */
- char* inbound;
-
- /**
- * The write head for `inbound`
- */
- size_t inbound_head;
-
- /**
- * The read head for `inbound`
- */
- size_t inbound_tail;
-
- /**
- * The allocation size of `inbound`
- */
- size_t inbound_size;
-
- /**
- * The value of 'Length' header in
- * the inbound message
- */
- size_t length;
-
- /**
- * The beginning of the current line that
- * is being read by `libcoopgamma_synchronise`
- */
- size_t curline;
-
+typedef struct libcoopgamma_context {
+ /**
+ * The error of the last failed function call
+ *
+ * This member is undefined after successful function call
+ */
+ libcoopgamma_error_t error;
+
+ /**
+ * File descriptor for the socket
+ */
+ int fd;
+
+ /* The members below are internal. */
+
+ /**
+ * Whether `libcoopgamma_synchronise` have
+ * read the empty end-of-headers line
+ */
+ int have_all_headers;
+
+ /**
+ * Whether `libcoopgamma_synchronise` is reading
+ * a corrupt but recoverable message
+ */
+ int bad_message;
+
+ /**
+ * Is communication blocking?
+ */
+ int blocking;
+
+ /**
+ * Message ID of the next message
+ */
+ uint32_t message_id;
+
+ /**
+ * The ID of outbound message to which the inbound
+ * message being read by `libcoopgamma_synchronise`
+ * is a response
+ */
+ uint32_t in_response_to;
+
+ /**
+ * Buffer with the outbound message
+ */
+ char *outbound;
+
+ /**
+ * The write head for `outbound`
+ */
+ size_t outbound_head;
+
+ /**
+ * The read head for `outbound`
+ */
+ size_t outbound_tail;
+
+ /**
+ * The allocation size of `outbound`
+ */
+ size_t outbound_size;
+
+ /**
+ * Buffer with the inbound message
+ */
+ char *inbound;
+
+ /**
+ * The write head for `inbound`
+ */
+ size_t inbound_head;
+
+ /**
+ * The read head for `inbound`
+ */
+ size_t inbound_tail;
+
+ /**
+ * The allocation size of `inbound`
+ */
+ size_t inbound_size;
+
+ /**
+ * The value of 'Length' header in
+ * the inbound message
+ */
+ size_t length;
+
+ /**
+ * The beginning of the current line that
+ * is being read by `libcoopgamma_synchronise`
+ */
+ size_t curline;
+
} libcoopgamma_context_t;
@@ -839,22 +807,21 @@ typedef struct libcoopgamma_context
* Information necessary to identify and
* parse a response from the server
*/
-typedef struct libcoopgamma_async_context
-{
- /* All members are internal. */
-
- /**
- * The value of the 'In response to' header
- * in the waited message
- */
- uint32_t message_id;
-
- /**
- * Whether to coalesce all filters
- * into one gamma ramp triplet
- */
- int coalesce;
-
+typedef struct libcoopgamma_async_context {
+ /* All members are internal. */
+
+ /**
+ * The value of the 'In response to' header
+ * in the waited message
+ */
+ uint32_t message_id;
+
+ /**
+ * Whether to coalesce all filters
+ * into one gamma ramp triplet
+ */
+ int coalesce;
+
} libcoopgamma_async_context_t;
@@ -868,8 +835,8 @@ typedef struct libcoopgamma_async_context
* @param this The record to initialise
* @return Zero on success, -1 on error
*/
-#define libcoopgamma_ramps_initialise(this) \
- (libcoopgamma_ramps_initialise_((this), sizeof(*((this)->red))))
+#define libcoopgamma_ramps_initialise(this)\
+ (libcoopgamma_ramps_initialise_((this), sizeof(*((this)->red))))
/**
* Marshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
@@ -881,8 +848,8 @@ typedef struct libcoopgamma_async_context
* @return The number of marshalled bytes, or if `buf == NULL`,
* how many bytes would be marshalled if `buf != NULL`
*/
-#define libcoopgamma_ramps_marshal(this, buf) \
- (libcoopgamma_ramps_marshal_((this), (buf), sizeof(*((this)->red))))
+#define libcoopgamma_ramps_marshal(this, buf)\
+ (libcoopgamma_ramps_marshal_((this), (buf), sizeof(*((this)->red))))
/**
* Unmarshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
@@ -894,8 +861,8 @@ typedef struct libcoopgamma_async_context
* @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
-#define libcoopgamma_ramps_unmarshal(this, buf, n) \
- (libcoopgamma_ramps_unmarshal_((this), (buf), (n), sizeof(*((this)->red))))
+#define libcoopgamma_ramps_unmarshal(this, buf, n)\
+ (libcoopgamma_ramps_unmarshal_((this), (buf), (n), sizeof(*((this)->red))))
/**
@@ -909,7 +876,7 @@ typedef struct libcoopgamma_async_context
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_ramps_initialise_(void* restrict, size_t);
+int libcoopgamma_ramps_initialise_(void *restrict, size_t);
/**
* Release all resources allocated to a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`,
@@ -923,7 +890,7 @@ int libcoopgamma_ramps_initialise_(void* restrict, size_t);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_ramps_destroy(void* restrict);
+void libcoopgamma_ramps_destroy(void *restrict);
/**
* Marshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
@@ -937,7 +904,7 @@ void libcoopgamma_ramps_destroy(void* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1), __leaf__)))
-size_t libcoopgamma_ramps_marshal_(const void* restrict, void* restrict, size_t);
+size_t libcoopgamma_ramps_marshal_(const void *restrict, void *restrict, size_t);
/**
* Unmarshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
@@ -951,7 +918,7 @@ size_t libcoopgamma_ramps_marshal_(const void* restrict, void* restrict, size_t)
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_ramps_unmarshal_(void* restrict, const void* restrict, size_t* restrict, size_t);
+int libcoopgamma_ramps_unmarshal_(void *restrict, const void *restrict, size_t *restrict, size_t);
/**
@@ -961,7 +928,7 @@ int libcoopgamma_ramps_unmarshal_(void* restrict, const void* restrict, size_t*
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_filter_initialise(libcoopgamma_filter_t* restrict);
+int libcoopgamma_filter_initialise(libcoopgamma_filter_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_filter_t`,
@@ -973,7 +940,7 @@ int libcoopgamma_filter_initialise(libcoopgamma_filter_t* restrict);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_filter_destroy(libcoopgamma_filter_t* restrict);
+void libcoopgamma_filter_destroy(libcoopgamma_filter_t *restrict);
/**
* Marshal a `libcoopgamma_filter_t` into a buffer
@@ -985,7 +952,7 @@ void libcoopgamma_filter_destroy(libcoopgamma_filter_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1))))
-size_t libcoopgamma_filter_marshal(const libcoopgamma_filter_t* restrict, void* restrict);
+size_t libcoopgamma_filter_marshal(const libcoopgamma_filter_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_filter_t` from a buffer
@@ -997,7 +964,7 @@ size_t libcoopgamma_filter_marshal(const libcoopgamma_filter_t* restrict, void*
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_filter_unmarshal(libcoopgamma_filter_t* restrict, const void* restrict, size_t* restrict);
+int libcoopgamma_filter_unmarshal(libcoopgamma_filter_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1007,7 +974,7 @@ int libcoopgamma_filter_unmarshal(libcoopgamma_filter_t* restrict, const void* r
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_crtc_info_initialise(libcoopgamma_crtc_info_t* restrict);
+int libcoopgamma_crtc_info_initialise(libcoopgamma_crtc_info_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_crtc_info_t`,
@@ -1019,7 +986,7 @@ int libcoopgamma_crtc_info_initialise(libcoopgamma_crtc_info_t* restrict);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_crtc_info_destroy(libcoopgamma_crtc_info_t* restrict);
+void libcoopgamma_crtc_info_destroy(libcoopgamma_crtc_info_t *restrict);
/**
* Marshal a `libcoopgamma_crtc_info_t` into a buffer
@@ -1031,7 +998,7 @@ void libcoopgamma_crtc_info_destroy(libcoopgamma_crtc_info_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1), __leaf__)))
-size_t libcoopgamma_crtc_info_marshal(const libcoopgamma_crtc_info_t* restrict, void* restrict);
+size_t libcoopgamma_crtc_info_marshal(const libcoopgamma_crtc_info_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_crtc_info_t` from a buffer
@@ -1043,8 +1010,7 @@ size_t libcoopgamma_crtc_info_marshal(const libcoopgamma_crtc_info_t* restrict,
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_crtc_info_unmarshal(libcoopgamma_crtc_info_t* restrict,
- const void* restrict, size_t* restrict);
+int libcoopgamma_crtc_info_unmarshal(libcoopgamma_crtc_info_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1054,7 +1020,7 @@ int libcoopgamma_crtc_info_unmarshal(libcoopgamma_crtc_info_t* restrict,
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_filter_query_initialise(libcoopgamma_filter_query_t* restrict);
+int libcoopgamma_filter_query_initialise(libcoopgamma_filter_query_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_filter_query_t`,
@@ -1066,7 +1032,7 @@ int libcoopgamma_filter_query_initialise(libcoopgamma_filter_query_t* restrict);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_filter_query_destroy(libcoopgamma_filter_query_t* restrict);
+void libcoopgamma_filter_query_destroy(libcoopgamma_filter_query_t *restrict);
/**
* Marshal a `libcoopgamma_filter_query_t` into a buffer
@@ -1078,7 +1044,7 @@ void libcoopgamma_filter_query_destroy(libcoopgamma_filter_query_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1), __leaf__)))
-size_t libcoopgamma_filter_query_marshal(const libcoopgamma_filter_query_t* restrict, void* restrict);
+size_t libcoopgamma_filter_query_marshal(const libcoopgamma_filter_query_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_filter_query_t` from a buffer
@@ -1090,8 +1056,7 @@ size_t libcoopgamma_filter_query_marshal(const libcoopgamma_filter_query_t* rest
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_filter_query_unmarshal(libcoopgamma_filter_query_t* restrict,
- const void* restrict, size_t* restrict);
+int libcoopgamma_filter_query_unmarshal(libcoopgamma_filter_query_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1101,7 +1066,7 @@ int libcoopgamma_filter_query_unmarshal(libcoopgamma_filter_query_t* restrict,
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_queried_filter_initialise(libcoopgamma_queried_filter_t* restrict);
+int libcoopgamma_queried_filter_initialise(libcoopgamma_queried_filter_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_queried_filter_t`,
@@ -1113,7 +1078,7 @@ int libcoopgamma_queried_filter_initialise(libcoopgamma_queried_filter_t* restri
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-void libcoopgamma_queried_filter_destroy(libcoopgamma_queried_filter_t* restrict);
+void libcoopgamma_queried_filter_destroy(libcoopgamma_queried_filter_t *restrict);
/**
* Marshal a `libcoopgamma_queried_filter_t` into a buffer
@@ -1126,8 +1091,7 @@ void libcoopgamma_queried_filter_destroy(libcoopgamma_queried_filter_t* restrict
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1))))
-size_t libcoopgamma_queried_filter_marshal(const libcoopgamma_queried_filter_t* restrict, void* restrict,
- libcoopgamma_depth_t);
+size_t libcoopgamma_queried_filter_marshal(const libcoopgamma_queried_filter_t *restrict, void *restrict, libcoopgamma_depth_t);
/**
* Unmarshal a `libcoopgamma_queried_filter_t` from a buffer
@@ -1140,8 +1104,8 @@ size_t libcoopgamma_queried_filter_marshal(const libcoopgamma_queried_filter_t*
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_queried_filter_unmarshal(libcoopgamma_queried_filter_t* restrict,
- const void* restrict, size_t* restrict, libcoopgamma_depth_t);
+int libcoopgamma_queried_filter_unmarshal(libcoopgamma_queried_filter_t *restrict, const void *restrict,
+ size_t *restrict, libcoopgamma_depth_t);
/**
@@ -1151,7 +1115,7 @@ int libcoopgamma_queried_filter_unmarshal(libcoopgamma_queried_filter_t* restric
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_filter_table_initialise(libcoopgamma_filter_table_t* restrict);
+int libcoopgamma_filter_table_initialise(libcoopgamma_filter_table_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_filter_table_t`,
@@ -1163,7 +1127,7 @@ int libcoopgamma_filter_table_initialise(libcoopgamma_filter_table_t* restrict);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-void libcoopgamma_filter_table_destroy(libcoopgamma_filter_table_t* restrict);
+void libcoopgamma_filter_table_destroy(libcoopgamma_filter_table_t *restrict);
/**
* Marshal a `libcoopgamma_filter_table_t` into a buffer
@@ -1175,7 +1139,7 @@ void libcoopgamma_filter_table_destroy(libcoopgamma_filter_table_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1))))
-size_t libcoopgamma_filter_table_marshal(const libcoopgamma_filter_table_t* restrict, void* restrict);
+size_t libcoopgamma_filter_table_marshal(const libcoopgamma_filter_table_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_filter_table_t` from a buffer
@@ -1187,8 +1151,7 @@ size_t libcoopgamma_filter_table_marshal(const libcoopgamma_filter_table_t* rest
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_filter_table_unmarshal(libcoopgamma_filter_table_t* restrict,
- const void* restrict, size_t* restrict);
+int libcoopgamma_filter_table_unmarshal(libcoopgamma_filter_table_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1198,7 +1161,7 @@ int libcoopgamma_filter_table_unmarshal(libcoopgamma_filter_table_t* restrict,
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_error_initialise(libcoopgamma_error_t* restrict);
+int libcoopgamma_error_initialise(libcoopgamma_error_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_error_t`,
@@ -1210,7 +1173,7 @@ int libcoopgamma_error_initialise(libcoopgamma_error_t* restrict);
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_error_destroy(libcoopgamma_error_t* restrict);
+void libcoopgamma_error_destroy(libcoopgamma_error_t *restrict);
/**
* Marshal a `libcoopgamma_error_t` into a buffer
@@ -1222,7 +1185,7 @@ void libcoopgamma_error_destroy(libcoopgamma_error_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1), __leaf__)))
-size_t libcoopgamma_error_marshal(const libcoopgamma_error_t* restrict, void* restrict);
+size_t libcoopgamma_error_marshal(const libcoopgamma_error_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_error_t` from a buffer
@@ -1234,7 +1197,7 @@ size_t libcoopgamma_error_marshal(const libcoopgamma_error_t* restrict, void* re
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_error_unmarshal(libcoopgamma_error_t* restrict, const void* restrict, size_t* restrict);
+int libcoopgamma_error_unmarshal(libcoopgamma_error_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1244,7 +1207,7 @@ int libcoopgamma_error_unmarshal(libcoopgamma_error_t* restrict, const void* res
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_context_initialise(libcoopgamma_context_t* restrict);
+int libcoopgamma_context_initialise(libcoopgamma_context_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_context_t`,
@@ -1257,7 +1220,7 @@ int libcoopgamma_context_initialise(libcoopgamma_context_t* restrict);
* @param disconnect Disconnect from the server?
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-void libcoopgamma_context_destroy(libcoopgamma_context_t* restrict, int);
+void libcoopgamma_context_destroy(libcoopgamma_context_t *restrict, int);
/**
* Marshal a `libcoopgamma_context_t` into a buffer
@@ -1269,7 +1232,7 @@ void libcoopgamma_context_destroy(libcoopgamma_context_t* restrict, int);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1))))
-size_t libcoopgamma_context_marshal(const libcoopgamma_context_t* restrict, void* restrict);
+size_t libcoopgamma_context_marshal(const libcoopgamma_context_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_context_t` from a buffer
@@ -1281,7 +1244,7 @@ size_t libcoopgamma_context_marshal(const libcoopgamma_context_t* restrict, void
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_context_unmarshal(libcoopgamma_context_t* restrict, const void* restrict, size_t* restrict);
+int libcoopgamma_context_unmarshal(libcoopgamma_context_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1291,7 +1254,7 @@ int libcoopgamma_context_unmarshal(libcoopgamma_context_t* restrict, const void*
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_async_context_initialise(libcoopgamma_async_context_t* restrict);
+int libcoopgamma_async_context_initialise(libcoopgamma_async_context_t *restrict);
/**
* Release all resources allocated to a `libcoopgamma_async_context_t`,
@@ -1303,7 +1266,7 @@ int libcoopgamma_async_context_initialise(libcoopgamma_async_context_t* restrict
* @param this The record to destroy
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-void libcoopgamma_async_context_destroy(libcoopgamma_async_context_t* restrict);
+void libcoopgamma_async_context_destroy(libcoopgamma_async_context_t *restrict);
/**
* Marshal a `libcoopgamma_async_context_t` into a buffer
@@ -1315,7 +1278,7 @@ void libcoopgamma_async_context_destroy(libcoopgamma_async_context_t* restrict);
* how many bytes would be marshalled if `buf != NULL`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1), __leaf__)))
-size_t libcoopgamma_async_context_marshal(const libcoopgamma_async_context_t* restrict, void* restrict);
+size_t libcoopgamma_async_context_marshal(const libcoopgamma_async_context_t *restrict, void *restrict);
/**
* Unmarshal a `libcoopgamma_async_context_t` from a buffer
@@ -1327,8 +1290,7 @@ size_t libcoopgamma_async_context_marshal(const libcoopgamma_async_context_t* re
* `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_async_context_unmarshal(libcoopgamma_async_context_t* restrict, const void* restrict,
- size_t* restrict);
+int libcoopgamma_async_context_unmarshal(libcoopgamma_async_context_t *restrict, const void *restrict, size_t *restrict);
/**
@@ -1341,7 +1303,7 @@ int libcoopgamma_async_context_unmarshal(libcoopgamma_async_context_t* restrict,
* outer pointer and cannot be freed. `NULL` on error.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__malloc__)))
-char** libcoopgamma_get_methods(void);
+char **libcoopgamma_get_methods(void);
/**
* Get the adjustment method and site
@@ -1360,8 +1322,7 @@ char** libcoopgamma_get_methods(void);
* with this parameter set to `NULL`.
* @return Zero on success, -1 on error
*/
-int libcoopgamma_get_method_and_site(const char* restrict, const char* restrict,
- char** restrict, char** restrict);
+int libcoopgamma_get_method_and_site(const char *restrict, const char *restrict, char **restrict, char **restrict);
/**
* Get the PID file of the coopgamma server
@@ -1375,7 +1336,7 @@ int libcoopgamma_get_method_and_site(const char* restrict, const char* restrict,
* case is detected by checking that `errno` is set to 0.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__malloc__)))
-char* libcoopgamma_get_pid_file(const char* restrict, const char* restrict);
+char *libcoopgamma_get_pid_file(const char *restrict, const char *restrict);
/**
* Get the socket file of the coopgamma server
@@ -1391,7 +1352,7 @@ char* libcoopgamma_get_pid_file(const char* restrict, const char* restrict);
* multi-server display server like mds.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__malloc__)))
-char* libcoopgamma_get_socket_file(const char* restrict, const char* restrict);
+char *libcoopgamma_get_socket_file(const char *restrict, const char *restrict);
/**
@@ -1408,7 +1369,7 @@ char* libcoopgamma_get_socket_file(const char* restrict, const char* restrict);
* to 0 if the server could not be initialised.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(3))))
-int libcoopgamma_connect(const char* restrict, const char* restrict, libcoopgamma_context_t* restrict);
+int libcoopgamma_connect(const char *restrict, const char *restrict, libcoopgamma_context_t *restrict);
/**
* By default communication is blocking, this function
@@ -1426,7 +1387,7 @@ int libcoopgamma_connect(const char* restrict, const char* restrict, libcoopgamm
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_set_nonblocking(libcoopgamma_context_t* restrict, int);
+int libcoopgamma_set_nonblocking(libcoopgamma_context_t *restrict, int);
/**
* Send all pending outbound data
@@ -1441,7 +1402,7 @@ int libcoopgamma_set_nonblocking(libcoopgamma_context_t* restrict, int);
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__, __leaf__)))
-int libcoopgamma_flush(libcoopgamma_context_t* restrict);
+int libcoopgamma_flush(libcoopgamma_context_t *restrict);
/**
* Wait for the next message to be received
@@ -1463,8 +1424,7 @@ int libcoopgamma_flush(libcoopgamma_context_t* restrict);
* beyond recover.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__(1, 4), __leaf__)))
-int libcoopgamma_synchronise(libcoopgamma_context_t* restrict, libcoopgamma_async_context_t* restrict,
- size_t, size_t* restrict);
+int libcoopgamma_synchronise(libcoopgamma_context_t *restrict, libcoopgamma_async_context_t *restrict, size_t, size_t *restrict);
/**
* Tell the library that you will not be parsing a receive message
@@ -1472,7 +1432,7 @@ int libcoopgamma_synchronise(libcoopgamma_context_t* restrict, libcoopgamma_asyn
* @param ctx The state of the library, must be connected
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-void libcoopgamma_skip_message(libcoopgamma_context_t* restrict);
+void libcoopgamma_skip_message(libcoopgamma_context_t *restrict);
/**
@@ -1486,7 +1446,7 @@ void libcoopgamma_skip_message(libcoopgamma_context_t* restrict);
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_crtcs_send(libcoopgamma_context_t* restrict, libcoopgamma_async_context_t* restrict);
+int libcoopgamma_get_crtcs_send(libcoopgamma_context_t *restrict, libcoopgamma_async_context_t *restrict);
/**
* List all available CRTC:s, receive response part
@@ -1500,7 +1460,7 @@ int libcoopgamma_get_crtcs_send(libcoopgamma_context_t* restrict, libcoopgamma_a
* for information about the error.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__malloc__, __nonnull__)))
-char** libcoopgamma_get_crtcs_recv(libcoopgamma_context_t* restrict, libcoopgamma_async_context_t* restrict);
+char **libcoopgamma_get_crtcs_recv(libcoopgamma_context_t *restrict, libcoopgamma_async_context_t *restrict);
/**
* List all available CRTC:s, synchronous version
@@ -1520,7 +1480,7 @@ char** libcoopgamma_get_crtcs_recv(libcoopgamma_context_t* restrict, libcoopgamm
* for information about the error.
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__malloc__, __nonnull__)))
-char** libcoopgamma_get_crtcs_sync(libcoopgamma_context_t* restrict);
+char **libcoopgamma_get_crtcs_sync(libcoopgamma_context_t *restrict);
/**
@@ -1535,8 +1495,7 @@ char** libcoopgamma_get_crtcs_sync(libcoopgamma_context_t* restrict);
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_info_send(const char* restrict, libcoopgamma_context_t* restrict,
- libcoopgamma_async_context_t* restrict);
+int libcoopgamma_get_gamma_info_send(const char *restrict, libcoopgamma_context_t *restrict, libcoopgamma_async_context_t *restrict);
/**
* Retrieve information about a CRTC:s gamma ramps, receive response part
@@ -1548,8 +1507,8 @@ int libcoopgamma_get_gamma_info_send(const char* restrict, libcoopgamma_context_
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_info_recv(libcoopgamma_crtc_info_t* restrict, libcoopgamma_context_t* restrict,
- libcoopgamma_async_context_t* restrict);
+int libcoopgamma_get_gamma_info_recv(libcoopgamma_crtc_info_t *restrict, libcoopgamma_context_t *restrict,
+ libcoopgamma_async_context_t *restrict);
/**
* Retrieve information about a CRTC:s gamma ramps, synchronous version
@@ -1568,8 +1527,7 @@ int libcoopgamma_get_gamma_info_recv(libcoopgamma_crtc_info_t* restrict, libcoop
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_info_sync(const char* restrict, libcoopgamma_crtc_info_t* restrict,
- libcoopgamma_context_t* restrict);
+int libcoopgamma_get_gamma_info_sync(const char *restrict, libcoopgamma_crtc_info_t *restrict, libcoopgamma_context_t *restrict);
/**
@@ -1584,8 +1542,8 @@ int libcoopgamma_get_gamma_info_sync(const char* restrict, libcoopgamma_crtc_inf
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_send(const libcoopgamma_filter_query_t* restrict, libcoopgamma_context_t* restrict,
- libcoopgamma_async_context_t* restrict);
+int libcoopgamma_get_gamma_send(const libcoopgamma_filter_query_t *restrict, libcoopgamma_context_t *restrict,
+ libcoopgamma_async_context_t *restrict);
/**
* Retrieve the current gamma ramp adjustments, receive response part
@@ -1597,8 +1555,8 @@ int libcoopgamma_get_gamma_send(const libcoopgamma_filter_query_t* restrict, lib
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_recv(libcoopgamma_filter_table_t* restrict, libcoopgamma_context_t* restrict,
- libcoopgamma_async_context_t* restrict);
+int libcoopgamma_get_gamma_recv(libcoopgamma_filter_table_t *restrict, libcoopgamma_context_t *restrict,
+ libcoopgamma_async_context_t *restrict);
/**
* Retrieve the current gamma ramp adjustments, synchronous version
@@ -1617,9 +1575,9 @@ int libcoopgamma_get_gamma_recv(libcoopgamma_filter_table_t* restrict, libcoopga
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_get_gamma_sync(const libcoopgamma_filter_query_t* restrict,
- libcoopgamma_filter_table_t* restrict,
- libcoopgamma_context_t* restrict);
+int libcoopgamma_get_gamma_sync(const libcoopgamma_filter_query_t *restrict,
+ libcoopgamma_filter_table_t *restrict,
+ libcoopgamma_context_t *restrict);
/**
@@ -1634,8 +1592,8 @@ int libcoopgamma_get_gamma_sync(const libcoopgamma_filter_query_t* restrict,
* @return Zero on success, -1 on error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_set_gamma_send(const libcoopgamma_filter_t* restrict,
- libcoopgamma_context_t* restrict, libcoopgamma_async_context_t* restrict);
+int libcoopgamma_set_gamma_send(const libcoopgamma_filter_t *restrict, libcoopgamma_context_t *restrict,
+ libcoopgamma_async_context_t *restrict);
/**
* Apply, update, or remove a gamma ramp adjustment, receive response part
@@ -1646,7 +1604,7 @@ int libcoopgamma_set_gamma_send(const libcoopgamma_filter_t* restrict,
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_set_gamma_recv(libcoopgamma_context_t* restrict, libcoopgamma_async_context_t* restrict);
+int libcoopgamma_set_gamma_recv(libcoopgamma_context_t *restrict, libcoopgamma_async_context_t *restrict);
/**
* Apply, update, or remove a gamma ramp adjustment, synchronous version
@@ -1664,7 +1622,7 @@ int libcoopgamma_set_gamma_recv(libcoopgamma_context_t* restrict, libcoopgamma_a
* (rather than `errno`) is read for information about the error
*/
LIBCOOPGAMMA_GCC_ONLY(__attribute__((__nonnull__)))
-int libcoopgamma_set_gamma_sync(const libcoopgamma_filter_t* restrict, libcoopgamma_context_t* restrict);
+int libcoopgamma_set_gamma_sync(const libcoopgamma_filter_t *restrict, libcoopgamma_context_t *restrict);
@@ -1674,7 +1632,4 @@ int libcoopgamma_set_gamma_sync(const libcoopgamma_filter_t* restrict, libcoopga
#undef LIBCOOPGAMMA_GCC_ONLY
-
-
#endif
-
diff --git a/src/libcoopgamma.c b/src/libcoopgamma.c
deleted file mode 100644
index 40baf77..0000000
--- a/src/libcoopgamma.c
+++ /dev/null
@@ -1,2620 +0,0 @@
-/**
- * libcoopgamma -- Library for interfacing with cooperative gamma servers
- * 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/>.
- */
-#define _DEFAULT_SOURCE
-#define _BSD_SOURCE
-
-#include "libcoopgamma.h"
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-#if !defined(COOPGAMMAD)
-# define COOPGAMMAD "coopgammad"
-#endif
-
-
-
-#if defined(__clang__)
-# pragma GCC diagnostic ignored "-Wdocumentation"
-# pragma GCC diagnostic ignored "-Wcovered-switch-default"
-# pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-
-
-
-#if defined(__GNUC__)
-# define NAME_OF_THE_PROCESS (argv0)
-extern const char* argv0;
-const char* argv0 __attribute__((weak)) = "libcoopgamma";
-#else
-# define NAME_OF_THE_PROCESS ("libcoopgamma")
-#endif
-
-
-
-#define SUBBUF \
- (buf ? buf + off : NULL)
-
-#define NNSUBBUF \
- (buf + off)
-
-#define MARSHAL_PROLOGUE \
- char* restrict buf = vbuf; \
- size_t off = 0;
-
-#define UNMARSHAL_PROLOGUE \
- const char* restrict buf = vbuf; \
- size_t off = 0;
-
-#define MARSHAL_EPILOGUE \
- return off
-
-#define UNMARSHAL_EPILOGUE \
- return *np = off, LIBCOOPGAMMA_SUCCESS
-
-#define marshal_prim(datum, type) \
- ((buf != NULL ? *(type*)(buf + off) = (datum) : 0), off += sizeof(type))
-
-#define unmarshal_prim(datum, type) \
- ((datum) = *(const type*)(buf + off), off += sizeof(type))
-
-#define marshal_version(version) \
- marshal_prim(version, int)
-
-#define unmarshal_version(version) \
- do \
- { \
- int version__; \
- unmarshal_prim(version__, int); \
- if (version__ < (version)) \
- return LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE; \
- if (version__ > (version)) \
- return LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE; \
- } \
- while (0)
-
-#define marshal_buffer(data, n) \
- ((buf != NULL ? (memcpy(buf + off, (data), (n)), 0) : 0), off += (n))
-
-#define unmarshal_buffer(data, n) \
- do \
- { \
- (data) = malloc(n); \
- if ((data) == NULL) \
- return LIBCOOPGAMMA_ERRNO_SET; \
- memcpy((data), buf + off, (n)); \
- off += (n); \
- } \
- while (0)
-
-#define marshal_string(datum) \
- ((datum) == NULL ? marshal_prim(0, char) : \
- (marshal_prim(1, char), marshal_buffer((datum), strlen(datum) + 1)))
-
-#define unmarshal_string(datum) \
- do \
- { \
- char nonnull__; \
- unmarshal_prim(nonnull__, char); \
- if (nonnull__) \
- unmarshal_buffer((datum), strlen(buf + off) + 1); \
- else \
- (datum) = NULL; \
- } \
- while (0)
-
-
-
-#define copy_errno(ctx) \
- ((errno == 0) ? NULL : \
- ((ctx)->error.number = (uint64_t)errno, \
- (ctx)->error.custom = 0, \
- (ctx)->error.server_side = 0, \
- free((ctx)->error.description), \
- (ctx)->error.description = NULL))
-
-
-#define SYNC_CALL(send_call, recv_call, fail_return) \
- libcoopgamma_async_context_t async; \
- size_t _selected; \
- if (send_call < 0) \
- { \
- reflush: \
- if (errno != EINTR) \
- return fail_return; \
- if (libcoopgamma_flush(ctx) < 0) \
- goto reflush; \
- } \
-resync: \
- if (libcoopgamma_synchronise(ctx, &async, (size_t)1, &_selected) < 0) \
- { \
- if ((errno != EINTR) && (errno != 0)) \
- return fail_return; \
- goto resync; \
- } \
- return recv_call
-
-
-#define INTEGRAL_DEPTHS \
- case LIBCOOPGAMMA_UINT8: \
- case LIBCOOPGAMMA_UINT16: \
- case LIBCOOPGAMMA_UINT32: \
- case LIBCOOPGAMMA_UINT64:
-
-
-
-/**
- * Initialise a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
- * `libcoopgamma_ramps64_t`, `libcoopgamma_rampsf_t`, or `libcoopgamma_rampsd_t`
- *
- * `this->red_size`, `this->green_size`, and `this->blue_size` must already be set
- *
- * @param this The record to initialise
- * @param width The `sizeof(*(this->red))`
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_ramps_initialise_(void* restrict this, size_t width)
-{
- libcoopgamma_ramps8_t* restrict this8 = (libcoopgamma_ramps8_t* restrict)this;
- this8->red = this8->green = this8->blue = NULL;
- this8->red = malloc((this8->red_size + this8->green_size + this8->blue_size) * width);
- if (this8->red == NULL)
- return -1;
- this8->green = this8->red + this8->red_size * width;
- this8->blue = this8->green + this8->green_size * width;
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`,
- * `libcoopgamma_ramps32_t`, `libcoopgamma_ramps64_t`, `libcoopgamma_rampsf_t`,
- * `libcoopgamma_rampsd_t`, or `libcoopgamma_ramps_t`, the allocation of the record
- * itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_ramps_initialise`
- * or failed call to `libcoopgamma_ramps_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_ramps_destroy(void* restrict this)
-{
- libcoopgamma_ramps8_t* restrict this8 = (libcoopgamma_ramps8_t* restrict)this;
- free(this8->red);
- this8->red = this8->green = this8->blue = NULL;
-}
-
-
-/**
- * Marshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
- * `libcoopgamma_ramps64_t`, `libcoopgamma_rampsf_t`, or `libcoopgamma_rampsd_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @param width The `sizeof(*(this->red))`
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_ramps_marshal_(const void* restrict this, void* restrict vbuf, size_t width)
-{
- const libcoopgamma_ramps8_t* restrict this8 = (const libcoopgamma_ramps8_t* restrict)this;
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_RAMPS_VERSION);
- marshal_prim(this8->red_size, size_t);
- marshal_prim(this8->green_size, size_t);
- marshal_prim(this8->blue_size, size_t);
- marshal_buffer(this8->red, (this8->red_size + this8->green_size + this8->blue_size) * width);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_ramps8_t`, `libcoopgamma_ramps16_t`, `libcoopgamma_ramps32_t`,
- * `libcoopgamma_ramps64_t`, `libcoopgamma_rampsf_t`, or `libcoopgamma_rampsd_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @param width The `sizeof(*(this->red))`
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_ramps_unmarshal_(void* restrict this, const void* restrict vbuf,
- size_t* restrict np, size_t width)
-{
- libcoopgamma_ramps8_t* restrict this8 = (libcoopgamma_ramps8_t* restrict)this;
- UNMARSHAL_PROLOGUE;
- unmarshal_version(LIBCOOPGAMMA_RAMPS_VERSION);
- unmarshal_prim(this8->red_size, size_t);
- unmarshal_prim(this8->green_size, size_t);
- unmarshal_prim(this8->blue_size, size_t);
- unmarshal_buffer(this8->red, (this8->red_size + this8->green_size + this8->blue_size) * width);
- this8->green = this8->red + this8->red_size * width;
- this8->blue = this8->green + this8->green_size * width;
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_filter_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_filter_initialise(libcoopgamma_filter_t* restrict this)
-{
- memset(this, 0, sizeof(*this));
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_filter_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_filter_initialise`
- * or failed call to `libcoopgamma_filter_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_filter_destroy(libcoopgamma_filter_t* restrict this)
-{
- free(this->crtc);
- free(this->class);
- free(this->ramps.u8.red);
- memset(this, 0, sizeof(*this));
-}
-
-
-/**
- * Marshal a `libcoopgamma_filter_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_filter_marshal(const libcoopgamma_filter_t* restrict this, void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_FILTER_VERSION);
- marshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- marshal_version(LIBCOOPGAMMA_LIFESPAN_VERSION);
- marshal_prim(this->depth, libcoopgamma_depth_t);
- marshal_prim(this->priority, int64_t);
- marshal_string(this->crtc);
- marshal_string(this->class);
- marshal_prim(this->lifespan, libcoopgamma_lifespan_t);
- switch (this->depth)
- {
- case LIBCOOPGAMMA_UINT8: off += libcoopgamma_ramps_marshal(&(this->ramps.u8), SUBBUF); break;
- case LIBCOOPGAMMA_UINT16: off += libcoopgamma_ramps_marshal(&(this->ramps.u16), SUBBUF); break;
- case LIBCOOPGAMMA_UINT32: off += libcoopgamma_ramps_marshal(&(this->ramps.u32), SUBBUF); break;
- case LIBCOOPGAMMA_UINT64: off += libcoopgamma_ramps_marshal(&(this->ramps.u64), SUBBUF); break;
- case LIBCOOPGAMMA_FLOAT: off += libcoopgamma_ramps_marshal(&(this->ramps.f), SUBBUF); break;
- case LIBCOOPGAMMA_DOUBLE: off += libcoopgamma_ramps_marshal(&(this->ramps.d), SUBBUF); break;
- default:
- break;
- }
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_filter_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_filter_unmarshal(libcoopgamma_filter_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- int r = LIBCOOPGAMMA_SUCCESS;
- size_t n = 0;
- UNMARSHAL_PROLOGUE;
- memset(this, 0, sizeof(*this));
- unmarshal_version(LIBCOOPGAMMA_FILTER_VERSION);
- unmarshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- unmarshal_version(LIBCOOPGAMMA_LIFESPAN_VERSION);
- unmarshal_prim(this->depth, libcoopgamma_depth_t);
- unmarshal_prim(this->priority, int64_t);
- unmarshal_string(this->crtc);
- unmarshal_string(this->class);
- unmarshal_prim(this->lifespan, libcoopgamma_lifespan_t);
- switch (this->depth)
- {
- case LIBCOOPGAMMA_UINT8: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u8), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT16: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u16), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT32: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u32), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT64: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u64), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_FLOAT: r = libcoopgamma_ramps_unmarshal(&(this->ramps.f), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_DOUBLE: r = libcoopgamma_ramps_unmarshal(&(this->ramps.d), NNSUBBUF, &n); break;
- default:
- break;
- }
- if (r != LIBCOOPGAMMA_SUCCESS)
- return r;
- off += n;
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_crtc_info_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_crtc_info_initialise(libcoopgamma_crtc_info_t* restrict this)
-{
- memset(this, 0, sizeof(*this));
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_crtc_info_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_crtc_info_initialise`
- * or failed call to `libcoopgamma_crtc_info_unmarshal`
- *
- * @param this The record to destroy
- */
-#if defined(__GNUC__)
-__attribute__((__const__))
-#endif
-void libcoopgamma_crtc_info_destroy(libcoopgamma_crtc_info_t* restrict this)
-{
- (void) this;
-}
-
-
-/**
- * Marshal a `libcoopgamma_crtc_info_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_crtc_info_marshal(const libcoopgamma_crtc_info_t* restrict this, void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_CRTC_INFO_VERSION);
- marshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- marshal_version(LIBCOOPGAMMA_SUPPORT_VERSION);
- marshal_version(LIBCOOPGAMMA_COLOURSPACE_VERSION);
- marshal_prim(this->cooperative, int);
- marshal_prim(this->depth, libcoopgamma_depth_t);
- marshal_prim(this->red_size, size_t);
- marshal_prim(this->green_size, size_t);
- marshal_prim(this->blue_size, size_t);
- marshal_prim(this->supported, libcoopgamma_support_t);
- marshal_prim(this->colourspace, libcoopgamma_colourspace_t);
- marshal_prim(this->have_gamut, int);
- marshal_prim(this->red_x, unsigned);
- marshal_prim(this->red_y, unsigned);
- marshal_prim(this->green_x, unsigned);
- marshal_prim(this->green_y, unsigned);
- marshal_prim(this->blue_x, unsigned);
- marshal_prim(this->blue_y, unsigned);
- marshal_prim(this->white_x, unsigned);
- marshal_prim(this->white_y, unsigned);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_crtc_info_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_crtc_info_unmarshal(libcoopgamma_crtc_info_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- UNMARSHAL_PROLOGUE;
- unmarshal_version(LIBCOOPGAMMA_CRTC_INFO_VERSION);
- unmarshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- unmarshal_version(LIBCOOPGAMMA_SUPPORT_VERSION);
- unmarshal_version(LIBCOOPGAMMA_COLOURSPACE_VERSION);
- unmarshal_prim(this->cooperative, int);
- unmarshal_prim(this->depth, libcoopgamma_depth_t);
- unmarshal_prim(this->red_size, size_t);
- unmarshal_prim(this->green_size, size_t);
- unmarshal_prim(this->blue_size, size_t);
- unmarshal_prim(this->supported, libcoopgamma_support_t);
- unmarshal_prim(this->colourspace, libcoopgamma_colourspace_t);
- unmarshal_prim(this->have_gamut, int);
- unmarshal_prim(this->red_x, unsigned);
- unmarshal_prim(this->red_y, unsigned);
- unmarshal_prim(this->green_x, unsigned);
- unmarshal_prim(this->green_y, unsigned);
- unmarshal_prim(this->blue_x, unsigned);
- unmarshal_prim(this->blue_y, unsigned);
- unmarshal_prim(this->white_x, unsigned);
- unmarshal_prim(this->white_y, unsigned);
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_filter_query_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_filter_query_initialise(libcoopgamma_filter_query_t* restrict this)
-{
- this->crtc = NULL;
- this->coalesce = 0;
- this->high_priority = INT64_MAX;
- this->low_priority = INT64_MIN;
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_filter_query_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_filter_query_initialise`
- * or failed call to `libcoopgamma_filter_query_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_filter_query_destroy(libcoopgamma_filter_query_t* restrict this)
-{
- free(this->crtc), this->crtc = NULL;
-}
-
-
-/**
- * Marshal a `libcoopgamma_filter_query_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_filter_query_marshal(const libcoopgamma_filter_query_t* restrict this, void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_FILTER_QUERY_VERSION);
- marshal_string(this->crtc);
- marshal_prim(this->coalesce, int);
- marshal_prim(this->high_priority, int64_t);
- marshal_prim(this->low_priority, int64_t);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_filter_query_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_filter_query_unmarshal(libcoopgamma_filter_query_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- UNMARSHAL_PROLOGUE;
- this->crtc = NULL;
- unmarshal_version(LIBCOOPGAMMA_FILTER_QUERY_VERSION);
- unmarshal_string(this->crtc);
- unmarshal_prim(this->coalesce, int);
- unmarshal_prim(this->high_priority, int64_t);
- unmarshal_prim(this->low_priority, int64_t);
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_queried_filter_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_queried_filter_initialise(libcoopgamma_queried_filter_t* restrict this)
-{
- memset(this, 0, sizeof(*this));
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_queried_filter_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_queried_filter_initialise`
- * or failed call to `libcoopgamma_queried_filter_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_queried_filter_destroy(libcoopgamma_queried_filter_t* restrict this)
-{
- free(this->class), this->class = NULL;
- libcoopgamma_ramps_destroy(&(this->ramps.u8));
-}
-
-
-/**
- * Marshal a `libcoopgamma_queried_filter_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @param depth The type used of ramp stops
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_queried_filter_marshal(const libcoopgamma_queried_filter_t* restrict this,
- void* restrict vbuf, libcoopgamma_depth_t depth)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_QUERIED_FILTER_VERSION);
- marshal_prim(this->priority, int64_t);
- marshal_string(this->class);
- switch (depth)
- {
- case LIBCOOPGAMMA_UINT8: off += libcoopgamma_ramps_marshal(&(this->ramps.u8), SUBBUF); break;
- case LIBCOOPGAMMA_UINT16: off += libcoopgamma_ramps_marshal(&(this->ramps.u16), SUBBUF); break;
- case LIBCOOPGAMMA_UINT32: off += libcoopgamma_ramps_marshal(&(this->ramps.u32), SUBBUF); break;
- case LIBCOOPGAMMA_UINT64: off += libcoopgamma_ramps_marshal(&(this->ramps.u64), SUBBUF); break;
- case LIBCOOPGAMMA_FLOAT: off += libcoopgamma_ramps_marshal(&(this->ramps.f), SUBBUF); break;
- case LIBCOOPGAMMA_DOUBLE: off += libcoopgamma_ramps_marshal(&(this->ramps.d), SUBBUF); break;
- default:
- break;
- }
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_queried_filter_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @param depth The type used of ramp stops
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_queried_filter_unmarshal(libcoopgamma_queried_filter_t* restrict this,
- const void* restrict vbuf, size_t* restrict np,
- libcoopgamma_depth_t depth)
-{
- int r = LIBCOOPGAMMA_SUCCESS;
- size_t n = 0;
- UNMARSHAL_PROLOGUE;
- memset(this, 0, sizeof(*this));
- unmarshal_version(LIBCOOPGAMMA_QUERIED_FILTER_VERSION);
- unmarshal_prim(this->priority, int64_t);
- unmarshal_string(this->class);
- switch (depth)
- {
- case LIBCOOPGAMMA_UINT8: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u8), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT16: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u16), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT32: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u32), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_UINT64: r = libcoopgamma_ramps_unmarshal(&(this->ramps.u64), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_FLOAT: r = libcoopgamma_ramps_unmarshal(&(this->ramps.f), NNSUBBUF, &n); break;
- case LIBCOOPGAMMA_DOUBLE: r = libcoopgamma_ramps_unmarshal(&(this->ramps.d), NNSUBBUF, &n); break;
- default:
- break;
- }
- if (r != LIBCOOPGAMMA_SUCCESS)
- return r;
- off += n;
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_filter_table_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_filter_table_initialise(libcoopgamma_filter_table_t* restrict this)
-{
- memset(this, 0, sizeof(*this));
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_filter_table_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_filter_table_initialise`
- * or failed call to `libcoopgamma_filter_table_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_filter_table_destroy(libcoopgamma_filter_table_t* restrict this)
-{
- while (this->filter_count)
- libcoopgamma_queried_filter_destroy(this->filters + --(this->filter_count));
- free(this->filters), this->filters = NULL;
-}
-
-
-/**
- * Marshal a `libcoopgamma_filter_table_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_filter_table_marshal(const libcoopgamma_filter_table_t* restrict this, void* restrict vbuf)
-{
- size_t i;
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_FILTER_TABLE_VERSION);
- marshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- marshal_prim(this->depth, libcoopgamma_depth_t);
- marshal_prim(this->red_size, size_t);
- marshal_prim(this->green_size, size_t);
- marshal_prim(this->blue_size, size_t);
- marshal_prim(this->filter_count, size_t);
- for (i = 0; i < this->filter_count; i++)
- off += libcoopgamma_queried_filter_marshal(this->filters + i, SUBBUF, this->depth);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_filter_table_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_filter_table_unmarshal(libcoopgamma_filter_table_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- size_t i, n, fn;
- int r;
- UNMARSHAL_PROLOGUE;
- this->filter_count = 0;
- this->filters = NULL;
- unmarshal_version(LIBCOOPGAMMA_FILTER_TABLE_VERSION);
- unmarshal_version(LIBCOOPGAMMA_DEPTH_VERSION);
- unmarshal_prim(this->depth, libcoopgamma_depth_t);
- unmarshal_prim(this->red_size, size_t);
- unmarshal_prim(this->green_size, size_t);
- unmarshal_prim(this->blue_size, size_t);
- unmarshal_prim(fn, size_t);
- this->filters = malloc(fn * sizeof(*(this->filters)));
- if (this->filters == NULL)
- return LIBCOOPGAMMA_ERRNO_SET;
- for (i = 0; i < fn; i++)
- {
- r = libcoopgamma_queried_filter_unmarshal(this->filters + i, NNSUBBUF, &n, this->depth);
- if (r != LIBCOOPGAMMA_SUCCESS)
- return r;
- off += n;
- this->filter_count += 1;
- }
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_error_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_error_initialise(libcoopgamma_error_t* restrict this)
-{
- this->number = 0;
- this->custom = 0;
- this->description = NULL;
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_error_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_error_initialise`
- * or failed call to `libcoopgamma_error_unmarshal`
- *
- * @param this The record to destroy
- */
-void libcoopgamma_error_destroy(libcoopgamma_error_t* restrict this)
-{
- free(this->description), this->description = NULL;
-}
-
-
-/**
- * Marshal a `libcoopgamma_error_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_error_marshal(const libcoopgamma_error_t* restrict this, void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_ERROR_VERSION);
- marshal_prim(this->number, uint64_t);
- marshal_prim(this->custom, int);
- marshal_prim(this->server_side, int);
- marshal_string(this->description);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_error_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_error_unmarshal(libcoopgamma_error_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- UNMARSHAL_PROLOGUE;
- this->description = NULL;
- unmarshal_version(LIBCOOPGAMMA_ERROR_VERSION);
- unmarshal_prim(this->number, uint64_t);
- unmarshal_prim(this->custom, int);
- unmarshal_prim(this->server_side, int);
- unmarshal_string(this->description);
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_context_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_context_initialise(libcoopgamma_context_t* restrict this)
-{
- memset(this, 0, sizeof(*this));
- this->fd = -1;
- this->blocking = 1;
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_context_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_context_initialise`
- * or failed call to `libcoopgamma_context_unmarshal`
- *
- * @param this The record to destroy
- * @param disconnect Disconnect from the server?
- */
-void libcoopgamma_context_destroy(libcoopgamma_context_t* restrict this, int disconnect)
-{
- if (disconnect && (this->fd >= 0))
- {
- shutdown(this->fd, SHUT_RDWR);
- close(this->fd);
- }
- this->fd = -1;
- libcoopgamma_error_destroy(&(this->error));
- free(this->outbound), this->outbound = NULL;
- free(this->inbound), this->inbound = NULL;
-}
-
-
-/**
- * Marshal a `libcoopgamma_context_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_context_marshal(const libcoopgamma_context_t* restrict this, void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_CONTEXT_VERSION);
- marshal_prim(this->fd, int);
- off += libcoopgamma_error_marshal(&(this->error), SUBBUF);
- marshal_prim(this->message_id, uint32_t);
- marshal_prim(this->outbound_head - this->outbound_tail, size_t);
- marshal_buffer(this->outbound + this->outbound_tail, this->outbound_head - this->outbound_tail);
- marshal_prim(this->inbound_head - this->inbound_tail, size_t);
- marshal_buffer(this->inbound + this->inbound_tail, this->inbound_head - this->inbound_tail);
- marshal_prim(this->length, size_t);
- marshal_prim(this->curline, size_t);
- marshal_prim(this->in_response_to, uint32_t);
- marshal_prim(this->have_all_headers, int);
- marshal_prim(this->bad_message, int);
- marshal_prim(this->blocking, int);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_context_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_context_unmarshal(libcoopgamma_context_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- size_t n;
- int r;
- UNMARSHAL_PROLOGUE;
- memset(this, 0, sizeof(*this));
- unmarshal_version(LIBCOOPGAMMA_CONTEXT_VERSION);
- unmarshal_prim(this->fd, int);
- r = libcoopgamma_error_unmarshal(&(this->error), NNSUBBUF, &n);
- if (r != LIBCOOPGAMMA_SUCCESS)
- return r;
- off += n;
- unmarshal_prim(this->message_id, uint32_t);
- unmarshal_prim(this->outbound_head, size_t);
- this->outbound_size = this->outbound_head;
- unmarshal_buffer(this->outbound, this->outbound_head);
- unmarshal_prim(this->inbound_head, size_t);
- this->inbound_size = this->inbound_head;
- unmarshal_buffer(this->inbound, this->inbound_head);
- unmarshal_prim(this->length, size_t);
- unmarshal_prim(this->curline, size_t);
- unmarshal_prim(this->in_response_to, uint32_t);
- unmarshal_prim(this->have_all_headers, int);
- unmarshal_prim(this->bad_message, int);
- unmarshal_prim(this->blocking, int);
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * Initialise a `libcoopgamma_async_context_t`
- *
- * @param this The record to initialise
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_async_context_initialise(libcoopgamma_async_context_t* restrict this)
-{
- this->message_id = 0;
- this->coalesce = 0;
- return 0;
-}
-
-
-/**
- * Release all resources allocated to a `libcoopgamma_async_context_t`,
- * the allocation of the record itself is not freed
- *
- * Always call this function after failed call to `libcoopgamma_async_context_initialise`
- * or failed call to `libcoopgamma_async_context_unmarshal`
- *
- * @param this The record to destroy
- */
-#if defined(__GNUC__)
-__attribute__((__const__))
-#endif
-void libcoopgamma_async_context_destroy(libcoopgamma_async_context_t* restrict this)
-{
- (void) this;
-}
-
-
-/**
- * Marshal a `libcoopgamma_async_context_t` into a buffer
- *
- * @param this The record to marshal
- * @param vbuf The output buffer, `NULL` to only measure
- * how large this buffer has to be
- * @return The number of marshalled bytes, or if `buf == NULL`,
- * how many bytes would be marshalled if `buf != NULL`
- */
-size_t libcoopgamma_async_context_marshal(const libcoopgamma_async_context_t* restrict this,
- void* restrict vbuf)
-{
- MARSHAL_PROLOGUE;
- marshal_version(LIBCOOPGAMMA_ASYNC_CONTEXT_VERSION);
- marshal_prim(this->message_id, uint32_t);
- marshal_prim(this->coalesce, int);
- MARSHAL_EPILOGUE;
-}
-
-
-/**
- * Unmarshal a `libcoopgamma_async_context_t` from a buffer
- *
- * @param this The output parameter for unmarshalled record
- * @param vbuf The buffer with the marshalled record
- * @param np Output parameter for the number of unmarshalled bytes, undefined on failure
- * @return `LIBCOOPGAMMA_SUCCESS` (0), `LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE`,
- * `LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE`, or `LIBCOOPGAMMA_ERRNO_SET`
- */
-int libcoopgamma_async_context_unmarshal(libcoopgamma_async_context_t* restrict this,
- const void* restrict vbuf, size_t* restrict np)
-{
- UNMARSHAL_PROLOGUE;
- unmarshal_version(LIBCOOPGAMMA_ASYNC_CONTEXT_VERSION);
- unmarshal_prim(this->message_id, uint32_t);
- unmarshal_prim(this->coalesce, int);
- UNMARSHAL_EPILOGUE;
-}
-
-
-
-/**
- * List all recognised adjustment method
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @return A `NULL`-terminated list of names. You should only free
- * the outer pointer, inner pointers are subpointers of the
- * outer pointer and cannot be freed. `NULL` on error.
- */
-char** libcoopgamma_get_methods(void)
-{
- char num[5]; /* The size is base on the fact that we have limited `n` in the loop below */
- char** methods = NULL;
- char** rc;
- char* buffer;
- int n = 0, saved_errno;
- size_t size = 0;
-
- methods = malloc(4 * sizeof(*methods));
- if (methods == NULL)
- goto fail;
-
- for (n = 0; n < 10000 /* just to be safe */; n++)
- {
- char* method;
- if ((n >= 4) && ((n & -n) == n))
- {
- void* new = realloc(methods, (size_t)(n << 1) * sizeof(*methods));
- if (new == NULL)
- goto fail;
- methods = new;
- }
- sprintf(num, "%i", n);
- if (libcoopgamma_get_method_and_site(num, NULL, &method, NULL))
- goto fail;
- if (!strcmp(method, num))
- {
- free(method);
- break;
- }
- methods[n] = method;
- size += strlen(method) + 1;
- }
-
- rc = malloc((size_t)(n + 1) * sizeof(char*) + size);
- if (rc == NULL)
- goto fail;
- buffer = ((char*)rc) + (size_t)(n + 1) * sizeof(char*);
- rc[n] = NULL;
- while (n--)
- {
- rc[n] = buffer;
- buffer = stpcpy(buffer, methods[n]) + 1;
- free(methods[n]);
- }
- free(methods);
-
- return rc;
-
- fail:
- saved_errno = errno;
- while (n--)
- free(methods[n]);
- free(methods);
- errno = saved_errno;
- return NULL;
-}
-
-
-/**
- * Run coopgammad with -q or -qq and return the response
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @param method The adjustment method, `NULL` for automatic
- * @param site The site, `NULL` for automatic
- * @param arg "-q" or "-qq", which shall be passed to coopgammad?
- * @return The output of coopgammad, `NULL` on error. This
- * will be NUL-terminated and will not contain any
- * other `NUL` bytes.
- */
-static char* libcoopgamma_query(const char* restrict method, const char* restrict site, const char* restrict arg)
-{
- const char* (args[7]) = {COOPGAMMAD, arg};
- size_t i = 2, n = 0, size = 0;
- int pipe_rw[2] = { -1, -1 };
- pid_t pid;
- int saved_errno, status;
- char* msg = NULL;
- ssize_t got;
-
- if (method != NULL) args[i++] = "-m", args[i++] = method;
- if (site != NULL) args[i++] = "-s", args[i++] = site;
- args[i] = NULL;
-
- if (pipe(pipe_rw) < 0)
- goto fail;
-
- switch ((pid = fork()))
- {
- case -1:
- goto fail;
- case 0:
- /* Child */
- close(pipe_rw[0]);
- if (pipe_rw[1] != STDOUT_FILENO)
- {
- close(STDOUT_FILENO);
- if (dup2(pipe_rw[1], STDOUT_FILENO) < 0)
- goto fail_child;
- close(pipe_rw[1]);
- }
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
- execvp(COOPGAMMAD, (char* const*)(args));
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
- fail_child:
- saved_errno = errno;
- perror(NAME_OF_THE_PROCESS);
- if (write(STDOUT_FILENO, &saved_errno, sizeof(int)) != sizeof(int))
- perror(NAME_OF_THE_PROCESS);
- exit(1);
- default:
- /* Parent */
- close(pipe_rw[1]), pipe_rw[1] = -1;
- for (;;)
- {
- if (n == size)
- {
- void* new = realloc(msg, size = (n ? (n << 1) : 256));
- if (new == NULL)
- goto fail;
- msg = new;
- }
- got = read(pipe_rw[0], msg + n, size - n);
- if (got < 0)
- {
- if (errno == EINTR)
- continue;
- goto fail;
- }
- else if (got == 0)
- break;
- n += (size_t)got;
- }
- close(pipe_rw[0]), pipe_rw[0] = -1;
- if (waitpid(pid, &status, 0) < 0)
- goto fail;
- if (status)
- {
- errno = EINVAL;
- if ((n == sizeof(int)) && (*(int*)msg != 0))
- errno = *(int*)msg;
- }
- break;
- }
-
- if (n == size)
- {
- void* new = realloc(msg, n + 1);
- if (new == NULL)
- goto fail;
- msg = new;
- }
- msg[n] = '\0';
-
- if (strchr(msg, '\0') != msg + n)
- {
- errno = EBADMSG;
- goto fail;
- }
-
- return msg;
- fail:
- saved_errno = errno;
- if (pipe_rw[0] >= 0) close(pipe_rw[0]);
- if (pipe_rw[1] >= 0) close(pipe_rw[1]);
- free(msg);
- errno = saved_errno;
- return NULL;
-}
-
-
-/**
- * Get the adjustment method and site
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @param method The adjustment method, `NULL` for automatic
- * @param site The site, `NULL` for automatic
- * @param methodp Output pointer for the selected adjustment method,
- * which cannot be `NULL`. It is safe to call
- * this function with this parameter set to `NULL`.
- * @param sitep Output pointer for the selected site, which will
- * be `NULL` the method only supports one site or if
- * `site == NULL` and no site can be selected
- * automatically. It is safe to call this function
- * with this parameter set to `NULL`.
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_get_method_and_site(const char* restrict method, const char* restrict site,
- char** restrict methodp, char** restrict sitep)
-{
- int saved_errno;
- char* raw;
- char* p;
- char* q;
-
- raw = libcoopgamma_query(method, site, "-q");
- if (raw == NULL)
- return -1;
-
- if (methodp != NULL) *methodp = NULL;
- if (sitep != NULL) *sitep = NULL;
-
- p = strchr(raw, '\n');
- if (p == NULL)
- {
- errno = EBADMSG;
- goto fail;
- }
- *p++ = '\0';
-
- if (methodp != NULL)
- {
- *methodp = malloc(strlen(raw) + 1);
- if (*methodp == NULL)
- goto fail;
- strcpy(*methodp, raw);
- }
-
- if ((site != NULL) && *(q = strchr(p, '\0') - 1))
- {
- if (*q != '\n')
- {
- errno = EBADMSG;
- goto fail;
- }
- *q = '\0';
- *sitep = malloc(strlen(p) + 1);
- if (*sitep == NULL)
- goto fail;
- strcpy(*sitep, p);
- }
-
- free(raw);
- return 0;
- fail:
- saved_errno = errno;
- if (methodp != NULL)
- free(*methodp), *methodp = NULL;
- free(raw);
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * Get the PID file of the coopgamma server
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @param method The adjustment method, `NULL` for automatic
- * @param site The site, `NULL` for automatic
- * @return The pathname of the server's PID file, `NULL` on error
- * or if there server does not use PID files. The later
- * case is detected by checking that `errno` is set to 0.
- */
-char* libcoopgamma_get_pid_file(const char* restrict method, const char* restrict site)
-{
- char* path;
- size_t n;
-
- path = libcoopgamma_get_socket_file(method, site);
- if (path == NULL)
- return NULL;
-
- n = strlen(path);
- if (n < 7 || strcmp(path + n - 7, ".socket"))
- {
- free(path);
- errno = EBADMSG;
- return NULL;
- }
-
- strcpy(path + n - 7, ".pid");
- return path;
-}
-
-
-/**
- * Get the socket file of the coopgamma server
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @param method The adjustment method, `NULL` for automatic
- * @param site The site, `NULL` for automatic
- * @return The pathname of the server's socket, `NULL` on error
- * or if there server does have its own socket. The later
- * case is detected by checking that `errno` is set to 0,
- * and is the case when communicating with a server in a
- * multi-server display server like mds.
- */
-char* libcoopgamma_get_socket_file(const char* restrict method, const char* restrict site)
-{
- int saved_errno;
- char* raw;
- char* p;
-
- raw = libcoopgamma_query(method, site, "-qq");
- if (raw == NULL)
- return NULL;
-
- p = strchr(raw, '\0') - 1;
- if ((p < raw) || (*p != '\n'))
- {
- errno = EBADMSG;
- goto fail;
- }
- *p = '\0';
- if (*raw == '\0')
- {
- errno = EBADMSG;
- goto fail;
- }
-
- return raw;
- fail:
- saved_errno = errno;
- free(raw);
- errno = saved_errno;
- return NULL;
-}
-
-
-
-/**
- * Connect to a coopgamma server, and start it if necessary
- *
- * Use `libcoopgamma_context_destroy` to disconnect
- *
- * SIGCHLD must not be ignored or blocked
- *
- * @param method The adjustment method, `NULL` for automatic
- * @param site The site, `NULL` for automatic
- * @param ctx The state of the library, must be initialised
- * @return Zero on success, -1 on error. On error, `errno` is set
- * to 0 if the server could not be initialised.
- */
-int libcoopgamma_connect(const char* restrict method, const char* restrict site,
- libcoopgamma_context_t* restrict ctx)
-{
- const char* (args[6]) = {COOPGAMMAD};
- struct sockaddr_un address;
- char* path;
- int saved_errno;
- int tries = 0, status;
- pid_t pid;
- size_t i = 1;
-
- ctx->blocking = 1;
-
- if (method != NULL) args[i++] = "-m", args[i++] = method;
- if (site != NULL) args[i++] = "-s", args[i++] = site;
- args[i] = NULL;
-
- path = libcoopgamma_get_socket_file(method, site);
- if (path == NULL)
- return -1;
- if (strlen(path) >= sizeof(address.sun_path))
- {
- free(path);
- errno = ENAMETOOLONG;
- return -1;
- }
-
- address.sun_family = AF_UNIX;
- strcpy(address.sun_path, path);
- free(path);
- if ((ctx->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- return -1;
-
- retry:
- if (connect(ctx->fd, (struct sockaddr*)(&address), (socklen_t)sizeof(address)) < 0)
- {
- if (((errno == ECONNREFUSED) || (errno == ENOENT) || (errno == ENOTDIR)) && !tries++)
- {
- switch ((pid = fork()))
- {
- case -1:
- goto fail;
- case 0:
- /* Child */
- close(ctx->fd);
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
- execvp(COOPGAMMAD, (char* const*)(args));
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
- perror(NAME_OF_THE_PROCESS);
- exit(1);
- default:
- /* Parent */
- if (waitpid(pid, &status, 0) < 0)
- goto fail;
- if (status)
- {
- errno = 0;
- goto fail;
- }
- break;
- }
- goto retry;
- }
- goto fail;
- }
-
- return 0;
- fail:
- saved_errno = errno;
- close(ctx->fd), ctx->fd = -1;
- errno = saved_errno;
- return -1;
-}
-
-
-/**
- * By default communication is blocking, this function
- * can be used to switch between blocking and nonblocking
- *
- * After setting the communication to nonblocking,
- * `libcoopgamma_flush`, `libcoopgamma_synchronise` and
- * and request-sending functions can fail with EAGAIN and
- * EWOULDBLOCK. It is safe to continue with `libcoopgamma_flush`
- * (for `libcoopgamma_flush` it selfand equest-sending functions)
- * or `libcoopgamma_synchronise` just like EINTR failure.
- *
- * @param ctx The state of the library, must be connected
- * @param nonblocking Nonblocking mode?
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_set_nonblocking(libcoopgamma_context_t* restrict ctx, int nonblocking)
-{
- int flags = fcntl(ctx->fd, F_GETFL);
- if (flags == -1)
- return -1;
- if (nonblocking)
- flags |= O_NONBLOCK;
- else
- flags &= ~O_NONBLOCK;
- if (fcntl(ctx->fd, F_SETFL, flags) == -1)
- return -1;
- ctx->blocking = !nonblocking;
- return 0;
-}
-
-
-/**
- * Send all pending outbound data
- *
- * If this function or another function that sends a request
- * to the server fails with EINTR, call this function to
- * complete the transfer. The `async` parameter will always
- * be in a properly configured state if a function fails
- * with EINTR.
- *
- * @param ctx The state of the library, must be connected
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_flush(libcoopgamma_context_t* restrict ctx)
-{
- ssize_t sent;
- size_t chunksize = ctx->outbound_head - ctx->outbound_tail;
- size_t sendsize;
-
- while (ctx->outbound_tail < ctx->outbound_head)
- {
- sendsize = ctx->outbound_head - ctx->outbound_tail;
- sendsize = sendsize < chunksize ? sendsize : chunksize;
- sent = send(ctx->fd, ctx->outbound + ctx->outbound_tail, sendsize, MSG_NOSIGNAL);
- if (sent < 0)
- {
- if (errno == EPIPE)
- errno = ECONNRESET;
- if (errno != EMSGSIZE)
- return -1;
- if ((chunksize >>= 1) == 0)
- return -1;
- continue;
- }
-
-#ifdef DEBUG_MODE
- fprintf(stderr, "\033[31m");
- fwrite(ctx->outbound + ctx->outbound_tail, (size_t)sent, 1, stderr);
- fprintf(stderr, "\033[m");
- fflush(stderr);
-#endif
-
- ctx->outbound_tail += (size_t)sent;
- }
-
- return 0;
-}
-
-
-/**
- * Wait for the next message to be received
- *
- * @param ctx The state of the library, must be connected
- * @param pending Information for each pending request
- * @param n The number of elements in `pending`
- * @param selected The index of the element in `pending` which corresponds
- * to the first inbound message, note that this only means
- * that the message is not for any of the other request,
- * if the message is corrupt any of the listed requests can
- * be selected even if it is not for any of the requests.
- * Functions that parse the message will detect such corruption.
- * @return Zero on success, -1 on error. If the the message is ignored,
- * which happens if corresponding `libcoopgamma_async_context_t`
- * is not listed, -1 is returned and `errno` is set to 0. If -1
- * is returned, `errno` is set to `ENOTRECOVERABLE` you have
- * received a corrupt message and the context has been tainted
- * beyond recover.
- */
-int libcoopgamma_synchronise(libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict pending,
- size_t n, size_t* restrict selected)
-{
- char temp[3 * sizeof(size_t) + 1];
- ssize_t got;
- size_t i;
- char* p;
- char* line;
- char* value;
- struct pollfd pollfd;
-
- if (ctx->inbound_head == ctx->inbound_tail)
- ctx->inbound_head = ctx->inbound_tail = ctx->curline = 0;
- else if (ctx->inbound_tail > 0)
- {
- memmove(ctx->inbound, ctx->inbound + ctx->inbound_tail, ctx->inbound_head -= ctx->inbound_tail);
- ctx->curline -= ctx->inbound_tail;
- ctx->inbound_tail = 0;
- }
-
- pollfd.fd = ctx->fd;
- pollfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
-
- if (ctx->inbound_head)
- goto skip_recv;
- for (;;)
- {
- if (ctx->inbound_head == ctx->inbound_size)
- {
- size_t new_size = ctx->inbound_size ? (ctx->inbound_size << 1) : 1024;
- void* new = realloc(ctx->inbound, new_size);
- if (new == NULL)
- return -1;
- ctx->inbound = new;
- ctx->inbound_size = new_size;
- }
-
- if (ctx->blocking)
- {
- pollfd.revents = 0;
- if (poll(&pollfd, (nfds_t)1, -1) < 0)
- return -1;
- }
- got = recv(ctx->fd, ctx->inbound + ctx->inbound_head, ctx->inbound_size - ctx->inbound_head, 0);
- if (got <= 0)
- {
- if (got == 0)
- errno = ECONNRESET;
- return -1;
- }
-
-#ifdef DEBUG_MODE
- fprintf(stderr, "\033[32m");
- fwrite(ctx->inbound + ctx->inbound_head, (size_t)got, 1, stderr);
- fprintf(stderr, "\033[m");
- fflush(stderr);
-#endif
-
- ctx->inbound_head += (size_t)got;
-
- skip_recv:
- while (ctx->have_all_headers == 0)
- {
- line = ctx->inbound + ctx->curline;
- p = memchr(line, '\n', ctx->inbound_head - ctx->curline);
- if (p == NULL)
- break;
- if (memchr(line, '\0', (size_t)(p - line)) != NULL)
- ctx->bad_message = 1;
- *p++ = '\0';
- ctx->curline = (size_t)(p - ctx->inbound);
- if (!*line)
- {
- ctx->have_all_headers = 1;
- }
- else if (strstr(line, "In response to: ") == line)
- {
- value = line + (sizeof("In response to: ") - 1);
- ctx->in_response_to = (uint32_t)atol(value);
- }
- else if (strstr(line, "Length: ") == line)
- {
- value = line + (sizeof("Length: ") - 1);
- ctx->length = (size_t)atol(value);
- sprintf(temp, "%zu", ctx->length);
- if (strcmp(value, temp))
- goto fatal;
- }
- }
-
- if (ctx->have_all_headers && (ctx->inbound_head >= ctx->curline + ctx->length))
- {
- ctx->curline += ctx->length;
- if (ctx->bad_message)
- {
- ctx->bad_message = 0;
- ctx->have_all_headers = 0;
- ctx->length = 0;
- ctx->inbound_tail = ctx->curline;
- errno = EBADMSG;
- return -1;
- }
- for (i = 0; i < n; i++)
- if (pending[i].message_id == ctx->in_response_to)
- {
- *selected = i;
- return 0;
- }
- *selected = 0;
- ctx->bad_message = 0;
- ctx->have_all_headers = 0;
- ctx->length = 0;
- ctx->inbound_tail = ctx->curline;
- errno = 0;
- return -1;
- }
- }
-
- fatal:
- errno = ENOTRECOVERABLE;
- return -1;
-}
-
-
-/**
- * Send a message to the server and wait for response
- *
- * @param resp:char** Output parameter for the response,
- * will be NUL-terminated
- * @param ctx:libcoopgamma_context_t* The state of the library
- * @param payload:void* Data to append to the end of the message
- * @param payload_size:size_t Byte-size of `payload`
- * @param format:string-literal Message formatting string
- * @param ... Message formatting arguments
- *
- * On error, the macro goes to `fail`.
- */
-#define SEND_MESSAGE(ctx, payload, payload_size, format, ...) \
- do \
- { \
- ssize_t n__; \
- char* msg__; \
- snprintf(NULL, (size_t)0, format "%zn", __VA_ARGS__, &n__); \
- msg__ = malloc((size_t)n__ + (payload_size) + (size_t)1); \
- if (msg__ == NULL) \
- goto fail; \
- sprintf(msg__, format, __VA_ARGS__); \
- if ((payload) != NULL) \
- memcpy(msg__ + n__, (payload), (payload_size)); \
- if (send_message((ctx), msg__, (size_t)n__ + (payload_size)) < 0) \
- goto fail; \
- } \
- while (0)
-
-
-/**
- * Send a message to the server and wait for response
- *
- * @param ctx The state of the library
- * @param msg The message to send
- * @param n The length of `msg`
- * @return Zero on success, -1 on error
- */
-static int send_message(libcoopgamma_context_t* restrict ctx, char* msg, size_t n)
-{
- if (ctx->outbound_head == ctx->outbound_tail)
- {
- free(ctx->outbound);
- ctx->outbound = msg;
- ctx->outbound_tail = 0;
- ctx->outbound_head = n;
- ctx->outbound_size = n;
- }
- else
- {
- if (ctx->outbound_head + n > ctx->outbound_size)
- {
- memmove(ctx->outbound, ctx->outbound + ctx->outbound_tail, ctx->outbound_head -= ctx->outbound_tail);
- ctx->outbound_tail = 0;
- }
- if (ctx->outbound_head + n > ctx->outbound_size)
- {
- void* new = realloc(ctx->outbound, ctx->outbound_head + n);
- if (new == NULL)
- {
- int saved_errno = errno;
- free(msg);
- errno = saved_errno;
- return -1;
- }
- ctx->outbound = new;
- ctx->outbound_size = ctx->outbound_head + n;
- }
- memcpy(ctx->outbound + ctx->outbound_head, msg, n);
- ctx->outbound_head += n;
- free(msg);
- }
- ctx->message_id += 1;
- return libcoopgamma_flush(ctx);
-}
-
-
-/**
- * Get the next header of the inbound message
- *
- * All headers must be read before the payload is read
- *
- * @param ctx The state of the library, must be connected
- * @return The next header line, can never be `NULL`,
- * the empty string marks the end of the headers.
- * This memory segment must not be freed.
- */
-static char* next_header(libcoopgamma_context_t* restrict ctx)
-{
- char* rc = ctx->inbound + ctx->inbound_tail;
- ctx->inbound_tail += strlen(rc) + 1;
- return rc;
-}
-
-
-/**
- * Get the payload of the inbound message
- *
- * Calling this function marks that the inbound message
- * has been fully ready. You must call this function
- * even if you do not expect a payload
- *
- * @param ctx The state of the library, must be connected
- * @param n Output parameter for the size of the payload
- * @return The payload (not NUL-terminated), `NULL` if
- * there is no payload. Failure is impossible.
- * This memory segment must not be freed.
- */
-static char* next_payload(libcoopgamma_context_t* restrict ctx, size_t* n)
-{
- ctx->have_all_headers = 0;
- if ((*n = ctx->length))
- {
- char* rc = ctx->inbound + ctx->inbound_tail;
- ctx->inbound_tail += *n;
- ctx->length = 0;
- return rc;
- }
- else
- return NULL;
-}
-
-
-/**
- * Tell the library that you will not be parsing a receive message
- *
- * @param ctx The state of the library, must be connected
- */
-void libcoopgamma_skip_message(libcoopgamma_context_t* restrict ctx)
-{
- size_t _n;
- while (*next_header(ctx));
- (void) next_payload(ctx, &_n);
-}
-
-
-/**
- * Check whether the server sent an error, if so copy it to `ctx`
- *
- * This function will also reports EBADMSG if the message ID
- * that the message is a response to does not match the request
- * information, or if it is missing
- *
- * @param ctx The state of the library, must be connected
- * @param async Information about the request
- * @return 1 if the server sent an error (even indicating success),
- * 0 on success, -1 on failure. Information about failure
- * is copied `ctx`.
- */
-static int check_error(libcoopgamma_context_t* restrict ctx, libcoopgamma_async_context_t* restrict async)
-{
- char temp[3 * sizeof(uint64_t) + 1];
- size_t old_tail = ctx->inbound_tail;
- char* line;
- char* value;
- int command_ok = 0;
- int have_in_response_to = 0;
- int have_error = 0;
- int bad = 0;
- char* payload;
- size_t n;
-
- for (;;)
- {
- line = next_header(ctx);
- value = strchr(line, ':') + 2;
- if (!*line)
- break;
- else if (!strcmp(line, "Command: error"))
- command_ok = 1;
- else if (strstr(line, "In response to: ") == line)
- {
- uint32_t id = (uint32_t)atol(value);
- have_in_response_to = 1 + !!have_in_response_to;
- if (id != async->message_id)
- bad = 1;
- else
- {
- sprintf(temp, "%" PRIu32, id);
- if (strcmp(value, temp))
- bad = 1;
- }
- }
- else if (strstr(line, "Error: ") == line)
- {
- have_error = 1 + !!have_error;
- ctx->error.server_side = 1;
- ctx->error.custom = (strstr(value, "custom") == value);
- if (ctx->error.custom)
- {
- if (value[6] == '\0')
- {
- ctx->error.number = 0;
- continue;
- }
- else if (value[6] != ' ')
- {
- bad = 1;
- continue;
- }
- value += 7;
- }
- ctx->error.number = (uint64_t)atoll(value);
- sprintf(temp, "%" PRIu64, ctx->error.number);
- if (strcmp(value, temp))
- bad = 1;
- }
- }
-
- if (command_ok == 0)
- {
- ctx->inbound_tail = old_tail;
- return 0;
- }
-
- payload = next_payload(ctx, &n);
- if (payload != NULL)
- {
- if (memchr(payload, '\0', n) || (payload[n - 1] != '\n'))
- goto badmsg;
- ctx->error.description = malloc(n);
- if (ctx->error.description == NULL)
- goto fail;
- memcpy(ctx->error.description, payload, n - 1);
- ctx->error.description[n - 1] = '\0';
- }
-
- if (bad || (have_in_response_to != 1) || (have_error != 1))
- goto badmsg;
-
- return 1;
-badmsg:
- errno = EBADMSG;
-fail:
- copy_errno(ctx);
- return -1;
-}
-
-
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wnonnull"
-#endif
-
-
-
-/**
- * List all available CRTC:s, send request part
- *
- * Cannot be used before connecting to the server
- *
- * @param ctx The state of the library, must be connected
- * @param async Information about the request, that is needed to
- * identify and parse the response, is stored here
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_get_crtcs_send(libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- async->message_id = ctx->message_id;
- SEND_MESSAGE(ctx, NULL, (size_t)0,
- "Command: enumerate-crtcs\n"
- "Message ID: %" PRIu32 "\n"
- "\n",
- ctx->message_id);
-
- return 0;
- fail:
- copy_errno(ctx);
- return -1;
-}
-
-
-/**
- * List all available CRTC:s, receive response part
- *
- * @param ctx The state of the library, must be connected
- * @param async Information about the request
- * @return A `NULL`-terminated list of names. You should only free
- * the outer pointer, inner pointers are subpointers of the
- * outer pointer and cannot be freed. `NULL` on error, in
- * which case `ctx->error` (rather than `errno`) is read
- * for information about the error.
- */
-char** libcoopgamma_get_crtcs_recv(libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- char* line;
- char* payload;
- char* end;
- int command_ok = 0;
- size_t i, n, lines, len, length;
- char** rc;
-
- if (check_error(ctx, async))
- return NULL;
-
- for (;;)
- {
- line = next_header(ctx);
- if (!*line)
- break;
- else if (!strcmp(line, "Command: crtc-enumeration"))
- command_ok = 1;
- }
-
- payload = next_payload(ctx, &n);
-
- if (!command_ok || ((n > 0) && (payload[n - 1] != '\n')))
- {
- errno = EBADMSG;
- copy_errno(ctx);
- return NULL;
- }
-
- line = payload;
- end = payload + n;
- lines = length = 0;
- while (line != end)
- {
- lines += 1;
- length += len = (size_t)(strchr(line, '\n') + 1 - line);
- line += len;
- line[-1] = '\0';
- }
-
- rc = malloc((lines + 1) * sizeof(char*) + length);
- if (rc == NULL)
- {
- copy_errno(ctx);
- return NULL;
- }
-
- line = ((char*)rc) + (lines + 1) * sizeof(char*);
- memcpy(line, payload, length);
- rc[lines] = NULL;
- for (i = 0; i < lines; i++)
- {
- rc[i] = line;
- line = strchr(line, '\0') + 1;
- }
-
- return rc;
-}
-
-
-/**
- * List all available CRTC:s, synchronous version
- *
- * This is a synchronous request function, as such,
- * you have to ensure that communication is blocking
- * (default), and that there are not asynchronous
- * requests waiting, it also means that EINTR:s are
- * silently ignored and there no wait to cancel the
- * operation without disconnection from the server
- *
- * @param ctx The state of the library, must be connected
- * @return A `NULL`-terminated list of names. You should only free
- * the outer pointer, inner pointers are subpointers of the
- * outer pointer and cannot be freed. `NULL` on error, in
- * which case `ctx->error` (rather than `errno`) is read
- * for information about the error.
- */
-char** libcoopgamma_get_crtcs_sync(libcoopgamma_context_t* restrict ctx)
-{
- SYNC_CALL(libcoopgamma_get_crtcs_send(ctx, &async),
- libcoopgamma_get_crtcs_recv(ctx, &async), (copy_errno(ctx), NULL));
-}
-
-
-
-/**
- * Retrieve information about a CRTC:s gamma ramps, send request part
- *
- * Cannot be used before connecting to the server
- *
- * @param crtc The name of the CRTC
- * @param ctx The state of the library, must be connected
- * @param async Information about the request, that is needed to
- * identify and parse the response, is stored here
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_get_gamma_info_send(const char* restrict crtc, libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wnonnull-compare"
-#endif
- if ((crtc == NULL) || strchr(crtc, '\n'))
- {
- errno = EINVAL;
- goto fail;
- }
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic pop
-#endif
-
- async->message_id = ctx->message_id;
- SEND_MESSAGE(ctx, NULL, (size_t)0,
- "Command: get-gamma-info\n"
- "Message ID: %" PRIu32 "\n"
- "CRTC: %s\n"
- "\n",
- ctx->message_id, crtc);
-
- return 0;
- fail:
- copy_errno(ctx);
- return 0;
-}
-
-
-/**
- * Retrieve information about a CRTC:s gamma ramps, receive response part
- *
- * @param info Output parameter for the information, must be initialised
- * @param ctx The state of the library, must be connected
- * @param async Information about the request
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_get_gamma_info_recv(libcoopgamma_crtc_info_t* restrict info,
- libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- char temp[3 * sizeof(size_t) + 1];
- char* line;
- char* value;
- size_t _n;
- int have_cooperative = 0, have_gamma_support = 0, have_colourspace = 0;
- int have_depth = 0, have_white_x = 0, have_white_y = 0;
- int have_red_size = 0, have_red_x = 0, have_red_y = 0;
- int have_green_size = 0, have_green_x = 0, have_green_y = 0;
- int have_blue_size = 0, have_blue_x = 0, have_blue_y = 0;
- int bad = 0, r = 0, g = 0, b = 0, x = 0;
-
- if (check_error(ctx, async))
- return -1;
-
- info->cooperative = 0; /* Should be in the response, but ... */
- info->colourspace = LIBCOOPGAMMA_UNKNOWN;
-
- for (;;)
- {
- line = next_header(ctx);
- value = strchr(line, ':') + 2;
- if (!*line)
- break;
- else if (strstr(line, "Cooperative: ") == line)
- {
- have_cooperative = 1 + !!have_cooperative;
- if (!strcmp(value, "yes")) info->cooperative = 1;
- else if (!strcmp(value, "no")) info->cooperative = 0;
- else
- bad = 1;
- }
- else if (strstr(line, "Depth: ") == line)
- {
- have_depth = 1 + !!have_depth;
- if (!strcmp(value, "8")) info->depth = LIBCOOPGAMMA_UINT8;
- else if (!strcmp(value, "16")) info->depth = LIBCOOPGAMMA_UINT16;
- else if (!strcmp(value, "32")) info->depth = LIBCOOPGAMMA_UINT32;
- else if (!strcmp(value, "64")) info->depth = LIBCOOPGAMMA_UINT64;
- else if (!strcmp(value, "f")) info->depth = LIBCOOPGAMMA_FLOAT;
- else if (!strcmp(value, "d")) info->depth = LIBCOOPGAMMA_DOUBLE;
- else
- bad = 1;
- }
- else if (strstr(line, "Gamma support: ") == line)
- {
- have_gamma_support = 1 + !!have_gamma_support;
- if (!strcmp(value, "yes")) info->supported = LIBCOOPGAMMA_YES;
- else if (!strcmp(value, "no")) info->supported = LIBCOOPGAMMA_NO;
- else if (!strcmp(value, "maybe")) info->supported = LIBCOOPGAMMA_MAYBE;
- else
- bad = 1;
- }
- else if (((r = (strstr(line, "Red size: ") == line))) ||
- ((g = (strstr(line, "Green size: ") == line))) ||
- (strstr(line, "Blue size: ") == line))
- {
- size_t* out;
- if (r) have_red_size = 1 + !!have_red_size, out = &(info->red_size);
- else if (g) have_green_size = 1 + !!have_green_size, out = &(info->green_size);
- else have_blue_size = 1 + !!have_blue_size, out = &(info->blue_size);
- *out = (size_t)atol(value);
- sprintf(temp, "%zu", *out);
- if (strcmp(value, temp))
- bad = 1;
- }
- else if ((x = r = (strstr(line, "Red x: ") == line)) ||
- (r = (strstr(line, "Red y: ") == line)) ||
- (x = g = (strstr(line, "Green x: ") == line)) ||
- (g = (strstr(line, "Green y: ") == line)) ||
- (x = b = (strstr(line, "Blue x: ") == line)) ||
- (b = (strstr(line, "Blue y: ") == line)) ||
- (x = (strstr(line, "White x: ") == line)) ||
- (strstr(line, "White y: ") == line))
- {
- unsigned* out;
- int* have;
- if (r && x) have = &have_red_x, out = &(info->red_x);
- else if (r) have = &have_red_y, out = &(info->red_y);
- else if (g && x) have = &have_green_x, out = &(info->green_x);
- else if (g) have = &have_green_y, out = &(info->green_y);
- else if (b && x) have = &have_blue_x, out = &(info->blue_x);
- else if (b) have = &have_blue_y, out = &(info->blue_y);
- else if (x) have = &have_white_x, out = &(info->white_x);
- else have = &have_white_y, out = &(info->white_y);
- *have = 1 + !!*have;
- *out = (unsigned)atoi(value);
- sprintf(temp, "%u", *out);
- if (strcmp(value, temp))
- bad = 1;
- }
- else if (strstr(line, "Colour space: ") == line)
- {
- have_colourspace = 1 + !!have_colourspace;
- if (!strcmp(value, "sRGB")) info->colourspace = LIBCOOPGAMMA_SRGB;
- else if (!strcmp(value, "RGB")) info->colourspace = LIBCOOPGAMMA_RGB;
- else if (!strcmp(value, "non-RGB")) info->colourspace = LIBCOOPGAMMA_NON_RGB;
- else if (!strcmp(value, "grey")) info->colourspace = LIBCOOPGAMMA_GREY;
- else
- info->colourspace = LIBCOOPGAMMA_UNKNOWN;
- }
- }
-
- (void) next_payload(ctx, &_n);
-
- info->have_gamut = (have_red_x && have_green_x && have_blue_x && have_white_x &&
- have_red_y && have_green_y && have_blue_y && have_white_y);
-
- if (bad || (have_gamma_support != 1) || (have_red_x > 1) || (have_red_y > 1) ||
- (have_green_x > 1) || (have_green_y > 1) || (have_blue_x > 1) || (have_blue_y > 1) ||
- (have_white_x > 1) || (have_white_y > 1) || (have_colourspace > 1))
- {
- errno = EBADMSG;
- copy_errno(ctx);
- return -1;
- }
- if (info->supported != LIBCOOPGAMMA_NO)
- if ((have_cooperative > 1) || (have_depth != 1) || (have_gamma_support != 1) ||
- (have_red_size != 1) || (have_green_size != 1) || (have_blue_size != 1))
- {
- errno = EBADMSG;
- copy_errno(ctx);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * Retrieve information about a CRTC:s gamma ramps, synchronous version
- *
- * This is a synchronous request function, as such,
- * you have to ensure that communication is blocking
- * (default), and that there are not asynchronous
- * requests waiting, it also means that EINTR:s are
- * silently ignored and there no wait to cancel the
- * operation without disconnection from the server
- *
- * @param crtc The name of the CRTC
- * @param info Output parameter for the information, must be initialised
- * @param ctx The state of the library, must be connected
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_get_gamma_info_sync(const char* restrict ctrc, libcoopgamma_crtc_info_t* restrict info,
- libcoopgamma_context_t* restrict ctx)
-{
- SYNC_CALL(libcoopgamma_get_gamma_info_send(ctrc, ctx, &async),
- libcoopgamma_get_gamma_info_recv(info, ctx, &async), (copy_errno(ctx), -1));
-}
-
-
-
-/**
- * Retrieve the current gamma ramp adjustments, send request part
- *
- * Cannot be used before connecting to the server
- *
- * @param query The query to send
- * @param ctx The state of the library, must be connected
- * @param async Information about the request, that is needed to
- * identify and parse the response, is stored here
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_get_gamma_send(const libcoopgamma_filter_query_t* restrict query,
- libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wnonnull-compare"
-#endif
- if ((query == NULL) || (query->crtc == NULL) || strchr(query->crtc, '\n'))
- {
- errno = EINVAL;
- goto fail;
- }
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic pop
-#endif
-
- async->message_id = ctx->message_id;
- async->coalesce = query->coalesce;
- SEND_MESSAGE(ctx, NULL, (size_t)0,
- "Command: get-gamma\n"
- "Message ID: %" PRIu32 "\n"
- "CRTC: %s\n"
- "Coalesce: %s\n"
- "High priority: %" PRIi64 "\n"
- "Low priority: %" PRIi64 "\n"
- "\n",
- ctx->message_id, query->crtc, query->coalesce ? "yes" : "no",
- query->high_priority, query->low_priority);
-
- return 0;
- fail:
- copy_errno(ctx);
- return -1;
-}
-
-
-/**
- * Retrieve the current gamma ramp adjustments, receive response part
- *
- * @param table Output for the response, must be initialised
- * @param ctx The state of the library, must be connected
- * @param async Information about the request
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_get_gamma_recv(libcoopgamma_filter_table_t* restrict table,
- libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- char temp[3 * sizeof(size_t) + 1];
- char* line;
- char* value;
- char* payload;
- size_t i, n, width, clutsize;
- int have_depth = 0;
- int have_red_size = 0;
- int have_green_size = 0;
- int have_blue_size = 0;
- int have_tables = 0;
- int bad = 0, r = 0, g = 0;
-
- if (check_error(ctx, async))
- return -1;
-
- libcoopgamma_filter_table_destroy(table);
-
- for (;;)
- {
- line = next_header(ctx);
- value = strchr(line, ':') + 2;
- if (!*line)
- break;
- else if (strstr(line, "Depth: ") == line)
- {
- have_depth = 1 + !!have_depth;
- if (!strcmp(value, "8")) table->depth = LIBCOOPGAMMA_UINT8;
- else if (!strcmp(value, "16")) table->depth = LIBCOOPGAMMA_UINT16;
- else if (!strcmp(value, "32")) table->depth = LIBCOOPGAMMA_UINT32;
- else if (!strcmp(value, "64")) table->depth = LIBCOOPGAMMA_UINT64;
- else if (!strcmp(value, "f")) table->depth = LIBCOOPGAMMA_FLOAT;
- else if (!strcmp(value, "d")) table->depth = LIBCOOPGAMMA_DOUBLE;
- else
- bad = 1;
- }
- else if (((r = (strstr(line, "Red size: ") == line))) ||
- ((g = (strstr(line, "Green size: ") == line))) ||
- (strstr(line, "Blue size: ") == line))
- {
- size_t* out;
- if (r) have_red_size = 1 + !!have_red_size, out = &(table->red_size);
- else if (g) have_green_size = 1 + !!have_green_size, out = &(table->green_size);
- else have_blue_size = 1 + !!have_blue_size, out = &(table->blue_size);
- *out = (size_t)atol(value);
- sprintf(temp, "%zu", *out);
- if (strcmp(value, temp))
- bad = 1;
- }
- else if (strstr(line, "Tables: ") == line)
- {
- have_tables = 1 + have_tables;
- table->filter_count = (size_t)atol(value);
- sprintf(temp, "%zu", table->filter_count);
- if (strcmp(value, temp))
- bad = 1;
- }
- }
-
- payload = next_payload(ctx, &n);
-
- if (bad || (have_depth != 1) || (have_red_size != 1) || (have_green_size != 1) ||
- (have_blue_size != 1) || (async->coalesce ? (have_tables > 1) : (have_tables == 0)) ||
- (((payload == NULL) || (n == 0)) && (async->coalesce || (table->filter_count > 0))) ||
- ((n > 0) && have_tables && (table->filter_count == 0)) ||
- (async->coalesce && have_tables && (table->filter_count != 1)))
- goto bad;
-
- switch (table->depth)
- {
- case LIBCOOPGAMMA_FLOAT: width = sizeof(float); break;
- case LIBCOOPGAMMA_DOUBLE: width = sizeof(double); break;
- default: INTEGRAL_DEPTHS
- if ((table->depth <= 0) || ((table->depth & 7) != 0))
- goto bad;
- width = (size_t)(table->depth / 8);
- break;
- }
-
- clutsize = table->red_size + table->green_size + table->blue_size;
- clutsize *= width;
-
- if (async->coalesce)
- {
- if (n != clutsize)
- goto bad;
- table->filters = malloc(sizeof(*(table->filters)));
- if (table->filters == NULL)
- goto fail;
- table->filters->priority = 0;
- table->filters->class = NULL;
- table->filters->ramps.u8.red_size = table->red_size;
- table->filters->ramps.u8.green_size = table->green_size;
- table->filters->ramps.u8.blue_size = table->blue_size;
- if (libcoopgamma_ramps_initialise_(&(table->filters->ramps), width) < 0)
- goto fail;
- memcpy(table->filters->ramps.u8.red, payload, clutsize);
- table->filter_count = 1;
- }
- else if (table->filter_count == 0)
- table->filters = NULL;
- else
- {
- size_t off = 0, len;
- table->filters = calloc(table->filter_count, sizeof(*(table->filters)));
- if (table->filters == NULL)
- goto fail;
- for (i = 0; i < table->filter_count; i++)
- {
- if (off + sizeof(int64_t) > n)
- goto bad;
- table->filters[i].priority = *(int64_t*)(payload + off);
- off += sizeof(int64_t);
- if (memchr(payload + off, '\0', n - off) == NULL)
- goto bad;
- len = strlen(payload + off) + 1;
- table->filters[i].class = malloc(len);
- if (table->filters[i].class == NULL)
- goto fail;
- memcpy(table->filters[i].class, payload + off, len);
- off += len;
- if (off + clutsize > n)
- goto bad;
- table->filters[i].ramps.u8.red_size = table->red_size;
- table->filters[i].ramps.u8.green_size = table->green_size;
- table->filters[i].ramps.u8.blue_size = table->blue_size;
- if (libcoopgamma_ramps_initialise_(&(table->filters[i].ramps), width) < 0)
- goto fail;
- memcpy(table->filters->ramps.u8.red, payload + off, clutsize);
- off += clutsize;
- }
- if (off != n)
- goto bad;
- }
-
- return 0;
- bad:
- errno = EBADMSG;
- fail:
- copy_errno(ctx);
- return -1;
-}
-
-
-/**
- * Retrieve the current gamma ramp adjustments, synchronous version
- *
- * This is a synchronous request function, as such,
- * you have to ensure that communication is blocking
- * (default), and that there are not asynchronous
- * requests waiting, it also means that EINTR:s are
- * silently ignored and there no wait to cancel the
- * operation without disconnection from the server
- *
- * @param query The query to send
- * @param table Output for the response, must be initialised
- * @param ctx The state of the library, must be connected
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_get_gamma_sync(const libcoopgamma_filter_query_t* restrict query,
- libcoopgamma_filter_table_t* restrict table,
- libcoopgamma_context_t* restrict ctx)
-{
- SYNC_CALL(libcoopgamma_get_gamma_send(query, ctx, &async),
- libcoopgamma_get_gamma_recv(table, ctx, &async), (copy_errno(ctx), -1));
-}
-
-
-
-/**
- * Apply, update, or remove a gamma ramp adjustment, send request part
- *
- * Cannot be used before connecting to the server
- *
- * @param filter The filter to apply, update, or remove, gamma ramp meta-data must match the CRTC's
- * @param ctx The state of the library, must be connected
- * @param async Information about the request, that is needed to
- * identify and parse the response, is stored here
- * @return Zero on success, -1 on error
- */
-int libcoopgamma_set_gamma_send(const libcoopgamma_filter_t* restrict filter,
- libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- const void* payload = NULL;
- const char* lifespan;
- char priority[sizeof("Priority: \n") + 3 * sizeof(int64_t)] = {'\0'};
- char length [sizeof("Length: \n") + 3 * sizeof(size_t) ] = {'\0'};
- size_t payload_size = 0, stopwidth = 0;
-
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wnonnull-compare"
-#endif
- if ((filter == NULL) || (filter->crtc == NULL) || strchr(filter->crtc, '\n') ||
- (filter->class == NULL) || strchr(filter->class, '\n'))
- {
- errno = EINVAL;
- goto fail;
- }
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic pop
-#endif
-
- switch (filter->lifespan)
- {
- case LIBCOOPGAMMA_REMOVE: lifespan = "remove"; break;
- case LIBCOOPGAMMA_UNTIL_DEATH: lifespan = "until-death"; break;
- case LIBCOOPGAMMA_UNTIL_REMOVAL: lifespan = "until-removal"; break;
- default:
- errno = EINVAL;
- goto fail;
- }
-
- if (filter->lifespan != LIBCOOPGAMMA_REMOVE)
- {
- switch (filter->depth)
- {
- case LIBCOOPGAMMA_FLOAT: stopwidth = sizeof(float); break;
- case LIBCOOPGAMMA_DOUBLE: stopwidth = sizeof(double); break;
- default: INTEGRAL_DEPTHS
- if ((filter->depth <= 0) || ((filter->depth & 7) != 0))
- {
- errno = EINVAL;
- goto fail;
- }
- stopwidth = (size_t)(filter->depth / 8);
- break;
- }
-
- payload_size = filter->ramps.u8.red_size;
- payload_size += filter->ramps.u8.green_size;
- payload_size += filter->ramps.u8.blue_size;
- payload_size *= stopwidth;
- payload = filter->ramps.u8.red;
- sprintf(priority, "Priority: %" PRIi64 "\n", filter->priority);
- sprintf(length, "Length: %zu\n", payload_size);
- }
-
- async->message_id = ctx->message_id;
- SEND_MESSAGE(ctx, payload, payload_size,
- "Command: set-gamma\n"
- "Message ID: %" PRIu32 "\n"
- "CRTC: %s\n"
- "Class: %s\n"
- "Lifespan: %s\n"
- "%s"
- "%s"
- "\n",
- ctx->message_id, filter->crtc, filter->class, lifespan,
- priority, length);
-
- return 0;
- fail:
- copy_errno(ctx);
- return -1;
-}
-
-
-/**
- * Apply, update, or remove a gamma ramp adjustment, receive response part
- *
- * @param ctx The state of the library, must be connected
- * @param async Information about the request
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_set_gamma_recv(libcoopgamma_context_t* restrict ctx,
- libcoopgamma_async_context_t* restrict async)
-{
- size_t _n = 0;
-
- if (check_error(ctx, async))
- return -(ctx->error.custom || ctx->error.number);
-
- while (*next_header(ctx));
- (void) next_payload(ctx, &_n);
-
- errno = EBADMSG;
- copy_errno(ctx);
- return -1;
-}
-
-
-/**
- * Apply, update, or remove a gamma ramp adjustment, synchronous version
- *
- * This is a synchronous request function, as such,
- * you have to ensure that communication is blocking
- * (default), and that there are not asynchronous
- * requests waiting, it also means that EINTR:s are
- * silently ignored and there no wait to cancel the
- * operation without disconnection from the server
- *
- * @param filter The filter to apply, update, or remove, gamma ramp meta-data must match the CRTC's
- * @param depth The datatype for the stops in the gamma ramps, must match the CRTC's
- * @param ctx The state of the library, must be connected
- * @return Zero on success, -1 on error, in which case `ctx->error`
- * (rather than `errno`) is read for information about the error
- */
-int libcoopgamma_set_gamma_sync(const libcoopgamma_filter_t* restrict filter,
- libcoopgamma_context_t* restrict ctx)
-{
- SYNC_CALL(libcoopgamma_set_gamma_send(filter, ctx, &async),
- libcoopgamma_set_gamma_recv(ctx, &async), (copy_errno(ctx), -1));
-}
-
-
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
-
diff --git a/src/test.c b/src/test.c
deleted file mode 100644
index 4a94a42..0000000
--- a/src/test.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * libcoopgamma -- Library for interfacing with cooperative gamma servers
- * 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 "libcoopgamma.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-static int streq(const char* a, const char* b)
-{
- if ((a == NULL) != (b == NULL))
- return 0;
- return (a == NULL) || !strcmp(a, b);
-}
-
-
-static int rampseq(const libcoopgamma_ramps_t* a, const libcoopgamma_ramps_t* b, libcoopgamma_depth_t depth)
-{
- size_t nr, ng, nb, width;
-
- if ((a->u8.red_size != b->u8.red_size) ||
- (a->u8.green_size != b->u8.green_size) ||
- (a->u8.blue_size != b->u8.blue_size))
- return 0;
-
- if (depth == -2)
- width = sizeof(double);
- else if (depth == -1)
- width = sizeof(float);
- else
- width = ((size_t)depth) / 8;
-
- nr = a->u8.red_size * width;
- ng = a->u8.green_size * width;
- nb = a->u8.blue_size * width;
-
- if (memcmp(a->u8.red, b->u8.red, nr + ng + nb))
- return 0;
- if (memcmp(a->u8.green, b->u8.green, ng + nb))
- return 0;
- if (memcmp(a->u8.blue, b->u8.blue, nb))
- return 0;
-
- return 1;
-}
-
-
-int main(void)
-{
- libcoopgamma_filter_t filter1, filter2;
- libcoopgamma_crtc_info_t crtc1, crtc2;
- libcoopgamma_filter_query_t query1, query2;
- libcoopgamma_filter_table_t table1, table2;
- libcoopgamma_context_t ctx1, ctx2;
- libcoopgamma_async_context_t async1, async2;
- size_t n, m, i;
- char* buf;
-
- filter1.priority = INT64_MIN;
- filter1.crtc = "CRTC";
- filter1.class = "A::B::C::D";
- filter1.lifespan = LIBCOOPGAMMA_UNTIL_REMOVAL;
- filter1.depth = LIBCOOPGAMMA_DOUBLE;
- filter1.ramps.d.red_size = 4;
- filter1.ramps.d.green_size = 5;
- filter1.ramps.d.blue_size = 6;
- filter1.ramps.d.red = (double[]){0.0, 0.1, 0.2, 0.5,
- 0.3, 0.11, 0.22, 0.45, 0.9,
- -1, -0.5, 0, 0.5, 1, 1.5};
- filter1.ramps.d.green = filter1.ramps.d.red + filter1.ramps.d.red_size;
- filter1.ramps.d.blue = filter1.ramps.d.green + filter1.ramps.d.green_size;
-
- crtc1.cooperative = 0;
- crtc1.depth = LIBCOOPGAMMA_DOUBLE;
- crtc1.supported = LIBCOOPGAMMA_YES;
- crtc1.red_size = 4;
- crtc1.green_size = 5;
- crtc1.blue_size = 6;
- crtc1.colourspace = LIBCOOPGAMMA_SRGB;
- crtc1.have_gamut = 1;
- crtc1.red_x = 100;
- crtc1.red_y = 50;
- crtc1.green_x = 300;
- crtc1.green_y = 350;
- crtc1.blue_x = 200;
- crtc1.blue_y = 260;
- crtc1.white_x = 500;
- crtc1.white_y = 999;
-
- query1.high_priority = INT64_MIN;
- query1.low_priority = INT64_MIN;
- query1.crtc = "crtc";
- query1.coalesce = 1;
-
- table1.red_size = 4;
- table1.green_size = 5;
- table1.blue_size = 6;
- table1.filter_count = 2;
- table1.filters = (libcoopgamma_queried_filter_t[]){
- {
- .priority = UINT64_MAX,
- .class = "a::b::c",
- .ramps.d = {
- .red_size = 4,
- .green_size = 5,
- .blue_size = 6,
- .red = (double[]){0.0, 0.1, 0.2, 0.5,
- 0.3, 0.11, 0.22, 0.45, 0.9,
- -1, -0.5, 0, 0.5, 1, 1.5}
- }
- }, {
- .priority = UINT64_MAX - 1,
- .class = NULL,
- .ramps.d = {
- .red_size = 4,
- .green_size = 5,
- .blue_size = 6,
- .red = (double[]){0.02, 0.12, 0.22, 0.52,
- 0.32, 0.112, 0.222, 0.452, 0.92,
- -12, -0.52, 0.2, 0.52, 12, 1.52}
- }
- }
- };
- table1.depth = LIBCOOPGAMMA_DOUBLE;
- table1.filters[0].ramps.d.green = table1.filters[0].ramps.d.red + table1.filters[0].ramps.d.red_size;
- table1.filters[1].ramps.d.green = table1.filters[1].ramps.d.red + table1.filters[1].ramps.d.red_size;
- table1.filters[0].ramps.d.blue = table1.filters[0].ramps.d.green + table1.filters[0].ramps.d.green_size;
- table1.filters[1].ramps.d.blue = table1.filters[1].ramps.d.green + table1.filters[1].ramps.d.green_size;
-
- ctx1.error.number = UINT64_MAX;
- ctx1.error.custom = 1;
- ctx1.error.server_side = 0;
- ctx1.error.description = "description";
- ctx1.fd = 3;
- ctx1.have_all_headers = 1;
- ctx1.bad_message = 0;
- ctx1.blocking = 2;
- ctx1.message_id = UINT32_MAX;
- ctx1.in_response_to = UINT32_MAX - 1;
- ctx1.outbound = "0123456789";
- ctx1.outbound_head = 7;
- ctx1.outbound_tail = 2;
- ctx1.outbound_size = 10;
- ctx1.inbound = "abcdefghi";
- ctx1.inbound_head = 6;
- ctx1.inbound_tail = 3;
- ctx1.inbound_size = 9;
- ctx1.length = 100;
- ctx1.curline = 5;
-
- async1.message_id = UINT32_MAX;
- async1.coalesce = 1;
-
- n = libcoopgamma_filter_marshal(&filter1, NULL);
- n += libcoopgamma_crtc_info_marshal(&crtc1, NULL);
- n += libcoopgamma_filter_query_marshal(&query1, NULL);
- n += libcoopgamma_filter_table_marshal(&table1, NULL);
- n += libcoopgamma_context_marshal(&ctx1, NULL);
- n += libcoopgamma_async_context_marshal(&async1, NULL);
-
- buf = malloc(n);
- n = libcoopgamma_filter_marshal(&filter1, buf);
- n += libcoopgamma_crtc_info_marshal(&crtc1, buf + n);
- n += libcoopgamma_filter_query_marshal(&query1, buf + n);
- n += libcoopgamma_filter_table_marshal(&table1, buf + n);
- n += libcoopgamma_context_marshal(&ctx1, buf + n);
- n += libcoopgamma_async_context_marshal(&async1, buf + n);
-
- if (libcoopgamma_filter_unmarshal(&filter2, buf, &m)) return 1; else n = m;
- if (libcoopgamma_crtc_info_unmarshal(&crtc2, buf + n, &m)) return 2; else n += m;
- if (libcoopgamma_filter_query_unmarshal(&query2, buf + n, &m)) return 3; else n += m;
- if (libcoopgamma_filter_table_unmarshal(&table2, buf + n, &m)) return 4; else n += m;
- if (libcoopgamma_context_unmarshal(&ctx2, buf + n, &m)) return 5; else n += m;
- if (libcoopgamma_async_context_unmarshal(&async2, buf + n, &m)) return 6;
- free(buf);
-
- if ((filter1.priority != filter2.priority) ||
- (!streq(filter1.crtc, filter2.crtc)) ||
- (!streq(filter1.class, filter2.class)) ||
- (filter1.lifespan != filter2.lifespan) ||
- (filter1.depth != filter2.depth) ||
- (!rampseq(&(filter1.ramps), &(filter2.ramps), filter1.depth)))
- return 7;
-
- if ((crtc1.cooperative != crtc2.cooperative) ||
- (crtc1.depth != crtc2.depth) ||
- (crtc1.supported != crtc2.supported) ||
- (crtc1.red_size != crtc2.red_size) ||
- (crtc1.green_size != crtc2.green_size) ||
- (crtc1.blue_size != crtc2.blue_size) ||
- (crtc1.colourspace != crtc2.colourspace) ||
- (crtc1.have_gamut != crtc2.have_gamut) ||
- (crtc1.red_x != crtc2.red_x) ||
- (crtc1.red_y != crtc2.red_y) ||
- (crtc1.green_x != crtc2.green_x) ||
- (crtc1.green_y != crtc2.green_y) ||
- (crtc1.blue_x != crtc2.blue_x) ||
- (crtc1.blue_y != crtc2.blue_y) ||
- (crtc1.white_x != crtc2.white_x) ||
- (crtc1.white_y != crtc2.white_y))
- return 8;
-
- if ((query1.high_priority != query2.high_priority) ||
- (query1.low_priority != query2.low_priority) ||
- !streq(query1.crtc, query2.crtc) ||
- (query1.coalesce != query2.coalesce))
- return 9;
-
- if ((table1.red_size != table2.red_size) ||
- (table1.green_size != table2.green_size) ||
- (table1.blue_size != table2.blue_size) ||
- (table1.filter_count != table2.filter_count) ||
- (table1.depth != table2.depth))
- return 10;
- for (i = 0; i < table1.filter_count; i++)
- if ((table1.filters[i].priority != table2.filters[i].priority) ||
- !streq(table1.filters[i].class, table2.filters[i].class) ||
- !rampseq(&(table1.filters[i].ramps), &(table2.filters[i].ramps), table1.depth))
- return 11;
-
- if ((ctx1.error.number != ctx2.error.number) ||
- (ctx1.error.custom != ctx2.error.custom) ||
- (ctx1.error.server_side != ctx2.error.server_side) ||
- !streq(ctx1.error.description, ctx2.error.description))
- return 12;
-
- if ((ctx1.fd != ctx2.fd) ||
- (ctx1.have_all_headers != ctx2.have_all_headers) ||
- (ctx1.bad_message != ctx2.bad_message) ||
- (ctx1.blocking != ctx2.blocking) ||
- (ctx1.message_id != ctx2.message_id) ||
- (ctx1.in_response_to != ctx2.in_response_to) ||
- (ctx1.length != ctx2.length) ||
- (ctx1.curline != ctx2.curline))
- return 13;
-
- if ((ctx2.outbound_head > ctx2.outbound_size) ||
- (ctx2.outbound_tail > ctx2.outbound_size) ||
- (ctx2.inbound_head > ctx2.inbound_size) ||
- (ctx2.inbound_tail > ctx2.inbound_size))
- return 14;
-
- if (((n = ctx1.outbound_head - ctx1.outbound_tail) != ctx2.outbound_head - ctx2.outbound_tail) ||
- ((m = ctx1.inbound_head - ctx1.inbound_tail) != ctx2.inbound_head - ctx2.inbound_tail))
- return 15;
-
- if (memcmp(ctx1.outbound + ctx1.outbound_tail, ctx2.outbound + ctx2.outbound_tail, n) ||
- memcmp(ctx1.inbound + ctx1.inbound_tail, ctx2.inbound + ctx2.inbound_tail, m))
- return 16;
-
- if ((async1.message_id != async2.message_id) ||
- (async1.coalesce != async2.coalesce))
- return 17;
-
- return 0;
-}
-