aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/gamma-dummy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gamma-dummy.c')
-rw-r--r--src/lib/gamma-dummy.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/src/lib/gamma-dummy.c b/src/lib/gamma-dummy.c
index 664bcf1..494e5fa 100644
--- a/src/lib/gamma-dummy.c
+++ b/src/lib/gamma-dummy.c
@@ -22,6 +22,217 @@
#include "gamma-dummy.h"
#include "libgamma-error.h"
+#include "libgamma-method.h"
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+
+
+/**
+ * Configuration set for the dummy adjustment method.
+ */
+typedef struct libgamma_dummy_configurations
+{
+ /**
+ * The method's capabilities.
+ */
+ libgamma_method_capabilities_t capabilities;
+
+ /**
+ * The adjustment method to use.
+ */
+ int real_method;
+
+ /**
+ * The number of sites on the system.
+ */
+ size_t site_count;
+
+ /**
+ * The number of paritions on a site before it has been configured.
+ */
+ size_t default_partition_count;
+
+ /**
+ * The number of CRTC:s on a paritions before it has been configured.
+ */
+ size_t default_crtc_count;
+
+ /**
+ * Whether the sites should be inherited from the real method.
+ */
+ unsigned inherit_sites : 1;
+
+ /**
+ * Whether the partitions should be inherited from the real method.
+ */
+ unsigned inherit_partition_count : 1;
+
+ /**
+ * Whether the CRTC:s should be inherited from the real method.
+ */
+ unsigned inherit_crtc_count : 1;
+
+ /**
+ * When a site has been created, stall until the partition count has
+ * been configured.
+ */
+ unsigned stall_for_partition_count : 1;
+
+ /**
+ * When a parition has been created, stall until the CRTC count has
+ * been configured.
+ */
+ unsigned stall_for_crtc_count : 1;
+
+ /**
+ * Methods should stall until the system has been configured
+ * unless $LIBGAMMA_DUMMY_STALL is not true.
+ */
+ unsigned stalled_start : 1;
+
+ /**
+ * Whether to print what is going on in the phony system.
+ */
+ unsigned verbose : 1;
+
+} libgamma_dummy_configurations_t;
+
+
+/**
+ * Dummy adjustment method internal data for a CRTC.
+ */
+typedef struct libgamma_dummy_crtc
+{
+ /**
+ * The gamma ramp for the red channel.
+ */
+ void* restrict gamma_red;
+
+ /**
+ * The gamma ramp for the green channel.
+ */
+ void* restrict gamma_green;
+
+ /**
+ * The gamma ramp for the blue channel.
+ */
+ void* restrict gamma_blue;
+
+ /**
+ * The number of stops in the gamma ramps.
+ */
+ size_t gamma_size;
+
+ /**
+ * The depth of the gamma ramps, -1 for `float`, -2 for `double`.
+ */
+ int gamma_depth;
+
+ /**
+ * CRTC state that contains this information.
+ */
+ libgamma_crtc_state_t* state;
+
+} libgamma_dummy_crtc_t;
+
+
+/**
+ * Dummy adjustment method internal data for a partition.
+ */
+typedef struct libgamma_dummy_partition
+{
+ /**
+ * The CRTC:s on the system.
+ */
+ libgamma_dummy_crtc_t* crtcs;
+
+ /**
+ * The number of CRTC:s on the system.
+ */
+ size_t crtc_count;
+
+ /**
+ * Partition state that contains this information.
+ */
+ libgamma_partition_state_t* state;
+
+} libgamma_dummy_partition_t;
+
+
+/**
+ * Dummy adjustment method internal data for a site.
+ */
+typedef struct libgamma_dummy_site
+{
+ /**
+ * The partitions on the system.
+ */
+ libgamma_dummy_partition_t* partitions;
+
+ /**
+ * The number of partitions on the system.
+ */
+ size_t partition_count;
+
+ /**
+ * Site state that contains this information.
+ */
+ libgamma_site_state_t* state;
+
+} libgamma_dummy_site_t;
+
+
+
+/**
+ * Restore the gamma ramps for a CRTC to the system settings for that CRTC
+ * and ignore the method's capabilities.
+ *
+ * @param this The CRTC data
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library.
+ */
+static int libgamma_dummy_crtc_restore_forced(libgamma_dummy_crtc_t* restrict data);
+
+
+
+/**
+ * Configurations for the dummy adjustment method.
+ */
+static libgamma_dummy_configurations_t libgamma_dummy_configurations =
+ {
+ .capabilities =
+ {
+ .crtc_information = 0, /* TODO */
+ .default_site_known = 1,
+ .multiple_sites = 1,
+ .multiple_partitions = 1,
+ .multiple_crtcs = 1,
+ .partitions_are_graphics_cards = 1,
+ .site_restore = 1,
+ .partition_restore = 1,
+ .crtc_restore = 1,
+ .identical_gamma_sizes = 0,
+ .fixed_gamma_size = 0,
+ .fixed_gamma_depth = 0,
+ .real = 0,
+ .fake = 0
+ },
+ .real_method = LIBGAMMA_METHOD_DUMMY,
+ .site_count = 2,
+ .default_partition_count = 2,
+ .default_crtc_count = 2,
+ .inherit_sites = 1,
+ .inherit_partition_count = 1,
+ .inherit_crtc_count = 1,
+ .stall_for_partition_count = 0,
+ .stall_for_crtc_count = 0,
+ .stalled_start = 1,
+ .verbose = 0
+ };
+
/**
@@ -31,6 +242,9 @@
*/
void libgamma_dummy_method_capabilities(libgamma_method_capabilities_t* restrict this)
{
+ *this = libgamma_dummy_configurations.capabilities;
+ this->real = libgamma_dummy_configurations.real_method != LIBGAMMA_METHOD_DUMMY;
+ this->fake = this->real;
}
@@ -60,6 +274,12 @@ int libgamma_dummy_site_initialise(libgamma_site_state_t* restrict this,
*/
void libgamma_dummy_site_destroy(libgamma_site_state_t* restrict this)
{
+ libgamma_dummy_site_t* data = this->data;
+ if (data == NULL)
+ return;
+
+ free(data->partitions);
+ free(data);
}
@@ -72,6 +292,18 @@ void libgamma_dummy_site_destroy(libgamma_site_state_t* restrict this)
*/
int libgamma_dummy_site_restore(libgamma_site_state_t* restrict this)
{
+ libgamma_dummy_site_t* data = this->data;
+ size_t i, j;
+
+ if (libgamma_dummy_configurations.capabilities.site_restore == 0)
+ return errno = ENOTSUP, LIBGAMMA_ERRNO_SET;
+
+ for (j = 0; j < data->partition_count; j++)
+ for (i = 0; i < data->partitions[j].crtc_count; i++)
+ if (libgamma_dummy_crtc_restore_forced(data->partitions[j].crtcs + i) < 0)
+ return -1;
+
+ return 0;
}
@@ -98,6 +330,12 @@ int libgamma_dummy_partition_initialise(libgamma_partition_state_t* restrict thi
*/
void libgamma_dummy_partition_destroy(libgamma_partition_state_t* restrict this)
{
+ libgamma_dummy_partition_t* data = this->data;
+ if (data == NULL)
+ return;
+
+ free(data->crtcs);
+ data->crtcs = NULL;
}
@@ -110,6 +348,17 @@ void libgamma_dummy_partition_destroy(libgamma_partition_state_t* restrict this)
*/
int libgamma_dummy_partition_restore(libgamma_partition_state_t* restrict this)
{
+ libgamma_dummy_partition_t* data = this->data;
+ size_t i;
+
+ if (libgamma_dummy_configurations.capabilities.partition_restore == 0)
+ return errno = ENOTSUP, LIBGAMMA_ERRNO_SET;
+
+ for (i = 0; i < data->crtc_count; i++)
+ if (libgamma_dummy_crtc_restore_forced(data->crtcs + i) < 0)
+ return -1;
+
+ return 0;
}
@@ -126,6 +375,40 @@ int libgamma_dummy_partition_restore(libgamma_partition_state_t* restrict this)
int libgamma_dummy_crtc_initialise(libgamma_crtc_state_t* restrict this,
libgamma_partition_state_t* restrict partition, size_t crtc)
{
+ libgamma_dummy_partition_t* partition_data = partition->data;
+ libgamma_dummy_crtc_t* data = partition_data->crtcs + crtc;
+ size_t stop_size;
+
+ this->data = NULL;
+
+ if (crtc >= partition_data->crtc_count)
+ return LIBGAMMA_NO_SUCH_CRTC;
+
+ this->data = data;
+ data->state = this;
+
+ if (data->gamma_depth == -1)
+ stop_size = sizeof(float);
+ else if (data->gamma_depth == -2)
+ stop_size = sizeof(double);
+ else
+ stop_size = (size_t)(data->gamma_depth) / 8;
+
+ data->gamma_red = malloc(3 * data->gamma_size * stop_size);
+ data->gamma_green = ((char*)(data->gamma_red)) + data->gamma_size * stop_size;
+ data->gamma_blue = ((char*)(data->gamma_green)) + data->gamma_size * stop_size;
+
+ if (data->gamma_red == NULL)
+ goto fail;
+
+ return libgamma_dummy_crtc_restore_forced(data);
+
+ fail:
+ free(data->gamma_red);
+ data->gamma_red = NULL;
+ data->gamma_green = NULL;
+ data->gamma_blue = NULL;
+ return LIBGAMMA_ERRNO_SET;
}
@@ -136,6 +419,14 @@ int libgamma_dummy_crtc_initialise(libgamma_crtc_state_t* restrict this,
*/
void libgamma_dummy_crtc_destroy(libgamma_crtc_state_t* restrict this)
{
+ libgamma_dummy_crtc_t* data = this->data;
+ if (data == NULL)
+ return;
+
+ free(data->gamma_red);
+ data->gamma_red = NULL;
+ data->gamma_green = NULL;
+ data->gamma_blue = NULL;
}
@@ -148,6 +439,87 @@ void libgamma_dummy_crtc_destroy(libgamma_crtc_state_t* restrict this)
*/
int libgamma_dummy_crtc_restore(libgamma_crtc_state_t* restrict this)
{
+ if (libgamma_dummy_configurations.capabilities.crtc_restore == 0)
+ return errno = ENOTSUP, LIBGAMMA_ERRNO_SET;
+
+ return libgamma_dummy_crtc_restore_forced(this->data);
+}
+
+
+/**
+ * Restore the gamma ramps for a CRTC to the system settings for that CRTC
+ * and ignore the method's capabilities.
+ *
+ * @param this The CRTC data
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library.
+ */
+static int libgamma_dummy_crtc_restore_forced(libgamma_dummy_crtc_t* restrict data)
+{
+ size_t i, n = data->gamma_size;
+ if (data->gamma_red == NULL)
+ return 0;
+
+ if (data->gamma_depth == 8)
+ {
+ int8_t* red = data->gamma_red;
+ int8_t* green = data->gamma_green;
+ int8_t* blue = data->gamma_blue;
+ double max = (double)INT8_MAX;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (int8_t)(max * ((double)i / (double)(n - 1)));
+ }
+ else if (data->gamma_depth == 16)
+ {
+ int16_t* red = data->gamma_red;
+ int16_t* green = data->gamma_green;
+ int16_t* blue = data->gamma_blue;
+ double max = (double)INT16_MAX;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (int16_t)(max * ((double)i / (double)(n - 1)));
+ }
+ else if (data->gamma_depth == 32)
+ {
+ int32_t* red = data->gamma_red;
+ int32_t* green = data->gamma_green;
+ int32_t* blue = data->gamma_blue;
+ double max = (double)INT32_MAX;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (int32_t)(max * ((double)i / (double)(n - 1)));
+ }
+ else if (data->gamma_depth == 64)
+ {
+ int64_t* red = data->gamma_red;
+ int64_t* green = data->gamma_green;
+ int64_t* blue = data->gamma_blue;
+ double max = (double)INT64_MAX;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (int64_t)(max * ((double)i / (double)(n - 1)));
+ }
+ else if (data->gamma_depth == -1)
+ {
+ float* red = data->gamma_red;
+ float* green = data->gamma_green;
+ float* blue = data->gamma_blue;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (float)((double)i / (double)(n - 1));
+ }
+ else
+ {
+ double* red = data->gamma_red;
+ double* green = data->gamma_green;
+ double* blue = data->gamma_blue;
+ for (i = 0; i < n; i++)
+ red[i] = green[i] = blue[i] =
+ (double)i / (double)(n - 1);
+ }
+
+ return 0;
}