aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-03-05 00:43:38 +0100
committerMattias Andrée <maandree@kth.se>2021-03-05 00:43:38 +0100
commit0ce0d8d6e0c420ccafa79e0203b928c3559a4311 (patch)
tree88e8228a93691c28811a49898abf86a96dd9d613
parentChange license + change style + misc (diff)
downloadlibgamma-0ce0d8d6e0c420ccafa79e0203b928c3559a4311.tar.gz
libgamma-0ce0d8d6e0c420ccafa79e0203b928c3559a4311.tar.bz2
libgamma-0ce0d8d6e0c420ccafa79e0203b928c3559a4311.tar.xz
Split source files, merge public header files, eliminite use gpp, rewrite makefile
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--.gitignore32
-rw-r--r--DEPENDENCIES50
-rw-r--r--Makefile484
-rw-r--r--TODO4
-rw-r--r--common.h352
-rw-r--r--config.mk6
-rwxr-xr-xconfigure211
-rw-r--r--debug.mk8
-rw-r--r--fake-quartz-cg.c (renamed from src/lib/fake-quartz-cg.c)0
-rw-r--r--fake-quartz-cg.h (renamed from src/lib/fake-quartz-cg.h)0
-rw-r--r--fake-w32-gdi.c (renamed from src/lib/fake-w32-gdi.c)0
-rw-r--r--fake-w32-gdi.h (renamed from src/lib/fake-w32-gdi.h)0
-rw-r--r--gamma-dummy.c.gpp (renamed from src/lib/gamma-dummy.c.gpp)10
-rw-r--r--gamma-dummy.h (renamed from src/lib/gamma-dummy.h)7
-rw-r--r--gamma-linux-drm.c (renamed from src/lib/gamma-linux-drm.c)6
-rw-r--r--gamma-linux-drm.h (renamed from src/lib/gamma-linux-drm.h)11
-rw-r--r--gamma-quartz-cg.c (renamed from src/lib/gamma-quartz-cg.c)0
-rw-r--r--gamma-quartz-cg.h (renamed from src/lib/gamma-quartz-cg.h)9
-rw-r--r--gamma-w32-gdi.c (renamed from src/lib/gamma-w32-gdi.c)0
-rw-r--r--gamma-w32-gdi.h (renamed from src/lib/gamma-w32-gdi.h)11
-rw-r--r--gamma-x-randr.c (renamed from src/lib/gamma-x-randr.c)4
-rw-r--r--gamma-x-randr.h (renamed from src/lib/gamma-x-randr.h)9
-rw-r--r--gamma-x-vidmode.c (renamed from src/lib/gamma-x-vidmode.c)0
-rw-r--r--gamma-x-vidmode.h (renamed from src/lib/gamma-x-vidmode.h)11
-rw-r--r--get_ramps.h30
-rw-r--r--libgamma.h2474
-rw-r--r--libgamma_behex_edid.c13
-rw-r--r--libgamma_behex_edid_lowercase.c33
-rw-r--r--libgamma_behex_edid_uppercase.c33
-rw-r--r--libgamma_connector_type_count.c9
-rw-r--r--libgamma_const_of_connector_type.c25
-rw-r--r--libgamma_const_of_method.c24
-rw-r--r--libgamma_const_of_subpixel_order.c25
-rw-r--r--libgamma_crtc_destroy.c23
-rw-r--r--libgamma_crtc_free.c11
-rw-r--r--libgamma_crtc_get_gamma_ramps16.c21
-rw-r--r--libgamma_crtc_get_gamma_ramps32.c21
-rw-r--r--libgamma_crtc_get_gamma_ramps64.c21
-rw-r--r--libgamma_crtc_get_gamma_ramps8.c21
-rw-r--r--libgamma_crtc_get_gamma_rampsd.c21
-rw-r--r--libgamma_crtc_get_gamma_rampsf.c21
-rw-r--r--libgamma_crtc_info_count.c12
-rw-r--r--libgamma_crtc_information_destroy.c15
-rw-r--r--libgamma_crtc_information_free.c11
-rw-r--r--libgamma_crtc_initialise.c29
-rw-r--r--libgamma_crtc_restore.c24
-rw-r--r--libgamma_crtc_set_gamma_ramps16.c21
-rw-r--r--libgamma_crtc_set_gamma_ramps16_f.c25
-rw-r--r--libgamma_crtc_set_gamma_ramps32.c21
-rw-r--r--libgamma_crtc_set_gamma_ramps32_f.c25
-rw-r--r--libgamma_crtc_set_gamma_ramps64.c21
-rw-r--r--libgamma_crtc_set_gamma_ramps64_f.c25
-rw-r--r--libgamma_crtc_set_gamma_ramps8.c21
-rw-r--r--libgamma_crtc_set_gamma_ramps8_f.c25
-rw-r--r--libgamma_crtc_set_gamma_rampsd.c21
-rw-r--r--libgamma_crtc_set_gamma_rampsd_f.c25
-rw-r--r--libgamma_crtc_set_gamma_rampsf.c21
-rw-r--r--libgamma_crtc_set_gamma_rampsf_f.c25
-rw-r--r--libgamma_error_min.c10
-rw-r--r--libgamma_gamma_ramps16_destroy.c16
-rw-r--r--libgamma_gamma_ramps16_free.c18
-rw-r--r--libgamma_gamma_ramps16_initialise.c28
-rw-r--r--libgamma_gamma_ramps32_destroy.c16
-rw-r--r--libgamma_gamma_ramps32_free.c18
-rw-r--r--libgamma_gamma_ramps32_initialise.c23
-rw-r--r--libgamma_gamma_ramps64_destroy.c16
-rw-r--r--libgamma_gamma_ramps64_free.c18
-rw-r--r--libgamma_gamma_ramps64_initialise.c23
-rw-r--r--libgamma_gamma_ramps8_destroy.c16
-rw-r--r--libgamma_gamma_ramps8_free.c18
-rw-r--r--libgamma_gamma_ramps8_initialise.c23
-rw-r--r--libgamma_gamma_rampsd_destroy.c16
-rw-r--r--libgamma_gamma_rampsd_free.c18
-rw-r--r--libgamma_gamma_rampsd_initialise.c23
-rw-r--r--libgamma_gamma_rampsf_destroy.c16
-rw-r--r--libgamma_gamma_rampsf_free.c18
-rw-r--r--libgamma_gamma_rampsf_initialise.c23
-rw-r--r--libgamma_get_crtc_information.c29
-rw-r--r--libgamma_group_gid.c37
-rw-r--r--libgamma_group_name.c44
-rw-r--r--libgamma_internal_allocated_any_ramp.c60
-rw-r--r--libgamma_internal_parse_edid.c (renamed from src/lib/edid.c)12
-rw-r--r--libgamma_internal_translate_from_64.c44
-rw-r--r--libgamma_internal_translate_to_64.c184
-rw-r--r--libgamma_internal_translated_ramp_get_.c60
-rw-r--r--libgamma_internal_translated_ramp_set_.c57
-rw-r--r--libgamma_is_method_available.c24
-rw-r--r--libgamma_list_methods.c135
-rw-r--r--libgamma_method_capabilities.c28
-rw-r--r--libgamma_method_count.c13
-rw-r--r--libgamma_method_default_site.c31
-rw-r--r--libgamma_method_default_site_variable.c25
-rw-r--r--libgamma_name_of_connector_type.c28
-rw-r--r--libgamma_name_of_error.c23
-rw-r--r--libgamma_name_of_method.c23
-rw-r--r--libgamma_name_of_subpixel_order.c27
-rw-r--r--libgamma_partition_destroy.c23
-rw-r--r--libgamma_partition_free.c11
-rw-r--r--libgamma_partition_initialise.c29
-rw-r--r--libgamma_partition_restore.c24
-rw-r--r--libgamma_perror.c40
-rw-r--r--libgamma_site_destroy.c24
-rw-r--r--libgamma_site_free.c11
-rw-r--r--libgamma_site_initialise.c34
-rw-r--r--libgamma_site_restore.c24
-rw-r--r--libgamma_strerror.c32
-rw-r--r--libgamma_strerror_r.c61
-rw-r--r--libgamma_subpixel_order_count.c9
-rw-r--r--libgamma_unhex_edid.c55
-rw-r--r--libgamma_value_of_connector_type.c29
-rw-r--r--libgamma_value_of_error.c23
-rw-r--r--libgamma_value_of_method.c28
-rw-r--r--libgamma_value_of_subpixel_order.c29
-rw-r--r--mk/linux.mk8
-rw-r--r--mk/macos.mk6
-rw-r--r--mk/method-dummy=no.mk0
-rw-r--r--mk/method-dummy=yes.mk3
-rw-r--r--mk/method-linux-drm=no.mk0
-rw-r--r--mk/method-linux-drm=yes.mk5
-rw-r--r--mk/method-quartz-cg=fake.mk3
-rw-r--r--mk/method-quartz-cg=no.mk0
-rw-r--r--mk/method-quartz-cg=yes.mk8
-rw-r--r--mk/method-w32-gdi=fake.mk3
-rw-r--r--mk/method-w32-gdi=no.mk0
-rw-r--r--mk/method-w32-gdi=yes.mk3
-rw-r--r--mk/method-x-randr=no.mk0
-rw-r--r--mk/method-x-randr=yes.mk5
-rw-r--r--mk/method-x-vidmode=no.mk0
-rw-r--r--mk/method-x-vidmode=yes.mk5
-rw-r--r--mk/windows.mk6
-rw-r--r--set_ramps.h25
-rw-r--r--set_ramps_fun.h50
-rw-r--r--src/lib/edid.h22
-rw-r--r--src/lib/gamma-helper.c372
-rw-r--r--src/lib/gamma-helper.h144
-rw-r--r--src/lib/libgamma-error.c.gpp178
-rw-r--r--src/lib/libgamma-error.h379
-rw-r--r--src/lib/libgamma-facade.c.gpp1097
-rw-r--r--src/lib/libgamma-facade.h537
-rw-r--r--src/lib/libgamma-method.c324
-rw-r--r--src/lib/libgamma-method.h1323
-rw-r--r--src/lib/libgamma.h11
142 files changed, 5628 insertions, 5034 deletions
diff --git a/.gitignore b/.gitignore
index 270192c..0c969eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,11 @@
-_/
-bin/
-obj/
-\#*\#
-.*
-!.git*
+*\#*
*~
-*.bak
-*.swp
-*.swo
-*.su
-*.gch
-*.out
*.o
-/config.mk
-/src/lib/libgamma-config.h
-*.info
-*.pdf
-*.dvi
-*.ps
-*.tar
-*.gz
-*.bz2
-*.xz
-
+*.lo
+*.su
+*.a
+*.so
+*.so.*
+*.dll
+*.dylib
+config.h
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 6a62f7d..c63ba29 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -10,26 +10,18 @@ RUNTIME DEPENDENCIES:
compile-time and are not utilisable if not selected at compile-time.
-CONFIGURE DEPENDENCIES:
-
- sh
- coreutils
- sed
-
-
BUILD DEPENDENCIES:
make
- grep
- sed
- coreutils
- c99 gcc is preferred
+ sh
+ printf
+ test
+ mv
+ rm
+ cat
+ c11
+ ar
pkg-config
- general-preprocessor (gpp)
- python Both Python 2 and Python 3 will work
- texinfo Optional: for info, pdf, ps and dvi manuals
- texlive-core Optional: for pdf, ps and dvi manuals
- bash Optional: for info, pdf, ps and dvi manuals
And all runtime dependencies that are mandatory or has been opted for.
@@ -37,25 +29,7 @@ BUILD DEPENDENCIES:
INSTALL DEPENDENCIES:
make
- coreutils
-
-
-DEPENDENCIES SOURCES:
-
- sh bash can provide sh
- make https://www.gnu.org/software/make
- grep https://www.gnu.org/software/grep
- sed https://www.gnu.org/software/sed
- coreutils https://www.gnu.org/software/coreutils
- c99 https://gcc.gnu.org
- pkg-config http://pkgconfig.freedesktop.org
- general-preprocessor (gpp) https://github.com/maandree/gpp
- python https://www.python.org/
- texinfo https://www.gnu.org/software/texinfo/
- texlive-core https://tug.org/texlive/
- bash https://www.gnu.org/software/bash
- libc https://www.gnu.org/software/libc
- libxcb http://xcb.freedesktop.org/
- libx11 (xlib) http://xorg.freedesktop.org/
- libxxf86vm http://xorg.freedesktop.org/
- libdrm http://dri.freedesktop.org/
+ sh
+ mkdir
+ cp
+ ln
diff --git a/Makefile b/Makefile
index 1e99d29..6b8746d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,312 +1,192 @@
-# Copying and distribution of this file, with or without modification,
-# are permitted in any medium without royalty provided the copyright
-# notice and this notice are preserved. This file is offered as-is,
-# without any warranty.
+.POSIX:
-
-# The package path prefix, if you want to install to another root, set DESTDIR to that root.
-PREFIX ?= /usr
-# The library path excluding prefix.
-LIB ?= /lib
-# The library header path excluding prefix.
-INCLUDE ?= /include
-# The resource path excluding prefix.
-DATA ?= /share
-# The library path including prefix.
-LIBDIR ?= $(PREFIX)$(LIB)
-# The library header including prefix.
-INCLUDEDIR ?= $(PREFIX)$(INCLUDE)
-# The resource path including prefix.
-DATADIR ?= $(PREFIX)$(DATA)
-# The generic documentation path including prefix.
-DOCDIR ?= $(DATADIR)/doc
-# The info manual documentation path including prefix.
-INFODIR ?= $(DATADIR)/info
-# The license base path including prefix.
-LICENSEDIR ?= $(DATADIR)/licenses
-
-# The name of the package as it should be installed.
-PKGNAME ?= libgamma
-
-# General-preprocess command. (https://github.com/maandree/gpp)
-GPP ?= gpp
-
-# C compiler, GNU C Compiler by default
-CC ?= gcc
-CC_BASE ?= $(shell echo $(CC) | cut -d ' ' -f 1)
-
-
-# Enabled warnings.
-WARN = -Wall -Wextra -pedantic -Wformat=2 -Winit-self -Wmissing-include-dirs \
- -Wfloat-equal -Wshadow -Wmissing-prototypes -Wmissing-declarations \
- -Wredundant-decls -Wnested-externs -Winline -Wno-variadic-macros \
- -Wswitch-default -Wconversion -Wcast-align -Wstrict-overflow \
- -Wdeclaration-after-statement -Wundef -Wcast-qual -Wbad-function-cast \
- -Wwrite-strings -Waggregate-return -Wpacked -Wstrict-prototypes \
- -Wold-style-definition
-
-ifeq ($(CC_BASE),gcc)
-WARN += -Wdouble-promotion -Wtrampolines -Wsign-conversion -Wsync-nand \
- -Wlogical-op -Wvector-operation-performance \
- -Wunsuffixed-float-constants -Wsuggest-attribute=const \
- -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
- -Wsuggest-attribute=format -Wnormalized=nfkc \
- -Wunsafe-loop-optimizations
-endif
-
-
-# The C standard used in the code.
-STD = c99
-
-# Library linking flags for the linker.
-LIBS_LD =
-# Library linking flags for the C compiler.
-LIBS_C =
-
-# Object files for the library.
-LIBOBJ = libgamma-facade libgamma-method libgamma-error gamma-helper edid
-
-# Header files for the library are parsed for the info manual.
-HEADERS_INFO = libgamma-error libgamma-facade libgamma-method
-
-# Header files for the library, as installed.
-HEADERS = libgamma libgamma-config $(HEADERS_INFO)
-
-# Object files for the test.
-TESTOBJ = test methods errors crtcinfo user ramps
-
-# The version of the library.
LIB_MAJOR = 0
-LIB_MINOR = 7
+LIB_MINOR = 8
LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR)
-# Change by .config.mk to reflect what is used in the OS, linux uses so: libgamma.so
-SO = so
-
-# These three below are changed by .config.mk if required
-SHARED = -shared
-LDSO = -Wl,-soname,libgamma.$(SO).$(LIB_MAJOR)
-PIC = -fPIC
-
-# Include configurations from `./configure`.
-include .config.mk
-
-# Optimisation level (and debug flags.)
-ifeq ($(DEBUG),y)
-ifeq ($(CC_BASE),gcc)
-OPTIMISE = -Og -g3
-else
-OPTIMISE = -g
-endif
-else
-ifeq ($(CC_BASE),gcc)
-OPTIMISE = -Ofast
-else
-OPTIMISE = -O
-endif
-endif
-
-# C compiler debug flags.
-DEBUG_FLAGS =
-ifeq ($(DEBUG),y)
-DEBUG_FLAGS += -D'DEBUG'
-endif
-
-# Options for the C compiler for the test.
-TEST_FLAGS = $(OPTIMISE) $(WARN) -std=$(STD) -fstrict-aliasing -fstrict-overflow -fno-builtin
-
-ifeq ($(CC_BASE),gcc)
-TEST_FLAGS += -fstack-usage -ftree-vrp -fipa-pure-const -funsafe-loop-optimizations
-endif
-
-
-# Options for the C compiler for the library.
-LIB_FLAGS = $(TEST_FLAGS) $(DEBUG_FLAGS) $(DEFINITIONS) -DLIBGAMMA_CONFIG_H
-
-ifeq ($(CC_BASE),gcc)
-TEST_FLAGS += -D__GCC__
-LIB_FLAGS += -D__GCC__
-endif
-
-ifeq ($(HAVE_INT128),y)
-LIB_FLAGS += -DHAVE_INT128
-endif
-
-
-
-# Build rules.
-
-.PHONY: default
-default: lib test info
-
-.PHONY: all
-all: lib test doc
-
-
-.PHONY: lib
-lib: bin/libgamma.$(SO).$(LIB_VERSION) bin/libgamma.$(SO).$(LIB_MAJOR) bin/libgamma.$(SO)
-
-bin/libgamma.$(SO).$(LIB_VERSION): $(foreach O,$(LIBOBJ),obj/lib/$(O).o)
- mkdir -p $(shell dirname $@)
- $(CC) $(LIB_FLAGS) $(LIBS_LD) $(SHARED) $(LDSO) -o $@ $^ $(LDFLAGS)
-
-bin/libgamma.$(SO).$(LIB_MAJOR):
- mkdir -p $(shell dirname $@)
- ln -sf libgamma.$(SO).$(LIB_VERSION) $@
-
-bin/libgamma.$(SO):
- mkdir -p $(shell dirname $@)
- ln -sf libgamma.$(SO).$(LIB_VERSION) $@
-
-obj/lib/%.o: src/lib/%.c src/lib/*.h
- mkdir -p $(shell dirname $@)
- $(CC) $(LIB_FLAGS) $(LIBS_C) $(PIC) -s -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
-obj/lib/%.o: obj/lib/%.c src/lib/*.h
- $(CC) $(LIB_FLAGS) $(LIBS_C) $(PIC) -iquote"$$(dirname "$<" | sed -e 's:^obj:src:')" -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
+X_RANDR_METHOD = no
+X_VIDMODE_METHOD = no
+LINUX_DRM_METHOD = no
+W32_GDI_METHOD = no
+QUARTZ_CG_METHOD = no
+DUMMY_METHOD = yes
+
+
+CONFIGFILE = config.mk
+include $(CONFIGFILE)
+
+OS = linux
+# Linux: linux
+# Mac OS: macos
+# Windows: windows
+include mk/$(OS).mk
+
+
+HDR_METHODS =
+CPPFLAGS_METHODS =
+METHODS_PARAMS =
+
+QUARTZ_CORE_GRAPHICS_METHOD = $(QUARTZ_CG_METHOD)
+include mk/method-x-randr=$(X_RANDR_METHOD).mk
+include mk/method-x-vidmode=$(X_VIDMODE_METHOD).mk
+include mk/method-linux-drm=$(LINUX_DRM_METHOD).mk
+include mk/method-w32-gdi=$(W32_GDI_METHOD).mk
+include mk/method-quartz-cg=$(QUARTZ_CORE_GRAPHICS_METHOD).mk
+include mk/method-dummy=$(DUMMY_METHOD).mk
+
+
+OBJ_PUBLIC =\
+ libgamma_behex_edid.o\
+ libgamma_behex_edid_lowercase.o\
+ libgamma_behex_edid_uppercase.o\
+ libgamma_connector_type_count.o\
+ libgamma_const_of_connector_type.o\
+ libgamma_const_of_method.o\
+ libgamma_const_of_subpixel_order.o\
+ libgamma_crtc_destroy.o\
+ libgamma_crtc_free.o\
+ libgamma_crtc_get_gamma_ramps16.o\
+ libgamma_crtc_get_gamma_ramps32.o\
+ libgamma_crtc_get_gamma_ramps64.o\
+ libgamma_crtc_get_gamma_ramps8.o\
+ libgamma_crtc_get_gamma_rampsd.o\
+ libgamma_crtc_get_gamma_rampsf.o\
+ libgamma_crtc_info_count.o\
+ libgamma_crtc_information_destroy.o\
+ libgamma_crtc_information_free.o\
+ libgamma_crtc_initialise.o\
+ libgamma_crtc_restore.o\
+ libgamma_crtc_set_gamma_ramps16.o\
+ libgamma_crtc_set_gamma_ramps16_f.o\
+ libgamma_crtc_set_gamma_ramps32.o\
+ libgamma_crtc_set_gamma_ramps32_f.o\
+ libgamma_crtc_set_gamma_ramps64.o\
+ libgamma_crtc_set_gamma_ramps64_f.o\
+ libgamma_crtc_set_gamma_ramps8.o\
+ libgamma_crtc_set_gamma_ramps8_f.o\
+ libgamma_crtc_set_gamma_rampsd.o\
+ libgamma_crtc_set_gamma_rampsd_f.o\
+ libgamma_crtc_set_gamma_rampsf.o\
+ libgamma_crtc_set_gamma_rampsf_f.o\
+ libgamma_error_min.o\
+ libgamma_gamma_ramps16_destroy.o\
+ libgamma_gamma_ramps16_free.o\
+ libgamma_gamma_ramps16_initialise.o\
+ libgamma_gamma_ramps32_destroy.o\
+ libgamma_gamma_ramps32_free.o\
+ libgamma_gamma_ramps32_initialise.o\
+ libgamma_gamma_ramps64_destroy.o\
+ libgamma_gamma_ramps64_free.o\
+ libgamma_gamma_ramps64_initialise.o\
+ libgamma_gamma_ramps8_destroy.o\
+ libgamma_gamma_ramps8_free.o\
+ libgamma_gamma_ramps8_initialise.o\
+ libgamma_gamma_rampsd_destroy.o\
+ libgamma_gamma_rampsd_free.o\
+ libgamma_gamma_rampsd_initialise.o\
+ libgamma_gamma_rampsf_destroy.o\
+ libgamma_gamma_rampsf_free.o\
+ libgamma_gamma_rampsf_initialise.o\
+ libgamma_get_crtc_information.o\
+ libgamma_group_gid.o\
+ libgamma_group_name.o\
+ libgamma_is_method_available.o\
+ libgamma_list_methods.o\
+ libgamma_method_capabilities.o\
+ libgamma_method_count.o\
+ libgamma_method_default_site.o\
+ libgamma_method_default_site_variable.o\
+ libgamma_name_of_connector_type.o\
+ libgamma_name_of_error.o\
+ libgamma_name_of_method.o\
+ libgamma_name_of_subpixel_order.o\
+ libgamma_partition_destroy.o\
+ libgamma_partition_free.o\
+ libgamma_partition_initialise.o\
+ libgamma_partition_restore.o\
+ libgamma_perror.o\
+ libgamma_site_destroy.o\
+ libgamma_site_free.o\
+ libgamma_site_initialise.o\
+ libgamma_site_restore.o\
+ libgamma_strerror.o\
+ libgamma_strerror_r.o\
+ libgamma_subpixel_order_count.o\
+ libgamma_unhex_edid.o\
+ libgamma_value_of_connector_type.o\
+ libgamma_value_of_error.o\
+ libgamma_value_of_method.o\
+ libgamma_value_of_subpixel_order.o
+
+OBJ_INTERNAL =\
+ libgamma_internal_allocated_any_ramp.o\
+ libgamma_internal_parse_edid.o\
+ libgamma_internal_translated_ramp_get_.o\
+ libgamma_internal_translated_ramp_set_.o\
+ libgamma_internal_translate_from_64.o\
+ libgamma_internal_translate_to_64.o\
+
+OBJ = $(OBJ_PUBLIC) $(OBJ_INTERNAL)
+LOBJ = $(OBJ:.o=.lo)
+
+HDR =\
+ common.h\
+ config.h\
+ get_ramps.h\
+ libgamma.h\
+ set_ramps.h\
+ set_ramps_fun.h\
+ $(HDR_METHODS)
+
+
+all: libgamma.a libgamma.$(LIBEXT)
+$(OBJ): $(@:.o=.c) $(HDR)
+$(LOBJ): $(@:.lo=.c) $(HDR)
+
+config.h: FORCE
+ printf '/* This file is auto-generated.mk */\n' > $@~
+ printf '#include "%s"\n' $(HDR_METHODS) >> $@~
+ printf '#define LIST_AVAILABLE_METHODS(_)' >> $@~
+ printf '\\\n\t_(%s, %s, %s, %s)' $(METHODS_PARAMS) >> $@~
+ printf '\n' >> $@~
+ if ! test -f $@ || ! test "$$(cat < $@)" = "$$(cat < $@~)"; then mv -- $@~ $@; fi
+
+libgamma.a: $(OBJ)
+ -rm -f -- $@
+ $(AR) -rc $@ $(OBJ)
+ $(AR) -s $@
+
+libgamma.$(LIBEXT): $(LOBJ)
+ $(CC) $(LIBFLAGS) $(LDFLAGS_METHODS) -o $@ $(LOBJ) $(LDFLAGS)
+
+.c.o:
+ $(CC) -c -o $@ $< $(CFLAGS) $(CFLAGS_METHODS) $(CPPFLAGS) $(CPPFLAGS_METHODS)
+
+.c.lo:
+ $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CFLAGS_METHODS) $(CPPFLAGS) $(CPPFLAGS_METHODS)
+
+install: libgamma.a libgamma.$(LIBEXT)
+ mkdir -p -- "$(DESTDIR)$(PREFIX)/lib/"
+ mkdir -p -- "$(DESTDIR)$(PREFIX)/include/"
+ cp -- libgamma.$(LIBEXT) "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBMINOREXT)"
+ ln -sf -- libgamma.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBMAJOREXT)"
+ ln -sf -- libgamma.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBEXT)"
+ cp -- libgamma.a "$(DESTDIR)$(PREFIX)/lib/"
+ cp -- libgamma.h "$(DESTDIR)$(PREFIX)/include/"
-obj/%: src/%.gpp src/extract/libgamma-*-extract
- mkdir -p $(shell dirname $@)
- $(GPP) --symbol '$$' --input $< --output $@
-
-
-.PHONY: test
-test: bin/test
-
-bin/test: $(foreach O,$(TESTOBJ),obj/test/$(O).o) bin/libgamma.$(SO).$(LIB_VERSION) bin/libgamma.$(SO)
- mkdir -p $(shell dirname $@)
- $(CC) $(TEST_FLAGS) $(LIBS_LD) -Lbin -lgamma -o $@ $(foreach O,$(TESTOBJ),obj/test/$(O).o) $(LDFLAGS)
-
-obj/test/%.o: src/test/%.c src/test/*.h src/lib/libgamma*.h
- mkdir -p $(shell dirname $@)
- $(CC) $(TEST_FLAGS) -Isrc/lib -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
-
-
-.PHONY: doc
-doc: info pdf dvi ps
-
-obj/libgamma.texinfo: info/libgamma.texinfo $(foreach H,$(HEADERS_INFO),src/lib/$(H).h) \
- src/extract/libgamma-*-extract info/texise info/behead
- mkdir -p obj
- $(GPP) --symbol '%' --input $< --output $@
-
-obj/%.texinfo: info/%.texinfo
- mkdir -p obj
- cp $< $@
-
-.PHONY: info
-info: libgamma.info
-%.info: obj/%.texinfo obj/fdl.texinfo
- makeinfo $<
-
-.PHONY: pdf
-pdf: libgamma.pdf
-%.pdf: obj/%.texinfo obj/fdl.texinfo
- @mkdir -p obj/pdf
- cd obj/pdf ; yes X | texi2pdf ../../$<
- mv obj/pdf/$@ $@
-
-.PHONY: dvi
-dvi: libgamma.dvi
-%.dvi: obj/%.texinfo obj/fdl.texinfo
- @mkdir -p obj/dvi
- cd obj/dvi ; yes X | $(TEXI2DVI) ../../$<
- mv obj/dvi/$@ $@
-
-.PHONY: ps
-ps: libgamma.ps
-%.ps: obj/%.texinfo obj/fdl.texinfo
- @mkdir -p obj/ps
- cd obj/ps ; yes X | texi2pdf --ps ../../$<
- mv obj/ps/$@ $@
-
-
-# Install rules.
-
-.PHONY: install
-install: install-base install-info
-
-.PHONY: install
-install-all: install-base install-doc
-
-.PHONY: install-base
-install-base: install-lib install-include install-copyright
-
-
-.PHONY: install-lib
-install-lib: bin/libgamma.$(SO).$(LIB_VERSION)
- install -dm755 -- "$(DESTDIR)$(LIBDIR)"
- install -m755 $< -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO).$(LIB_VERSION)"
- ln -sf libgamma.$(SO).$(LIB_VERSION) -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO).$(LIB_MAJOR)"
- ln -sf libgamma.$(SO).$(LIB_VERSION) -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO)"
-
-.PHONY: install-include
-install-include:
- install -dm755 -- "$(DESTDIR)$(INCLUDEDIR)"
- install -m644 $(foreach H,$(HEADERS),src/lib/$(H).h) -- "$(DESTDIR)$(INCLUDEDIR)"
-
-
-.PHONY: install-copyright
-install-copyright: install-copying install-license
-
-.PHONY: install-copying
-install-copying:
- install -dm755 -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)"
- install -m644 COPYING -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING"
-
-.PHONY: install-license
-install-license:
- install -dm755 -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)"
- install -m644 LICENSE -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/LICENSE"
-
-
-.PHONY: install-doc
-install-doc: install-info install-pdf install-ps install-dvi
-
-.PHONY: install-info
-install-info: libgamma.info
- install -dm755 -- "$(DESTDIR)$(INFODIR)"
- install -m644 $< -- "$(DESTDIR)$(INFODIR)/$(PKGNAME).info"
-
-.PHONY: install-pdf
-install-pdf: libgamma.pdf
- install -dm755 -- "$(DESTDIR)$(DOCDIR)"
- install -m644 $< -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).pdf"
-
-.PHONY: install-ps
-install-ps: libgamma.ps
- install -dm755 -- "$(DESTDIR)$(DOCDIR)"
- install -m644 $< -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).ps"
-
-.PHONY: install-dvi
-install-dvi: libgamma.dvi
- install -dm755 -- "$(DESTDIR)$(DOCDIR)"
- install -m644 $< -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).dvi"
-
-
-# Uninstall rules.
-
-.PHONY: uninstall
uninstall:
- -rm -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO).$(LIB_VERSION)"
- -rm -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO).$(LIB_MAJOR)"
- -rm -- "$(DESTDIR)$(LIBDIR)/libgamma.$(SO)"
- -rm -- $(foreach H,$(HEADERS),"$(DESTDIR)$(INCLUDEDIR)/$(H).h")
- -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING"
- -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/LICENSE"
- -rmdir -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)"
- -rm -- "$(DESTDIR)$(INFODIR)/$(PKGNAME).info"
- -rm -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).pdf"
- -rm -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).ps"
- -rm -- "$(DESTDIR)$(DOCDIR)/$(PKGNAME).dvi"
-
+ -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBMAJOREXT)"
+ -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBMINOREXT)"
+ -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libgamma.$(LIBEXT)"
+ -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libgamma.a"
+ -rm -f -- "$(DESTDIR)$(PREFIX)/include/libgamma.h"
-# Clean rules.
-
-.PHONY: clean
clean:
- -rm -rf obj bin libgamma.info libgamma.pdf libgamma.ps libgamma.dvi
+ -rm -f -- *.o *.lo *.su *.a *.$(LIBEXT)
+
+.SUFFIXES:
+.SUFFIXES: .lo .o .c
-.PHONY: distclean
-distclean: clean
- -rm -f .config.mk src/lib/libgamma-config.h
+FORCE:
+.PHONY: all install uninstall clean FORCE
diff --git a/TODO b/TODO
index 974b98c..81f2af2 100644
--- a/TODO
+++ b/TODO
@@ -6,10 +6,6 @@ Important functionality:
non-RGB, and monochrome/greyscale). This information
is obtainable from the monitor's EDID.
-libgamma-intl
- An extension with support for text description
- of constants and internationalisation.
-
Unsupported display servers:
GNU Hurd TTY Does it have gamma ramp support?
The BSD TTY:s Do they have gamma ramp support?
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..a6584f1
--- /dev/null
+++ b/common.h
@@ -0,0 +1,352 @@
+/* See LICENSE file for copyright and license details. */
+#include "libgamma.h"
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "config.h"
+
+
+#if !defined(HAVE_INT128) && defined(__GNUC__)
+# define HAVE_INT128
+#endif
+
+
+
+#define LIST_ERRORS(_)\
+ _(LIBGAMMA_ERRNO_SET, NULL)\
+ _(LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD, "No such adjustment method")\
+ _(LIBGAMMA_NO_SUCH_SITE, "No such site")\
+ _(LIBGAMMA_NO_SUCH_PARTITION, "No such partition")\
+ _(LIBGAMMA_NO_SUCH_CRTC, "No such CRTC")\
+ _(LIBGAMMA_IMPOSSIBLE_AMOUNT, "Impossible amount")\
+ _(LIBGAMMA_CONNECTOR_DISABLED, "Connector is disabled")\
+ _(LIBGAMMA_OPEN_CRTC_FAILED, "Could not open CRTC")\
+ _(LIBGAMMA_CRTC_INFO_NOT_SUPPORTED, "CRTC information is not supported")\
+ _(LIBGAMMA_GAMMA_RAMP_READ_FAILED, "Could not read readm gamma ramp")\
+ _(LIBGAMMA_GAMMA_RAMP_WRITE_FAILED, "Could not write to gamma ramp")\
+ _(LIBGAMMA_GAMMA_RAMP_SIZE_CHANGED, "Gamma ramp size changed")\
+ _(LIBGAMMA_MIXED_GAMMA_RAMP_SIZE, "Mixed gamma ramp size")\
+ _(LIBGAMMA_WRONG_GAMMA_RAMP_SIZE, "Wrong gamma ramp size")\
+ _(LIBGAMMA_SINGLETON_GAMMA_RAMP, "Single-stop gamma ramp")\
+ _(LIBGAMMA_LIST_CRTCS_FAILED, "Could not retrieve list of CRTCs")\
+ _(LIBGAMMA_ACQUIRING_MODE_RESOURCES_FAILED, "Could not acquire mode resources")\
+ _(LIBGAMMA_NEGATIVE_PARTITION_COUNT, "Number of partitions is negative")\
+ _(LIBGAMMA_NEGATIVE_CRTC_COUNT, "Number of CRTCs is negative")\
+ _(LIBGAMMA_DEVICE_RESTRICTED, "Device is restricted to root")\
+ _(LIBGAMMA_DEVICE_ACCESS_FAILED, "Failed to access device")\
+ _(LIBGAMMA_DEVICE_REQUIRE_GROUP, "Device requires group membership")\
+ _(LIBGAMMA_GRAPHICS_CARD_REMOVED, "Graphics card was removed")\
+ _(LIBGAMMA_STATE_UNKNOWN, "Unknown state")\
+ _(LIBGAMMA_CONNECTOR_UNKNOWN, "Unknwon connector")\
+ _(LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED, "Connector type not recognised")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED, "Subpixel order not recognised")\
+ _(LIBGAMMA_EDID_LENGTH_UNSUPPORTED, "Unsupported EDID length")\
+ _(LIBGAMMA_EDID_WRONG_MAGIC_NUMBER, "Incorrect magic number in EDID")\
+ _(LIBGAMMA_EDID_REVISION_UNSUPPORTED, "Unsupported EDID revision")\
+ _(LIBGAMMA_GAMMA_NOT_SPECIFIED, "No gamma information specified")\
+ _(LIBGAMMA_EDID_CHECKSUM_ERROR, "Incorrect checksum in EDID")\
+ _(LIBGAMMA_GAMMA_NOT_SPECIFIED_AND_EDID_CHECKSUM_ERROR, "No gamma information specified and incorrect checksum in EDID")\
+ _(LIBGAMMA_GAMMA_RAMPS_SIZE_QUERY_FAILED, "Could not retrieve gamma ramp size")\
+ _(LIBGAMMA_OPEN_PARTITION_FAILED, "Could not open partition")\
+ _(LIBGAMMA_OPEN_SITE_FAILED, "Could not open site")\
+ _(LIBGAMMA_PROTOCOL_VERSION_QUERY_FAILED, "Could not retreive protocol version")\
+ _(LIBGAMMA_PROTOCOL_VERSION_NOT_SUPPORTED, "Protocol version not supported")\
+ _(LIBGAMMA_LIST_PARTITIONS_FAILED, "Could not retrieve list of partitions")\
+ _(LIBGAMMA_NULL_PARTITION, "Null partition retrieved")\
+ _(LIBGAMMA_NOT_CONNECTED, "Not connected to subsystem")\
+ _(LIBGAMMA_REPLY_VALUE_EXTRACTION_FAILED, "Could not extract value from reply")\
+ _(LIBGAMMA_EDID_NOT_FOUND, "No EDID found")\
+ _(LIBGAMMA_LIST_PROPERTIES_FAILED, "Could not list properties")\
+ _(LIBGAMMA_PROPERTY_VALUE_QUERY_FAILED, "Could not query the value of a property")\
+ _(LIBGAMMA_OUTPUT_INFORMATION_QUERY_FAILED, "Could not query information for output")
+
+#define X(A, B) -1
+# if (LIST_ERRORS(X)) != LIBGAMMA_ERROR_MIN
+# error There is a mismatch between LIST_ERRORS and LIBGAMMA_ERROR_MIN
+# endif
+#undef X
+
+
+
+#ifdef HAVE_LIBGAMMA_METHOD_DUMMY
+# define HAVE_METHOD_DUMMY 1
+#else
+# define HAVE_METHOD_DUMMY 0
+#endif
+
+#ifdef HAVE_LIBGAMMA_METHOD_X_RANDR
+# define HAVE_METHOD_X_RANDR 1
+#else
+# define HAVE_METHOD_X_RANDR 0
+#endif
+
+#ifdef HAVE_LIBGAMMA_METHOD_X_VIDMODE
+# define HAVE_METHOD_X_VIDMODE 1
+#else
+# define HAVE_METHOD_X_VIDMODE 0
+#endif
+
+#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
+# define HAVE_METHOD_LINUX_DRM 1
+#else
+# define HAVE_METHOD_LINUX_DRM 0
+#endif
+
+#ifdef HAVE_LIBGAMMA_METHOD_W32_GDI
+# define HAVE_METHOD_W32_GDI 1
+#else
+# define HAVE_METHOD_W32_GDI 0
+#endif
+
+#ifdef HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
+# define HAVE_METHOD_QUARTZ_CORE_GRAPHICS 1
+#else
+# define HAVE_METHOD_QUARTZ_CORE_GRAPHICS 0
+#endif
+
+#define LIST_METHODS(_)\
+ _(LIBGAMMA_METHOD_X_RANDR, randr, x_randr, HAVE_METHOD_X_RANDR)\
+ _(LIBGAMMA_METHOD_X_VIDMODE, vidmode, x_vidmode, HAVE_METHOD_X_VIDMODE)\
+ _(LIBGAMMA_METHOD_LINUX_DRM, drm, linux_drm, HAVE_METHOD_LINUX_DRM)\
+ _(LIBGAMMA_METHOD_W32_GDI, w32gdi, w32_gdi, HAVE_METHOD_W32_GDI)\
+ _(LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS, quartz, quartz_cg, HAVE_METHOD_QUARTZ_CORE_GRAPHICS)\
+ _(LIBGAMMA_METHOD_DUMMY, dummy, dummy, HAVE_METHOD_DUMMY)
+
+#define X(...) +1
+# if (LIST_METHODS(X)) != LIBGAMMA_METHOD_COUNT
+# error There is a mismatch between LIST_METHODS and LIBGAMMA_METHOD_COUNT
+# endif
+#undef X
+
+
+
+#define LIST_CONNECTOR_TYPES(_)\
+ _(LIBGAMMA_CONNECTOR_TYPE_Unknown, "Unknown")\
+ _(LIBGAMMA_CONNECTOR_TYPE_VGA, "VGA")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DVI, "DVI")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DVII, "DVI-I")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DVID, "DVI-D")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DVIA, "DVI-A")\
+ _(LIBGAMMA_CONNECTOR_TYPE_Composite, "Composite")\
+ _(LIBGAMMA_CONNECTOR_TYPE_SVIDEO, "S-video")\
+ _(LIBGAMMA_CONNECTOR_TYPE_LVDS, "LVDS")\
+ _(LIBGAMMA_CONNECTOR_TYPE_Component, "Component")\
+ _(LIBGAMMA_CONNECTOR_TYPE_9PinDIN, "9 pin DIN")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DisplayPort, "DisplayPort")\
+ _(LIBGAMMA_CONNECTOR_TYPE_HDMI, "HDMI")\
+ _(LIBGAMMA_CONNECTOR_TYPE_HDMIA, "HDMI-A")\
+ _(LIBGAMMA_CONNECTOR_TYPE_HDMIB, "HDMI-B")\
+ _(LIBGAMMA_CONNECTOR_TYPE_TV, "TV")\
+ _(LIBGAMMA_CONNECTOR_TYPE_eDP, "eDP")\
+ _(LIBGAMMA_CONNECTOR_TYPE_VIRTUAL, "Virtual")\
+ _(LIBGAMMA_CONNECTOR_TYPE_DSI, "DSI")\
+ _(LIBGAMMA_CONNECTOR_TYPE_LFP, "LFP")
+
+#define X(A, B) +1
+# if (LIST_CONNECTOR_TYPES(X)) != LIBGAMMA_CONNECTOR_TYPE_COUNT
+# error There is a mismatch between LIST_CONNECTOR_TYPES and LIBGAMMA_CONNECTOR_TYPE_COUNT
+# endif
+#undef X
+
+
+
+#define LIST_SUBPIXEL_ORDERS(_)\
+ _(LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN, "Unknown")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_NONE, "None")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB, "Horizontal RGB")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR, "Horizontal BGR")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB, "Vertical RGB")\
+ _(LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR, "Vertical BGR")
+
+#define X(A, B) +1
+# if (LIST_SUBPIXEL_ORDERS(X)) != LIBGAMMA_SUBPIXEL_ORDER_COUNT
+# error There is a mismatch between LIST_SUBPIXEL_ORDERS and LIBGAMMA_SUBPIXEL_ORDER_COUNT
+# endif
+#undef X
+
+
+
+/**
+ * Gamma ramp structure union for different depths
+ */
+typedef union gamma_ramps_any {
+ /**
+ * 8-bit gamma ramps
+ */
+ libgamma_gamma_ramps8_t bits8;
+
+ /**
+ * 16-bit gamma ramps
+ */
+ libgamma_gamma_ramps16_t bits16;
+
+ /**
+ * 32-bit gamma ramps
+ */
+ libgamma_gamma_ramps32_t bits32;
+
+ /**
+ * 64-bit gamma ramps
+ */
+ libgamma_gamma_ramps64_t bits64;
+
+ /**
+ * Single precision float gamma ramps
+ */
+ libgamma_gamma_rampsf_t float_single;
+
+ /**
+ * Double precision float gamma ramps
+ */
+ libgamma_gamma_rampsd_t float_double;
+
+} gamma_ramps_any_t;
+
+
+/**
+ * A function for reading the gamma ramps from a CRTC
+ *
+ * @param this The CRTC state
+ * @param ramps The store for the gamma ramps
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+typedef int get_ramps_any_fun(libgamma_crtc_state_t *restrict, gamma_ramps_any_t *restrict);
+
+/**
+ * A function for writing the gamma ramps to a CRTC
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+typedef int set_ramps_any_fun(libgamma_crtc_state_t *restrict, gamma_ramps_any_t);
+
+
+
+/**
+ * Get the current gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used read the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+#define libgamma_internal_translated_ramp_get(this, ramps, depth_user, depth_system, fun)\
+ libgamma_internal_translated_ramp_get_((this), (ramps), (depth_user), (depth_system), (get_ramps_any_fun *)(fun))
+
+/**
+ * Set the gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used write the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+#define libgamma_internal_translated_ramp_set(this, ramps, depth_user, depth_system, fun)\
+ libgamma_internal_translated_ramp_set_((this), (ramps), (depth_user), (depth_system), (set_ramps_any_fun *)fun)
+
+/**
+ * Get the current gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used read the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int libgamma_internal_translated_ramp_get_(libgamma_crtc_state_t *restrict, gamma_ramps_any_t *restrict,
+ signed, signed, get_ramps_any_fun *);
+
+/**
+ * Set the gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used write the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int libgamma_internal_translated_ramp_set_(libgamma_crtc_state_t *restrict, gamma_ramps_any_t,
+ signed, signed, set_ramps_any_fun *);
+
+/**
+ * Convert any set of gamma ramps into a 64-bit integer array with all channels
+ *
+ * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
+ * @param n The grand size of gamma ramps (sum of all channels' sizes)
+ * @param out Output array
+ * @param in Input gamma ramps
+ */
+void libgamma_internal_translate_to_64(signed, size_t, uint64_t *restrict, gamma_ramps_any_t);
+
+/**
+ * Undo the actions of `libgamma_internal_translate_to_64`
+ *
+ * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
+ * @param n The grand size of gamma ramps (sum of all channels' sizes)
+ * @param out Output gamma ramps
+ * @param in Input array, may be modified
+ */
+void libgamma_internal_translate_from_64(signed, size_t, gamma_ramps_any_t, uint64_t *restrict);
+
+/**
+ * Allocate and initalise a gamma ramp with any depth
+ *
+ * @param ramps_sys Output gamma ramps
+ * @param ramps The gamma ramps whose sizes should be duplicated
+ * @param depth The depth of the gamma ramps to allocate,
+ * `-1` for `float`, `-2` for `double`
+ * @param elements Output reference for the grand size of the gamma ramps
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int libgamma_internal_allocated_any_ramp(gamma_ramps_any_t *restrict, gamma_ramps_any_t, signed, size_t *restrict);
+
+
+/**
+ * Parse the EDID of a monitor
+ *
+ * @param this Instance of a data structure to fill with the information about the EDID;
+ * it must contain the EDID and its length
+ * @param fields OR:ed identifiers for the information about the EDID that should be parsed;
+ * fields that do not have to do with EDID are ignored
+ * @return Non-zero on error
+ */
+int libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict, int32_t);
diff --git a/config.mk b/config.mk
new file mode 100644
index 0000000..cc02d6e
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,6 @@
+PREFIX = /usr
+MANPREFIX = $(PREFIX)/share/man
+
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700
+CFLAGS = -std=c11 -O2
+LDFLAGS = -s
diff --git a/configure b/configure
deleted file mode 100755
index b662f13..0000000
--- a/configure
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/bin/sh
-
-# Copying and distribution of this file, with or without modification,
-# are permitted in any medium without royalty provided the copyright
-# notice and this notice are preserved. This file is offered as-is,
-# without any warranty.
-
-
-have_debug='No, enable with --debug'
-have_dummy='No, enable with --enable-dummy'
-have_randr='No, enable with --enable-randr'
-have_vidmode='No, enable with --enable-vidmode'
-have_drm='No, enable with --enable-drm'
-have_w32gdi='No, enable with --enable-w32gdi[=fake]'
-have_quartz='No, enable with --enable-quartz[=fake]'
-
-enable_debug=0
-enable_dummy=0
-enable_randr=0
-enable_vidmode=0
-enable_drm=0
-enable_w32gdi=0
-enable_quartz=0
-fake_w32gdi=0
-fake_quartz=0
-
-os=common
-
-
-for arg in "$@"; do
- case "${arg}" in
- (--linux=developer|--developer) enable_debug=1
- enable_dummy=1
- enable_vidmode=1
- enable_randr=1
- enable_drm=1
- fake_w32gdi=1
- fake_quartz=1
- os=gnu
- ;;
- (--linux) enable_vidmode=1
- enable_randr=1
- enable_drm=1
- os=gnu
- ;;
- (--*bsd=developer) enable_debug=1
- enable_dummy=1
- enable_vidmode=1
- enable_randr=1
- fake_w32gdi=1
- fake_quartz=1
- ;;
- (--*bsd) enable_vidmode=1
- enable_randr=1
- ;;
- (--windows=developer) enable_debug=1
- enable_dummy=1
- enable_w32gdi=1
- os=w32
- ;;
- (--windows) enable_w32gdi=1
- os=w32
- ;;
- (--mac-os-x=developer) enable_debug=1
- enable_dummy=1
- enable_quartz=1
- os=osx
- ;;
- (--mac-os-x) enable_quartz=1
- os=osx
- ;;
- (--debug) enable_debug=1 ;;
- (--enable-dummy) enable_dummy=1 ;;
- (--enable-randr) enable_randr=1 ;;
- (--enable-vidmode) enable_vidmode=1 ;;
- (--enable-drm) enable_drm=1 ;;
- (--enable-w32gdi) enable_w32gdi=1 ;;
- (--enable-quartz) enable_quartz=1 ;;
- (--enable-w32gdi=fake) fake_w32gdi=1 ;;
- (--enable-quartz=fake) fake_quartz=1 ;;
- (*)
- echo "$0: unrecognised option: ${arg}" >&2
- exit 1
- ;;
- esac
-done
-
-
-exec 3> "$(dirname "$0")/.config.mk"
-exec 4> "$(dirname "$0")/src/lib/libgamma-config.h"
-echo 'DEFINITIONS =' >&3
-
-echo '/**' >&4
-cat "$(dirname "$0")/COPYING" | sed -e 's:^: \* :' >&4
-echo ' */' >&4
-echo '#ifndef LIBGAMMA_CONFIG_H' >&4
-echo '#define LIBGAMMA_CONFIG_H' >&4
-echo >&4
-echo >&4
-
-if [ ${fake_w32gdi} = 1 ]; then
- enable_w32gdi=1
-fi
-if [ ${fake_quartz} = 1 ]; then
- enable_quartz=1
-fi
-if [ ${enable_debug} = 1 ]; then
- echo "DEBUG = y" >&3
- echo 'DEBUG_FLAGS += -DDEBUG' >&3
- have_debug='Yes'
-fi
-if [ ${enable_dummy} = 1 ]; then
- echo 'LIBOBJ += gamma-dummy' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_DUMMY' >&3
- echo '#define HAVE_LIBGAMMA_METHOD_DUMMY' >&4
- have_dummy='Yes'
-fi
-if [ ${enable_randr} = 1 ]; then
- echo 'LIBOBJ += gamma-x-randr' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_X_RANDR' >&3
- echo 'LIBS_LD += $$(pkg-config --libs xcb xcb-randr)' >&3
- echo 'LIBS_C += $$(pkg-config --cflags xcb xcb-randr)' >&3
- echo '#define HAVE_LIBGAMMA_METHOD_X_RANDR' >&4
- have_randr='Yes'
-fi
-if [ ${enable_vidmode} = 1 ]; then
- echo 'LIBOBJ += gamma-x-vidmode' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_X_VIDMODE' >&3
- echo 'LIBS_LD += $$(pkg-config --libs x11 xxf86vm)' >&3
- echo 'LIBS_C += $$(pkg-config --cflags x11 xxf86vm)' >&3
- echo '#define HAVE_LIBGAMMA_METHOD_X_VIDMODE' >&4
- have_vidmode='Yes'
-fi
-if [ ${enable_drm} = 1 ]; then
- echo 'LIBOBJ += gamma-linux-drm' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_LINUX_DRM' >&3
- echo 'LIBS_LD += $$(pkg-config --libs libdrm)' >&3
- echo 'LIBS_C += $$(pkg-config --cflags libdrm)' >&3
- echo '#define HAVE_LIBGAMMA_METHOD_LINUX_DRM' >&4
- have_drm='Yes'
-fi
-if [ ${enable_w32gdi} = 1 ]; then
- echo 'LIBOBJ += gamma-w32-gdi' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_W32_GDI' >&3
- echo '#define HAVE_LIBGAMMA_METHOD_W32_GDI' >&4
- have_w32gdi='Yes'
-fi
-if [ ${enable_quartz} = 1 ]; then
- echo 'LIBOBJ += gamma-quartz-cg' >&3
- echo 'DEFINITIONS += -DHAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS' >&3
- if [ ${fake_w32gdi} = 0 ]; then
- F_ApplicationServices="/System/Library/Frameworks/ApplicationServices.framework"
- I_ApplicationServices="${F_ApplicationServices}/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Headers"
- echo "LIBS_LD += -I${I_ApplicationServices} -F${F_ApplicationServices} -framework ApplicationServices" >&3
- fi
- echo '#define HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS' >&4
- have_quartz='Yes'
-fi
-if [ ${fake_w32gdi} = 1 ]; then
- echo 'LIBOBJ += fake-w32-gdi' >&3
- echo 'DEFINITIONS += -DFAKE_LIBGAMMA_METHOD_W32_GDI' >&3
- echo '#define FAKE_LIBGAMMA_METHOD_W32_GDI' >&4
- if [ ${enable_randr} = 1 ]; then
- have_w32gdi='Yes, fake via the RandR protocol for X'
- else
- have_w32gdi='Yes, fake via dummy method, `/dev/null`-style'
- fi
-fi
-if [ ${fake_quartz} = 1 ]; then
- echo 'LIBOBJ += fake-quartz-cg' >&3
- echo 'DEFINITIONS += -DFAKE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS' >&3
- echo '#define FAKE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS' >&4
- if [ ${enable_randr} = 1 ]; then
- have_quartz='Yes, fake via the RandR protocol for X'
- else
- have_quartz='Yes, fake via dummy method, `/dev/null`-style'
- fi
-fi
-if [ ${os} = w32 ]; then
- echo 'SO = dll' >&3
- echo 'PIC = ' >&3
- echo 'SHARED = -mdll' >&3
-elif [ ${os} = osx ]; then
- echo 'SO = dylib' >&3
- echo 'SHARED = -dynamiclib' >&3
- echo 'LDSO = ' >&3
-elif [ ${os} = gnu ]; then
- echo 'HAVE_INT128 = y' >&3
-fi
-
-echo >&4
-echo >&4
-echo '#endif' >&4
-echo >&4
-
-exec 4<&-
-exec 3<&-
-
-
-echo 'libgamma has now been configured.'
-echo
-echo " Debug mode: ${have_debug}"
-echo " Dummy method: ${have_dummy}"
-echo " X.org via RandR: ${have_randr}"
-echo " X.org via VidMode: ${have_vidmode}"
-echo " Linux DRM: ${have_drm}"
-echo " Windows GDI: ${have_w32gdi}"
-echo " Quartz via CoreGraphics: ${have_quartz}"
-echo
-echo 'Compile with `make`.'
-
diff --git a/debug.mk b/debug.mk
new file mode 100644
index 0000000..f9ba3db
--- /dev/null
+++ b/debug.mk
@@ -0,0 +1,8 @@
+include config.mk
+
+CFLAGS = -std=c11 -Og -g
+LDFLAGS =
+
+W32_GDI_METHOD = fake
+QUARTZ_CG_METHOD = fake
+DUMMY_METHOD = yes
diff --git a/src/lib/fake-quartz-cg.c b/fake-quartz-cg.c
index 75f1fb2..75f1fb2 100644
--- a/src/lib/fake-quartz-cg.c
+++ b/fake-quartz-cg.c
diff --git a/src/lib/fake-quartz-cg.h b/fake-quartz-cg.h
index 361a73c..361a73c 100644
--- a/src/lib/fake-quartz-cg.h
+++ b/fake-quartz-cg.h
diff --git a/src/lib/fake-w32-gdi.c b/fake-w32-gdi.c
index 68847ca..68847ca 100644
--- a/src/lib/fake-w32-gdi.c
+++ b/fake-w32-gdi.c
diff --git a/src/lib/fake-w32-gdi.h b/fake-w32-gdi.h
index bcc2fa9..bcc2fa9 100644
--- a/src/lib/fake-w32-gdi.h
+++ b/fake-w32-gdi.h
diff --git a/src/lib/gamma-dummy.c.gpp b/gamma-dummy.c.gpp
index a9aa724..4cc758d 100644
--- a/src/lib/gamma-dummy.c.gpp
+++ b/gamma-dummy.c.gpp
@@ -669,7 +669,7 @@ libgamma_dummy_get_crtc_information(libgamma_crtc_information_t *restrict this,
if (this->edid_error)
this->width_mm_edid_error = this->height_mm_edid_error = this->gamma_error = this->edid_error;
else if (fields & (LIBGAMMA_CRTC_INFO_MACRO_EDID ^ LIBGAMMA_CRTC_INFO_EDID))
- e |= libgamma_parse_edid(this, fields);
+ e |= libgamma_internal_parse_edid(this, fields);
/* Test errors */
#define _E(FIELD, VAR)\
@@ -717,7 +717,7 @@ int
libgamma_dummy_crtc_get_gamma_${2}(libgamma_crtc_state_t *restrict this, libgamma_gamma_${2}_t *restrict ramps)
{
libgamma_dummy_crtc_t *data = this->data;
- libgamma_gamma_ramps_any_t ramps_;
+ gamma_ramps_any_t ramps_;
${1}* r_ramp = data->gamma_red;
${1}* g_ramp = data->gamma_green;
${1}* b_ramp = data->gamma_blue;
@@ -742,7 +742,7 @@ libgamma_dummy_crtc_get_gamma_${2}(libgamma_crtc_state_t *restrict this, libgamm
do {\
if (data->info.gamma_depth == DEPTH) {\
ramps_.${3} = *ramps;\
- return libgamma_translated_ramp_get(this, &ramps_, ${4}, DEPTH, libgamma_crtc_get_gamma_ramps ## SUFFIX);\
+ return libgamma_internal_translated_ramp_get(this, &ramps_, ${4}, DEPTH, libgamma_crtc_get_gamma_ramps ## SUFFIX);\
}\
} while (0)
@@ -796,7 +796,7 @@ int
libgamma_dummy_crtc_set_gamma_${2}(libgamma_crtc_state_t *restrict this, libgamma_gamma_${2}_t ramps)
{
libgamma_dummy_crtc_t *data = this->data;
- libgamma_gamma_ramps_any_t ramps_;
+ gamma_ramps_any_t ramps_;
${1} *r_ramp = data->gamma_red;
${1} *g_ramp = data->gamma_green;
${1} *b_ramp = data->gamma_blue;
@@ -821,7 +821,7 @@ libgamma_dummy_crtc_set_gamma_${2}(libgamma_crtc_state_t *restrict this, libgamm
do {\
if (data->info.gamma_depth == DEPTH) {\
ramps_.${3} = ramps;\
- return libgamma_translated_ramp_set(this, ramps_, ${4}, DEPTH, libgamma_crtc_set_gamma_ramps ## SUFFIX);\
+ return libgamma_internal_translated_ramp_set(this, ramps_, ${4}, DEPTH, libgamma_crtc_set_gamma_ramps ## SUFFIX);\
}\
} while (0)
diff --git a/src/lib/gamma-dummy.h b/gamma-dummy.h
index a52b087..684934e 100644
--- a/src/lib/gamma-dummy.h
+++ b/gamma-dummy.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_DUMMY_H
#define LIBGAMMA_GAMMA_DUMMY_H
-#ifndef HAVE_LIBGAMMA_METHOD_DUMMY
-# error Including gamma-dummy.h without HAVE_LIBGAMMA_METHOD_DUMMY
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
diff --git a/src/lib/gamma-linux-drm.c b/gamma-linux-drm.c
index c2fc646..25a5861 100644
--- a/src/lib/gamma-linux-drm.c
+++ b/gamma-linux-drm.c
@@ -803,7 +803,7 @@ libgamma_linux_drm_get_crtc_information(libgamma_crtc_information_t *restrict th
}
/* Parse EDID */
if (fields & (LIBGAMMA_CRTC_INFO_MACRO_EDID ^ LIBGAMMA_CRTC_INFO_EDID))
- e |= libgamma_parse_edid(this, fields);
+ e |= libgamma_internal_parse_edid(this, fields);
cont:
/* Get gamma ramp size */
@@ -890,8 +890,8 @@ libgamma_linux_drm_crtc_set_gamma_ramps16(libgamma_crtc_state_t *restrict this,
case EBADF:
case ENODEV:
case ENXIO:
- /* XXX: I have not actually tested removing my graphics card or,
- * monitor but I imagine either of these is what would happen. */
+ /* TODO: I have not actually tested removing my graphics card or,
+ * monitor but I imagine either of these is what would happen. */
return LIBGAMMA_GRAPHICS_CARD_REMOVED;
default:
diff --git a/src/lib/gamma-linux-drm.h b/gamma-linux-drm.h
index 41a654d..a8f1e1c 100644
--- a/src/lib/gamma-linux-drm.h
+++ b/gamma-linux-drm.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_LINUX_DRM_H
#define LIBGAMMA_GAMMA_LINUX_DRM_H
-#ifndef HAVE_LIBGAMMA_METHOD_LINUX_DRM
-# error Including gamma-linux-drm.h without HAVE_LIBGAMMA_METHOD_LINUX_DRM
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
@@ -37,7 +30,7 @@ int libgamma_linux_drm_site_initialise(libgamma_site_state_t *restrict, char *re
*
* @param this The site state
*/
-void libgamma_linux_drm_site_destroy(libgamma_site_state_t *restrict) __attribute__((const));
+void libgamma_linux_drm_site_destroy(libgamma_site_state_t *restrict);
/**
* Restore the gamma ramps all CRTC:s with a site to the system settings
@@ -93,7 +86,7 @@ int libgamma_linux_drm_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma
*
* @param this The CRTC state
*/
-void libgamma_linux_drm_crtc_destroy(libgamma_crtc_state_t *restrict) __attribute__((const));
+void libgamma_linux_drm_crtc_destroy(libgamma_crtc_state_t *restrict);
/**
* Restore the gamma ramps for a CRTC to the system settings for that CRTC
diff --git a/src/lib/gamma-quartz-cg.c b/gamma-quartz-cg.c
index b0e3a29..b0e3a29 100644
--- a/src/lib/gamma-quartz-cg.c
+++ b/gamma-quartz-cg.c
diff --git a/src/lib/gamma-quartz-cg.h b/gamma-quartz-cg.h
index 211e055..6044680 100644
--- a/src/lib/gamma-quartz-cg.h
+++ b/gamma-quartz-cg.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_QUARTZ_CG_H
#define LIBGAMMA_GAMMA_QUARTZ_CG_H
-#ifndef HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
-# error Including gamma-quartz-cg.h without HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
@@ -94,7 +87,7 @@ int libgamma_quartz_cg_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma
*
* @param this The CRTC state
*/
-void libgamma_quartz_cg_crtc_destroy(libgamma_crtc_state_t *restrict) __attribute__((const));
+void libgamma_quartz_cg_crtc_destroy(libgamma_crtc_state_t *restrict);
/**
* Restore the gamma ramps for a CRTC to the system settings for that CRTC
diff --git a/src/lib/gamma-w32-gdi.c b/gamma-w32-gdi.c
index e93b53d..e93b53d 100644
--- a/src/lib/gamma-w32-gdi.c
+++ b/gamma-w32-gdi.c
diff --git a/src/lib/gamma-w32-gdi.h b/gamma-w32-gdi.h
index d139f16..245a94d 100644
--- a/src/lib/gamma-w32-gdi.h
+++ b/gamma-w32-gdi.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_W32_GDI_H
#define LIBGAMMA_GAMMA_W32_GDI_H
-#ifndef HAVE_LIBGAMMA_METHOD_W32_GDI
-# error Including gamma-w32-gdi.h without HAVE_LIBGAMMA_METHOD_W32_GDI
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
@@ -37,7 +30,7 @@ int libgamma_w32_gdi_site_initialise(libgamma_site_state_t *restrict, char *rest
*
* @param this The site state
*/
-void libgamma_w32_gdi_site_destroy(libgamma_site_state_t *restrict) __attribute__((const));
+void libgamma_w32_gdi_site_destroy(libgamma_site_state_t *restrict);
/**
* Restore the gamma ramps all CRTC:s with a site to the system settings
@@ -65,7 +58,7 @@ int libgamma_w32_gdi_partition_initialise(libgamma_partition_state_t *restrict,
*
* @param this The partition state
*/
-void libgamma_w32_gdi_partition_destroy(libgamma_partition_state_t *restrict) __attribute__((const));
+void libgamma_w32_gdi_partition_destroy(libgamma_partition_state_t *restrict);
/**
* Restore the gamma ramps all CRTC:s with a partition to the system settings
diff --git a/src/lib/gamma-x-randr.c b/gamma-x-randr.c
index fce65d1..95d730c 100644
--- a/src/lib/gamma-x-randr.c
+++ b/gamma-x-randr.c
@@ -192,7 +192,7 @@ libgamma_x_randr_site_initialise(libgamma_site_state_t *restrict this, char *res
/* Release resources */
free(reply);
/* If `xcb_connect` failed, both `error` and `reply` will be `NULL`.
- XXX: Can both be `NULL` for any other reason? */
+ * TODO: Can both be `NULL` for any other reason? */
if (!error && !reply)
return LIBGAMMA_OPEN_SITE_FAILED;
xcb_disconnect(connection);
@@ -874,7 +874,7 @@ libgamma_x_randr_get_crtc_information(libgamma_crtc_information_t *restrict this
}
/* Parse EDID */
if ((fields & (LIBGAMMA_CRTC_INFO_MACRO_EDID ^ LIBGAMMA_CRTC_INFO_EDID)))
- e |= libgamma_parse_edid(this, fields);
+ e |= libgamma_internal_parse_edid(this, fields);
cont:
/* Get gamma ramp size */
diff --git a/src/lib/gamma-x-randr.h b/gamma-x-randr.h
index 59c64bc..3591192 100644
--- a/src/lib/gamma-x-randr.h
+++ b/gamma-x-randr.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_X_RANDR_H
#define LIBGAMMA_GAMMA_X_RANDR_H
-#ifndef HAVE_LIBGAMMA_METHOD_X_RANDR
-# error Including gamma-x-randr.h without HAVE_LIBGAMMA_METHOD_X_RANDR
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
@@ -93,7 +86,7 @@ int libgamma_x_randr_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma_p
*
* @param this The CRTC state
*/
-void libgamma_x_randr_crtc_destroy(libgamma_crtc_state_t *restrict) __attribute__((const));
+void libgamma_x_randr_crtc_destroy(libgamma_crtc_state_t *restrict);
/**
* Restore the gamma ramps for a CRTC to the system settings for that CRTC
diff --git a/src/lib/gamma-x-vidmode.c b/gamma-x-vidmode.c
index bae9d31..bae9d31 100644
--- a/src/lib/gamma-x-vidmode.c
+++ b/gamma-x-vidmode.c
diff --git a/src/lib/gamma-x-vidmode.h b/gamma-x-vidmode.h
index 618d5c4..8a95442 100644
--- a/src/lib/gamma-x-vidmode.h
+++ b/gamma-x-vidmode.h
@@ -2,13 +2,6 @@
#ifndef LIBGAMMA_GAMMA_X_VIDMODE_H
#define LIBGAMMA_GAMMA_X_VIDMODE_H
-#ifndef HAVE_LIBGAMMA_METHOD_X_VIDMODE
-# error Including gamma-x-vidmode.h without HAVE_LIBGAMMA_METHOD_X_VIDMODE
-#endif
-
-
-#include "libgamma-method.h"
-
/**
* Return the capabilities of the adjustment method
@@ -65,7 +58,7 @@ int libgamma_x_vidmode_partition_initialise(libgamma_partition_state_t *restrict
*
* @param this The partition state
*/
-void libgamma_x_vidmode_partition_destroy(libgamma_partition_state_t *restrict) __attribute__((const));
+void libgamma_x_vidmode_partition_destroy(libgamma_partition_state_t *restrict);
/**
* Restore the gamma ramps all CRTC:s with a partition to the system settings
@@ -94,7 +87,7 @@ int libgamma_x_vidmode_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma
*
* @param this The CRTC state
*/
-void libgamma_x_vidmode_crtc_destroy(libgamma_crtc_state_t *restrict) __attribute__((const));
+void libgamma_x_vidmode_crtc_destroy(libgamma_crtc_state_t *restrict);
/**
* Restore the gamma ramps for a CRTC to the system settings for that CRTC
diff --git a/get_ramps.h b/get_ramps.h
new file mode 100644
index 0000000..8d4c011
--- /dev/null
+++ b/get_ramps.h
@@ -0,0 +1,30 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * This file is intended to be included from
+ * libgamma_crtc_get_gamma_ramps{8,16,32,64,f,d}
+ */
+
+#define CONCAT(A, B) A##B
+
+
+gamma_ramps_any_t ramps_;
+switch (this->partition->site->method) {
+#define X(CONST, CNAME, MDEPTH, MRAMPS)\
+case CONST:\
+ if (!(MDEPTH)) {\
+ return APPEND_RAMPS(libgamma_dummy_crtc_get_gamma_)(this, ramps);\
+ } else if ((DEPTH) == (MDEPTH)) {\
+ return libgamma_##CNAME##_crtc_get_gamma_##MRAMPS(this, (void *)ramps);\
+ } else {\
+ ramps_.TYPE = *ramps;\
+ return libgamma_internal_translated_ramp_get(this, &ramps_, DEPTH, MDEPTH, libgamma_crtc_get_gamma_##MRAMPS);\
+ }
+LIST_AVAILABLE_METHODS(X)
+#undef X
+default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+}
+
+
+#undef CONCAT
diff --git a/libgamma.h b/libgamma.h
new file mode 100644
index 0000000..d798f33
--- /dev/null
+++ b/libgamma.h
@@ -0,0 +1,2474 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef LIBGAMMA_H
+#define LIBGAMMA_H
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+
+#ifndef __GNUC__
+# define LIBGAMMA_GCC_ONLY__(X) X
+#else
+# define LIBGAMMA_GCC_ONLY__(X)
+#endif
+
+
+
+/**
+ * `errno` has be set with a standard error number
+ * to indicate the what has gone wrong
+ */
+#define LIBGAMMA_ERRNO_SET (-1)
+
+/**
+ * The selected adjustment method does not exist
+ * or has been excluded at compile-time
+ */
+#define LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD (-2) /* TODO use separate error code if disable at compile-time */
+
+/**
+ * The selected site does not exist
+ */
+#define LIBGAMMA_NO_SUCH_SITE (-3)
+
+/**
+ * The selected partition does not exist
+ */
+#define LIBGAMMA_NO_SUCH_PARTITION (-4)
+
+/**
+ * The selected CRTC does not exist
+ */
+#define LIBGAMMA_NO_SUCH_CRTC (-5)
+
+/**
+ * Counter overflowed when counting the number
+ * of available items
+ */
+#define LIBGAMMA_IMPOSSIBLE_AMOUNT (-6)
+
+/**
+ * The selected connector is disabled, it does
+ * not have a CRTC
+ */
+#define LIBGAMMA_CONNECTOR_DISABLED (-7)
+
+/**
+ * The selected CRTC could not be opened,
+ * reason unknown
+ */
+#define LIBGAMMA_OPEN_CRTC_FAILED (-8)
+
+/**
+ * The CRTC information field is not supported
+ * by the adjustment method
+ */
+#define LIBGAMMA_CRTC_INFO_NOT_SUPPORTED (-9)
+
+/**
+ * Failed to read the current gamma ramps for
+ * the selected CRTC, reason unknown
+ */
+#define LIBGAMMA_GAMMA_RAMP_READ_FAILED (-10)
+
+/**
+ * Failed to write the current gamma ramps for
+ * the selected CRTC, reason unknown
+ */
+#define LIBGAMMA_GAMMA_RAMP_WRITE_FAILED (-11)
+
+/**
+ * The specified ramp sizes does not match the
+ * ramps sizes returned by the adjustment methods
+ * in response to the query/command
+ */
+#define LIBGAMMA_GAMMA_RAMP_SIZE_CHANGED (-12)
+
+/**
+ * The specified ramp sizes are not identical
+ * which is required by the adjustment method
+ *
+ * (Only returned in debug mode)
+ */
+#define LIBGAMMA_MIXED_GAMMA_RAMP_SIZE (-13)
+
+/**
+ * The specified ramp sizes are not supported
+ * by the adjustment method
+ *
+ * (Only returned in debug mode)
+ */
+#define LIBGAMMA_WRONG_GAMMA_RAMP_SIZE (-14)
+
+/**
+ * The adjustment method reported that the gamma
+ * ramps size is 1, or perhaps even zero or negative
+ */
+#define LIBGAMMA_SINGLETON_GAMMA_RAMP (-15)
+
+/**
+ * The adjustment method failed to list
+ * available CRTC:s, reason unknown
+ */
+#define LIBGAMMA_LIST_CRTCS_FAILED (-16)
+
+/**
+ * Failed to acquire mode resources from the
+ * adjustment method
+ */
+#define LIBGAMMA_ACQUIRING_MODE_RESOURCES_FAILED (-17)
+
+/**
+ * The adjustment method reported that a negative
+ * number of partitions exists in the site
+ */
+#define LIBGAMMA_NEGATIVE_PARTITION_COUNT (-18)
+
+/**
+ * The adjustment method reported that a negative
+ * number of CRTC:s exists in the partition
+ */
+#define LIBGAMMA_NEGATIVE_CRTC_COUNT (-19)
+
+/**
+ * Device cannot be access becauses of
+ * insufficient permissions
+ */
+#define LIBGAMMA_DEVICE_RESTRICTED (-20)
+
+/**
+ * Device cannot be access, reason unknown
+ */
+#define LIBGAMMA_DEVICE_ACCESS_FAILED (-21)
+
+/**
+ * Device cannot be access, membership of the
+ * `libgamma_group_gid` (named by `libgamma_group_name`
+ * (can be `NULL`, if so `errno` may have been set
+ * to tell why)) is required
+ */
+#define LIBGAMMA_DEVICE_REQUIRE_GROUP (-22)
+
+/**
+ * The graphics card appear to have been removed
+ */
+#define LIBGAMMA_GRAPHICS_CARD_REMOVED (-23)
+
+/**
+ * The state of the requested information is unknown
+ */
+#define LIBGAMMA_STATE_UNKNOWN (-24)
+
+/**
+ * Failed to determine which connector the
+ * CRTC belongs to
+ */
+#define LIBGAMMA_CONNECTOR_UNKNOWN (-25)
+
+/**
+ * The detected connector type is not listed
+ * in this library and has to be updated
+ */
+#define LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED (-26)
+
+/**
+ * The detected subpixel order is not listed
+ * in this library and has to be updated
+ */
+#define LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED (-27)
+
+/**
+ * The length of the EDID does not match that
+ * of any supported EDID structure revision
+ */
+#define LIBGAMMA_EDID_LENGTH_UNSUPPORTED (-28)
+
+/**
+ * The magic number in the EDID does not match
+ * that of any supported EDID structure revision
+ */
+#define LIBGAMMA_EDID_WRONG_MAGIC_NUMBER (-29)
+
+/**
+ * The EDID structure revision used by the
+ * monitor is not supported
+ */
+#define LIBGAMMA_EDID_REVISION_UNSUPPORTED (-30)
+
+/**
+ * The gamma characteristics field in the EDID
+ * is left unspecified
+ *
+ * (This could be considered a non-error)
+ */
+#define LIBGAMMA_GAMMA_NOT_SPECIFIED (-31)
+
+/**
+ * The checksum in the EDID is incorrect, all
+ * request information has been provided
+ * by you cannot count on it
+ */
+#define LIBGAMMA_EDID_CHECKSUM_ERROR (-32)
+
+/**
+ * Both of the errors `LIBGAMMA_GAMMA_NOT_SPECIFIED`
+ * and `LIBGAMMA_EDID_CHECKSUM_ERROR` have occurred
+ */
+#define LIBGAMMA_GAMMA_NOT_SPECIFIED_AND_EDID_CHECKSUM_ERROR (-33)
+
+/**
+ * Failed to query the gamma ramps size from the
+ * adjustment method, reason unknown
+ */
+#define LIBGAMMA_GAMMA_RAMPS_SIZE_QUERY_FAILED (-34)
+
+/**
+ * The selected partition could not be opened,
+ * reason unknown
+ */
+#define LIBGAMMA_OPEN_PARTITION_FAILED (-35)
+
+/**
+ * The selected site could not be opened,
+ * reason unknown
+ */
+#define LIBGAMMA_OPEN_SITE_FAILED (-36)
+
+/**
+ * Failed to query the adjustment method for
+ * its protocol version, reason unknown
+ */
+#define LIBGAMMA_PROTOCOL_VERSION_QUERY_FAILED (-37)
+
+/**
+ * The adjustment method's version of its
+ * protocol is not supported
+ */
+#define LIBGAMMA_PROTOCOL_VERSION_NOT_SUPPORTED (-38)
+
+/**
+ * The adjustment method failed to list
+ * available partitions, reason unknown
+ */
+#define LIBGAMMA_LIST_PARTITIONS_FAILED (-39)
+
+/**
+ * Partition exists by index, but the partition
+ * at that index does not exist
+ */
+#define LIBGAMMA_NULL_PARTITION (-40)
+
+/**
+ * There is not monitor connected to the
+ * connector of the selected CRTC
+ */
+#define LIBGAMMA_NOT_CONNECTED (-41)
+
+/**
+ * Data extraction from a reply from the
+ * adjustment method failed, reason unknown
+ */
+#define LIBGAMMA_REPLY_VALUE_EXTRACTION_FAILED (-42)
+
+/**
+ * No EDID property was found on the output
+ */
+#define LIBGAMMA_EDID_NOT_FOUND (-43)
+
+/**
+ * Failed to list properties on the output,
+ * reason unknown
+ */
+#define LIBGAMMA_LIST_PROPERTIES_FAILED (-44)
+
+/**
+ * Failed to query a property's value from
+ * the output, reason unknown
+ */
+#define LIBGAMMA_PROPERTY_VALUE_QUERY_FAILED (-45)
+
+/**
+ * A request for information on an output
+ * failed, reason unknown
+ */
+#define LIBGAMMA_OUTPUT_INFORMATION_QUERY_FAILED (-46)
+
+/* DEVELOPERS: Remember to update LIBGAMMA_ERROR_MIN below and LIST_ERRORS in common.h when adding errors */
+
+/**
+ * The number of the libgamma error with the
+ * lowest number in the version of the library
+ * that the program is compiled against
+ */
+#define LIBGAMMA_ERROR_MIN (-46)
+
+/**
+ * The number of the libgamma error with the
+ * lowest number in the version of the library
+ * that the program is linked against
+ */
+extern const int libgamma_error_min;
+
+
+
+/**
+ * The identifier for the dummy adjustment method
+ *
+ * This method can be configured and is useful for
+ * testing your program's ability to handle errors
+ */
+#define LIBGAMMA_METHOD_DUMMY 0
+
+/**
+ * The identifier for the adjustment method with
+ * uses the RandR protocol under the X display server
+ */
+#define LIBGAMMA_METHOD_X_RANDR 1
+
+/**
+ * The identifier for the adjustment method with
+ * uses the VidMode protocol under the X display server
+ *
+ * This is an older alternative to RandR that can
+ * work on some drivers that are not supported by RandR,
+ * however it can only control the primary CRTC per
+ * screen (partition)
+ */
+#define LIBGAMMA_METHOD_X_VIDMODE 2
+
+/**
+ * The identifier for the Direct Rendering Manager
+ * adjustment method that is available in Linux
+ * (built in to the Linux kernel with a userland
+ * library for access) and is a part of the
+ * Direct Rendering Infrastructure.
+ *
+ * This adjustment method will work when you are
+ * in non-graphical mode; however a display server
+ * cannot be started while this is running, but it
+ * can be started while a display server is running
+ */
+#define LIBGAMMA_METHOD_LINUX_DRM 3
+
+/**
+ * The identifier for the Graphics Device Interface
+ * adjustment method that is available in Windows
+ *
+ * This method is not well tested; it can be compiled
+ * to be available under X.org using a translation layer
+ */
+#define LIBGAMMA_METHOD_W32_GDI 4
+
+/**
+ * The identifier for the CoreGraphics adjustment
+ * method that is available in Mac OS X that can
+ * adjust gamma ramps under the Quartz display server
+ *
+ * This method is not well tested; it can be compiled
+ * to be available under X.org using a translation layer
+ */
+#define LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS 5
+
+/* DEVELOPERS: Remember to update LIBGAMMA_METHOD_COUNT below and LIST_METHODS in common.h when adding methods */
+
+/**
+ * The number adjustment methods provided by the
+ * version this library the program is compiled
+ * against
+ *
+ * This number includes both compile-time enabled
+ * and compile-time disabled adjustment methods
+ */
+#define LIBGAMMA_METHOD_COUNT 6
+
+/**
+ * The number adjustment methods provided by the
+ * version this library the program is linked
+ * against
+ *
+ * This number includes both compile-time enabled
+ * and compile-time disabled adjustment methods
+ */
+extern const int libgamma_method_count;
+
+
+
+/**
+ * Types for connectors
+ */
+typedef enum libgamma_connector_type {
+ /**
+ * The adjustment method does not know the connector's type
+ *
+ * (This could be considered an error)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_Unknown = 0,
+
+ /**
+ * Video Graphics Array (VGA)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_VGA,
+
+ /**
+ * Digital Visual Interface, unknown type
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DVI,
+
+ /**
+ * Digital Visual Interface, integrated (DVI-I)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DVII,
+
+ /**
+ * Digital Visual Interface, digital only (DVI-D)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DVID,
+
+ /**
+ * Digital Visual Interface, analogue only (DVI-A)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DVIA,
+
+ /**
+ * Composite video
+ */
+ LIBGAMMA_CONNECTOR_TYPE_Composite,
+
+ /**
+ * Separate Video (S-video)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_SVIDEO,
+
+ /**
+ * Low-voltage differential signaling (LVDS)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_LVDS,
+
+ /**
+ * Component video, usually separate cables for each channel
+ */
+ LIBGAMMA_CONNECTOR_TYPE_Component,
+
+ /**
+ * 9 pin DIN (Deutsches Institut für Normung) connector
+ */
+ LIBGAMMA_CONNECTOR_TYPE_9PinDIN,
+
+ /**
+ * DisplayPort
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DisplayPort,
+
+ /**
+ * High-Definition Multimedia Interface (HDMI), unknown type
+ */
+ LIBGAMMA_CONNECTOR_TYPE_HDMI,
+
+ /**
+ * High-Definition Multimedia Interface, type A (HDMI-A)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_HDMIA,
+
+ /**
+ * High-Definition Multimedia Interface, type B (HDMI-B)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_HDMIB,
+
+ /**
+ * Television, unknown connector
+ */
+ LIBGAMMA_CONNECTOR_TYPE_TV,
+
+ /**
+ * Embedded DisplayPort (eDP)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_eDP,
+
+ /**
+ * A virtual connector
+ */
+ LIBGAMMA_CONNECTOR_TYPE_VIRTUAL,
+
+ /**
+ * Display Serial Interface (DSI)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_DSI,
+
+ /**
+ * LFP connector
+ *
+ * (What is this?)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_LFP
+
+ /* DEVELOPERS: Remember to update LIBGAMMA_CONNECTOR_TYPE_COUNT below
+ * and LIST_CONNECTOR_TYPES in common.h when adding methods */
+
+} libgamma_connector_type_t;
+
+/**
+ * The number of values defined in `libgamma_connector_type_t`
+ * in the version of the library the program is compiled against
+ */
+#define LIBGAMMA_CONNECTOR_TYPE_COUNT 20
+
+/**
+ * The number of values defined in `libgamma_connector_type_t`
+ * in the version of the library the program is linked against
+ */
+extern const int libgamma_connector_type_count;
+
+
+
+/**
+ * Orders for subpixels
+ *
+ * Currently the possible values are very biased
+ * to LCD, Plasma and monochrome monitors
+ */
+typedef enum libgamma_subpixel_order {
+ /**
+ * The adjustment method does not know the order of the subpixels
+ *
+ * (This could be considered an error)
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN = 0,
+
+ /**
+ * There are no subpixels in the monitor
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_NONE,
+
+ /**
+ * The subpixels are ordered red, green and then blue, from left to right
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB,
+
+ /**
+ * The subpixels are ordered blue, green and then red, from left to right
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR,
+
+ /**
+ * The subpixels are ordered red, green and then blue, from the top down
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB,
+
+ /**
+ * The subpixels are ordered blue, green and then red, from the top down
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR
+
+ /* DEVELOPERS: Remember to update LIBGAMMA_SUBPIXEL_ORDER_COUNT below
+ * and LIST_SUBPIXEL_ORDERS in common.h when adding methods */
+
+} libgamma_subpixel_order_t;
+
+/**
+ * The number of values defined in `libgamma_subpixel_order_t`
+ * in the version of the library the program is compiled against
+ */
+#define LIBGAMMA_SUBPIXEL_ORDER_COUNT 6
+
+/**
+ * The number of values defined in `libgamma_subpixel_order_t`
+ * in the version of the library the program is linked against
+ */
+extern const int libgamma_subpixel_order_count;
+
+
+
+/**
+ * Answer enum to a decision problem
+ */
+typedef enum libgamma_decision {
+ /**
+ * The answer is negative
+ */
+ LIBGAMMA_NO = 0,
+
+ /**
+ * The answer is unknown
+ */
+ LIBGAMMA_MAYBE = 1,
+
+ /**
+ * The answer is positive
+ */
+ LIBGAMMA_YES = 2
+
+} libgamma_decision_t;
+
+
+
+/**
+ * Capabilities of adjustment methods
+ */
+typedef struct libgamma_method_capabilities {
+ /**
+ * OR of the CRTC information fields in `libgamma_crtc_information_t`
+ * that may (but can fail) be read successfully
+ */
+ int32_t crtc_information;
+
+ /**
+ * Whether the default site is known, if true the site is integrated
+ * to the system or can be determined using environment variables
+ */
+ unsigned default_site_known : 1;
+
+ /**
+ * Whether the adjustment method supports multiple sites rather
+ * than just the default site
+ */
+ unsigned multiple_sites : 1;
+
+ /**
+ * Whether the adjustment method supports multiple partitions
+ * per site
+ */
+ unsigned multiple_partitions : 1;
+
+ /**
+ * Whether the adjustment method supports multiple CRTC:s
+ * per partition per site
+ */
+ unsigned multiple_crtcs : 1;
+
+ /**
+ * Whether the partition to graphics card is a bijection
+ */
+ unsigned partitions_are_graphics_cards : 1;
+
+ /**
+ * Whether the adjustment method supports `libgamma_site_restore`
+ */
+ unsigned site_restore : 1;
+
+ /**
+ * Whether the adjustment method supports `libgamma_partition_restore`
+ */
+ unsigned partition_restore : 1;
+
+ /**
+ * Whether the adjustment method supports `libgamma_crtc_restore`
+ */
+ unsigned crtc_restore : 1;
+
+ /**
+ * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size`
+ * fields in `libgamma_crtc_information_t` will always have the same
+ * values as each other for the adjustment method
+ */
+ unsigned identical_gamma_sizes : 1;
+
+ /**
+ * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size`
+ * fields in `libgamma_crtc_information_t` will always be filled with the
+ * same value for the adjustment method
+ */
+ unsigned fixed_gamma_size : 1;
+
+ /**
+ * Whether the `gamma_depth` field in `libgamma_crtc_information_t`
+ * will always be filled with the same value for the adjustment method
+ */
+ unsigned fixed_gamma_depth : 1;
+
+ /**
+ * Whether the adjustment method will actually perform adjustments
+ */
+ unsigned real : 1;
+
+ /**
+ * Whether the adjustment method is implement using a translation layer
+ */
+ unsigned fake : 1;
+
+ /**
+ * Whether adjustments are undone when the process disconnects from
+ * the display server
+ */
+ unsigned auto_restore : 1;
+
+} libgamma_method_capabilities_t;
+
+
+/**
+ * Site state
+ *
+ * On operating systems that integrate a graphical environment
+ * there is usually just one site. However, one systems with
+ * pluggable graphics, like Unix-like systems such as GNU/Linux
+ * and the BSD:s, there can usually be any (feasible) number of
+ * sites. In X.org parlance they are called displays.
+ */
+typedef struct libgamma_site_state {
+ /**
+ * Adjustment method implementation specific data
+ *
+ * You as a user of this library should not touch this
+ */
+ void *data;
+
+ /**
+ * This field specifies, for the methods if this library,
+ * which adjustment method (display server and protocol)
+ * is used to adjust the gamma ramps
+ */
+ int method;
+
+ /**
+ * The site identifier. It can either be `NULL` or a string.
+ * `NULL` indicates the default site. On systems like the
+ * Unix-like systems, where the graphics are pluggable, this
+ * is usually resolved by an environment variable, such as
+ * "DISPLAY" for X.org.
+ */
+ char *site;
+
+ /**
+ * The number of partitions that is available on this site.
+ * Probably the majority of display server only one partition
+ * per site. However, X.org can, and traditional used to have
+ * on multi-headed environments, multiple partitions per site.
+ * In X.org partitions are called 'screens'. It is not to be
+ * confused with monitor. A screen is a collection of monitors,
+ * and the mapping from monitors to screens is a surjection.
+ * On hardware-level adjustment methods, such as Direct
+ * Rendering Manager, a partition is a graphics card.
+ */
+ size_t partitions_available;
+
+} libgamma_site_state_t;
+
+
+/**
+ * Partition state
+ *
+ * Probably the majority of display server only one partition
+ * per site. However, X.org can, and traditional used to have
+ * on multi-headed environments, multiple partitions per site.
+ * In X.org partitions are called 'screens'. It is not to be
+ * confused with monitor. A screen is a collection of monitors,
+ * and the mapping from monitors to screens is a surjection.
+ * On hardware-level adjustment methods, such as Direct
+ * Rendering Manager, a partition is a graphics card.
+ */
+typedef struct libgamma_partition_state {
+ /**
+ * Adjustment method implementation specific data
+ *
+ * You as a user of this library should not touch this
+ */
+ void *data;
+
+ /**
+ * The site this partition belongs to
+ */
+ libgamma_site_state_t *site;
+
+ /**
+ * The index of the partition
+ */
+ size_t partition;
+
+ /**
+ * The number of CRTC:s that are available
+ * under this partition
+ *
+ * Note that the CRTC:s are not necessarily
+ * online
+ */
+ size_t crtcs_available;
+
+} libgamma_partition_state_t;
+
+
+/**
+ * Cathode ray tube controller state
+ *
+ * The CRTC controls the gamma ramps for the
+ * monitor that is plugged in to the connector
+ * that the CRTC belongs to
+ */
+typedef struct libgamma_crtc_state {
+ /**
+ * Adjustment method implementation specific data
+ *
+ * You as a user of this library should not touch this
+ */
+ void *data;
+
+ /**
+ * The partition this CRTC belongs to
+ */
+ libgamma_partition_state_t *partition;
+
+ /**
+ * The index of the CRTC within its partition
+ */
+ size_t crtc;
+
+} libgamma_crtc_state_t;
+
+
+/**
+ * Cathode ray tube controller information data structure
+ */
+typedef struct libgamma_crtc_information {
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the values for
+ * `edid` and `edid_length` and report errors to `edid_error`
+ */
+#define LIBGAMMA_CRTC_INFO_EDID (1 << 0)
+
+ /**
+ * The Extended Display Identification Data associated with
+ * the attached monitor.
+ *
+ * This is raw byte array that is usually 128 bytes long.
+ * It is not NUL-terminate, rather its length is stored in
+ * `edid_length`.
+ */
+ unsigned char *edid;
+
+ /**
+ * The length of `edid`
+ */
+ size_t edid_length;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int edid_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value
+ * for `width_mm` and report errors to `width_mm_error`
+ */
+#define LIBGAMMA_CRTC_INFO_WIDTH_MM (1 << 1)
+
+ /**
+ * The phyical width, in millimetres, of the viewport of the
+ * attached monitor, as reported by the adjustment method
+ *
+ * This value may be incorrect, which is a known issue with
+ * the X server where it is the result of the X server
+ * attempting the estimate the size on its own
+ *
+ * Zero means that its is not applicable, which is the case
+ * for projectors
+ */
+ size_t width_mm;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int width_mm_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value
+ * for `height_mm` and report errors to `height_mm_error`
+ */
+#define LIBGAMMA_CRTC_INFO_HEIGHT_MM (1 << 2)
+
+ /**
+ * The phyical height, in millimetres, of the viewport of the
+ * attached monitor, as reported by the adjustment method
+ *
+ * This value may be incorrect, which is a known issue with
+ * the X server where it is the result of the X server
+ * attempting the estimate the size on its own
+ *
+ * Zero means that its is not applicable, which is the case
+ * for projectors
+ */
+ size_t height_mm;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int height_mm_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `width_mm_edid` and report errors to `width_mm_edid_error`
+ */
+#define LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID (1 << 3)
+
+ /**
+ * The phyical width, in millimetres, of the viewport of the
+ * attached monitor, as reported by it the monitor's Extended
+ * Display Information Data
+ *
+ * This value can only contain whole centimetres, which means
+ * that the result is always zero modulus ten. However, this
+ * could change with revisions of the EDID structure.
+ *
+ * Zero means that its is not applicable, which is the case
+ * for projectors.
+ */
+ size_t width_mm_edid;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int width_mm_edid_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `height_mm_edid` and report errors to `height_mm_edid_error`
+ */
+#define LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID (1 << 4)
+
+ /**
+ * The phyical height, in millimetres, of the viewport of the
+ * attached monitor, as reported by it the monitor's Extended
+ * Display Information Data
+ *
+ * This value can only contain whole centimetres, which means
+ * that the result is always zero modulus ten. However, this
+ * could change with revisions of the EDID structure.
+ *
+ * Zero means that its is not applicable, which is the case
+ * for projectors
+ */
+ size_t height_mm_edid;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int height_mm_edid_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the values for
+ * `red_gamma_size`, `green_gamma_size`, and `blue_gamma_size`,
+ * and report errors to `gamma_size_error`
+ */
+#define LIBGAMMA_CRTC_INFO_GAMMA_SIZE (1 << 5)
+
+ /**
+ * The size of the encoding axis of the red gamma ramp
+ */
+ size_t red_gamma_size;
+
+ /**
+ * The size of the encoding axis of the green gamma ramp
+ */
+ size_t green_gamma_size;
+
+ /**
+ * The size of the encoding axis of the blue gamma ramp
+ */
+ size_t blue_gamma_size;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int gamma_size_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `gamma_depth` and report errors to `gamma_depth_error`
+ */
+#define LIBGAMMA_CRTC_INFO_GAMMA_DEPTH (1 << 6)
+
+ /**
+ * The bit-depth of the value axes of gamma ramps,
+ * -1 for single precision floating point, and -2 for
+ * double precision floating point
+ */
+ signed gamma_depth;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int gamma_depth_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `gamma_support` and report errors to `gamma_support_error`
+ */
+#define LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT (1 << 7)
+
+ /**
+ * `LIBGAMMA_NO` indicates that the CRTC does not support
+ * gamma ramp adjustments. `LIBGAMMA_MAYBE` indicates that
+ * the CRTC may or may not support gamma ramp adjustments,
+ * meaning that the display server really does not know, but
+ * the protocol is available. `LIBGAMMA_NO` indicates that
+ * the CRTC does support gamma ramp adjustments.
+ */
+ libgamma_decision_t gamma_support;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int gamma_support_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `subpixel_order` and report errors to `subpixel_order_error`
+ */
+#define LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER (1 << 8)
+
+ /**
+ * The layout of the subpixels
+ *
+ * You cannot count on this value — especially for CRT:s —
+ * but it is provided anyway as a means of distinguishing
+ * monitors
+ */
+ libgamma_subpixel_order_t subpixel_order;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int subpixel_order_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the
+ * value for `active` and report errors to `active_error`
+ */
+#define LIBGAMMA_CRTC_INFO_ACTIVE (1 << 9)
+
+ /**
+ * Whether there is a monitor connected to the CRTC
+ */
+ int active;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int active_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `connector_name` and report errors to `connector_name_error`
+ */
+#define LIBGAMMA_CRTC_INFO_CONNECTOR_NAME (1 << 10)
+
+ /**
+ * The name of the connector as designated by the display
+ * server or as give by this library in case the display
+ * server lacks this feature.
+ */
+ char *connector_name;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int connector_name_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the value for
+ * `connector_type` and report errors to `connector_type_error`
+ */
+#define LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE (1 << 11)
+
+ /**
+ * The type of the connector that is associated with the CRTC
+ */
+ libgamma_connector_type_t connector_type;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int connector_type_error;
+
+
+/**
+ * For a `libgamma_crtc_information_t` fill in the
+ * values for `gamma_red`, `gamma_green`, and `gamma_blue`
+ * and report errors to `gamma_error`
+ */
+#define LIBGAMMA_CRTC_INFO_GAMMA (1 << 12)
+
+ /**
+ * The gamma characteristics of the monitor as reported
+ * in its Extended Display Information Data. The value
+ * holds the value for the red channel.
+ *
+ * If you do not have and more accurate measurement of the
+ * gamma for the monitor this could be used to give a rought
+ * gamma correction; simply divide the value with 2.2 and use
+ * the result for the red channel in the gamma correction
+ */
+ float gamma_red;
+
+ /**
+ * The gamma characteristics of the monitor as reported
+ * in its Extended Display Information Data. The value
+ * holds the value for the green channel.
+ *
+ * If you do not have and more accurate measurement of the
+ * gamma for the monitor this could be used to give a rought
+ * gamma correction; simply divide the value with 2.2 and use
+ * the result for the green channel in the gamma correction
+ */
+ float gamma_green;
+
+ /**
+ * The gamma characteristics of the monitor as reported
+ * in its Extended Display Information Data. The value
+ * holds the value for the blue channel.
+ *
+ * If you do not have and more accurate measurement of the
+ * gamma for the monitor this could be used to give a rought
+ * gamma correction; simply divide the value with 2.2 and use
+ * the result for the blue channel in the gamma correction
+ */
+ float gamma_blue;
+
+ /**
+ * Zero on success, positive it holds the value `errno` had
+ * when the reading failed, otherwise (negative) the value
+ * of an error identifier provided by this library
+ */
+ int gamma_error;
+
+ /* DEVELOPERS: Remember to update LIBGAMMA_CRTC_INFO_COUNT below and maybe
+ * also some of the list of LIBGAMMA_CRTC_INFO_* macros below */
+
+} libgamma_crtc_information_t;
+
+/**
+ * The number of `LIBGAMMA_CRTC_INFO_*` values defined in
+ * the version of the library the program is compiled against
+ *
+ * This exclude the combining macros defined below this macro
+ */
+#define LIBGAMMA_CRTC_INFO_COUNT 13
+
+/**
+ * The number of `LIBGAMMA_CRTC_INFO_*` values defined in
+ * the version of the library the program is linked against
+ */
+extern const int libgamma_crtc_info_count;
+
+/**
+ * Macro for both `libgamma_crtc_information_t` fields
+ * that can specify the size of the monitor's viewport
+ * as specified in the monitor's Extended Display
+ * Information Data
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT (LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID | LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID)
+
+/**
+ * Macro for all `libgamma_crtc_information_t` fields
+ * that can be filled if the adjustment method have
+ * support for reading the monitors' Extended Display
+ * Information Data
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_EDID (LIBGAMMA_CRTC_INFO_EDID | LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT | LIBGAMMA_CRTC_INFO_GAMMA)
+
+/**
+ * Macro for both `libgamma_crtc_information_t` fields
+ * that can specify the size of the monitor's viewport
+ * as provided by the adjustment method without this
+ * library having to parse the monitor's Extended Display
+ * Information Data
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT (LIBGAMMA_CRTC_INFO_WIDTH_MM | LIBGAMMA_CRTC_INFO_HEIGHT_MM)
+
+/**
+ * Macro for the `libgamma_crtc_information_t` fields
+ * that specifies the CRTC's gamma ramp sizes and gamma
+ * ramp depth
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_RAMP (LIBGAMMA_CRTC_INFO_GAMMA_SIZE | LIBGAMMA_CRTC_INFO_GAMMA_DEPTH)
+
+/**
+ * Macro for the `libgamma_crtc_information_t` fields
+ * that specifies the CRTC's connector type and the
+ * partition unique name of the connector
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_CONNECTOR (LIBGAMMA_CRTC_INFO_CONNECTOR_NAME | LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE)
+
+/**
+ * Macro for the `libgamma_crtc_information_t` fields
+ * that required there is a monitor attached to the
+ * connector, and that status itself
+ */
+#define LIBGAMMA_CRTC_INFO_MACRO_ACTIVE (LIBGAMMA_CRTC_INFO_MACRO_EDID | LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT |\
+ LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER | LIBGAMMA_CRTC_INFO_ACTIVE)
+
+
+
+/**
+ * Gamma ramp structure for 8-bit gamma ramps
+ */
+typedef struct libgamma_gamma_ramps8 {
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ uint8_t *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ uint8_t *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ uint8_t *blue;
+
+} libgamma_gamma_ramps8_t;
+
+
+/**
+ * Gamma ramp structure for 16-bit gamma ramps
+ */
+typedef struct libgamma_gamma_ramps16
+{
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ uint16_t *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ uint16_t *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ uint16_t *blue;
+
+} libgamma_gamma_ramps16_t;
+
+
+/**
+ * Gamma ramp structure for 32-bit gamma ramps
+ */
+typedef struct libgamma_gamma_ramps32
+{
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ uint32_t *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ uint32_t *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ uint32_t *blue;
+
+} libgamma_gamma_ramps32_t;
+
+
+/**
+ * Gamma ramp structure for 64-bit gamma ramps
+ */
+typedef struct libgamma_gamma_ramps64
+{
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ uint64_t *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ uint64_t *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ uint64_t *blue;
+
+} libgamma_gamma_ramps64_t;
+
+
+/**
+ * Gamma ramp structure for `float` gamma ramps
+ */
+typedef struct libgamma_gamma_rampsf
+{
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ float *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ float *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ float *blue;
+
+} libgamma_gamma_rampsf_t;
+
+
+/**
+ * Gamma ramp structure for `double` gamma ramps
+ */
+typedef struct libgamma_gamma_rampsd
+{
+ /**
+ * The size of `red`
+ */
+ size_t red_size;
+
+ /**
+ * The size of `green`
+ */
+ size_t green_size;
+
+ /**
+ * The size of `blue`
+ */
+ size_t blue_size;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ double *red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ double *green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ double *blue;
+
+} libgamma_gamma_rampsd_t;
+
+
+/**
+ * Mapping function from [0, 1] float encoding value to [0, 2⁸ − 1] integer output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 2⁸ − 1] integer output value
+ */
+typedef uint8_t libgamma_gamma_ramps8_fun(float);
+
+/**
+ * Mapping function from [0, 1] float encoding value to [0, 2¹⁶ − 1] integer output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 2¹⁶ − 1] integer output value
+ */
+typedef uint16_t libgamma_gamma_ramps16_fun(float);
+
+/**
+ * Mapping function from [0, 1] float encoding value to [0, 2³² − 1] integer output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 2³² − 1] integer output value
+ */
+typedef uint32_t libgamma_gamma_ramps32_fun(float);
+
+/**
+ * Mapping function from [0, 1] float encoding value to [0, 2⁶⁴ − 1] integer output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 2⁶⁴ − 1] integer output value
+ */
+typedef uint64_t libgamma_gamma_ramps64_fun(float);
+
+/**
+ * Mapping function from [0, 1] float encoding value to [0, 1] float output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 1] float output value
+ */
+typedef float libgamma_gamma_rampsf_fun(float);
+
+/**
+ * Mapping function from [0, 1] double precision float encoding
+ * value to [0, 1] double precision float output value
+ *
+ * @param encoding [0, 1] float encoding value
+ * @return [0, 1] float output value
+ */
+typedef double libgamma_gamma_rampsd_fun(double);
+
+
+
+/**
+ * Prints an error to stderr in a `perror` fashion
+ *
+ * @param name The text to add at the beginning
+ * @param error_code The error code, may be an `errno` value
+ */
+void libgamma_perror(const char *, int);
+
+/**
+ * Get a description of an error
+ *
+ * @param error_code The error code, may be an `errno` value, if
+ * `LIBGAMMA_ERRNO_SET`, the current value of `errno`
+ * will be used
+ * @return The description associated with the error code,
+ * `NULL` if the error code is not recognised
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+const char *libgamma_strerror(int);
+
+/**
+ * Get a description of an error
+ *
+ * @param error_code The error code, may be an `errno` value, if
+ * `LIBGAMMA_ERRNO_SET`, the current value of `errno`
+ * will be used
+ * @param buf Buffer that shall be used if a description must be generated
+ * @param bufsize The size of `buf`, 1024 is recommended
+ * @return The description associated with the error code;
+ * can only be `NULL` if `buf` is `NULL`. If the buffer
+ * is insufficient, a truncated but NUL-terminated
+ * description is returned and `errno` is set to `ERANGE`;
+ * `errno` is otherwise unmodified
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+const char *libgamma_strerror_r(int, char[], size_t);
+
+/**
+ * Get the name of the definition associated with a `libgamma` error code
+ *
+ * @param value The error code
+ * @return The name of the definition associated with the error code,
+ * `NULL` if the error code does not exist
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_name_of_error(int);
+
+/**
+ * Get the value of a `libgamma` error definition refered to by name
+ *
+ * @param name The name of the definition associated with the error code
+ * @return The error code, zero if the name is `NULL`
+ * or does not refer to a `libgamma` error
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __pure__)))
+int libgamma_value_of_error(const char *);
+
+/**
+ * Get the group that the user needs to be a member
+ * of if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @return The group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ */
+#ifndef __WIN32__
+gid_t libgamma_group_gid_get(void);
+#else
+short libgamma_group_gid_get(void);
+#endif
+
+/**
+ * Set the group that the user needs to be a member
+ * of if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @param value The group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ */
+#ifndef __WIN32__
+void libgamma_group_gid_set(gid_t);
+#else
+void libgamma_group_gid_set(short);
+#endif
+
+/**
+ * Get the group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @return The group that the user needs to be a member of if
+ * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned, `NULL`
+ * if the name of the group `libgamma_group_gid` cannot
+ * be determined
+ */
+const char *libgamma_group_name_get(void);
+
+/**
+ * Set the group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @param value The group that the user needs to be a member of if
+ * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned, may be `NULL`
+ */
+void libgamma_group_name_set(const char *);
+
+
+
+
+/**
+ * Get the name of an adjustment method,
+ * for example "randr" for `LIBGAMMA_METHOD_X_RANDR`
+ *
+ * @param method The adjustment method
+ * @return The name adjustment method, `NULL` if not
+ * recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_name_of_method(int);
+
+/**
+ * Get the name of the constant for an adjustment
+ * method, for example "LIBGAMMA_METHOD_X_RANDR"
+ * for `LIBGAMMA_METHOD_X_RANDR`
+ *
+ * @param method The adjustment method
+ * @return The name of the constant for adjustment method,
+ * `NULL` if not recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_const_of_method(int);
+
+/**
+ * Check whether an adjustment method is available,
+ * non-existing (invalid) methods will be identified
+ * as not available under the rationale that the
+ * library may be out of date
+ *
+ * @param method The adjustment method
+ * @return Whether the adjustment method is available
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+int libgamma_is_method_available(int);
+
+/**
+ * Get the value of an adjustment method
+ *
+ * @param method The name of the adjustment method, for example
+ * "randr" or "LIBGAMMA_METHOD_X_RANDR"
+ * @return The adjustment method; for example `LIBGAMMA_METHOD_X_RANDR`
+ * for "randr" and "LIBGAMMA_METHOD_X_RANDR"
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __pure__)))
+int libgamma_value_of_method(const char *);
+
+
+
+/**
+ * Get the name of a connector type,
+ * for example "VGA" for `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ *
+ * "Unknown" is returned for `LIBGAMMA_CONNECTOR_TYPE_Unknown`,
+ * "TV" is returned for `LIBGAMMA_CONNECTOR_TYPE_TV`,
+ * "Virtual" is returned for `LIBGAMMA_CONNECTOR_TYPE_Virtual`
+ *
+ * @param connector The connector type
+ * @return The name connector type, `NULL` if not
+ * recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_name_of_connector_type(int);
+
+/**
+ * Get the name of the constant for a connector
+ * type, for example "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ * for `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ *
+ * @param connector The connector type
+ * @return The name of the constant for connector type,
+ * `NULL` if not recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_const_of_connector_type(int);
+
+/**
+ * Get the value of a connector type
+ *
+ * @param connector The name of the connector type, for example
+ * "VGA" or "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ * @return The connector type; for example `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ * for "VGA" and "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __pure__)))
+int libgamma_value_of_connector_type(const char *);
+
+
+
+/**
+ * Get the name of a subpixel order, for example
+ * "Horizontal RGB" for `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ *
+ * "Unknown" is returned for `LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN`,
+ * "None" is returned for `LIBGAMMA_SUBPIXEL_ORDER_NONE`
+ *
+ * @param order The subpixel order
+ * @return The name subpixel order, `NULL` if not
+ * recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_name_of_subpixel_order(int);
+
+/**
+ * Get the name of the constant for a subpixel order,
+ * for example "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ * for `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ *
+ * @param order The subpixel order
+ * @return The name of the constant for subpixel order,
+ * `NULL` if not recognised (errno is not changed)
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __const__)))
+const char *libgamma_const_of_subpixel_order(int);
+
+/**
+ * Get the value of a subpixel order
+ *
+ * @param order The name of the subpixel order, for example
+ * "Horizontal RGB" or "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ * @return The subpixel order; for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ * for "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __pure__)))
+int libgamma_value_of_subpixel_order(const char *);
+
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_ramps8_initialise(libgamma_gamma_ramps8_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps8_destroy(libgamma_gamma_ramps8_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps8_free(libgamma_gamma_ramps8_t *restrict);
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_ramps16_initialise(libgamma_gamma_ramps16_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps16_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps16_destroy(libgamma_gamma_ramps16_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps16_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps16_free(libgamma_gamma_ramps16_t *restrict);
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated.
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_ramps32_initialise(libgamma_gamma_ramps32_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps32_destroy(libgamma_gamma_ramps32_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps32_free(libgamma_gamma_ramps32_t *restrict);
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation.
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated.
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_ramps64_initialise(libgamma_gamma_ramps64_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps64_destroy(libgamma_gamma_ramps64_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_ramps64_free(libgamma_gamma_ramps64_t *restrict);
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_rampsf_initialise(libgamma_gamma_rampsf_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_rampsf_destroy(libgamma_gamma_rampsf_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_rampsf_free(libgamma_gamma_rampsf_t *restrict);
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_gamma_rampsd_initialise(libgamma_gamma_rampsd_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
+ * initialised in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_rampsd_destroy(libgamma_gamma_rampsd_t *restrict);
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
+ * initialised in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_gamma_rampsd_free(libgamma_gamma_rampsd_t *restrict);
+
+
+
+/**
+ * List available adjustment methods by their order of preference based on the environment
+ *
+ * @param methods Output array of methods, should be able to hold `LIBGAMMA_METHOD_COUNT` elements
+ * @param buf_size The number of elements that fits in `methods`, it should be `LIBGAMMA_METHOD_COUNT`,
+ * This is used to avoid writing outside the output buffer if this library adds new
+ * adjustment methods without the users of the library recompiling
+ * @param operation Allowed values:
+ * 0: Methods that the environment suggests will work, excluding fake
+ * 1: Methods that the environment suggests will work, including fake
+ * 2: All real non-fake methods
+ * 3: All real methods
+ * 4: All methods
+ * Other values invoke undefined behaviour
+ * @return The number of element that have been stored in `methods`, or should
+ * have been stored if the buffer was large enough
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+size_t libgamma_list_methods(int *restrict, size_t, int);
+
+/**
+ * Return the capabilities of an adjustment method
+ *
+ * @param this The data structure to fill with the method's capabilities
+ * @param method The adjustment method (display server and protocol)
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int libgamma_method_capabilities(libgamma_method_capabilities_t *restrict, int);
+
+/**
+ * Return the default site for an adjustment method
+ *
+ * @param method The adjustment method (display server and protocol)
+ * @return The default site, `NULL` if it cannot be determined or
+ * if multiple sites are not supported by the adjustment
+ * method
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+const char *libgamma_method_default_site(int);
+
+/**
+ * Return the default variable that determines
+ * the default site for an adjustment method
+ *
+ * @param method The adjustment method (display server and protocol)
+ * @return The environ variables that is used to determine the
+ * default site, `NULL` if there is none, that is, if
+ * the method does not support multiple sites
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+const char *libgamma_method_default_site_variable(int);
+
+
+
+/**
+ * Initialise an allocated site state
+ *
+ * @param this The site state to initialise
+ * @param method The adjustment method (display server and protocol)
+ * @param site The site identifier, unless it is `NULL` it must a
+ * `free`:able. Once the state is destroyed the library
+ * will attempt to free it. There you should not free
+ * it yourself, and it must not be a string constant
+ * or allocate on the stack. Note however that it will
+ * not be `free`:d if this function fails.
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__(1))))
+int libgamma_site_initialise(libgamma_site_state_t *restrict, int, char *restrict);
+
+/**
+ * Release all resources held by a site state
+ *
+ * @param this The site state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_site_destroy(libgamma_site_state_t *restrict);
+
+/**
+ * Release all resources held by a site state
+ * and free the site state pointer
+ *
+ * @param this The site state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+inline void
+libgamma_site_free(libgamma_site_state_t *restrict this__)
+{
+ libgamma_site_destroy(this__);
+ free(this__);
+}
+
+/**
+ * Restore the gamma ramps all CRTC:s within a site to the system settings
+ *
+ * @param this The site state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_site_restore(libgamma_site_state_t *restrict);
+
+
+
+/**
+ * Initialise an allocated partition state
+ *
+ * @param this The partition state to initialise
+ * @param site The site state for the site that the partition belongs to
+ * @param partition The index of the partition within the site
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_partition_initialise(libgamma_partition_state_t *restrict, libgamma_site_state_t *restrict, size_t);
+
+/**
+ * Release all resources held by a partition state
+ *
+ * @param this The partition state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_partition_destroy(libgamma_partition_state_t *restrict);
+
+/**
+ * Release all resources held by a partition state
+ * and free the partition state pointer
+ *
+ * @param this The partition state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+inline void
+libgamma_partition_free(libgamma_partition_state_t *restrict this__)
+{
+ libgamma_partition_destroy(this__);
+ free(this__);
+}
+
+/**
+ * Restore the gamma ramps all CRTC:s within a partition to the system settings
+ *
+ * @param this The partition state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_partition_restore(libgamma_partition_state_t *restrict);
+
+
+
+/**
+ * Initialise an allocated CRTC state
+ *
+ * @param this The CRTC state to initialise
+ * @param partition The partition state for the partition that the CRTC belongs to
+ * @param crtc The index of the CRTC within the partition
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma_partition_state_t *restrict, size_t);
+
+/**
+ * Release all resources held by a CRTC state
+ *
+ * @param this The CRTC state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_crtc_destroy(libgamma_crtc_state_t *restrict);
+
+/**
+ * Release all resources held by a CRTC state
+ * and free the CRTC state pointer
+ *
+ * @param this The CRTC state
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+inline void
+libgamma_crtc_free(libgamma_crtc_state_t *restrict this__)
+{
+ libgamma_crtc_destroy(this__);
+ free(this__);
+}
+
+/**
+ * Restore the gamma ramps for a CRTC to the system settings for that CRTC
+ *
+ * @param this The CRTC state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_restore(libgamma_crtc_state_t *restrict);
+
+
+/**
+ * Read information about a CRTC
+ *
+ * @param this Instance of a data structure to fill with the information about the CRTC
+ * @param crtc The state of the CRTC whose information should be read
+ * @param fields OR:ed identifiers for the information about the CRTC that should be read
+ * @return Zero on success, -1 on error; on error refer to the error reports in `this`
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t);
+
+/**
+ * Release all resources in an information data structure for a CRTC
+ *
+ * @param this The CRTC information
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+void libgamma_crtc_information_destroy(libgamma_crtc_information_t *restrict);
+
+/**
+ * Release all resources in an information data structure for a CRTC
+ * and free the data structure pointer
+ *
+ * @param this The CRTC information
+ */
+inline void
+libgamma_crtc_information_free(libgamma_crtc_information_t *restrict this__)
+{
+ libgamma_crtc_information_destroy(this__);
+ free(this__);
+}
+
+
+/**
+ * Convert a raw representation of an EDID to a lowercase hexadecimal representation
+ *
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in lowercase hexadecimal representation
+ * `NULL` on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+char *libgamma_behex_edid_lowercase(const unsigned char *restrict, size_t);
+
+/**
+ * Convert a raw representation of an EDID to an uppercase hexadecimal representation
+ *
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in uppercase hexadecimal representation,
+ * NULL` on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+char *libgamma_behex_edid_uppercase(const unsigned char *restrict, size_t);
+
+/**
+ * Convert a raw representation of an EDID to a lowercase hexadecimal representation
+ *
+ * @param edid:const unsigned char* The EDID in raw representation
+ * @param length:size_t The length of `edid`
+ * @return :char* The EDID in lowercase hexadecimal representation,
+ * `NULL` on allocation error, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__)))
+inline char *
+libgamma_behex_edid(const unsigned char *restrict edid__, size_t length__)
+{
+ return libgamma_behex_edid_lowercase(edid__, length__);
+}
+
+/**
+ * Convert an hexadecimal representation of an EDID to a raw representation
+ *
+ * @param edid The EDID in hexadecimal representation
+ * @return The EDID in raw representation, it will be half the length
+ * of `edid` (the input value); `NULL` on allocation error or
+ * if the EDID is malformated, `errno` will be set accordingly
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __nonnull__)))
+unsigned char *libgamma_unhex_edid(const char *restrict);
+
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 8-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_get_gamma_ramps8(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, 8-bit gamma-depth version.
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps8(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_t);
+
+/**
+ * Set the gamma ramps for a CRTC, 8-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps8_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_fun *,
+ libgamma_gamma_ramps8_fun *, libgamma_gamma_ramps8_fun *);
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __hot__)))
+int libgamma_crtc_get_gamma_ramps16(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, 16-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __hot__)))
+int libgamma_crtc_set_gamma_ramps16(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_t);
+
+/**
+ * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __hot__)))
+int libgamma_crtc_set_gamma_ramps16_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_fun *,
+ libgamma_gamma_ramps16_fun *, libgamma_gamma_ramps16_fun *);
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 32-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_get_gamma_ramps32(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, 32-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps32(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_t);
+
+/**
+ * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps32_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_fun *,
+ libgamma_gamma_ramps32_fun *, libgamma_gamma_ramps32_fun *);
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 64-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_get_gamma_ramps64(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, 64-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps64(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_t);
+
+/**
+ * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_ramps64_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_fun *,
+ libgamma_gamma_ramps64_fun *, libgamma_gamma_ramps64_fun *);
+
+
+/**
+ * Set the gamma ramps for a CRTC, `float` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_rampsf(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_t);
+
+/**
+ * Get the current gamma ramps for a CRTC, `float` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_get_gamma_rampsf(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, `float` function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_rampsf_f(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_fun *,
+ libgamma_gamma_rampsf_fun *, libgamma_gamma_rampsf_fun *);
+
+
+/**
+ * Get the current gamma ramps for a CRTC, `double` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_get_gamma_rampsd(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_t *restrict);
+
+/**
+ * Set the gamma ramps for a CRTC, `double` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_t);
+
+/**
+ * Set the gamma ramps for a CRTC, `double` function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__)))
+int libgamma_crtc_set_gamma_rampsd_f(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_fun *,
+ libgamma_gamma_rampsd_fun *, libgamma_gamma_rampsd_fun *);
+
+
+
+#undef LIBGAMMA_GCC_ONLY__
+#endif
diff --git a/libgamma_behex_edid.c b/libgamma_behex_edid.c
new file mode 100644
index 0000000..269d68f
--- /dev/null
+++ b/libgamma_behex_edid.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Convert a raw representation of an EDID to a lowercase hexadecimal representation
+ *
+ * @param edid:const unsigned char* The EDID in raw representation
+ * @param length:size_t The length of `edid`
+ * @return :char* The EDID in lowercase hexadecimal representation,
+ * `NULL` on allocation error, `errno` will be set accordingly
+ */
+extern inline char *libgamma_behex_edid(const unsigned char *restrict, size_t);
diff --git a/libgamma_behex_edid_lowercase.c b/libgamma_behex_edid_lowercase.c
new file mode 100644
index 0000000..9c4f04e
--- /dev/null
+++ b/libgamma_behex_edid_lowercase.c
@@ -0,0 +1,33 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Convert a raw representation of an EDID to a lowercase hexadecimal representation
+ *
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in lowercase hexadecimal representation,
+ * `NULL` on allocation error, `errno` will be set accordingly
+ */
+char *
+libgamma_behex_edid_lowercase(const unsigned char *restrict edid, size_t length)
+{
+ char *restrict out;
+ size_t i;
+
+ /* Allocate memory area for the output string */
+ out = malloc((length * 2 + 1) * sizeof(char));
+ if (!out)
+ return NULL;
+
+ /* Translate from raw octets to hexadecimal */
+ for (i = 0; i < length; i++) {
+ out[i * 2 + 0] = "0123456789abcdef"[(edid[i] >> 4) & 15];
+ out[i * 2 + 1] = "0123456789abcdef"[(edid[i] >> 0) & 15];
+ }
+ /* NUL-terminate the output string */
+ out[length * 2] = '\0';
+
+ return out;
+}
diff --git a/libgamma_behex_edid_uppercase.c b/libgamma_behex_edid_uppercase.c
new file mode 100644
index 0000000..5545aa5
--- /dev/null
+++ b/libgamma_behex_edid_uppercase.c
@@ -0,0 +1,33 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Convert a raw representation of an EDID to an uppercase hexadecimal representation
+ *
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in uppercase hexadecimal representation,
+ * NULL` on allocation error, `errno` will be set accordingly
+ */
+char *
+libgamma_behex_edid_uppercase(const unsigned char *restrict edid, size_t length)
+{
+ char *restrict out;
+ size_t i;
+
+ /* Allocate memory area for the output string */
+ out = malloc((length * 2 + 1) * sizeof(char));
+ if (!out)
+ return NULL;
+
+ /* Translate from raw octets to hexadecimal */
+ for (i = 0; i < length; i++) {
+ out[i * 2 + 0] = "0123456789ABCDEF"[(edid[i] >> 4) & 15];
+ out[i * 2 + 1] = "0123456789ABCDEF"[(edid[i] >> 0) & 15];
+ }
+ /* NUL-terminate the output string */
+ out[length * 2] = '\0';
+
+ return out;
+}
diff --git a/libgamma_connector_type_count.c b/libgamma_connector_type_count.c
new file mode 100644
index 0000000..75934e1
--- /dev/null
+++ b/libgamma_connector_type_count.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * The number of values defined in `libgamma_connector_type_t`
+ * in the version of the library the program is linked against
+ */
+extern const int libgamma_connector_type_count;
diff --git a/libgamma_const_of_connector_type.c b/libgamma_const_of_connector_type.c
new file mode 100644
index 0000000..a006b88
--- /dev/null
+++ b/libgamma_const_of_connector_type.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the name of the constant for a connector
+ * type, for example "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ * for `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ *
+ * @param connector The connector type
+ * @return The name of the constant for connector type,
+ * `NULL` if not recognised (errno is not changed)
+ */
+const char *
+libgamma_const_of_connector_type(int connector)
+{
+ switch (connector) {
+#define X(CONST, NAME)\
+ case CONST: return #CONST;
+ LIST_CONNECTOR_TYPES(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_const_of_method.c b/libgamma_const_of_method.c
new file mode 100644
index 0000000..e6fd872
--- /dev/null
+++ b/libgamma_const_of_method.c
@@ -0,0 +1,24 @@
+#include "common.h"
+
+
+/**
+ * Get the name of the constant for an adjustment
+ * method, for example "LIBGAMMA_METHOD_X_RANDR"
+ * for `LIBGAMMA_METHOD_X_RANDR`
+ *
+ * @param method The adjustment method
+ * @return The name of the constant for adjustment method,
+ * `NULL` if not recognised (errno is not changed)
+ */
+const char *
+libgamma_const_of_method(int method)
+{
+ switch (method) {
+#define X(CONST, NAME, CNAME, ENABLED)\
+ case CONST: return #CONST;
+ LIST_METHODS(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_const_of_subpixel_order.c b/libgamma_const_of_subpixel_order.c
new file mode 100644
index 0000000..7f69bea
--- /dev/null
+++ b/libgamma_const_of_subpixel_order.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the name of the constant for a subpixel order,
+ * for example "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ * for `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ *
+ * @param order The subpixel order
+ * @return The name of the constant for subpixel order,
+ * `NULL` if not recognised (errno is not changed)
+ */
+const char *
+libgamma_const_of_subpixel_order(int order)
+{
+ switch (order) {
+#define X(CONST, NAME)\
+ case CONST: return #CONST;
+ LIST_SUBPIXEL_ORDERS(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_crtc_destroy.c b/libgamma_crtc_destroy.c
new file mode 100644
index 0000000..9724e31
--- /dev/null
+++ b/libgamma_crtc_destroy.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a CRTC state
+ *
+ * @param this The CRTC state
+ */
+void
+libgamma_crtc_destroy(libgamma_crtc_state_t *restrict this)
+{
+ switch (this->partition->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ libgamma_##CNAME##_crtc_destroy(this);\
+ break;
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ break;
+ }
+}
diff --git a/libgamma_crtc_free.c b/libgamma_crtc_free.c
new file mode 100644
index 0000000..986fd96
--- /dev/null
+++ b/libgamma_crtc_free.c
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a CRTC state
+ * and free the CRTC state pointer
+ *
+ * @param this The CRTC state
+ */
+extern inline void libgamma_crtc_free(libgamma_crtc_state_t *restrict);
diff --git a/libgamma_crtc_get_gamma_ramps16.c b/libgamma_crtc_get_gamma_ramps16.c
new file mode 100644
index 0000000..388f03f
--- /dev/null
+++ b/libgamma_crtc_get_gamma_ramps16.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_ramps16(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps16_t* restrict ramps)
+{
+#define DEPTH 16
+#define RAMPS ramps16
+#define TYPE bits16
+#define APPEND_RAMPS(X) X##ramps16
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_get_gamma_ramps32.c b/libgamma_crtc_get_gamma_ramps32.c
new file mode 100644
index 0000000..32ce2ef
--- /dev/null
+++ b/libgamma_crtc_get_gamma_ramps32.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 32-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_ramps32(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps32_t* restrict ramps)
+{
+#define DEPTH 32
+#define RAMPS ramps32
+#define TYPE bits32
+#define APPEND_RAMPS(X) X##ramps32
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_get_gamma_ramps64.c b/libgamma_crtc_get_gamma_ramps64.c
new file mode 100644
index 0000000..3db19f9
--- /dev/null
+++ b/libgamma_crtc_get_gamma_ramps64.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 64-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_ramps64(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps64_t* restrict ramps)
+{
+#define DEPTH 64
+#define RAMPS ramps64
+#define TYPE bits64
+#define APPEND_RAMPS(X) X##ramps64
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_get_gamma_ramps8.c b/libgamma_crtc_get_gamma_ramps8.c
new file mode 100644
index 0000000..9e359aa
--- /dev/null
+++ b/libgamma_crtc_get_gamma_ramps8.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, 8-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_ramps8(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps8_t* restrict ramps)
+{
+#define DEPTH 8
+#define RAMPS ramps8
+#define TYPE bits8
+#define APPEND_RAMPS(X) X##ramps8
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_get_gamma_rampsd.c b/libgamma_crtc_get_gamma_rampsd.c
new file mode 100644
index 0000000..e00e86c
--- /dev/null
+++ b/libgamma_crtc_get_gamma_rampsd.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, `double` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_rampsd(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsd_t* restrict ramps)
+{
+#define DEPTH -2
+#define RAMPS rampsd
+#define TYPE float_double
+#define APPEND_RAMPS(X) X##rampsd
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_get_gamma_rampsf.c b/libgamma_crtc_get_gamma_rampsf.c
new file mode 100644
index 0000000..ee233ca
--- /dev/null
+++ b/libgamma_crtc_get_gamma_rampsf.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the current gamma ramps for a CRTC, `float` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_get_gamma_rampsf(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsf_t* restrict ramps)
+{
+#define DEPTH -1
+#define RAMPS rampsf
+#define TYPE float_single
+#define APPEND_RAMPS(X) X##rampsf
+#include "get_ramps.h"
+}
diff --git a/libgamma_crtc_info_count.c b/libgamma_crtc_info_count.c
new file mode 100644
index 0000000..1b68fe3
--- /dev/null
+++ b/libgamma_crtc_info_count.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * The number of `LIBGAMMA_CRTC_INFO_*` values defined in
+ * the version of the library the program is linked against
+ *
+ * This exclude the combining macros defined below the
+ * `LIBGAMMA_CRTC_INFO_COUNT` macro
+ */
+const int libgamma_crtc_info_count = LIBGAMMA_CRTC_INFO_COUNT;
diff --git a/libgamma_crtc_information_destroy.c b/libgamma_crtc_information_destroy.c
new file mode 100644
index 0000000..0789451
--- /dev/null
+++ b/libgamma_crtc_information_destroy.c
@@ -0,0 +1,15 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources in an information data structure for a CRTC
+ *
+ * @param this The CRTC information
+ */
+void
+libgamma_crtc_information_destroy(libgamma_crtc_information_t *restrict this)
+{
+ free(this->edid);
+ free(this->connector_name);
+}
diff --git a/libgamma_crtc_information_free.c b/libgamma_crtc_information_free.c
new file mode 100644
index 0000000..84048f4
--- /dev/null
+++ b/libgamma_crtc_information_free.c
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources in an information data structure for a CRTC
+ * and free the data structure pointer
+ *
+ * @param this The CRTC information
+ */
+extern inline void libgamma_crtc_information_free(libgamma_crtc_information_t *restrict);
diff --git a/libgamma_crtc_initialise.c b/libgamma_crtc_initialise.c
new file mode 100644
index 0000000..0d010b7
--- /dev/null
+++ b/libgamma_crtc_initialise.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise an allocated CRTC state
+ *
+ * @param this The CRTC state to initialise
+ * @param partition The partition state for the partition that the CRTC belongs to
+ * @param crtc The index of the CRTC within the partition
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_initialise(libgamma_crtc_state_t *restrict this, libgamma_partition_state_t *restrict partition, size_t crtc)
+{
+ this->partition = partition;
+ this->crtc = crtc;
+
+ switch (partition->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_crtc_initialise(this, partition, crtc);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_crtc_restore.c b/libgamma_crtc_restore.c
new file mode 100644
index 0000000..d2a716f
--- /dev/null
+++ b/libgamma_crtc_restore.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Restore the gamma ramps for a CRTC to the system settings for that CRTC
+ *
+ * @param this The CRTC state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_restore(libgamma_crtc_state_t *restrict this)
+{
+ switch (this->partition->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_crtc_restore(this);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_crtc_set_gamma_ramps16.c b/libgamma_crtc_set_gamma_ramps16.c
new file mode 100644
index 0000000..2ad0b03
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps16.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 16-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps16(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps16_t ramps)
+{
+#define DEPTH 16
+#define RAMPS ramps16
+#define TYPE bits16
+#define APPEND_RAMPS(X) X##ramps16
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps16_f.c b/libgamma_crtc_set_gamma_ramps16_f.c
new file mode 100644
index 0000000..7b12530
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps16_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps16_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps16_fun *red_function,
+ libgamma_gamma_ramps16_fun *green_function, libgamma_gamma_ramps16_fun *blue_function)
+{
+#define TYPE uint16_t
+#define RAMPS ramps16
+#define APPEND_RAMPS(X) X##ramps16
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps32.c b/libgamma_crtc_set_gamma_ramps32.c
new file mode 100644
index 0000000..f042c68
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps32.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 32-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps32(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps32_t ramps)
+{
+#define DEPTH 32
+#define RAMPS ramps32
+#define TYPE bits32
+#define APPEND_RAMPS(X) X##ramps32
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps32_f.c b/libgamma_crtc_set_gamma_ramps32_f.c
new file mode 100644
index 0000000..d0bfef1
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps32_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps32_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps32_fun *red_function,
+ libgamma_gamma_ramps32_fun *green_function, libgamma_gamma_ramps32_fun *blue_function)
+{
+#define TYPE uint32_t
+#define RAMPS ramps32
+#define APPEND_RAMPS(X) X##ramps32
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps64.c b/libgamma_crtc_set_gamma_ramps64.c
new file mode 100644
index 0000000..4314738
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps64.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 64-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps64(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps64_t ramps)
+{
+#define DEPTH 64
+#define RAMPS ramps64
+#define TYPE bits64
+#define APPEND_RAMPS(X) X##ramps64
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps64_f.c b/libgamma_crtc_set_gamma_ramps64_f.c
new file mode 100644
index 0000000..3a0417d
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps64_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps64_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps64_fun *red_function,
+ libgamma_gamma_ramps64_fun *green_function, libgamma_gamma_ramps64_fun *blue_function)
+{
+#define TYPE uint64_t
+#define RAMPS ramps64
+#define APPEND_RAMPS(X) X##ramps64
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps8.c b/libgamma_crtc_set_gamma_ramps8.c
new file mode 100644
index 0000000..b0f041b
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps8.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 8-bit gamma-depth version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps8(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps8_t ramps)
+{
+#define DEPTH 8
+#define RAMPS ramps8
+#define TYPE bits8
+#define APPEND_RAMPS(X) X##ramps8
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_ramps8_f.c b/libgamma_crtc_set_gamma_ramps8_f.c
new file mode 100644
index 0000000..f33d960
--- /dev/null
+++ b/libgamma_crtc_set_gamma_ramps8_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, 8-bit gamma-depth function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_ramps8_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps8_fun *red_function,
+ libgamma_gamma_ramps8_fun *green_function, libgamma_gamma_ramps8_fun *blue_function)
+{
+#define TYPE uint8_t
+#define RAMPS ramps8
+#define APPEND_RAMPS(X) X##ramps8
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_crtc_set_gamma_rampsd.c b/libgamma_crtc_set_gamma_rampsd.c
new file mode 100644
index 0000000..7d02bdb
--- /dev/null
+++ b/libgamma_crtc_set_gamma_rampsd.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, `double` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsd_t ramps)
+{
+#define DEPTH -2
+#define RAMPS rampsd
+#define TYPE float_double
+#define APPEND_RAMPS(X) X##rampsd
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_rampsd_f.c b/libgamma_crtc_set_gamma_rampsd_f.c
new file mode 100644
index 0000000..7154b60
--- /dev/null
+++ b/libgamma_crtc_set_gamma_rampsd_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, `double` function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_rampsd_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsd_fun *red_function,
+ libgamma_gamma_rampsd_fun *green_function, libgamma_gamma_rampsd_fun *blue_function)
+{
+#define TYPE double
+#define RAMPS rampsd
+#define APPEND_RAMPS(X) X##rampsd
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_crtc_set_gamma_rampsf.c b/libgamma_crtc_set_gamma_rampsf.c
new file mode 100644
index 0000000..a31a007
--- /dev/null
+++ b/libgamma_crtc_set_gamma_rampsf.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, `float` version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_rampsf(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsf_t ramps)
+{
+#define DEPTH -1
+#define RAMPS rampsf
+#define TYPE float_single
+#define APPEND_RAMPS(X) X##rampsf
+#include "set_ramps.h"
+}
diff --git a/libgamma_crtc_set_gamma_rampsf_f.c b/libgamma_crtc_set_gamma_rampsf_f.c
new file mode 100644
index 0000000..a5a639f
--- /dev/null
+++ b/libgamma_crtc_set_gamma_rampsf_f.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Set the gamma ramps for a CRTC, `float` function version
+ *
+ * Note that this will probably involve the library allocating temporary data
+ *
+ * @param this The CRTC state
+ * @param red_function The function that generates the gamma ramp for the red channel
+ * @param green_function The function that generates the gamma ramp for the green channel
+ * @param blue_function The function that generates the gamma ramp for the blue channel
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_crtc_set_gamma_rampsf_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_rampsf_fun *red_function,
+ libgamma_gamma_rampsf_fun *green_function, libgamma_gamma_rampsf_fun *blue_function)
+{
+#define TYPE float
+#define RAMPS rampsf
+#define APPEND_RAMPS(X) X##rampsf
+#include "set_ramps_fun.h"
+}
diff --git a/libgamma_error_min.c b/libgamma_error_min.c
new file mode 100644
index 0000000..199429c
--- /dev/null
+++ b/libgamma_error_min.c
@@ -0,0 +1,10 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * The number of the libgamma error with the
+ * lowest number in the version of the library
+ * that the program is linked against
+ */
+const int libgamma_error_min = LIBGAMMA_ERROR_MIN;
diff --git a/libgamma_gamma_ramps16_destroy.c b/libgamma_gamma_ramps16_destroy.c
new file mode 100644
index 0000000..09a00f1
--- /dev/null
+++ b/libgamma_gamma_ramps16_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps16_destroy(libgamma_gamma_ramps16_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_ramps16_free.c b/libgamma_gamma_ramps16_free.c
new file mode 100644
index 0000000..70b9368
--- /dev/null
+++ b/libgamma_gamma_ramps16_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps16_free(libgamma_gamma_ramps16_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_ramps16_initialise.c b/libgamma_gamma_ramps16_initialise.c
new file mode 100644
index 0000000..c1c55cb
--- /dev/null
+++ b/libgamma_gamma_ramps16_initialise.c
@@ -0,0 +1,28 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_ramps16_initialise(libgamma_gamma_ramps16_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
+ /* Valgrind complains about us reading uninitialize memory if we just use malloc */
+ this->red = calloc(n, sizeof(uint16_t));
+#else
+ this->red = malloc(n * sizeof(uint16_t));
+#endif
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_gamma_ramps32_destroy.c b/libgamma_gamma_ramps32_destroy.c
new file mode 100644
index 0000000..4eabb6a
--- /dev/null
+++ b/libgamma_gamma_ramps32_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps32_destroy(libgamma_gamma_ramps32_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_ramps32_free.c b/libgamma_gamma_ramps32_free.c
new file mode 100644
index 0000000..96f7909
--- /dev/null
+++ b/libgamma_gamma_ramps32_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps32_free(libgamma_gamma_ramps32_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_ramps32_initialise.c b/libgamma_gamma_ramps32_initialise.c
new file mode 100644
index 0000000..28c1a00
--- /dev/null
+++ b/libgamma_gamma_ramps32_initialise.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_ramps32_initialise(libgamma_gamma_ramps32_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+ this->red = malloc(n * sizeof(uint32_t));
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_gamma_ramps64_destroy.c b/libgamma_gamma_ramps64_destroy.c
new file mode 100644
index 0000000..aeb85c4
--- /dev/null
+++ b/libgamma_gamma_ramps64_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps64_destroy(libgamma_gamma_ramps64_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_ramps64_free.c b/libgamma_gamma_ramps64_free.c
new file mode 100644
index 0000000..493d8be
--- /dev/null
+++ b/libgamma_gamma_ramps64_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps64_free(libgamma_gamma_ramps64_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_ramps64_initialise.c b/libgamma_gamma_ramps64_initialise.c
new file mode 100644
index 0000000..1196670
--- /dev/null
+++ b/libgamma_gamma_ramps64_initialise.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_ramps64_initialise(libgamma_gamma_ramps64_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+ this->red = malloc(n * sizeof(uint64_t));
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_gamma_ramps8_destroy.c b/libgamma_gamma_ramps8_destroy.c
new file mode 100644
index 0000000..630d8cc
--- /dev/null
+++ b/libgamma_gamma_ramps8_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps8_destroy(libgamma_gamma_ramps8_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_ramps8_free.c b/libgamma_gamma_ramps8_free.c
new file mode 100644
index 0000000..78be13a
--- /dev/null
+++ b/libgamma_gamma_ramps8_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_ramps8_free(libgamma_gamma_ramps8_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_ramps8_initialise.c b/libgamma_gamma_ramps8_initialise.c
new file mode 100644
index 0000000..6c64614
--- /dev/null
+++ b/libgamma_gamma_ramps8_initialise.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_ramps8_initialise(libgamma_gamma_ramps8_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+ this->red = malloc(n * sizeof(uint8_t));
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_gamma_rampsd_destroy.c b/libgamma_gamma_rampsd_destroy.c
new file mode 100644
index 0000000..47e27f3
--- /dev/null
+++ b/libgamma_gamma_rampsd_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_rampsd_destroy(libgamma_gamma_rampsd_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_rampsd_free.c b/libgamma_gamma_rampsd_free.c
new file mode 100644
index 0000000..c9b18bc
--- /dev/null
+++ b/libgamma_gamma_rampsd_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_rampsd_free(libgamma_gamma_rampsd_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_rampsd_initialise.c b/libgamma_gamma_rampsd_initialise.c
new file mode 100644
index 0000000..bb98d0b
--- /dev/null
+++ b/libgamma_gamma_rampsd_initialise.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_rampsd_initialise(libgamma_gamma_rampsd_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+ this->red = malloc(n * sizeof(double));
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_gamma_rampsf_destroy.c b/libgamma_gamma_rampsf_destroy.c
new file mode 100644
index 0000000..0b184d7
--- /dev/null
+++ b/libgamma_gamma_rampsf_destroy.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
+ * initialises in the proper manner
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_rampsf_destroy(libgamma_gamma_rampsf_t *restrict this)
+{
+ free(this->red);
+}
diff --git a/libgamma_gamma_rampsf_free.c b/libgamma_gamma_rampsf_free.c
new file mode 100644
index 0000000..fdaf590
--- /dev/null
+++ b/libgamma_gamma_rampsf_free.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release resources that are held by a gamma ramp strcuture that
+ * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
+ * initialises in the proper manner, as well as release the pointer
+ * to the structure
+ *
+ * @param this The gamma ramps
+ */
+void
+libgamma_gamma_rampsf_free(libgamma_gamma_rampsf_t *restrict this)
+{
+ free(this->red);
+ free(this);
+}
diff --git a/libgamma_gamma_rampsf_initialise.c b/libgamma_gamma_rampsf_initialise.c
new file mode 100644
index 0000000..b77fc83
--- /dev/null
+++ b/libgamma_gamma_rampsf_initialise.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise a gamma ramp in the proper way that allows all adjustment
+ * methods to read from and write to it without causing segmentation violation
+ *
+ * The input must have `red_size`, `green_size`, and `blue_size` set to the
+ * sizes of the gamma ramps that should be allocated
+ *
+ * @param this The gamma ramps
+ * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
+ */
+int
+libgamma_gamma_rampsf_initialise(libgamma_gamma_rampsf_t *restrict this)
+{
+ size_t n = this->red_size + this->green_size + this->blue_size;
+ this->red = malloc(n * sizeof(float));
+ this->green = &this-> red[this-> red_size];
+ this->blue = &this->green[this->green_size];
+ return this->red ? 0 : -1;
+}
diff --git a/libgamma_get_crtc_information.c b/libgamma_get_crtc_information.c
new file mode 100644
index 0000000..023c07f
--- /dev/null
+++ b/libgamma_get_crtc_information.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+
+/**
+ * Read information about a CRTC
+ *
+ * @param this Instance of a data structure to fill with the information about the CRTC
+ * @param crtc The state of the CRTC whose information should be read
+ * @param fields OR:ed identifiers for the information about the CRTC that should be read
+ * @return Zero on success, -1 on error; on error refer to the error reports in `this`
+ */
+int
+libgamma_get_crtc_information(libgamma_crtc_information_t *restrict this, libgamma_crtc_state_t *restrict crtc, int32_t fields)
+{
+ this->edid = NULL;
+ this->connector_name = NULL;
+
+ switch (crtc->partition->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_get_crtc_information(this, crtc, fields);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_group_gid.c b/libgamma_group_gid.c
new file mode 100644
index 0000000..b493a0d
--- /dev/null
+++ b/libgamma_group_gid.c
@@ -0,0 +1,37 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+#ifdef __WIN32__
+#define gid_t short
+#endif
+
+
+static _Thread_local gid_t libgamma_group_gid;
+
+
+/**
+ * Get the group that the user needs to be a member
+ * of if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @return The group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ */
+gid_t
+libgamma_group_gid_get(void)
+{
+ return libgamma_group_gid;
+}
+
+
+/**
+ * Set the group that the user needs to be a member
+ * of if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @param value The group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ */
+void
+libgamma_group_gid_set(gid_t value)
+{
+ libgamma_group_gid = value;
+}
diff --git a/libgamma_group_name.c b/libgamma_group_name.c
new file mode 100644
index 0000000..ce59300
--- /dev/null
+++ b/libgamma_group_name.c
@@ -0,0 +1,44 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+static _Thread_local char group_name[64]; /* Group names can only be up to 16 bytes logn, 63 is a very safe number */
+
+
+/**
+ * Get the group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @return The group that the user needs to be a member of if
+ * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned, `NULL`
+ * if the name of the group `libgamma_group_gid` cannot
+ * be determined
+ */
+const char *
+libgamma_group_name_get(void)
+{
+ return *group_name ? group_name : NULL;
+}
+
+
+/**
+ * Set the group that the user needs to be a member of
+ * if `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
+ *
+ * @param value The group that the user needs to be a member of if
+ * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned, may be `NULL`
+ */
+void
+libgamma_group_name_set(const char *value)
+{
+ size_t n;
+ if (!value) {
+ *group_name = 0;
+ } else {
+ n = strlen(value);
+ if (n >= sizeof(group_name))
+ *group_name = 0;
+ else
+ memcpy(group_name, value, n + 1);
+ }
+}
diff --git a/libgamma_internal_allocated_any_ramp.c b/libgamma_internal_allocated_any_ramp.c
new file mode 100644
index 0000000..7e6953d
--- /dev/null
+++ b/libgamma_internal_allocated_any_ramp.c
@@ -0,0 +1,60 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Just an arbitrary version
+ */
+#define ANY bits64
+
+/**
+ * Concatenation of all ramps
+ */
+#define ALL red
+
+
+/**
+ * Allocate and initalise a gamma ramp with any depth
+ *
+ * @param ramps_sys Output gamma ramps
+ * @param ramps The gamma ramps whose sizes should be duplicated
+ * @param depth The depth of the gamma ramps to allocate,
+ * `-1` for `float`, `-2` for `double`
+ * @param elements Output reference for the grand size of the gamma ramps
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_internal_allocated_any_ramp(gamma_ramps_any_t *restrict ramps_sys, gamma_ramps_any_t ramps,
+ signed depth, size_t *restrict elements)
+{
+ /* Calculate the size of the allocation to do */
+ size_t d, n = ramps.ANY.red_size + ramps.ANY.green_size + ramps.ANY.blue_size;
+ switch (depth) {
+ case 8: d = sizeof(uint8_t); break;
+ case 16: d = sizeof(uint16_t); break;
+ case 32: d = sizeof(uint32_t); break;
+ case 64: d = sizeof(uint64_t); break;
+ case -1: d = sizeof(float); break;
+ case -2: d = sizeof(double); break;
+ default:
+ return errno = EINVAL, LIBGAMMA_ERRNO_SET;
+ }
+
+ /* Copy the gamma ramp sizes */
+ ramps_sys->ANY = ramps.ANY;
+ /* Allocate the new ramps */
+#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
+ /* Valgrind complains about us reading uninitialize memory if we just use malloc */
+ ramps_sys->ANY.red = calloc(n, d);
+#else
+ ramps_sys->ANY.red = malloc(n * d);
+#endif
+ ramps_sys->ANY.green = (void *)&((char *)ramps_sys->ANY. red)[ramps.ANY. red_size * d / sizeof(char)];
+ ramps_sys->ANY.blue = (void *)&((char *)ramps_sys->ANY.green)[ramps.ANY.green_size * d / sizeof(char)];
+
+ /* Report the total gamma ramp size */
+ *elements = n;
+ /* Report successfulness */
+ return ramps_sys->ANY.red ? 0 : LIBGAMMA_ERRNO_SET;
+}
diff --git a/src/lib/edid.c b/libgamma_internal_parse_edid.c
index fc7b498..aa1b87c 100644
--- a/src/lib/edid.c
+++ b/libgamma_internal_parse_edid.c
@@ -1,10 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "edid.h"
-
-#include "libgamma-method.h"
-#include "libgamma-error.h"
-
-#include <stdint.h>
+#include "common.h"
/*
@@ -26,7 +21,7 @@
* @return Non-zero on error
*/
int
-libgamma_parse_edid(libgamma_crtc_information_t *restrict this, int32_t fields)
+libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict this, int32_t fields)
{
#define __test_version(edid, major, minor_min, minor_max)\
((edid)[18] == (major) && (minor_min) <= (edid)[19] && (edid)[19] <= (minor_max))
@@ -79,10 +74,9 @@ libgamma_parse_edid(libgamma_crtc_information_t *restrict this, int32_t fields)
/* If not error has occurred, calculate and test the checksum.
It is not considered an error that the gamma characteristics
is left unspecified in the EDID. */
- if (!error) {
+ if (!error)
for (i = 0; i < this->edid_length; i++)
checksum += (int)this->edid[i];
- }
/* The checksum should be zero. */
if (checksum & 255) {
/* Store the error in all fields that require the EDID to be parsed,
diff --git a/libgamma_internal_translate_from_64.c b/libgamma_internal_translate_from_64.c
new file mode 100644
index 0000000..b8adbfe
--- /dev/null
+++ b/libgamma_internal_translate_from_64.c
@@ -0,0 +1,44 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Concatenation of all ramps
+ */
+#define ALL red
+
+/**
+ * Preform installation in an `for (i = 0; i < n; i++)`
+ * loop and do a `break` afterwords
+ */
+#define __translate(instruction) for (i = 0; i < n; i++) instruction; break
+
+
+/**
+ * Undo the actions of `libgamma_internal_translate_to_64`
+ *
+ * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
+ * @param n The grand size of gamma ramps (sum of all channels' sizes)
+ * @param out Output gamma ramps
+ * @param in Input array, may be modified
+ */
+void
+libgamma_internal_translate_from_64(signed depth, size_t n, gamma_ramps_any_t out, uint64_t *restrict in)
+{
+ size_t i;
+ switch (depth) {
+ /* Translate integer */
+ case 8: __translate(out.bits8. ALL[i] = (uint8_t)(in[i] / 0x0101010101010101ULL));
+ case 16: __translate(out.bits16.ALL[i] = (uint16_t)(in[i] / 0x0001000100010001ULL));
+ case 32: __translate(out.bits32.ALL[i] = (uint32_t)(in[i] / 0x0000000100000001ULL));
+ /* Identity translation */
+ case 64: __translate(out.bits64.ALL[i] = in[i]);
+ /* Translate floating point */
+ case -1: __translate(out.float_single.ALL[i] = (float)(in[i]) / (float)UINT64_MAX);
+ case -2: __translate(out.float_double.ALL[i] = (double)(in[i]) / (double)UINT64_MAX);
+ default:
+ /* This is not possible */
+ abort();
+ break;
+ }
+}
diff --git a/libgamma_internal_translate_to_64.c b/libgamma_internal_translate_to_64.c
new file mode 100644
index 0000000..3733186
--- /dev/null
+++ b/libgamma_internal_translate_to_64.c
@@ -0,0 +1,184 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Just an arbitrary version
+ */
+#define ANY bits64
+
+/**
+ * Concatenation of all ramps
+ */
+#define ALL red
+
+
+/**
+ * Preform installation in an `for (i = 0; i < n; i++)`
+ * loop and do a `break` afterwords
+ */
+#define __translate(instruction) for (i = 0; i < n; i++) instruction; break
+
+
+/**
+ * Convert a [0, 1] `float` to a full range `uint64_t`
+ * and mark sure rounding errors does not cause the
+ * value be 0 instead of ~0 and vice versa
+ *
+ * @param value To `float` to convert
+ * @return The value as an `uint64_t`
+ */
+static uint64_t
+float_to_64(float value)
+{
+ /* TODO Which is faster? */
+
+#if defined(HAVE_INT128) && __WORDSIZE == 64
+ /* `__int128` is a GNU C extension, which
+ (because it is not ISO C) emits a warning
+ under -pedantic */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpedantic"
+
+ /* In GCC we can use `__int128`, this is
+ a signed 128-bit integer. It fits all
+ uint64_t values but also native values,
+ which is a nice because it eleminates
+ some overflow condition tests. It is
+ also more readable. */
+
+ /* Convert to integer */
+ __int128 product = (__int128)(value * (float)UINT64_MAX);
+ /* Negative overflow */
+ if (product > UINT64_MAX)
+ return UINT64_MAX;
+ /* Positive overflow */
+ if (product < 0)
+ return 0;
+ /* Did not overflow */
+ return (uint64_t)product;
+
+# pragma GCC diagnostic pop
+#else
+
+ /* If we are not using GCC we cannot be
+ sure that we have `__int128` so we have
+ to use `uint64_t` and perform overflow
+ checkes based on the input value */
+
+ /* Convert to integer. */
+ uint64_t product = (uint64_t)(value * (float)UINT64_MAX);
+ /* Negative overflow,
+ if the input is less than 0.5 but
+ the output is greater then we got
+ -1 when we should have gotten 0 */
+ if (value < 0.1f && product > 0xF000000000000000ULL)
+ return 0;
+ /* Positive overflow,
+ if the input is greater than 0.5
+ but the output is less then we got
+ 0 when we should have gotten ~0 */
+ else if (value > 0.9f && product < 0x1000000000000000ULL)
+ return (uint64_t)~0;
+ /* Did not overflow */
+ return product;
+
+#endif
+}
+
+
+/**
+ * Convert a [0, 1] `double` to a full range `uint64_t`
+ * and mark sure rounding errors does not cause the
+ * value be 0 instead of ~0 and vice versa
+ *
+ * @param value To `double` to convert
+ * @return The value as an `uint64_t`
+ */
+static uint64_t
+double_to_64(double value)
+{
+ /* TODO Which is faster? */
+
+#if defined(HAVE_INT128) && __WORDSIZE == 64
+ /* `__int128` is a GNU C extension, which
+ (because it is not ISO C) emits a warning
+ under -pedantic */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpedantic"
+
+ /* In GCC we can use `__int128`, this is
+ a signed 128-bit integer. It fits all
+ uint64_t values but also native values,
+ which is a nice because it eleminates
+ some overflow condition tests. It is
+ also more readable. */
+
+ /* Convert to integer */
+ __int128 product = (__int128)(value * (double)UINT64_MAX);
+ /* Negative overflow */
+ if (product > UINT64_MAX)
+ return UINT64_MAX;
+ /* Positive overflow */
+ if (product < 0)
+ return 0;
+ /* Did not overflow */
+ return (uint64_t)product;
+
+# pragma GCC diagnostic pop
+#else
+
+ /* If we are not using GCC we cannot be
+ sure that we have `__int128` so we have
+ to use `uint64_t` and perform overflow
+ checkes based on the input value. */
+
+ /* Convert to integer. */
+ uint64_t product = (uint64_t)(value * (double)UINT64_MAX);
+ /* Negative overflow,
+ if the input is less than 0.5 but
+ the output is greater then we got
+ -1 when we should have gotten 0 */
+ if (value < (double)0.1f && product > 0xF000000000000000ULL)
+ product = 0;
+ /* Positive overflow,
+ if the input is greater than 0.5
+ but the output is less then we got
+ 0 when we should have gotten ~0 */
+ else if ((value > (double)0.9f) && (product < 0x1000000000000000ULL))
+ product = (uint64_t)~0;
+ /* Did not overflow */
+ return product;
+
+#endif
+}
+
+
+/**
+ * Convert any set of gamma ramps into a 64-bit integer array with all channels
+ *
+ * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
+ * @param n The grand size of gamma ramps (sum of all channels' sizes)
+ * @param out Output array
+ * @param in Input gamma ramps
+ */
+void
+libgamma_internal_translate_to_64(signed depth, size_t n, uint64_t *restrict out, gamma_ramps_any_t in)
+{
+ size_t i;
+ switch (depth) {
+ /* Translate integer */
+ case 8: __translate(out[i] = (uint64_t)(in.bits8. ALL[i]) * 0x0101010101010101ULL);
+ case 16: __translate(out[i] = (uint64_t)(in.bits16.ALL[i]) * 0x0001000100010001ULL);
+ case 32: __translate(out[i] = (uint64_t)(in.bits32.ALL[i]) * 0x0000000100000001ULL);
+ /* Identity translation */
+ case 64: __translate(out[i] = in.bits64.ALL[i]);
+ /* Translate floating point */
+ case -1: __translate(out[i] = float_to_64(in.float_single.ALL[i]));
+ case -2: __translate(out[i] = double_to_64(in.float_double.ALL[i]));
+ default:
+ /* This is not possible */
+ abort();
+ break;
+ }
+}
diff --git a/libgamma_internal_translated_ramp_get_.c b/libgamma_internal_translated_ramp_get_.c
new file mode 100644
index 0000000..1ea4bdc
--- /dev/null
+++ b/libgamma_internal_translated_ramp_get_.c
@@ -0,0 +1,60 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Just an arbitrary version
+ */
+#define ANY bits64
+
+
+/**
+ * Get the current gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to fill with the current values
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used read the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_internal_translated_ramp_get_(libgamma_crtc_state_t *restrict this, gamma_ramps_any_t *restrict ramps,
+ signed depth_user, signed depth_system, get_ramps_any_fun *fun)
+{
+ size_t n;
+ int r;
+ gamma_ramps_any_t ramps_sys;
+ uint64_t *restrict ramps_full;
+
+ /* Allocate ramps with proper data type */
+ if ((r = libgamma_internal_allocated_any_ramp(&ramps_sys, *ramps, depth_system, &n)))
+ return r;
+
+ /* Fill the ramps */
+ if ((r = fun(this, &ramps_sys))) {
+ free(ramps_sys.ANY.red);
+ return r;
+ }
+
+ /* Allocate intermediary ramps */
+ ramps_full = malloc(n * sizeof(uint64_t));
+ if (!ramps_full) {
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
+
+ /* Translate ramps to 64-bit integers */
+ libgamma_internal_translate_to_64(depth_system, n, ramps_full, ramps_sys);
+ free(ramps_sys.ANY.red);
+
+ /* Translate ramps to the user's format */
+ libgamma_internal_translate_from_64(depth_user, n, *ramps, ramps_full);
+ free(ramps_full);
+ return 0;
+}
diff --git a/libgamma_internal_translated_ramp_set_.c b/libgamma_internal_translated_ramp_set_.c
new file mode 100644
index 0000000..4b4a9af
--- /dev/null
+++ b/libgamma_internal_translated_ramp_set_.c
@@ -0,0 +1,57 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Just an arbitrary version
+ */
+#define ANY bits64
+
+
+/**
+ * Set the gamma ramps for a CRTC, re-encoding version
+ *
+ * @param this The CRTC state
+ * @param ramps The gamma ramps to apply
+ * @param depth_user The depth of the gamma ramps that are provided by the user,
+ * `-1` for `float`, `-2` for `double`
+ * @param depth_system The depth of the gamma ramps as required by the adjustment method,
+ * `-1` for `float`, `-2` for `double`
+ * @param fun Function that is to be used write the ramps, its parameters have
+ * the same function as those of this function with the same names,
+ * and the return value too is identical
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_internal_translated_ramp_set_(libgamma_crtc_state_t *restrict this, gamma_ramps_any_t ramps,
+ signed depth_user, signed depth_system, set_ramps_any_fun *fun)
+{
+ size_t n;
+ int r;
+ gamma_ramps_any_t ramps_sys;
+ uint64_t *restrict ramps_full;
+
+ /* Allocate ramps with proper data type */
+ if ((r = libgamma_internal_allocated_any_ramp(&ramps_sys, ramps, depth_system, &n)))
+ return r;
+
+ /* Allocate intermediary ramps */
+ ramps_full = malloc(n * sizeof(uint64_t));
+ if (!ramps_full) {
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
+
+ /* Translate ramps to 64-bit integers. */
+ libgamma_internal_translate_to_64(depth_user, n, ramps_full, ramps);
+ /* Translate ramps to the proper format. */
+ libgamma_internal_translate_from_64(depth_system, n, ramps_sys, ramps_full);
+ free(ramps_full);
+
+ /* Apply the ramps */
+ r = fun(this, ramps_sys);
+
+ free(ramps_sys.ANY.red);
+ return r;
+}
diff --git a/libgamma_is_method_available.c b/libgamma_is_method_available.c
new file mode 100644
index 0000000..c114295
--- /dev/null
+++ b/libgamma_is_method_available.c
@@ -0,0 +1,24 @@
+#include "common.h"
+
+
+/**
+ * Check whether an adjustment method is available,
+ * non-existing (invalid) methods will be identified
+ * as not available under the rationale that the
+ * library may be out of date
+ *
+ * @param method The adjustment method
+ * @return Whether the adjustment method is available
+ */
+int
+libgamma_is_method_available(int method)
+{
+ switch (method) {
+#define X(CONST, NAME, CNAME, ENABLED)\
+ case CONST: return ENABLED;
+ LIST_METHODS(X)
+#undef X
+ default:
+ return 0;
+ }
+}
diff --git a/libgamma_list_methods.c b/libgamma_list_methods.c
new file mode 100644
index 0000000..6b912e1
--- /dev/null
+++ b/libgamma_list_methods.c
@@ -0,0 +1,135 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Test whether a file descriptor refers to a VT
+ *
+ * @param fd The file descriptor
+ * @return Whether the file descriptor refers to a VT
+ */
+static int
+is_vt_proper(int fd)
+{
+ char buf[32], digit0;
+
+ /* Get TTY */
+ if (ttyname_r(fd, buf, sizeof(buf) / sizeof(char)))
+ return 0;
+
+ /* Validate TTY path */
+ if (!strcmp(buf, "/dev/console"))
+ return 1;
+ if (strncmp(buf, "/dev/tty", sizeof("/dev/tty") - 1))
+ return 0;
+
+ /* Validate TTY name */
+ digit0 = buf[sizeof("/dev/tty") - 1];
+ return '1' <= digit0 && digit0 <= '9';
+}
+
+
+/**
+ * Test the availability of an adjustment method
+ *
+ * @param method The adjustment method
+ * @param operation Allowed values:
+ * 0: Pass if the environment suggests it will work but is not fake
+ * 1: Pass if the environment suggests it will work
+ * 2: Pass if real and not fake
+ * 3: Pass if real
+ * 4: Always pass
+ * Other values invoke undefined behaviour
+ * @return Whether the test passed
+ */
+static int
+list_method_test(int method, int operation)
+{
+ libgamma_method_capabilities_t caps;
+ int fd, r, saved_errno;
+
+ libgamma_method_capabilities(&caps, method);
+
+ switch (operation) {
+ case 0:
+ /* Methods that the environment suggests will work, excluding fake */
+ if (caps.fake)
+ return 0;
+ /* fall through */
+
+ case 1:
+ /* Methods that the environment suggests will work, including fake */
+ if (!caps.real)
+ return 0;
+#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
+ if (method == LIBGAMMA_METHOD_LINUX_DRM) {
+ saved_errno = errno;
+ if (is_vt_proper(STDIN_FILENO)) {
+ r = 1;
+ } else if (is_vt_proper(STDOUT_FILENO)) {
+ r = 1;
+ } else if (is_vt_proper(STDERR_FILENO)) {
+ r = 1;
+ } else {
+ r = 0;
+ fd = open("/dev/tty", O_RDONLY);
+ if (fd >= 0) {
+ r = is_vt_proper(fd);
+ close(fd);
+ }
+ }
+ errno = saved_errno;
+ return r;
+ }
+#endif
+#ifdef HAVE_LIBGAMMA_METHOD_DUMMY
+ if (method == LIBGAMMA_METHOD_DUMMY)
+ return 0;
+#endif
+ return caps.default_site_known;
+
+ case 2:
+ /* All real non-fake methods */
+ return caps.real && !caps.fake;
+
+ case 3:
+ /* All real methods */
+ return caps.real;
+
+ default:
+ /* All methods */
+ return 1;
+ }
+}
+
+
+/**
+ * List available adjustment methods by their order of preference based on the environment
+ *
+ * @param methods Output array of methods, should be able to hold `LIBGAMMA_METHOD_COUNT` elements
+ * @param buf_size The number of elements that fits in `methods`, it should be `LIBGAMMA_METHOD_COUNT`,
+ * This is used to avoid writing outside the output buffer if this library adds new
+ * adjustment methods without the users of the library recompiling
+ * @param operation Allowed values:
+ * 0: Methods that the environment suggests will work, excluding fake
+ * 1: Methods that the environment suggests will work, including fake
+ * 2: All real non-fake methods
+ * 3: All real methods
+ * 4: All methods
+ * Other values invoke undefined behaviour
+ * @return The number of element that have been stored in `methods`, or should
+ * have been stored if the buffer was large enough
+ */
+size_t
+libgamma_list_methods(int *restrict methods, size_t buf_size, int operation)
+{
+ size_t n = 0;
+
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ if (list_method_test(CONST, operation) && n++ < buf_size)\
+ methods[n - 1] = CONST;
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+
+ return n;
+}
diff --git a/libgamma_method_capabilities.c b/libgamma_method_capabilities.c
new file mode 100644
index 0000000..34623af
--- /dev/null
+++ b/libgamma_method_capabilities.c
@@ -0,0 +1,28 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Return the capabilities of an adjustment method
+ *
+ * @param this The data structure to fill with the method's capabilities
+ * @param method The adjustment method (display server and protocol)
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_method_capabilities(libgamma_method_capabilities_t *restrict this, int method)
+{
+ memset(this, 0, sizeof(*this));
+
+ switch (method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ libgamma_##CNAME##_method_capabilities(this);\
+ return 0;
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_method_count.c b/libgamma_method_count.c
new file mode 100644
index 0000000..34dd4fa
--- /dev/null
+++ b/libgamma_method_count.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * The number adjustment methods provided by the
+ * version this library the program is linked
+ * against
+ *
+ * This number includes both compile-time enabled
+ * and compile-time disabled adjustment methods
+ */
+const int libgamma_method_count = LIBGAMMA_METHOD_COUNT;
diff --git a/libgamma_method_default_site.c b/libgamma_method_default_site.c
new file mode 100644
index 0000000..5da2c72
--- /dev/null
+++ b/libgamma_method_default_site.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Return the default site for an adjustment method
+ *
+ * @param method The adjustment method (display server and protocol)
+ * @return The default site, `NULL` if it cannot be determined or
+ * if multiple sites are not supported by the adjustment
+ * method
+ */
+const char *
+libgamma_method_default_site(int method)
+{
+ const char *restrict var = libgamma_method_default_site_variable(method);
+ const char *restrict env;
+
+ /* Return `NULL` if there is no variable to read */
+ if (!var)
+ return NULL;
+
+ /* Read the variable */
+ env = getenv(var);
+ /* Return `NULL` if it does not exist (or is empty) */
+ if (!env || !*env)
+ return NULL;
+
+ /* Return the variable's value */
+ return env;
+}
diff --git a/libgamma_method_default_site_variable.c b/libgamma_method_default_site_variable.c
new file mode 100644
index 0000000..146041f
--- /dev/null
+++ b/libgamma_method_default_site_variable.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Return the default variable that determines
+ * the default site for an adjustment method
+ *
+ * @param method The adjustment method (display server and protocol)
+ * @return The environ variables that is used to determine the
+ * default site, `NULL` if there is none, that is, if
+ * the method does not support multiple sites
+ */
+const char *
+libgamma_method_default_site_variable(int method)
+{
+ switch (method) {
+ case LIBGAMMA_METHOD_X_RANDR:
+ return "DISPLAY";
+ case LIBGAMMA_METHOD_X_VIDMODE:
+ return "DISPLAY";
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_name_of_connector_type.c b/libgamma_name_of_connector_type.c
new file mode 100644
index 0000000..2f9b377
--- /dev/null
+++ b/libgamma_name_of_connector_type.c
@@ -0,0 +1,28 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the name of a connector type,
+ * for example "VGA" for `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ *
+ * "Unknown" is returned for `LIBGAMMA_CONNECTOR_TYPE_Unknown`,
+ * "TV" is returned for `LIBGAMMA_CONNECTOR_TYPE_TV`,
+ * "Virtual" is returned for `LIBGAMMA_CONNECTOR_TYPE_Virtual`
+ *
+ * @param connector The connector type
+ * @return The name connector type, `NULL` if not
+ * recognised (errno is not changed)
+ */
+const char *
+libgamma_name_of_connector_type(int connector)
+{
+ switch (connector) {
+#define X(CONST, NAME)\
+ case CONST: return NAME;
+ LIST_CONNECTOR_TYPES(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_name_of_error.c b/libgamma_name_of_error.c
new file mode 100644
index 0000000..56de28a
--- /dev/null
+++ b/libgamma_name_of_error.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the name of the definition associated with a `libgamma` error code
+ *
+ * @param value The error code
+ * @return The name of the definition associated with the error code,
+ * `NULL` if the error code does not exist
+ */
+const char *
+libgamma_name_of_error(int value)
+{
+ switch (value) {
+#define X(NAME, DESC)\
+ case NAME: return #NAME;
+ LIST_ERRORS(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_name_of_method.c b/libgamma_name_of_method.c
new file mode 100644
index 0000000..3e1843d
--- /dev/null
+++ b/libgamma_name_of_method.c
@@ -0,0 +1,23 @@
+#include "common.h"
+
+
+/**
+ * Get the name of an adjustment method,
+ * for example "randr" for `LIBGAMMA_METHOD_X_RANDR`
+ *
+ * @param method The adjustment method
+ * @return The name adjustment method, `NULL` if not
+ * recognised (errno is not changed)
+ */
+const char *
+libgamma_name_of_method(int method)
+{
+ switch (method) {
+#define X(CONST, NAME, CNAME, ENABLED)\
+ case CONST: return #NAME;
+ LIST_METHODS(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_name_of_subpixel_order.c b/libgamma_name_of_subpixel_order.c
new file mode 100644
index 0000000..f8c0bf8
--- /dev/null
+++ b/libgamma_name_of_subpixel_order.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the name of a subpixel order, for example
+ * "Horizontal RGB" for `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ *
+ * "Unknown" is returned for `LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN`,
+ * "None" is returned for `LIBGAMMA_SUBPIXEL_ORDER_NONE`
+ *
+ * @param order The subpixel order
+ * @return The name subpixel order, `NULL` if not
+ * recognised (errno is not changed)
+ */
+const char *
+libgamma_name_of_subpixel_order(int order)
+{
+ switch (order) {
+#define X(CONST, NAME)\
+ case CONST: return NAME;
+ LIST_SUBPIXEL_ORDERS(X)
+#undef X
+ default:
+ return NULL;
+ }
+}
diff --git a/libgamma_partition_destroy.c b/libgamma_partition_destroy.c
new file mode 100644
index 0000000..9709865
--- /dev/null
+++ b/libgamma_partition_destroy.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a partition state
+ *
+ * @param this The partition state
+ */
+void
+libgamma_partition_destroy(libgamma_partition_state_t *restrict this)
+{
+ switch (this->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ libgamma_##CNAME##_partition_destroy(this);\
+ break;
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ break;
+ }
+}
diff --git a/libgamma_partition_free.c b/libgamma_partition_free.c
new file mode 100644
index 0000000..787d3f4
--- /dev/null
+++ b/libgamma_partition_free.c
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a partition state
+ * and free the partition state pointer
+ *
+ * @param this The partition state
+ */
+extern inline void libgamma_partition_free(libgamma_partition_state_t *restrict);
diff --git a/libgamma_partition_initialise.c b/libgamma_partition_initialise.c
new file mode 100644
index 0000000..80b5976
--- /dev/null
+++ b/libgamma_partition_initialise.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise an allocated partition state
+ *
+ * @param this The partition state to initialise
+ * @param site The site state for the site that the partition belongs to
+ * @param partition The index of the partition within the site
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_partition_initialise(libgamma_partition_state_t *restrict this, libgamma_site_state_t *restrict site, size_t partition)
+{
+ this->site = site;
+ this->partition = partition;
+
+ switch (site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_partition_initialise(this, site, partition);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_partition_restore.c b/libgamma_partition_restore.c
new file mode 100644
index 0000000..0b20626
--- /dev/null
+++ b/libgamma_partition_restore.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Restore the gamma ramps all CRTC:s with a partition to the system settings
+ *
+ * @param this The partition state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_partition_restore(libgamma_partition_state_t *restrict this)
+{
+ switch (this->site->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_partition_restore(this);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_perror.c b/libgamma_perror.c
new file mode 100644
index 0000000..92060d8
--- /dev/null
+++ b/libgamma_perror.c
@@ -0,0 +1,40 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Prints an error to stderr in a `perror` fashion
+ *
+ * @param name The text to add at the beginning
+ * @param value The error code, may be an `errno` value
+ */
+void
+libgamma_perror(const char *name, int error_code)
+{
+ const char *desc, *gname;
+ char buf[1024];
+ long int gid;
+
+ desc = libgamma_strerror_r(error_code, buf, sizeof(buf));
+
+ if (error_code == LIBGAMMA_DEVICE_REQUIRE_GROUP) {
+ gid = (intmax_t)libgamma_group_gid_get();
+ gname = libgamma_group_name_get();
+ if (!gname) {
+ if (name && *name)
+ fprintf(stderr, "%s: %s in group %ji\n", name, desc, gid);
+ else
+ fprintf(stderr, "%s in group %ji\n", desc, gid);
+ } else {
+ if (name && *name)
+ fprintf(stderr, "%s: %s in group %s (%ji)\n", name, desc, gname, gid);
+ else
+ fprintf(stderr, "%s in group %s (%ji)\n", desc, gname, gid);
+ }
+ } else {
+ if (name && *name)
+ fprintf(stderr, "%s: %s\n", name, desc);
+ else
+ fprintf(stderr, "%s\n", desc);
+ }
+}
diff --git a/libgamma_site_destroy.c b/libgamma_site_destroy.c
new file mode 100644
index 0000000..c3e060a
--- /dev/null
+++ b/libgamma_site_destroy.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a site state
+ *
+ * @param this The site state
+ */
+void
+libgamma_site_destroy(libgamma_site_state_t *restrict this)
+{
+ switch (this->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ libgamma_##CNAME##_site_destroy(this);\
+ break;
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ break;
+ }
+ free(this->site);
+}
diff --git a/libgamma_site_free.c b/libgamma_site_free.c
new file mode 100644
index 0000000..142ce70
--- /dev/null
+++ b/libgamma_site_free.c
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Release all resources held by a site state
+ * and free the site state pointer
+ *
+ * @param this The site state
+ */
+extern inline void libgamma_site_free(libgamma_site_state_t *restrict this);
diff --git a/libgamma_site_initialise.c b/libgamma_site_initialise.c
new file mode 100644
index 0000000..23acc2d
--- /dev/null
+++ b/libgamma_site_initialise.c
@@ -0,0 +1,34 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Initialise an allocated site state
+ *
+ * @param this The site state to initialise
+ * @param method The adjustment method (display server and protocol)
+ * @param site The site identifier, unless it is `NULL` it must a
+ * `free`:able. Once the state is destroyed the library
+ * will attempt to free it. There you should not free
+ * it yourself, and it must not be a string constant
+ * or allocated on the stack. Note however that it will
+ * not be `free`:d if this function fails.
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_site_initialise(libgamma_site_state_t *restrict this, int method, char *restrict site)
+{
+ this->method = method;
+ this->site = site;
+
+ switch (method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_site_initialise(this, site);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_site_restore.c b/libgamma_site_restore.c
new file mode 100644
index 0000000..b6c936a
--- /dev/null
+++ b/libgamma_site_restore.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Restore the gamma ramps all CRTC:s with a site to the system settings
+ *
+ * @param this The site state
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
+ */
+int
+libgamma_site_restore(libgamma_site_state_t *restrict this)
+{
+ switch (this->method) {
+#define X(CONST, CNAME, DEPTH, RAMPS)\
+ case CONST:\
+ return libgamma_##CNAME##_site_restore(this);
+ LIST_AVAILABLE_METHODS(X)
+#undef X
+ default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+ }
+}
diff --git a/libgamma_strerror.c b/libgamma_strerror.c
new file mode 100644
index 0000000..c252a49
--- /dev/null
+++ b/libgamma_strerror.c
@@ -0,0 +1,32 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get a description of an error
+ *
+ * @param error_code The error code, may be an `errno` value, if
+ * `LIBGAMMA_ERRNO_SET`, the current value of `errno`
+ * will be used
+ * @return The description associated with the error code,
+ * `NULL` if the error code is not recognised
+ */
+const char *
+libgamma_strerror(int error_code)
+{
+ const char *desc;
+ if (error_code == LIBGAMMA_ERRNO_SET)
+ error_code = errno;
+ switch (error_code) {
+#define X(NAME, DESC)\
+ case NAME:\
+ desc = #NAME;\
+ break;
+ LIST_ERRORS(X)
+#undef X
+ default:
+ desc = NULL;
+ break;
+ }
+ return desc ? desc : error_code < 0 ? NULL : strerror(error_code);
+}
diff --git a/libgamma_strerror_r.c b/libgamma_strerror_r.c
new file mode 100644
index 0000000..42f396e
--- /dev/null
+++ b/libgamma_strerror_r.c
@@ -0,0 +1,61 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get a description of an error
+ *
+ * @param error_code The error code, may be an `errno` value, if
+ * `LIBGAMMA_ERRNO_SET`, the current value of `errno`
+ * will be used
+ * @param buf Buffer that shall be used if a description must be generated
+ * @param bufsize The size of `buf`, 1024 is recommended
+ * @return The description associated with the error code;
+ * can only be `NULL` if `buf` is `NULL`. If the buffer
+ * is insufficient, a truncated but NUL-terminated
+ * description is returned and `errno` is set to `ERANGE`;
+ * `errno` is otherwise unmodified
+ */
+const char *
+libgamma_strerror_r(int error_code, char buf[], size_t bufsize)
+{
+ const char *desc;
+ int saved_errno;
+ if (error_code == LIBGAMMA_ERRNO_SET)
+ error_code = errno;
+ switch (error_code) {
+#define X(NAME, DESC)\
+ case NAME:\
+ desc = #NAME;\
+ break;
+ LIST_ERRORS(X)
+#undef X
+ default:
+ desc = NULL;
+ break;
+ }
+ if (desc)
+ return desc;
+ if (error_code >= 0) {
+ saved_errno = errno;
+ desc = _Generic(strerror_r(error_code, buf, bufsize),
+ /* XSI strerror_r */
+ int: (errno = (int)(intptr_t)strerror_r(error_code, buf, bufsize)) ? NULL : buf,
+ /* GNU strerror_r */
+ char *: (desc = (char *)(uintptr_t)strerror_r(error_code, buf, bufsize)));
+ if (desc) {
+ errno = saved_errno;
+ if (!buf || strcmp(buf, "No error information"))
+ return buf;
+ } else if (errno == ERANGE) {
+ return buf;
+ } else {
+ errno = saved_errno;
+ }
+ }
+ if (!buf)
+ return buf;
+ *buf = '\0'; /* TODO what happended here? */
+ snprintf(buf, bufsize, "Unknown error #%i\n", error_code);
+ return buf;
+}
diff --git a/libgamma_subpixel_order_count.c b/libgamma_subpixel_order_count.c
new file mode 100644
index 0000000..d77a748
--- /dev/null
+++ b/libgamma_subpixel_order_count.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * The number of values defined in `libgamma_subpixel_order_t`
+ * in the version of the library the program is linked against
+ */
+const int libgamma_subpixel_order_count = LIBGAMMA_SUBPIXEL_ORDER_COUNT;
diff --git a/libgamma_unhex_edid.c b/libgamma_unhex_edid.c
new file mode 100644
index 0000000..37c9681
--- /dev/null
+++ b/libgamma_unhex_edid.c
@@ -0,0 +1,55 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Convert an hexadecimal representation of an EDID to a raw representation
+ *
+ * @param edid The EDID in hexadecimal representation
+ * @return The EDID in raw representation, it will be half the length
+ * of `edid` (the input value); `NULL` on allocation error or
+ * if the EDID is malformated, `errno` will be set accordingly
+ */
+unsigned char *
+libgamma_unhex_edid(const char *restrict edid)
+{
+ unsigned char *restrict out;
+ size_t i, n = strlen(edid);
+ char a, b;
+
+ /* Check that the length of the strings is even,
+ * otherwise it cannot represent bytes */
+ if (n & 1) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Allocate memory area for output octet array */
+ n /= 2 * sizeof(unsigned char);
+ out = malloc(n);
+ if (!out)
+ return NULL;
+
+ /* Convert to raw octet array */
+ for (i = 0; i < n; i++) {
+ /* Get the next character pair that, it represents an octet. */
+ a = edid[i * 2 + 0];
+ b = edid[i * 2 + 1];
+
+ /* Verify that the input is in hexadecimal */
+ if (!isxdigit(a) || !isxdigit(b)) {
+ free(out);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Convert each chararacter to raw format */
+ a = (char)((a & 15) + (a > '9' ? 9 : 0));
+ b = (char)((b & 15) + (b > '9' ? 9 : 0));
+
+ /* Combine the two characters into one octet */
+ out[i] = (unsigned char)((a << 4) | b);
+ }
+
+ return out;
+}
diff --git a/libgamma_value_of_connector_type.c b/libgamma_value_of_connector_type.c
new file mode 100644
index 0000000..ff81bfc
--- /dev/null
+++ b/libgamma_value_of_connector_type.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the value of a connector type
+ *
+ * @param connector The name of the connector type, for example
+ * "VGA" or "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ * @return The connector type; for example `LIBGAMMA_CONNECTOR_TYPE_VGA`
+ * for "VGA" and "LIBGAMMA_CONNECTOR_TYPE_VGA"
+ */
+int
+libgamma_value_of_connector_type(const char *connector)
+{
+#define X(CONST, NAME)\
+ if (!strcmp(connector, NAME))\
+ return CONST;
+ LIST_CONNECTOR_TYPES(X)
+#undef X
+
+#define X(CONST, NAME)\
+ if (!strcmp(connector, #CONST))\
+ return CONST;
+ LIST_CONNECTOR_TYPES(X)
+#undef X
+
+ return 0;
+}
diff --git a/libgamma_value_of_error.c b/libgamma_value_of_error.c
new file mode 100644
index 0000000..6d2f878
--- /dev/null
+++ b/libgamma_value_of_error.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the value of a `libgamma` error definition refered to by name
+ *
+ * @param name The name of the definition associated with the error code
+ * @return The error code, zero if the name does is `NULL`
+ * or does not refer to a `libgamma` error
+ */
+int
+libgamma_value_of_error(const char *name)
+{
+ if (!name)
+ return 0;
+#define X(NAME, DESC)\
+ if (!strcmp(name, #NAME))\
+ return NAME;
+ LIST_ERRORS(X)
+ #undef X
+ return 0;
+}
diff --git a/libgamma_value_of_method.c b/libgamma_value_of_method.c
new file mode 100644
index 0000000..ffd69c8
--- /dev/null
+++ b/libgamma_value_of_method.c
@@ -0,0 +1,28 @@
+#include "common.h"
+
+
+/**
+ * Get the value of an adjustment method
+ *
+ * @param method The name of the adjustment method, for example
+ * "randr" or "LIBGAMMA_METHOD_X_RANDR"
+ * @return The adjustment method; for example `LIBGAMMA_METHOD_X_RANDR`
+ * for "randr" and "LIBGAMMA_METHOD_X_RANDR"
+ */
+int
+libgamma_value_of_method(const char *method)
+{
+#define X(CONST, NAME, CNAME, ENABLED)\
+ if (!strcmp(method, #NAME))\
+ return CONST;
+ LIST_METHODS(X)
+#undef X
+
+#define X(CONST, NAME, CNAME, ENABLED)\
+ if (!strcmp(method, #CONST))\
+ return CONST;
+ LIST_METHODS(X)
+#undef X
+
+ return 0;
+}
diff --git a/libgamma_value_of_subpixel_order.c b/libgamma_value_of_subpixel_order.c
new file mode 100644
index 0000000..02a1fa7
--- /dev/null
+++ b/libgamma_value_of_subpixel_order.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Get the value of a subpixel order
+ *
+ * @param order The name of the subpixel order, for example
+ * "Horizontal RGB" or "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ * @return The subpixel order; for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
+ * for "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
+ */
+int
+libgamma_value_of_subpixel_order(const char *order)
+{
+#define X(CONST, NAME)\
+ if (!strcmp(order, NAME))\
+ return CONST;
+ LIST_SUBPIXEL_ORDERS(X)
+#undef X
+
+#define X(CONST, NAME)\
+ if (!strcmp(order, #CONST))\
+ return CONST;
+ LIST_SUBPIXEL_ORDERS(X)
+#undef X
+
+ return 0;
+}
diff --git a/mk/linux.mk b/mk/linux.mk
new file mode 100644
index 0000000..32d9953
--- /dev/null
+++ b/mk/linux.mk
@@ -0,0 +1,8 @@
+LINUX_DRM_METHOD = yes
+X_RANDR_METHOD = yes
+X_VIDMODE_METHOD = yes
+
+LIBEXT = so
+LIBFLAGS = -shared -Wl,-soname,libgamma.$(LIBEXT).$(LIB_MAJOR)
+LIBMAJOREXT = $(LIBEXT).$(LIB_MAJOR)
+LIBMINOREXT = $(LIBEXT).$(LIB_VERSION)
diff --git a/mk/macos.mk b/mk/macos.mk
new file mode 100644
index 0000000..3a670b1
--- /dev/null
+++ b/mk/macos.mk
@@ -0,0 +1,6 @@
+QUARTZ_CG_METHOD = yes
+
+LIBEXT = dylib
+LIBFLAGS = -dynamiclib
+LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT)
+LIBMINOREXT = $(LIB_VERSION).$(LIBEXT)
diff --git a/mk/method-dummy=no.mk b/mk/method-dummy=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-dummy=no.mk
diff --git a/mk/method-dummy=yes.mk b/mk/method-dummy=yes.mk
new file mode 100644
index 0000000..18773cf
--- /dev/null
+++ b/mk/method-dummy=yes.mk
@@ -0,0 +1,3 @@
+HDR_METHODS += gamma-dummy.h
+METHODS_PARAMS += LIBGAMMA_METHOD_DUMMY dummy 0 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_DUMMY
diff --git a/mk/method-linux-drm=no.mk b/mk/method-linux-drm=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-linux-drm=no.mk
diff --git a/mk/method-linux-drm=yes.mk b/mk/method-linux-drm=yes.mk
new file mode 100644
index 0000000..8799388
--- /dev/null
+++ b/mk/method-linux-drm=yes.mk
@@ -0,0 +1,5 @@
+HDR_METHODS += gamma-linux-drm.h
+METHODS_PARAMS += LIBGAMMA_METHOD_LINUX_DRM linux_drm 16 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_LINUX_DRM
+CFLAGS_METHODS += $$(pkg-config --cflags libdrm)
+LDFLAGS_METHODS += $$(pkg-config --libs libdrm)
diff --git a/mk/method-quartz-cg=fake.mk b/mk/method-quartz-cg=fake.mk
new file mode 100644
index 0000000..e33253a
--- /dev/null
+++ b/mk/method-quartz-cg=fake.mk
@@ -0,0 +1,3 @@
+HDR_METHODS += gamma-quartz-cg.h
+METHODS_PARAMS += LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS quartz_cg -1 rampsf
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS -DFAKE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
diff --git a/mk/method-quartz-cg=no.mk b/mk/method-quartz-cg=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-quartz-cg=no.mk
diff --git a/mk/method-quartz-cg=yes.mk b/mk/method-quartz-cg=yes.mk
new file mode 100644
index 0000000..b98d03d
--- /dev/null
+++ b/mk/method-quartz-cg=yes.mk
@@ -0,0 +1,8 @@
+F_APPLICATION_SERVICES = /System/Library/Frameworks/ApplicationServices.framework
+I_APPLICATION_SERVICES = $(F_APPLICATION_SERVICES)/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Headers
+
+HDR_METHODS += gamma-quartz-cg.h
+METHODS_PARAMS += LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS quartz_cg -1 rampsf
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
+CFLAGS_METHODS += -I$(I_APPLICATION_SERVICES) -F$(F_APPLICATION_SERVICES)
+LDFLAGS_METHODS += -framework ApplicationServices
diff --git a/mk/method-w32-gdi=fake.mk b/mk/method-w32-gdi=fake.mk
new file mode 100644
index 0000000..add5f79
--- /dev/null
+++ b/mk/method-w32-gdi=fake.mk
@@ -0,0 +1,3 @@
+HDR_METHODS += gamma-w32-gdi.h
+METHODS_PARAMS += LIBGAMMA_METHOD_W32_GDI w32_gdi 16 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_W32_GDI -DFAKE_LIBGAMMA_METHOD_W32_GDI
diff --git a/mk/method-w32-gdi=no.mk b/mk/method-w32-gdi=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-w32-gdi=no.mk
diff --git a/mk/method-w32-gdi=yes.mk b/mk/method-w32-gdi=yes.mk
new file mode 100644
index 0000000..348b71f
--- /dev/null
+++ b/mk/method-w32-gdi=yes.mk
@@ -0,0 +1,3 @@
+HDR_METHODS += gamma-w32-gdi.h
+METHODS_PARAMS += LIBGAMMA_METHOD_W32_GDI w32_gdi 16 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_W32_GDI
diff --git a/mk/method-x-randr=no.mk b/mk/method-x-randr=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-x-randr=no.mk
diff --git a/mk/method-x-randr=yes.mk b/mk/method-x-randr=yes.mk
new file mode 100644
index 0000000..91a935b
--- /dev/null
+++ b/mk/method-x-randr=yes.mk
@@ -0,0 +1,5 @@
+HDR_METHODS += gamma-x-randr.h
+METHODS_PARAMS += LIBGAMMA_METHOD_X_RANDR x_randr 16 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_X_RANDR
+CFLAGS_METHODS += $$(pkg-config --cflags xcb xcb-randr)
+LDFLAGS_METHODS += $$(pkg-config --libs xcb xcb-randr)
diff --git a/mk/method-x-vidmode=no.mk b/mk/method-x-vidmode=no.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk/method-x-vidmode=no.mk
diff --git a/mk/method-x-vidmode=yes.mk b/mk/method-x-vidmode=yes.mk
new file mode 100644
index 0000000..e54d98a
--- /dev/null
+++ b/mk/method-x-vidmode=yes.mk
@@ -0,0 +1,5 @@
+HDR_METHODS += gamma-x-vidmode.h
+METHODS_PARAMS += LIBGAMMA_METHOD_X_VIDMODE x_vidmode 16 ramps16
+CPPFLAGS_METHODS += -DHAVE_LIBGAMMA_METHOD_X_VIDMODE
+CFLAGS_METHODS += $$(pkg-config --cflags x11 xxf86vm)
+LDFLAGS_METHODS += $$(pkg-config --libs x11 xxf86vm)
diff --git a/mk/windows.mk b/mk/windows.mk
new file mode 100644
index 0000000..4520743
--- /dev/null
+++ b/mk/windows.mk
@@ -0,0 +1,6 @@
+W32_GDI_METHOD = yes
+
+LIBEXT = dll
+LIBFLAGS = -mdll
+LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT)
+LIBMINOREXT = $(LIB_VERSION).$(LIBEXT)
diff --git a/set_ramps.h b/set_ramps.h
new file mode 100644
index 0000000..b396450
--- /dev/null
+++ b/set_ramps.h
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * This file is intended to be included from
+ * libgamma_crtc_set_gamma_ramps{8,16,32,64,f,d}
+ */
+
+
+gamma_ramps_any_t ramps_;
+switch (this->partition->site->method) {
+#define X(CONST, CNAME, MDEPTH, MRAMPS)\
+case CONST:\
+ if (!(MDEPTH)) {\
+ return APPEND_RAMPS(libgamma_dummy_crtc_set_gamma_)(this, ramps);\
+ } else if ((DEPTH) == (MDEPTH)) {\
+ return libgamma_##CNAME##_crtc_set_gamma_##MRAMPS(this, *(libgamma_gamma_##MRAMPS##_t *)&ramps); \
+ } else {\
+ ramps_.TYPE = ramps;\
+ return libgamma_internal_translated_ramp_set(this, ramps_, DEPTH, MDEPTH, libgamma_crtc_set_gamma_##MRAMPS);\
+ }
+LIST_AVAILABLE_METHODS(X)
+#undef X
+default:
+ return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
+}
diff --git a/set_ramps_fun.h b/set_ramps_fun.h
new file mode 100644
index 0000000..bdd1fe8
--- /dev/null
+++ b/set_ramps_fun.h
@@ -0,0 +1,50 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * This file is intended to be included from
+ * libgamma_crtc_set_gamma_ramps{8,16,32,64,f,d}_f
+ */
+
+
+libgamma_crtc_information_t info;
+struct APPEND_RAMPS(libgamma_gamma_) ramps;
+size_t i, n;
+int e;
+
+/* Get the size of the gamma ramps */
+if (libgamma_get_crtc_information(&info, this, LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) {
+ e = info.gamma_size_error;
+ if (e < 0)
+ return e;
+ errno = e;
+ return LIBGAMMA_ERRNO_SET;
+ }
+
+/* Copy the size of the gamma ramps and calculte the grand size */
+n = ramps. red_size = info. red_gamma_size;
+n += ramps.green_size = info.green_gamma_size;
+n += ramps. blue_size = info. blue_gamma_size;
+
+/* Allocate gamma ramps */
+ramps. red = malloc(n * sizeof(TYPE));
+ramps.green = &ramps. red[ramps. red_size];
+ramps. blue = &ramps.green[ramps.green_size];
+if (!ramps.red)
+ return LIBGAMMA_ERRNO_SET;
+
+/* Generate the gamma ramp for the red channel */
+for (i = 0, n = ramps.red_size; i < n; i++)
+ ramps.red[i] = red_function((float)i / (float)(n - 1));
+
+/* Generate the gamma ramp for the green channel */
+for (i = 0, n = ramps.green_size; i < n; i++)
+ ramps.green[i] = green_function((float)i / (float)(n - 1));
+
+/* Generate the gamma ramp for the blue channel */
+for (i = 0, n = ramps.blue_size; i < n; i++)
+ ramps.blue[i] = blue_function((float)i / (float)(n - 1));
+
+/* Apply the gamma ramps */
+e = APPEND_RAMPS(libgamma_crtc_set_gamma_)(this, ramps);
+free(ramps.red);
+return e;
diff --git a/src/lib/edid.h b/src/lib/edid.h
deleted file mode 100644
index 51529ae..0000000
--- a/src/lib/edid.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_EDID_H
-#define LIBGAMMA_EDID_H
-
-#include "libgamma-method.h"
-
-#include <stdint.h>
-
-
-/**
- * Parse the EDID of a monitor
- *
- * @param this Instance of a data structure to fill with the information about the EDID;
- * it must contain the EDID and its length
- * @param fields OR:ed identifiers for the information about the EDID that should be parsed;
- * fields that do not have to do with EDID are ignored
- * @return Non-zero on error
- */
-int libgamma_parse_edid(libgamma_crtc_information_t *restrict, int32_t);
-
-
-#endif
diff --git a/src/lib/gamma-helper.c b/src/lib/gamma-helper.c
deleted file mode 100644
index f67e107..0000000
--- a/src/lib/gamma-helper.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "gamma-helper.h"
-
-#include "libgamma-method.h"
-#include "libgamma-error.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-
-/**
- * Just an arbitrary version
- */
-#define ANY bits64
-
-/**
- * Concatenation of all ramps
- */
-#define ALL red
-
-
-/**
- * Preform installation in an `for (i = 0; i < n; i++)`
- * loop and do a `break` afterwords
- */
-#define __translate(instruction) for (i = 0; i < n; i++) instruction; break
-
-
-/**
- * Convert a [0, 1] `float` to a full range `uint64_t`
- * and mark sure rounding errors does not cause the
- * value be 0 instead of ~0 and vice versa
- *
- * @param value To `float` to convert
- * @return The value as an `uint64_t`
- */
-static inline uint64_t
-float_to_64(float value)
-{
- /* TODO Which is faster? */
-
-#if defined(HAVE_INT128) && __WORDSIZE == 64
- /* `__int128` is a GNU C extension, which
- (because it is not ISO C) emits a warning
- under -pedantic */
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wpedantic"
-
- /* In GCC we can use `__int128`, this is
- a signed 128-bit integer. It fits all
- uint64_t values but also native values,
- which is a nice because it eleminates
- some overflow condition tests. It is
- also more readable. */
-
- /* Convert to integer */
- __int128 product = (__int128)(value * (float)UINT64_MAX);
- /* Negative overflow */
- if (product > UINT64_MAX)
- return UINT64_MAX;
- /* Positive overflow */
- if (product < 0)
- return 0;
- /* Did not overflow */
- return (uint64_t)product;
-
-# pragma GCC diagnostic pop
-#else
-
- /* If we are not using GCC we cannot be
- sure that we have `__int128` so we have
- to use `uint64_t` and perform overflow
- checkes based on the input value */
-
- /* Convert to integer. */
- uint64_t product = (uint64_t)(value * (float)UINT64_MAX);
- /* Negative overflow,
- if the input is less than 0.5 but
- the output is greater then we got
- -1 when we should have gotten 0 */
- if (value < 0.1f && product > 0xF000000000000000ULL)
- return 0;
- /* Positive overflow,
- if the input is greater than 0.5
- but the output is less then we got
- 0 when we should have gotten ~0 */
- else if (value > 0.9f && product < 0x1000000000000000ULL)
- return (uint64_t)~0;
- /* Did not overflow */
- return product;
-
-#endif
-}
-
-
-/**
- * Convert a [0, 1] `double` to a full range `uint64_t`
- * and mark sure rounding errors does not cause the
- * value be 0 instead of ~0 and vice versa
- *
- * @param value To `double` to convert
- * @return The value as an `uint64_t`
- */
-static inline uint64_t
-double_to_64(double value)
-{
- /* XXX Which is faster? */
-
-#if defined(HAVE_INT128) && __WORDSIZE == 64
- /* `__int128` is a GNU C extension, which
- (because it is not ISO C) emits a warning
- under -pedantic */
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wpedantic"
-
- /* In GCC we can use `__int128`, this is
- a signed 128-bit integer. It fits all
- uint64_t values but also native values,
- which is a nice because it eleminates
- some overflow condition tests. It is
- also more readable. */
-
- /* Convert to integer */
- __int128 product = (__int128)(value * (double)UINT64_MAX);
- /* Negative overflow */
- if (product > UINT64_MAX)
- return UINT64_MAX;
- /* Positive overflow */
- if (product < 0)
- return 0;
- /* Did not overflow */
- return (uint64_t)product;
-
-# pragma GCC diagnostic pop
-#else
-
- /* If we are not using GCC we cannot be
- sure that we have `__int128` so we have
- to use `uint64_t` and perform overflow
- checkes based on the input value. */
-
- /* Convert to integer. */
- uint64_t product = (uint64_t)(value * (double)UINT64_MAX);
- /* Negative overflow,
- if the input is less than 0.5 but
- the output is greater then we got
- -1 when we should have gotten 0 */
- if (value < (double)0.1f && product > 0xF000000000000000ULL)
- product = 0;
- /* Positive overflow,
- if the input is greater than 0.5
- but the output is less then we got
- 0 when we should have gotten ~0 */
- else if ((value > (double)0.9f) && (product < 0x1000000000000000ULL))
- product = (uint64_t)~0;
- /* Did not overflow */
- return product;
-
-#endif
-}
-
-
-/**
- * Convert any set of gamma ramps into a 64-bit integer array with all channels
- *
- * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
- * @param n The grand size of gamma ramps (sum of all channels' sizes)
- * @param out Output array
- * @param in Input gamma ramps
- */
-static void
-translate_to_64(signed depth, size_t n, uint64_t *restrict out, libgamma_gamma_ramps_any_t in)
-{
- size_t i;
- switch (depth) {
- /* Translate integer */
- case 8: __translate(out[i] = (uint64_t)(in.bits8. ALL[i]) * 0x0101010101010101ULL);
- case 16: __translate(out[i] = (uint64_t)(in.bits16.ALL[i]) * 0x0001000100010001ULL);
- case 32: __translate(out[i] = (uint64_t)(in.bits32.ALL[i]) * 0x0000000100000001ULL);
- /* Identity translation */
- case 64: __translate(out[i] = in.bits64.ALL[i]);
- /* Translate floating point */
- case -1: __translate(out[i] = float_to_64(in.float_single.ALL[i]));
- case -2: __translate(out[i] = double_to_64(in.float_double.ALL[i]));
- default:
- /* This is not possible */
- abort();
- break;
- }
-}
-
-
-/**
- * Undo the actions of `translate_to_64`
- *
- * @param depth The depth of the gamma ramp, `-1` for `float`, `-2` for `double`
- * @param n The grand size of gamma ramps (sum of all channels' sizes)
- * @param out Output gamma ramps
- * @param in Input array, may be modified
- */
-static void
-translate_from_64(signed depth, size_t n, libgamma_gamma_ramps_any_t out, uint64_t *restrict in)
-{
- size_t i;
- switch (depth) {
- /* Translate integer */
- case 8: __translate(out.bits8. ALL[i] = (uint8_t)(in[i] / 0x0101010101010101ULL));
- case 16: __translate(out.bits16.ALL[i] = (uint16_t)(in[i] / 0x0001000100010001ULL));
- case 32: __translate(out.bits32.ALL[i] = (uint32_t)(in[i] / 0x0000000100000001ULL));
- /* Identity translation */
- case 64: __translate(out.bits64.ALL[i] = in[i]);
- /* Translate floating point */
- case -1: __translate(out.float_single.ALL[i] = (float)(in[i]) / (float)UINT64_MAX);
- case -2: __translate(out.float_double.ALL[i] = (double)(in[i]) / (double)UINT64_MAX);
- default:
- /* This is not possible */
- abort();
- break;
- }
-}
-
-
-/**
- * Allocate and initalise a gamma ramp with any depth
- *
- * @param ramps_sys Output gamma ramps
- * @param ramps The gamma ramps whose sizes should be duplicated
- * @param depth The depth of the gamma ramps to allocate,
- * `-1` for `float`, `-2` for `double`
- * @param elements Output reference for the grand size of the gamma ramps
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-static int
-allocated_any_ramp(libgamma_gamma_ramps_any_t *restrict ramps_sys,
- libgamma_gamma_ramps_any_t ramps, signed depth, size_t *restrict elements)
-{
- /* Calculate the size of the allocation to do */
- size_t d, n = ramps.ANY.red_size + ramps.ANY.green_size + ramps.ANY.blue_size;
- switch (depth) {
- case 8: d = sizeof(uint8_t); break;
- case 16: d = sizeof(uint16_t); break;
- case 32: d = sizeof(uint32_t); break;
- case 64: d = sizeof(uint64_t); break;
- case -1: d = sizeof(float); break;
- case -2: d = sizeof(double); break;
- default:
- return errno = EINVAL, LIBGAMMA_ERRNO_SET;
- }
-
- /* Copy the gamma ramp sizes */
- ramps_sys->ANY = ramps.ANY;
- /* Allocate the new ramps */
-#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
- /* Valgrind complains about us reading uninitialize memory if we just use malloc */
- ramps_sys->ANY.red = calloc(n, d);
-#else
- ramps_sys->ANY.red = malloc(n * d);
-#endif
- ramps_sys->ANY.green = (void *)&((char *)ramps_sys->ANY. red)[ramps.ANY. red_size * d / sizeof(char)];
- ramps_sys->ANY.blue = (void *)&((char *)ramps_sys->ANY.green)[ramps.ANY.green_size * d / sizeof(char)];
-
- /* Report the total gamma ramp size */
- *elements = n;
- /* Report successfulness */
- return ramps_sys->ANY.red ? 0 : LIBGAMMA_ERRNO_SET;
-}
-
-
-/**
- * Get the current gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used read the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_translated_ramp_get_(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps_any_t *restrict ramps,
- signed depth_user, signed depth_system, libgamma_get_ramps_any_fun *fun)
-{
- size_t n;
- int r;
- libgamma_gamma_ramps_any_t ramps_sys;
- uint64_t *restrict ramps_full;
-
- /* Allocate ramps with proper data type */
- if ((r = allocated_any_ramp(&ramps_sys, *ramps, depth_system, &n)))
- return r;
-
- /* Fill the ramps */
- if ((r = fun(this, &ramps_sys)))
- return free(ramps_sys.ANY.red), r;
-
- /* Allocate intermediary ramps */
- ramps_full = malloc(n * sizeof(uint64_t));
- if (!ramps_full) {
- free(ramps_sys.ANY.red);
- return LIBGAMMA_ERRNO_SET;
- }
-
- /* Translate ramps to 64-bit integers */
- translate_to_64(depth_system, n, ramps_full, ramps_sys);
- free(ramps_sys.ANY.red);
-
- /* Translate ramps to the user's format */
- translate_from_64(depth_user, n, *ramps, ramps_full);
- free(ramps_full);
- return 0;
-}
-
-
-/**
- * Set the gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used write the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_translated_ramp_set_(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps_any_t ramps,
- signed depth_user, signed depth_system, libgamma_set_ramps_any_fun *fun)
-{
- size_t n;
- int r;
- libgamma_gamma_ramps_any_t ramps_sys;
- uint64_t *restrict ramps_full;
-
- /* Allocate ramps with proper data type */
- if ((r = allocated_any_ramp(&ramps_sys, ramps, depth_system, &n)))
- return r;
-
- /* Allocate intermediary ramps */
- ramps_full = malloc(n * sizeof(uint64_t));
- if (!ramps_full) {
- free(ramps_sys.ANY.red);
- return LIBGAMMA_ERRNO_SET;
- }
-
- /* Translate ramps to 64-bit integers. */
- translate_to_64(depth_user, n, ramps_full, ramps);
- /* Translate ramps to the proper format. */
- translate_from_64(depth_system, n, ramps_sys, ramps_full);
- free(ramps_full);
-
- /* Apply the ramps */
- r = fun(this, ramps_sys);
-
- free(ramps_sys.ANY.red);
- return r;
-}
-
-
-#undef __translate
-#undef ALL
-#undef ANY
diff --git a/src/lib/gamma-helper.h b/src/lib/gamma-helper.h
deleted file mode 100644
index 38d678d..0000000
--- a/src/lib/gamma-helper.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_GAMMA_HELPER_H
-#define LIBGAMMA_GAMMA_HELPER_H
-
-
-#include "libgamma-method.h"
-
-
-/**
- * Gamma ramp structure union for different depths
- */
-typedef union libgamma_gamma_ramps_any {
- /**
- * 8-bit gamma ramps
- */
- libgamma_gamma_ramps8_t bits8;
-
- /**
- * 16-bit gamma ramps
- */
- libgamma_gamma_ramps16_t bits16;
-
- /**
- * 32-bit gamma ramps
- */
- libgamma_gamma_ramps32_t bits32;
-
- /**
- * 64-bit gamma ramps
- */
- libgamma_gamma_ramps64_t bits64;
-
- /**
- * Single precision float gamma ramps
- */
- libgamma_gamma_rampsf_t float_single;
-
- /**
- * Double precision float gamma ramps
- */
- libgamma_gamma_rampsd_t float_double;
-
-} libgamma_gamma_ramps_any_t;
-
-
-/**
- * A function for reading the gamma ramps from a CRTC
- *
- * @param this The CRTC state
- * @param ramps The store for the gamma ramps
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-typedef int libgamma_get_ramps_any_fun(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps_any_t *restrict);
-
-/**
- * A function for writing the gamma ramps to a CRTC
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-typedef int libgamma_set_ramps_any_fun(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps_any_t);
-
-
-
-/**
- * Get the current gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used read the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-#define libgamma_translated_ramp_get(this, ramps, depth_user, depth_system, fun)\
- libgamma_translated_ramp_get_((this), (ramps), (depth_user), (depth_system), (libgamma_get_ramps_any_fun *)(fun))
-
-
-/**
- * Set the gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used write the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-#define libgamma_translated_ramp_set(this, ramps, depth_user, depth_system, fun)\
- libgamma_translated_ramp_set_((this), (ramps), (depth_user), (depth_system), (libgamma_set_ramps_any_fun *)fun)
-
-
-/**
- * Get the current gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used read the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_translated_ramp_get_(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps_any_t *restrict,
- signed, signed, libgamma_get_ramps_any_fun *);
-
-
-/**
- * Set the gamma ramps for a CRTC, re-encoding version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @param depth_user The depth of the gamma ramps that are provided by the user,
- * `-1` for `float`, `-2` for `double`
- * @param depth_system The depth of the gamma ramps as required by the adjustment method,
- * `-1` for `float`, `-2` for `double`
- * @param fun Function that is to be used write the ramps, its parameters have
- * the same function as those of this function with the same names,
- * and the return value too is identical
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_translated_ramp_set_(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps_any_t,
- signed, signed, libgamma_set_ramps_any_fun *);
-
-
-#endif
diff --git a/src/lib/libgamma-error.c.gpp b/src/lib/libgamma-error.c.gpp
deleted file mode 100644
index d43f336..0000000
--- a/src/lib/libgamma-error.c.gpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- c -*- */
-/* See LICENSE file for copyright and license details. */
-#include "libgamma-error.h"
-
-
-#include <stddef.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-
-
-$>set -u
-$>cd src/extract
-$>export PATH=".:${PATH}"
-
-
-
-/**
- * Group that the user needs to be a member of if
- * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
- */
-#ifndef __WIN32__
-__thread gid_t libgamma_group_gid = 0;
-gid_t
-libgamma_group_gid_get(void)
-{
- return libgamma_group_gid;
-}
-void
-libgamma_group_gid_set(gid_t value)
-{
- libgamma_group_gid = value;
-}
-#else
-short libgamma_group_gid = 0;
-#endif
-
-/**
- * Group that the user needs to be a member of if
- * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned,
- * `NULL` if the name of the group `libgamma_group_gid`
- * cannot be determined
- */
-#ifndef __WIN32__
-__thread const char *libgamma_group_name = NULL;
-const char *
-libgamma_group_name_get(void) {
- return libgamma_group_name;
-}
-void
-libgamma_group_name_set(const char *value)
-{
- libgamma_group_name = value;
-}
-#else
-const char *libgamma_group_name = NULL;
-#endif
-
-
-
-/**
- * Prints an error to stderr in a `perror` fashion,
- * however this function will not translate the `libgamma`
- * errors into human-readable strings, it will simply
- * print the name of the error. If the value `error_code`
- * is the value of `LIBGAMMA_ERRNO_SET`, `perror` will be
- * used to print the current error stored in `errno`.
- * If `error_code` is non-negative (an `errno` value`), that
- * value will be stored in `errno` and `perror` will be
- * used to print it. Additionally, if the `error_code` is
- * the value of `LIBGAMMA_DEVICE_REQUIRE_GROUP` the
- * required group will be printed with its numerical value
- * and, if known, its name.
- *
- * @param name The text to add at the beginning
- * @param value The error code, may be an `errno` value
- */
-void
-libgamma_perror(const char *name, int error_code)
-{
- const char *error;
- long int gid;
-
- if (error_code >= 0) {
- /* Print the stored errno value */
- errno = error_code;
- perror(name);
- } else if (error_code == LIBGAMMA_ERRNO_SET) {
- /* Print errno */
- perror(name);
- } else if (error_code == LIBGAMMA_DEVICE_REQUIRE_GROUP) {
- /* Print the error name and the required group membership */
- error = libgamma_name_of_error(error_code);
- gid = (long int)libgamma_group_gid;
- if (!libgamma_group_name) {
- /* Group name unknown */
- if (name && *name)
- fprintf(stderr, "%s: %s: %ld\n", name, error, gid);
- else
- fprintf(stderr, "%s: %ld\n", error, gid);
- } else {
- /* Group name known, ID is second class */
- if (name && *name)
- fprintf(stderr, "%s: %s: %s (%ld)\n", name, error, libgamma_group_name, gid);
- else
- fprintf(stderr, "%s: %s (%ld)\n", error, libgamma_group_name, gid);
- }
- } else if (error_code < LIBGAMMA_ERROR_MIN) {
- /* If the error code does not exist, print "(?)" */
- if (name && *name)
- fprintf(stderr, "%s: (?)\n", name);
- else
- fprintf(stderr, "(?)\n");
- } else {
- /* Print the name of the error */
- if (name && *name)
- fprintf(stderr, "%s: %s\n", name, libgamma_name_of_error(error_code));
- else
- fprintf(stderr, "%s\n", libgamma_name_of_error(error_code));
- }
-}
-
-
-/**
- * Returns the name of the definition associated with a `libgamma` error code
- *
- * @param value The error code
- * @return The name of the definition associated with the error code,
- * `NULL` if the error code does not exist; the return string
- * should not be `free`:d
- */
-const char *
-libgamma_name_of_error(int value)
-{
- /* Map from error codes to error names.
- The output of $(libgamma-error-extract --list)
- is sorted by error code in decreasing order */
- static const char* error_names[] = {
-$>for error in $(libgamma-error-extract --list); do
- "${error}",
-$>done
- };
-
- /* Return `NULL` if the error code is invalid */
- if (value < LIBGAMMA_ERROR_MIN || value >= 0)
- return NULL;
-
- /* Convert error code from {-1, -2, -3, ...} to {0, 1, 2, ...}
- * and look up the error's name and return it */
- return error_names[-value - 1];
-}
-
-
-/**
- * Return the value of a `libgamma` error definition refered to by name
- *
- * @param name The name of the definition associated with the error code
- * @return The error code, zero if the name does is `NULL`
- * or does not refer to a `libgamma` error
- */
-int
-libgamma_value_of_error(const char *name)
-{
- /* Return 0 (not a valid error code) if the error name is `NULL` */
- if (!name)
- return 0;
-
- /* Test error names against `name` and return the value of the match error */
-$>for error in $(libgamma-error-extract --list); do
- if (!strcmp(name, "${error}"))
- return ${error};
-$>done
-
- /* Return 0 (not a valid error code) if the error name is unknown */
- return 0;
-}
diff --git a/src/lib/libgamma-error.h b/src/lib/libgamma-error.h
deleted file mode 100644
index a026e79..0000000
--- a/src/lib/libgamma-error.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_ERROR_H
-#define LIBGAMMA_ERROR_H
-
-#if !defined(LIBGAMMA_CONFIG_H) && !defined(DEBUG)
-# error libgamma-error.h should not be included directly, include libgamma.h instead
-#endif
-
-
-#include <sys/types.h>
-
-#ifndef __GNUC__
-# define __attribute__(x)
-#endif
-
-
-/**
- * Group that the user needs to be a member of if
- * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned
- */
-#ifndef __WIN32__
-extern __thread gid_t libgamma_group_gid;
-gid_t libgamma_group_gid_get(void) __attribute__((pure));
-void libgamma_group_gid_set(gid_t value);
-#else
-extern short libgamma_group_gid;
-#endif
-
-/**
- * Group that the user needs to be a member of if
- * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned,
- * `NULL` if the name of the group `libgamma_group_gid`
- * cannot be determined
- */
-#ifndef __WIN32__
-extern __thread const char *libgamma_group_name;
-const char *libgamma_group_name_get(void) __attribute__((pure));
-void libgamma_group_name_set(const char *value);
-#else
-extern const char *libgamma_group_name;
-#endif
-
-
-/**
- * `errno` has be set with a standard error number
- * to indicate the what has gone wrong
- */
-#define LIBGAMMA_ERRNO_SET (-1)
-
-/**
- * The selected adjustment method does not exist
- * or has been excluded at compile-time
- */
-#define LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD (-2)
-
-/**
- * The selected site does not exist
- */
-#define LIBGAMMA_NO_SUCH_SITE (-3)
-
-/**
- * The selected partition does not exist
- */
-#define LIBGAMMA_NO_SUCH_PARTITION (-4)
-
-/**
- * The selected CRTC does not exist
- */
-#define LIBGAMMA_NO_SUCH_CRTC (-5)
-
-/**
- * Counter overflowed when counting the number
- * of available items
- */
-#define LIBGAMMA_IMPOSSIBLE_AMOUNT (-6)
-
-/**
- * The selected connector is disabled, it does
- * not have a CRTC
- */
-#define LIBGAMMA_CONNECTOR_DISABLED (-7)
-
-/**
- * The selected CRTC could not be opened,
- * reason unknown
- */
-#define LIBGAMMA_OPEN_CRTC_FAILED (-8)
-
-/**
- * The CRTC information field is not supported
- * by the adjustment method
- */
-#define LIBGAMMA_CRTC_INFO_NOT_SUPPORTED (-9)
-
-/**
- * Failed to read the current gamma ramps for
- * the selected CRTC, reason unknown
- */
-#define LIBGAMMA_GAMMA_RAMP_READ_FAILED (-10)
-
-/**
- * Failed to write the current gamma ramps for
- * the selected CRTC, reason unknown
- */
-#define LIBGAMMA_GAMMA_RAMP_WRITE_FAILED (-11)
-
-/**
- * The specified ramp sizes does not match the
- * ramps sizes returned by the adjustment methods
- * in response to the query/command
- */
-#define LIBGAMMA_GAMMA_RAMP_SIZE_CHANGED (-12)
-
-/**
- * The specified ramp sizes are not identical
- * which is required by the adjustment method
- *
- * (Only returned in debug mode)
- */
-#define LIBGAMMA_MIXED_GAMMA_RAMP_SIZE (-13)
-
-/**
- * The specified ramp sizes are not supported
- * by the adjustment method
- *
- * (Only returned in debug mode)
- */
-#define LIBGAMMA_WRONG_GAMMA_RAMP_SIZE (-14)
-
-/**
- * The adjustment method reported that the gamma
- * ramps size is 1, or perhaps even zero or negative
- */
-#define LIBGAMMA_SINGLETON_GAMMA_RAMP (-15)
-
-/**
- * The adjustment method failed to list
- * available CRTC:s, reason unknown
- */
-#define LIBGAMMA_LIST_CRTCS_FAILED (-16)
-
-/**
- * Failed to acquire mode resources from the
- * adjustment method
- */
-#define LIBGAMMA_ACQUIRING_MODE_RESOURCES_FAILED (-17)
-
-/**
- * The adjustment method reported that a negative
- * number of partitions exists in the site
- */
-#define LIBGAMMA_NEGATIVE_PARTITION_COUNT (-18)
-
-/**
- * The adjustment method reported that a negative
- * number of CRTC:s exists in the partition
- */
-#define LIBGAMMA_NEGATIVE_CRTC_COUNT (-19)
-
-/**
- * Device cannot be access becauses of
- * insufficient permissions
- */
-#define LIBGAMMA_DEVICE_RESTRICTED (-20)
-
-/**
- * Device cannot be access, reason unknown
- */
-#define LIBGAMMA_DEVICE_ACCESS_FAILED (-21)
-
-/**
- * Device cannot be access, membership of the
- * `libgamma_group_gid` (named by `libgamma_group_name`
- * (can be `NULL`, if so `errno` may have been set
- * to tell why)) is required
- */
-#define LIBGAMMA_DEVICE_REQUIRE_GROUP (-22)
-
-/**
- * The graphics card appear to have been removed
- */
-#define LIBGAMMA_GRAPHICS_CARD_REMOVED (-23)
-
-/**
- * The state of the requested information is unknown
- */
-#define LIBGAMMA_STATE_UNKNOWN (-24)
-
-/**
- * Failed to determine which connector the
- * CRTC belongs to
- */
-#define LIBGAMMA_CONNECTOR_UNKNOWN (-25)
-
-/**
- * The detected connector type is not listed
- * in this library and has to be updated
- */
-#define LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED (-26)
-
-/**
- * The detected subpixel order is not listed
- * in this library and has to be updated
- */
-#define LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED (-27)
-
-/**
- * The length of the EDID does not match that
- * of any supported EDID structure revision
- */
-#define LIBGAMMA_EDID_LENGTH_UNSUPPORTED (-28)
-
-/**
- * The magic number in the EDID does not match
- * that of any supported EDID structure revision
- */
-#define LIBGAMMA_EDID_WRONG_MAGIC_NUMBER (-29)
-
-/**
- * The EDID structure revision used by the
- * monitor is not supported
- */
-#define LIBGAMMA_EDID_REVISION_UNSUPPORTED (-30)
-
-/**
- * The gamma characteristics field in the EDID
- * is left unspecified
- *
- * (This could be considered a non-error)
- */
-#define LIBGAMMA_GAMMA_NOT_SPECIFIED (-31)
-
-/**
- * The checksum in the EDID is incorrect, all
- * request information has been provided
- * by you cannot count on it
- */
-#define LIBGAMMA_EDID_CHECKSUM_ERROR (-32)
-
-/**
- * Both of the errors `LIBGAMMA_GAMMA_NOT_SPECIFIED`
- * and `LIBGAMMA_EDID_CHECKSUM_ERROR` have occurred
- */
-#define LIBGAMMA_GAMMA_NOT_SPECIFIED_AND_EDID_CHECKSUM_ERROR (-33)
-
-/**
- * Failed to query the gamma ramps size from the
- * adjustment method, reason unknown
- */
-#define LIBGAMMA_GAMMA_RAMPS_SIZE_QUERY_FAILED (-34)
-
-/**
- * The selected partition could not be opened,
- * reason unknown
- */
-#define LIBGAMMA_OPEN_PARTITION_FAILED (-35)
-
-/**
- * The selected site could not be opened,
- * reason unknown
- */
-#define LIBGAMMA_OPEN_SITE_FAILED (-36)
-
-/**
- * Failed to query the adjustment method for
- * its protocol version, reason unknown
- */
-#define LIBGAMMA_PROTOCOL_VERSION_QUERY_FAILED (-37)
-
-/**
- * The adjustment method's version of its
- * protocol is not supported
- */
-#define LIBGAMMA_PROTOCOL_VERSION_NOT_SUPPORTED (-38)
-
-/**
- * The adjustment method failed to list
- * available partitions, reason unknown
- */
-#define LIBGAMMA_LIST_PARTITIONS_FAILED (-39)
-
-/**
- * Partition exists by index, but the partition
- * at that index does not exist
- */
-#define LIBGAMMA_NULL_PARTITION (-40)
-
-/**
- * There is not monitor connected to the
- * connector of the selected CRTC
- */
-#define LIBGAMMA_NOT_CONNECTED (-41)
-
-/**
- * Data extraction from a reply from the
- * adjustment method failed, reason unknown
- */
-#define LIBGAMMA_REPLY_VALUE_EXTRACTION_FAILED (-42)
-
-/**
- * No EDID property was found on the output
- */
-#define LIBGAMMA_EDID_NOT_FOUND (-43)
-
-/**
- * Failed to list properties on the output,
- * reason unknown
- */
-#define LIBGAMMA_LIST_PROPERTIES_FAILED (-44)
-
-/**
- * Failed to query a property's value from
- * the output, reason unknown
- */
-#define LIBGAMMA_PROPERTY_VALUE_QUERY_FAILED (-45)
-
-/**
- * A request for information on an output
- * failed, reason unknown
- */
-#define LIBGAMMA_OUTPUT_INFORMATION_QUERY_FAILED (-46)
-
-
-
-/**
- * The number of the libgamma error with the
- * lowest number. If this is lower than the
- * number your program thinks it should be sould
- * update your program for new errors.
- */
-#define LIBGAMMA_ERROR_MIN (-46)
-
-
-
-/**
- * Prints an error to stderr in a `perror` fashion,
- * however this function will not translate the `libgamma`
- * errors into human-readable strings, it will simply
- * print the name of the error. If the value `error_code`
- * is the value of `LIBGAMMA_ERRNO_SET`, `perror` will be
- * used to print the current error stored in `errno`.
- * If `error_code` is non-negative (an `errno` value`), that
- * value will be stored in `errno` and `perror` will be
- * used to print it. Additionally, if the `error_code` is
- * the value of `LIBGAMMA_DEVICE_REQUIRE_GROUP` the
- * required group will be printed with its numerical value
- * and, if known, its name.
- *
- * @param name The text to add at the beginning
- * @param error_code The error code, may be an `errno` value
- */
-void libgamma_perror(const char *, int);
-
-/**
- * Returns the name of the definition associated with a `libgamma` error code
- *
- * @param value The error code
- * @return The name of the definition associated with the error code,
- * `NULL` if the error code does not exist. The return string
- * should not be `free`:d.
- */
-const char *libgamma_name_of_error(int) __attribute__((const));
-
-/**
- * Return the value of a `libgamma` error definition refered to by name
- *
- * @param name The name of the definition associated with the error code
- * @return The error code, zero if the name is `NULL`
- * or does not refer to a `libgamma` error
- */
-int libgamma_value_of_error(const char *) __attribute__((const));
-
-
-
-#ifndef __GNUC__
-# undef __attribute__
-#endif
-
-#endif
diff --git a/src/lib/libgamma-facade.c.gpp b/src/lib/libgamma-facade.c.gpp
deleted file mode 100644
index 9f90ed6..0000000
--- a/src/lib/libgamma-facade.c.gpp
+++ /dev/null
@@ -1,1097 +0,0 @@
-/* -*- c -*- */
-/* See LICENSE file for copyright and license details. */
-#include "libgamma-facade.h"
-
-#include "libgamma-error.h"
-#include "libgamma-method.h"
-#include "gamma-helper.h"
-
-
-/* Initialise the general preprocessor */
-$>cd src/extract
-$>export PATH=".:${PATH}"
-
-/* Some general preprocessor we will use frequently */
-$<
-get-methods ()
-{
- ./libgamma-method-extract --list --method | cut -d _ -f 1,2 --complement
-}
-lowercase ()
-{
- echo "$*" | sed -e y/QWERTYUIOPASDFGHJKLZXCVBNM/qwertyuiopasdfghjklzxcvbnm/ | sed -e s:core_graphics:cg:g
-}
-$>
-
-/* Include all adjustment methods that are enabled at compile-time. */
-$>for method in $(get-methods); do
-#ifdef HAVE_LIBGAMMA_METHOD_${method}
-# include "gamma-$(lowercase $method | sed -e s:_:-:g).h"
-# ifndef HAVE_LIBGAMMA_METHODS
-# define HAVE_LIBGAMMA_METHODS
-# endif
-#endif
-$>done
-
-#include <unistd.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-
-/* Some things to reduce warnings when we do
- * not have any adjustment methods enabled */
-#ifndef HAVE_LIBGAMMA_METHODS
-# define HAVE_NO_LIBGAMMA_METHODS
-# ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
-# endif
-#endif
-
-
-
-#ifdef HAVE_LIBGAMMA_METHODS
-# ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
-/**
- * Test whether a file descriptor refers to a VT
- *
- * @param fd The file descriptor
- * @return Whether the file descriptor refers to a VT
- */
-static int
-libgamma_is_vt_proper(int fd)
-{
- char buf[32], digit0;
-
- /* Get TTY */
- if (ttyname_r(fd, buf, sizeof(buf) / sizeof(char)))
- return 0;
-
- /* Validate TTY path */
- if (!strcmp(buf, "/dev/console"))
- return 1;
- if (strstr(buf, "/dev/tty") != buf)
- return 0;
-
- /* Validate TTY name */
- digit0 = buf[strlen("/dev/tty")];
- return '1' <= digit0 && digit0 <= '9';
-}
-# endif
-
-
-/**
- * Test the availability of an adjustment method
- *
- * @param method The adjustment method
- * @param operation Allowed values:
- * 0: Pass if the environment suggests it will work but is not fake
- * 1: Pass if the environment suggests it will work
- * 2: Pass if real and not fake
- * 3: Pass if real
- * 4: Always pass
- * Other values invoke undefined behaviour
- * @return Whether the test passed
- */
-static int
-libgamma_list_method_test(int method, int operation)
-{
- libgamma_method_capabilities_t caps;
- libgamma_method_capabilities(&caps, method);
-
- switch (operation) {
- case 0:
- /* Methods that the environment suggests will work, excluding fake */
- if (caps.fake)
- return 0;
- /* fall through */
-
- case 1:
- /* Methods that the environment suggests will work, including fake */
- if (!caps.real)
- return 0;
-#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
- if (method == LIBGAMMA_METHOD_LINUX_DRM) {
- return libgamma_is_vt_proper(STDIN_FILENO) ||
- libgamma_is_vt_proper(STDOUT_FILENO) ||
- libgamma_is_vt_proper(STDERR_FILENO);
- }
-#endif
-#ifdef HAVE_LIBGAMMA_METHOD_DUMMY
- if (method == LIBGAMMA_METHOD_DUMMY)
- return 0;
-#endif
- return caps.default_site_known;
-
- case 2:
- /* All real non-fake methods */
- return caps.real && !caps.fake;
-
- case 3:
- /* All real methods */
- return caps.real;
-
- default:
- /* All methods */
- return 1;
- }
-}
-#endif
-
-
-/**
- * List available adjustment methods by their order of preference based on the environment
- *
- * @param methods Output array of methods, should be able to hold `LIBGAMMA_METHOD_COUNT` elements
- * @param buf_size The number of elements that fits in `methods`, it should be `LIBGAMMA_METHOD_COUNT`,
- * This is used to avoid writing outside the output buffer if this library adds new
- * adjustment methods without the users of the library recompiling
- * @param operation Allowed values:
- * 0: Methods that the environment suggests will work, excluding fake
- * 1: Methods that the environment suggests will work, including fake
- * 2: All real non-fake methods
- * 3: All real methods
- * 4: All methods
- * Other values invoke undefined behaviour
- * @return The number of element that have been stored in `methods`, or should
- * have been stored if the buffer was large enough.
- */
-size_t
-libgamma_list_methods(int *restrict methods, size_t buf_size, int operation)
-{
-#ifdef HAVE_NO_LIBGAMMA_METHODS
- (void) methods;
- (void) buf_size;
- (void) operation;
- return 0;
-#else
- size_t n = 0;
-
-$>for method in $(get-methods); do
-#ifdef HAVE_LIBGAMMA_METHOD_${method}
- if (libgamma_list_method_test(LIBGAMMA_METHOD_${method}, operation) && n++ < buf_size)
- methods[n - 1] = LIBGAMMA_METHOD_${method};
-#endif
-$>done
-
- return n;
-#endif
-}
-
-
-/**
- * Check whether an adjustment method is available, non-existing (invalid) methods will be
- * identified as not available under the rationale that the library may be out of date
- *
- * @param method The adjustment method
- * @return Whether the adjustment method is available
- */
-int
-libgamma_is_method_available(int method)
-{
-#ifdef HAVE_NO_LIBGAMMA_METHODS
- (void) method;
- return 0;
-#else
- switch (method) {
-$>for method in $(get-methods); do
-#ifdef HAVE_LIBGAMMA_METHOD_${method}
- case LIBGAMMA_METHOD_${method}:
-#endif
-$>done
- return 1;
-
- default:
- return 0;
- }
-#endif
-}
-
-
-/**
- * Call the adjustment method's implementation of the called function
- *
- * @param 1 The adjustment method, you may use `.` instead of `->` when resolving it
- * @param 2 `return` if the function returns a value, `break` otherwise
- * @param 3 The base name of the function to call, that is, the name of the function
- * this is expended into without the libgamma namespace prefix
- * @param * The function's parameters
- */
-$<switch ()
-$>{
- /* Read out macro's parameters */
-$<method="${1//./->}"
- ctrl=$2
- fun=$3
- shift 3
- params="$*"
-$>params="${params// /, }"
-
- switch (${method}) {
-$>for adjmethod in $(get-methods); do
-#ifdef HAVE_LIBGAMMA_METHOD_${adjmethod}
- case LIBGAMMA_METHOD_${adjmethod}:
- /* Call the adjustment method's implementation, either
- * return or break after it depending on macro parameter's */
-$> if [ $ctrl = return ]; then
- return
- libgamma_$(lowercase $adjmethod)_${fun}(${params});
-$> elif [ ! $ctrl = return ]; then
- break;
-$> fi
-#endif
-$>done
-
- default:
- /* If the adjustment method does not exists, either return
- * that error, or do nothing because the function this is
- * expanded into does return errors */
-$>if [ $ctrl = return ]; then
- return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
-$>else
- /* Method does not exists/excluded at compile-time.
- * We will assume that this is not done... */
- break;
-$>fi
- }
-$>}
-
-
-/**
- * Return the capabilities of an adjustment method
- *
- * @param this The data structure to fill with the method's capabilities
- * @param method The adjustment method (display server and protocol)
- */
-void
-libgamma_method_capabilities(libgamma_method_capabilities_t *restrict this, int method)
-{
- memset(this, 0, sizeof(libgamma_method_capabilities_t));
-$>switch method break method_capabilities this
-}
-
-
-/**
- * Return the default site for an adjustment method
- *
- * @param method The adjustment method (display server and protocol)
- * @return The default site, `NULL` if it cannot be determined or
- * if multiple sites are not supported by the adjustment
- * method; this value should not be `free`:d
- */
-char *
-libgamma_method_default_site(int method)
-{
- const char *restrict var = libgamma_method_default_site_variable(method);
- char *restrict env;
-
- /* Return `NULL` there is not variable to read */
- if (!var)
- return NULL;
-
- /* Read the variable */
- env = getenv(var);
- /* Return `NULL` if it does not exist (or is empty) */
- if (!env || !*env)
- return NULL;
-
- /* Return the variable's value */
- return env;
-}
-
-
-/**
- * Return the default variable that determines
- * the default site for an adjustment method
- *
- * @param method The adjustment method (display server and protocol)
- * @return The environ variables that is used to determine the
- * default site. `NULL` if there is none, that is, if
- * the method does not support multiple sites.
- * This value should not be `free`:d.
- */
-const char *
-libgamma_method_default_site_variable(int method)
-{
- switch (method) {
-#ifdef HAVE_LIBGAMMA_METHOD_X_RANDR
- case LIBGAMMA_METHOD_X_RANDR:
- return "DISPLAY";
-#endif
-#ifdef HAVE_LIBGAMMA_METHOD_X_VIDMODE
- case LIBGAMMA_METHOD_X_VIDMODE:
- return "DISPLAY";
-#endif
- default:
- return NULL;
- }
-}
-
-
-/**
- * Initialise an allocated site state
- *
- * @param this The site state to initialise
- * @param method The adjustment method (display server and protocol)
- * @param site The site identifier, unless it is `NULL` it must a
- * `free`:able. Once the state is destroyed the library
- * will attempt to free it. There you should not free
- * it yourself, and it must not be a string constant
- * or allocated on the stack. Note however that it will
- * not be `free`:d if this function fails.
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_site_initialise(libgamma_site_state_t *restrict this, int method, char *restrict site)
-{
- this->method = method;
- this->site = site;
-$>switch method return site_initialise this site
-}
-
-
-/**
- * Release all resources held by a site state
- *
- * @param this The site state
- */
-void
-libgamma_site_destroy(libgamma_site_state_t *restrict this)
-{
-$>switch this.method break site_destroy this
- free(this->site);
-}
-
-
-/**
- * Release all resources held by a site state
- * and free the site state pointer
- *
- * @param this The site state
- */
-void
-libgamma_site_free(libgamma_site_state_t *restrict this)
-{
- libgamma_site_destroy(this);
- free(this);
-}
-
-
-/**
- * Restore the gamma ramps all CRTC:s with a site to the system settings
- *
- * @param this The site state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_site_restore(libgamma_site_state_t *restrict this)
-{
-$>switch this.method return site_restore this
-}
-
-
-
-/**
- * Initialise an allocated partition state
- *
- * @param this The partition state to initialise
- * @param site The site state for the site that the partition belongs to
- * @param partition The index of the partition within the site
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_partition_initialise(libgamma_partition_state_t *restrict this, libgamma_site_state_t *restrict site, size_t partition)
-{
- this->site = site;
- this->partition = partition;
-$>switch site.method return partition_initialise this site partition
-}
-
-
-/**
- * Release all resources held by a partition state
- *
- * @param this The partition state
- */
-void
-libgamma_partition_destroy(libgamma_partition_state_t *restrict this)
-{
-$>switch this.site.method break partition_destroy this
-}
-
-
-/**
- * Release all resources held by a partition state
- * and free the partition state pointer
- *
- * @param this The partition state
- */
-void
-libgamma_partition_free(libgamma_partition_state_t *restrict this)
-{
- libgamma_partition_destroy(this);
- free(this);
-}
-
-
-/**
- * Restore the gamma ramps all CRTC:s with a partition to the system settings
- *
- * @param this The partition state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_partition_restore(libgamma_partition_state_t *restrict this)
-{
-$>switch this.site.method return partition_restore this
-}
-
-
-
-/**
- * Initialise an allocated CRTC state
- *
- * @param this The CRTC state to initialise
- * @param partition The partition state for the partition that the CRTC belongs to
- * @param crtc The index of the CRTC within the partition
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_crtc_initialise(libgamma_crtc_state_t *restrict this, libgamma_partition_state_t *restrict partition, size_t crtc)
-{
- this->partition = partition;
- this->crtc = crtc;
-$>switch partition.site.method return crtc_initialise this partition crtc
-}
-
-
-/**
- * Release all resources held by a CRTC state
- *
- * @param this The CRTC state
- */
-void
-libgamma_crtc_destroy(libgamma_crtc_state_t *restrict this)
-{
-$>switch this.partition.site.method break crtc_destroy this
-}
-
-
-/**
- * Release all resources held by a CRTC state
- * and free the CRTC state pointer
- *
- * @param this The CRTC state
- */
-void
-libgamma_crtc_free(libgamma_crtc_state_t *restrict this)
-{
- libgamma_crtc_destroy(this);
- free(this);
-}
-
-
-/**
- * Restore the gamma ramps for a CRTC to the system settings for that CRTC
- *
- * @param this The CRTC state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_crtc_restore(libgamma_crtc_state_t *restrict this)
-{
-$>switch this.partition.site.method return crtc_restore this
-}
-
-
-
-/**
- * Read information about a CRTC
- *
- * @param this Instance of a data structure to fill with the information about the CRTC
- * @param crtc The state of the CRTC whose information should be read
- * @param fields OR:ed identifiers for the information about the CRTC that should be read
- * @return Zero on success, -1 on error; on error refer to the error reports in `this`
- */
-int
-libgamma_get_crtc_information(libgamma_crtc_information_t *restrict this, libgamma_crtc_state_t *restrict crtc, int32_t fields)
-{
-#ifdef HAVE_NO_LIBGAMMA_METHODS
- (void) fields;
-#endif
- this->edid = NULL;
- this->connector_name = NULL;
-$>switch crtc.partition.site.method return get_crtc_information this crtc fields
-}
-
-
-/**
- * Release all resources in an information data structure for a CRTC
- *
- * @param this The CRTC information
- */
-void
-libgamma_crtc_information_destroy(libgamma_crtc_information_t *restrict this)
-{
- free(this->edid);
- free(this->connector_name);
-}
-
-
-/**
- * Release all resources in an information data structure for a CRTC
- * and free the data structure pointer
- *
- * @param this The CRTC information
- */
-void
-libgamma_crtc_information_free(libgamma_crtc_information_t *restrict this)
-{
- libgamma_crtc_information_destroy(this);
- free(this);
-}
-
-
-/**
- * Convert a raw representation of an EDID to a hexadecimal representation
- *
- * @param 1 Casing name
- * @param 2 The hexadecimal alphabet
- * @param edid The EDID in raw representation
- * @param length The length of `edid`
- * @return The EDID in hexadecimal representation
- * `NULL` on allocation error, `errno` will be set accordingly
- */
-$>behex_edid ()
-$>{
-char *
-libgamma_behex_edid_${1}(const unsigned char *restrict edid, size_t length)
-{
- char *restrict out;
- size_t i;
-
- /* Allocate memory area for the output string */
- out = malloc((length * 2 + 1) * sizeof(char));
- if (!out)
- return NULL;
-
- /* Translate from raw octets to hexadecimal */
- for (i = 0; i < length; i++) {
- out[i * 2 + 0] = "${2}"[(edid[i] >> 4) & 15];
- out[i * 2 + 1] = "${2}"[(edid[i] >> 0) & 15];
- }
- /* NUL-terminate the output string */
- out[length * 2] = '\0';
-
- return out;
-}
-$>}
-
-
-/**
- * Convert a raw representation of an EDID to a lowercase hexadecimal representation
- *
- * @param edid The EDID in raw representation
- * @param length The length of `edid`
- * @return The EDID in lowercase hexadecimal representation,
- * `NULL` on allocation error, `errno` will be set accordingly
- */
-$>behex_edid lowercase 0123456789abcdef
-
-
-/**
- * Convert a raw representation of an EDID to an uppercase hexadecimal representation
- *
- * @param edid The EDID in raw representation
- * @param length The length of `edid`
- * @return The EDID in uppercase hexadecimal representation,
- * NULL` on allocation error, `errno` will be set accordingly
- */
-$>behex_edid uppercase 0123456789ABCDEF
-
-
-/**
- * Convert an hexadecimal representation of an EDID to a raw representation
- *
- * @param edid The EDID in hexadecimal representation
- * @return The EDID in raw representation, it will be half the length
- * of `edid` (the input value); `NULL` on allocation error or
- * if the EDID is malformated, `errno` will be set accordingly
- */
-unsigned char *
-libgamma_unhex_edid(const char *restrict edid)
-{
-#define not_range(lower, V, upper) (V < lower || upper < V)
-#define is_not_hex(V) (not_range('0', V, '9') && not_range('a', V, 'f') && not_range('A', V, 'F'))
-
- unsigned char *restrict out;
- size_t i, n = strlen(edid);
- char a, b;
-
- /* Check that the length of the strings is even,
- * otherwise it cannot represent bytes */
- if (n & 1) {
- errno = EINVAL;
- return NULL;
- }
-
- /* Allocate memory area for output octet array */
- n /= 2 * sizeof(unsigned char);
- out = malloc(n);
- if (!out)
- return NULL;
-
- /* Convert to raw octet array */
- for (i = 0; i < n; i++) {
- /* Get the next character pair that, it represents an octet. */
- a = edid[i * 2 + 0];
- b = edid[i * 2 + 1];
-
- /* Verify that the input is in hexadecimal */
- if (is_not_hex(a) || is_not_hex(b)) {
- free(out);
- errno = EINVAL;
- return NULL;
- }
-
- /* Convert each chararacter to raw format */
- a = (char)((a & 15) + (a > '9' ? 9 : 0));
- b = (char)((b & 15) + (b > '9' ? 9 : 0));
-
- /* Combine the two characters into one octet */
- out[i] = (unsigned char)((a << 4) | b);
- }
-
- return out;
-
-#undef is_hex
-#undef not_range
-}
-
-
-/**
- * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_crtc_get_gamma_ramps16(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps16_t *restrict ramps)
-{
- libgamma_gamma_ramps_any_t ramps_;
-
-#ifdef HAVE_NO_LIBGAMMA_METHODS
- (void) ramps;
-#endif
-
- switch (this->partition->site->method) {
- /* Methods other than Quartz/CoreGraphics uses 16-bit integers */
-$>for method in $(get-methods | grep -v QUARTZ_CORE_GRAPHICS); do
-#ifdef HAVE_LIBGAMMA_METHOD_${method}
- case LIBGAMMA_METHOD_${method}:
- return libgamma_$(lowercase $method)_crtc_get_gamma_ramps16(this, ramps);
-#endif
-
- /* The Quartz/CoreGraphics method uses single precision float */
-$>done
-#ifdef HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
- case LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS:
- ramps_.bits16 = *ramps;
- return libgamma_translated_ramp_get(this, &ramps_, 16, -1, libgamma_crtc_get_gamma_rampsf);
-#endif
-
- /* The selected method does not exist */
- default:
- return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
- }
-}
-
-
-/**
- * Set the gamma ramps for a CRTC, 16-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int
-libgamma_crtc_set_gamma_ramps16(libgamma_crtc_state_t *restrict this, libgamma_gamma_ramps16_t ramps)
-{
- libgamma_gamma_ramps_any_t ramps_;
-
-#ifdef HAVE_NO_LIBGAMMA_METHODS
- (void) ramps;
-#endif
-
- switch (this->partition->site->method) {
- /* Methods other than Quartz/CoreGraphics uses 16-bit integers */
-$>for method in $(get-methods | grep -v QUARTZ_CORE_GRAPHICS); do
-#ifdef HAVE_LIBGAMMA_METHOD_${method}
- case LIBGAMMA_METHOD_${method}:
- return libgamma_$(lowercase $method)_crtc_set_gamma_ramps16(this, ramps);
-#endif
-$>done
-
- /* The Quartz/CoreGraphics method uses single precision float */
-#ifdef HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
- case LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS:
- ramps_.bits16 = ramps;
- return libgamma_translated_ramp_set(this, ramps_, 16, -1, libgamma_crtc_set_gamma_rampsf);
-#endif
-
- /* The selected method does not exist. */
- default:
- return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD;
- }
-}
-
-
-
-/**
- * Set or get the gamma ramps for a CRTC, non-16-bit gamma-depth version
- *
- * @param 1 Either `get` or `set`, for the action that the name of value implies
- * @param 2 The `ramp*` pattern for the ramp structure and function to call
- * @param 3 Either of `bit8`, `bit16`, `bit32`, `bit64`, `float_single`, `float_double`;
- * rather self-explanatory
- * @param 4 The number of bits in the gamma depth, -1 for single precision float,
- * (`float`) and -2 for double percition float (`double`)
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply, or
- * the gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps ()
-$>{
-$<action=$1
- ramps=$2
- type=$3
- bits=$4
- p=
- if [ $action = get ]; then
- p='*'
- fi
-$>
-int
-libgamma_crtc_${action}_gamma_${ramps}(libgamma_crtc_state_t *restrict this, libgamma_gamma_${ramps}_t${p:+* restrict} ramps)
-{
- libgamma_gamma_ramps_any_t ramps_;
- switch (this->partition->site->method) {
- /* The dummy method supports all ramp depths */
-#ifdef HAVE_LIBGAMMA_METHOD_DUMMY
- case LIBGAMMA_METHOD_DUMMY:
- return libgamma_dummy_crtc_${action}_gamma_${ramps}(this, ramps);
-#endif
-
- /* The Quartz/CoreGraphics method uses single precision float */
-#ifdef HAVE_LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS
- case LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS:
-$>if [ $bits = -1 ]; then
- /* Single precision float is used */
- return libgamma_quartz_cg_crtc_${action}_gamma_${ramps}(this, ramps);
-$>else
- /* Something else is used and we convert to Single precision float */
- ramps_.${type} = ${p}ramps;
- return libgamma_translated_ramp_${action}(this, ${p:+&}ramps_, ${bits}, -1, libgamma_crtc_${action}_gamma_rampsf);
-$>fi
-#endif
-
- /* Other methods use 16-bit integers. */
- default:
- ramps_.${type} = ${p}ramps;
- return libgamma_translated_ramp_${action}(this, ${p:+&}ramps_, ${bits}, 16, libgamma_crtc_${action}_gamma_ramps16);
- }
-}
-$>}
-
-
-
-/**
- * Get the current gamma ramps for a CRTC, 8-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps get ramps8 bits8 8
-
-
-/**
- * Set the gamma ramps for a CRTC, 32-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps set ramps8 bits8 8
-
-
-
-/**
- * Get the current gamma ramps for a CRTC, 32-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps get ramps32 bits32 32
-
-
-/**
- * Set the gamma ramps for a CRTC, 32-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps set ramps32 bits32 32
-
-
-
-/**
- * Get the current gamma ramps for a CRTC, 64-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps get ramps64 bits64 64
-
-
-/**
- * Set the gamma ramps for a CRTC, 64-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps set ramps64 bits64 64
-
-
-/**
- * Get the current gamma ramps for a CRTC, `float` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps get rampsf float_single -1
-
-
-/**
- * Set the gamma ramps for a CRTC, `float` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps set rampsf float_single -1
-
-
-
-/**
- * Get the current gamma ramps for a CRTC, `double` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps get rampsd float_double -2
-
-
-/**
- * Set the gamma ramps for a CRTC, `double` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_get_gamma_ramps set rampsd float_double -2
-
-
-
-/**
- * Set the gamma ramps for a CRTC
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param 1 The data type for the ramp stop elements
- * @param 2 The `ramp*` pattern for the ramp structure and function to call
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f ()
-$>{
-int
-libgamma_crtc_set_gamma_${2}_f(libgamma_crtc_state_t *restrict this, libgamma_gamma_${2}_fun *red_function,
- libgamma_gamma_${2}_fun *green_function, libgamma_gamma_${2}_fun *blue_function)
-{
- libgamma_crtc_information_t info;
- libgamma_gamma_${2}_t ramps;
- size_t i, n;
- int e;
-
- /* Get the size of the gamma ramps */
- if (libgamma_get_crtc_information(&info, this, LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) {
- e = info.gamma_size_error;
- if (e < 0)
- return e;
- errno = e;
- return LIBGAMMA_ERRNO_SET;
- }
-
- /* Copy the size of the gamma ramps and calculte the grand size */
- n = ramps. red_size = info. red_gamma_size;
- n += ramps.green_size = info.green_gamma_size;
- n += ramps. blue_size = info. blue_gamma_size;
-
- /* Allocate gamma ramps */
- ramps. red = malloc(n * sizeof(${1}));
- ramps.green = &ramps. red[ramps. red_size];
- ramps. blue = &ramps.green[ramps.green_size];
- if (!ramps.red)
- return LIBGAMMA_ERRNO_SET;
-
- /* Generate the gamma ramp for the red chennel */
- for (i = 0, n = ramps.red_size; i < n; i++)
- ramps.red[i] = red_function((float)i / (float)(n - 1));
-
- /* Generate the gamma ramp for the green chennel */
- for (i = 0, n = ramps.green_size; i < n; i++)
- ramps.green[i] = green_function((float)i / (float)(n - 1));
-
- /* Generate the gamma ramp for the blue chennel */
- for (i = 0, n = ramps.blue_size; i < n; i++)
- ramps.blue[i] = blue_function((float)i / (float)(n - 1));
-
- /* Apply the gamma ramps */
- e = libgamma_crtc_set_gamma_${2}(this, ramps);
- free(ramps.red);
- return e;
-}
-$>}
-
-
-/**
- * Set the gamma ramps for a CRTC, 8-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f uint8_t ramps8
-
-
-/**
- * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f uint16_t ramps16
-
-
-/**
- * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f uint32_t ramps32
-
-
-/**
- * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f uint64_t ramps64
-
-
-/**
- * Set the gamma ramps for a CRTC, `float` function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f float rampsf
-
-
-/**
- * Set the gamma ramps for a CRTC, `double` function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-$>crtc_set_gamma_ramps_f double rampsd
-
-
-
-#ifdef HAVE_NO_LIBGAMMA_METHODS
-# ifdef __GNUC__
-# pragma GCC diagnostic pop
-# endif
-#endif
diff --git a/src/lib/libgamma-facade.h b/src/lib/libgamma-facade.h
deleted file mode 100644
index 596094c..0000000
--- a/src/lib/libgamma-facade.h
+++ /dev/null
@@ -1,537 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_FACADE_H
-#define LIBGAMMA_FACADE_H
-
-#if !defined(LIBGAMMA_CONFIG_H) && !defined(DEBUG)
-# error libgamma-facade.h should not be included directly, include libgamma.h instead
-#endif
-
-
-#include "libgamma-method.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef __GNUC__
-# define __attribute__(x)
-#endif
-
-
-
-/**
- * Mapping function from [0, 1] float encoding value to [0, 2⁸ − 1] integer output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 2⁸ − 1] integer output value
- */
-typedef uint8_t libgamma_gamma_ramps8_fun(float);
-
-/**
- * Mapping function from [0, 1] float encoding value to [0, 2¹⁶ − 1] integer output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 2¹⁶ − 1] integer output value
- */
-typedef uint16_t libgamma_gamma_ramps16_fun(float);
-
-/**
- * Mapping function from [0, 1] float encoding value to [0, 2³² − 1] integer output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 2³² − 1] integer output value
- */
-typedef uint32_t libgamma_gamma_ramps32_fun(float);
-
-/**
- * Mapping function from [0, 1] float encoding value to [0, 2⁶⁴ − 1] integer output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 2⁶⁴ − 1] integer output value
- */
-typedef uint64_t libgamma_gamma_ramps64_fun(float);
-
-/**
- * Mapping function from [0, 1] float encoding value to [0, 1] float output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 1] float output value
- */
-typedef float libgamma_gamma_rampsf_fun(float);
-
-/**
- * Mapping function from [0, 1] double precision float encoding
- * value to [0, 1] double precision float output value
- *
- * @param encoding [0, 1] float encoding value
- * @return [0, 1] float output value
- */
-typedef double libgamma_gamma_rampsd_fun(double);
-
-
-
-/**
- * List available adjustment methods by their order of preference based on the environment
- *
- * @param methods Output array of methods, should be able to hold `LIBGAMMA_METHOD_COUNT` elements
- * @param buf_size The number of elements that fits in `methods`, it should be `LIBGAMMA_METHOD_COUNT`,
- * This is used to avoid writing outside the output buffer if this library adds new
- * adjustment methods without the users of the library recompiling
- * @param operation Allowed values:
- * 0: Methods that the environment suggests will work, excluding fake
- * 1: Methods that the environment suggests will work, including fake
- * 2: All real non-fake methods
- * 3: All real methods
- * 4: All methods
- * Other values invoke undefined behaviour
- * @return The number of element that have been stored in `methods`, or should
- * have been stored if the buffer was large enough
- */
-size_t libgamma_list_methods(int *restrict, size_t, int);
-
-/**
- * Check whether an adjustment method is available, non-existing (invalid) methods will be
- * identified as not available under the rationale that the library may be out of date
- *
- * @param method The adjustment method
- * @return Whether the adjustment method is available
- */
-int libgamma_is_method_available(int) __attribute__((const));
-
-/**
- * Return the capabilities of an adjustment method
- *
- * @param this The data structure to fill with the method's capabilities
- * @param method The adjustment method (display server and protocol)
- */
-void libgamma_method_capabilities(libgamma_method_capabilities_t *restrict, int);
-
-/**
- * Return the default site for an adjustment method
- *
- * @param method The adjustment method (display server and protocol)
- * @return The default site, `NULL` if it cannot be determined or
- * if multiple sites are not supported by the adjustment
- * method; this value should not be `free`:d
- */
-char *libgamma_method_default_site(int);
-
-/**
- * Return the default variable that determines
- * the default site for an adjustment method
- *
- * @param method The adjustment method (display server and protocol)
- * @return The environ variables that is used to determine the
- * default site, `NULL` if there is none, that is, if
- * the method does not support multiple sites; this
- * value should not be `free`:d
- */
-const char *libgamma_method_default_site_variable(int) __attribute__((const));
-
-
-/**
- * Initialise an allocated site state
- *
- * @param this The site state to initialise
- * @param method The adjustment method (display server and protocol)
- * @param site The site identifier, unless it is `NULL` it must a
- * `free`:able. Once the state is destroyed the library
- * will attempt to free it. There you should not free
- * it yourself, and it must not be a string constant
- * or allocate on the stack. Note however that it will
- * not be `free`:d if this function fails.
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_site_initialise(libgamma_site_state_t *restrict, int, char *restrict);
-
-/**
- * Release all resources held by a site state
- *
- * @param this The site state
- */
-void libgamma_site_destroy(libgamma_site_state_t *restrict);
-
-/**
- * Release all resources held by a site state
- * and free the site state pointer
- *
- * @param this The site state
- */
-void libgamma_site_free(libgamma_site_state_t *restrict);
-
-/**
- * Restore the gamma ramps all CRTC:s within a site to the system settings
- *
- * @param this The site state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_site_restore(libgamma_site_state_t *restrict);
-
-
-/**
- * Initialise an allocated partition state
- *
- * @param this The partition state to initialise
- * @param site The site state for the site that the partition belongs to
- * @param partition The index of the partition within the site
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_partition_initialise(libgamma_partition_state_t *restrict, libgamma_site_state_t *restrict, size_t);
-
-/**
- * Release all resources held by a partition state
- *
- * @param this The partition state
- */
-void libgamma_partition_destroy(libgamma_partition_state_t *restrict);
-
-/**
- * Release all resources held by a partition state
- * and free the partition state pointer
- *
- * @param this The partition state
- */
-void libgamma_partition_free(libgamma_partition_state_t *restrict);
-
-/**
- * Restore the gamma ramps all CRTC:s within a partition to the system settings
- *
- * @param this The partition state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_partition_restore(libgamma_partition_state_t *restrict);
-
-
-/**
- * Initialise an allocated CRTC state
- *
- * @param this The CRTC state to initialise
- * @param partition The partition state for the partition that the CRTC belongs to
- * @param crtc The index of the CRTC within the partition
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_initialise(libgamma_crtc_state_t *restrict, libgamma_partition_state_t *restrict, size_t);
-
-/**
- * Release all resources held by a CRTC state
- *
- * @param this The CRTC state
- */
-void libgamma_crtc_destroy(libgamma_crtc_state_t *restrict);
-
-/**
- * Release all resources held by a CRTC state
- * and free the CRTC state pointer
- *
- * @param this The CRTC state
- */
-void libgamma_crtc_free(libgamma_crtc_state_t *restrict);
-
-/**
- * Restore the gamma ramps for a CRTC to the system settings for that CRTC
- *
- * @param this The CRTC state
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_restore(libgamma_crtc_state_t *restrict);
-
-
-/**
- * Read information about a CRTC
- *
- * @param this Instance of a data structure to fill with the information about the CRTC
- * @param crtc The state of the CRTC whose information should be read
- * @param fields OR:ed identifiers for the information about the CRTC that should be read
- * @return Zero on success, -1 on error; on error refer to the error reports in `this`
- */
-int libgamma_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t);
-
-/**
- * Release all resources in an information data structure for a CRTC
- *
- * @param this The CRTC information
- */
-void libgamma_crtc_information_destroy(libgamma_crtc_information_t *restrict);
-
-/**
- * Release all resources in an information data structure for a CRTC
- * and free the data structure pointer
- *
- * @param this The CRTC information
- */
-void libgamma_crtc_information_free(libgamma_crtc_information_t *restrict);
-
-/**
- * Convert a raw representation of an EDID to a lowercase hexadecimal representation
- *
- * @param edid:const unsigned char* The EDID in raw representation
- * @param length:size_t The length of `edid`
- * @return :char* The EDID in lowercase hexadecimal representation,
- * `NULL` on allocation error, `errno` will be set accordingly
- */
-#define libgamma_behex_edid(edid, length) libgamma_behex_edid_lowercase((edid), (length))
-
-/**
- * Convert a raw representation of an EDID to a lowercase hexadecimal representation
- *
- * @param edid The EDID in raw representation
- * @param length The length of `edid`
- * @return The EDID in lowercase hexadecimal representation
- * `NULL` on allocation error, `errno` will be set accordingly
- */
-char *libgamma_behex_edid_lowercase(const unsigned char *restrict, size_t);
-
-/**
- * Convert a raw representation of an EDID to an uppercase hexadecimal representation
- *
- * @param edid The EDID in raw representation
- * @param length The length of `edid`
- * @return The EDID in uppercase hexadecimal representation,
- * NULL` on allocation error, `errno` will be set accordingly
- */
-char *libgamma_behex_edid_uppercase(const unsigned char *restrict, size_t);
-
-/**
- * Convert an hexadecimal representation of an EDID to a raw representation
- *
- * @param edid The EDID in hexadecimal representation
- * @return The EDID in raw representation, it will be half the length
- * of `edid` (the input value); `NULL` on allocation error or
- * if the EDID is malformated, `errno` will be set accordingly
- */
-unsigned char *libgamma_unhex_edid(const char *restrict);
-
-
-/**
- * Get the current gamma ramps for a CRTC, 8-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_ramps8(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_t *restrict);
-
-/**
- * Set the gamma ramps for a CRTC, 8-bit gamma-depth version.
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_ramps8(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_t);
-
-
-/**
- * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_ramps16(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_t *restrict);
-
-/**
- * Set the gamma ramps for a CRTC, 16-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_ramps16(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_t) __attribute__((hot));
-
-
-/**
- * Get the current gamma ramps for a CRTC, 32-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_ramps32(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_t *restrict);
-
-/**
- * Set the gamma ramps for a CRTC, 32-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_ramps32(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_t);
-
-
-/**
- * Get the current gamma ramps for a CRTC, 64-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_ramps64(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_t *restrict);
-
-/**
- * Set the gamma ramps for a CRTC, 64-bit gamma-depth version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_ramps64(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_t);
-
-
-/**
- * Set the gamma ramps for a CRTC, `float` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_rampsf(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_t);
-
-/**
- * Get the current gamma ramps for a CRTC, `float` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_rampsf(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_t *restrict);
-
-
-/**
- * Get the current gamma ramps for a CRTC, `double` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to fill with the current values
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_get_gamma_rampsd(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_t *restrict);
-
-/**
- * Set the gamma ramps for a CRTC, `double` version
- *
- * @param this The CRTC state
- * @param ramps The gamma ramps to apply
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-int libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_t);
-
-
-/**
- * Set the gamma ramps for a CRTC, 8-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold))
-int libgamma_crtc_set_gamma_ramps8_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_fun *,
- libgamma_gamma_ramps8_fun *, libgamma_gamma_ramps8_fun *);
-
-/**
- * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold))
-int libgamma_crtc_set_gamma_ramps16_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps16_fun *,
- libgamma_gamma_ramps16_fun *, libgamma_gamma_ramps16_fun *);
-
-/**
- * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold))
-int libgamma_crtc_set_gamma_ramps32_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps32_fun *,
- libgamma_gamma_ramps32_fun *, libgamma_gamma_ramps32_fun *);
-
-/**
- * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold));
-int libgamma_crtc_set_gamma_ramps64_f(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_fun *,
- libgamma_gamma_ramps64_fun *, libgamma_gamma_ramps64_fun *);
-
-/**
- * Set the gamma ramps for a CRTC, `float` function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold))
-int libgamma_crtc_set_gamma_rampsf_f(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_fun *,
- libgamma_gamma_rampsf_fun *, libgamma_gamma_rampsf_fun *);
-
-/**
- * Set the gamma ramps for a CRTC, `double` function version
- *
- * Note that this will probably involve the library allocating temporary data
- *
- * @param this The CRTC state
- * @param red_function The function that generates the gamma ramp for the red channel
- * @param green_function The function that generates the gamma ramp for the green channel
- * @param blue_function The function that generates the gamma ramp for the blue channel
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
- */
-__attribute__((cold))
-int libgamma_crtc_set_gamma_rampsd_f(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_fun *,
- libgamma_gamma_rampsd_fun *, libgamma_gamma_rampsd_fun *);
-
-
-#ifndef __GNUC__
-# undef __attribute__
-#endif
-
-#endif
diff --git a/src/lib/libgamma-method.c b/src/lib/libgamma-method.c
deleted file mode 100644
index cf9a23b..0000000
--- a/src/lib/libgamma-method.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "libgamma-method.h"
-
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_ramps8_initialise(libgamma_gamma_ramps8_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
- this->red = malloc(n * sizeof(uint8_t));
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps8_destroy(libgamma_gamma_ramps8_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps8_free(libgamma_gamma_ramps8_t *restrict this)
-{
- free(this->red);
- free(this);
-}
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_ramps16_initialise(libgamma_gamma_ramps16_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
-#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
- /* Valgrind complains about us reading uninitialize memory if we just use malloc */
- this->red = calloc(n, sizeof(uint16_t));
-#else
- this->red = malloc(n * sizeof(uint16_t));
-#endif
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps16_destroy(libgamma_gamma_ramps16_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps16_free(libgamma_gamma_ramps16_t *restrict this)
-{
- free(this->red);
- free(this);
-}
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_ramps32_initialise(libgamma_gamma_ramps32_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
- this->red = malloc(n * sizeof(uint32_t));
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps32_destroy(libgamma_gamma_ramps32_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps32_free(libgamma_gamma_ramps32_t *restrict this)
-{
- free(this->red);
- free(this);
-}
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_ramps64_initialise(libgamma_gamma_ramps64_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
- this->red = malloc(n * sizeof(uint64_t));
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps64_destroy(libgamma_gamma_ramps64_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_ramps64_free(libgamma_gamma_ramps64_t *restrict this)
-{
- free(this->red);
- free(this);
-}
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_rampsf_initialise(libgamma_gamma_rampsf_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
- this->red = malloc(n * sizeof(float));
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_rampsf_destroy(libgamma_gamma_rampsf_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_rampsf_free(libgamma_gamma_rampsf_t *restrict this)
-{
- free(this->red);
- free(this);
-}
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int
-libgamma_gamma_rampsd_initialise(libgamma_gamma_rampsd_t *restrict this)
-{
- size_t n = this->red_size + this->green_size + this->blue_size;
- this->red = malloc(n * sizeof(double));
- this->green = &this-> red[this-> red_size];
- this->blue = &this->green[this->green_size];
- return this->red ? 0 : -1;
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
- * initialises in the proper manner
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_rampsd_destroy(libgamma_gamma_rampsd_t *restrict this)
-{
- free(this->red);
-}
-
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
- * initialises in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void
-libgamma_gamma_rampsd_free(libgamma_gamma_rampsd_t *restrict this)
-{
- free(this->red);
- free(this);
-}
diff --git a/src/lib/libgamma-method.h b/src/lib/libgamma-method.h
deleted file mode 100644
index e2a35c6..0000000
--- a/src/lib/libgamma-method.h
+++ /dev/null
@@ -1,1323 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_METHOD_H
-#define LIBGAMMA_METHOD_H
-
-#if !defined(LIBGAMMA_CONFIG_H) && !defined(DEBUG)
-# error libgamma-method.h should not be included directly, include libgamma.h instead
-#endif
-
-
-#ifndef __GNUC__
-# define __attribute__(x)
-#endif
-
-#include <stddef.h>
-#include <stdint.h>
-
-
-
-/**
- * The identifier for the dummy adjustment method
- *
- * This method can be configured and is useful for
- * testing your program's ability to handle errors
- */
-#define LIBGAMMA_METHOD_DUMMY 0
-
-/**
- * The identifier for the adjustment method with
- * uses the RandR protocol under the X display server
- */
-#define LIBGAMMA_METHOD_X_RANDR 1
-
-/**
- * The identifier for the adjustment method with
- * uses the VidMode protocol under the X display server
- *
- * This is an older alternative to RandR that can
- * work on some drivers that are not supported by RandR,
- * however it can only control the primary CRTC per
- * screen (partition)
- */
-#define LIBGAMMA_METHOD_X_VIDMODE 2
-
-/**
- * The identifier for the Direct Rendering Manager
- * adjustment method that is available in Linux
- * (built in to the Linux kernel with a userland
- * library for access) and is a part of the
- * Direct Rendering Infrastructure.
- *
- * This adjustment method will work when you are
- * in non-graphical mode; however a display server
- * cannot be started while this is running, but it
- * can be started while a display server is running
- */
-#define LIBGAMMA_METHOD_LINUX_DRM 3
-
-/**
- * The identifier for the Graphics Device Interface
- * adjustment method that is available in Windows
- *
- * This method is not well tested; it can be compiled
- * to be available under X.org using a translation layer
- */
-#define LIBGAMMA_METHOD_W32_GDI 4
-
-/**
- * The identifier for the CoreGraphics adjustment
- * method that is available in Mac OS X that can
- * adjust gamma ramps under the Quartz display server
- *
- * This method is not well tested; it can be compiled
- * to be available under X.org using a translation layer
- */
-#define LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS 5
-
-
-/**
- * The index of the last gamma method, neither it
- * nor any index before it may actually be supported
- * as it could have been disabled at compile-time
- */
-#define LIBGAMMA_METHOD_MAX 5
-
-/**
- * The number adjustment methods provided by this library.
- * Note however that this includes adjstment methods that
- * have been removed at compile-time
- */
-#define LIBGAMMA_METHOD_COUNT (LIBGAMMA_METHOD_MAX + 1)
-
-
-
-/**
- * Capabilities of adjustment methods
- */
-typedef struct libgamma_method_capabilities {
- /**
- * OR of the CRTC information fields in `libgamma_crtc_information_t`
- * that may (but can fail) be read successfully
- */
- int32_t crtc_information;
-
- /**
- * Whether the default site is known, if true the site is integrated
- * to the system or can be determined using environment variables
- */
- unsigned default_site_known : 1;
-
- /**
- * Whether the adjustment method supports multiple sites rather
- * than just the default site
- */
- unsigned multiple_sites : 1;
-
- /**
- * Whether the adjustment method supports multiple partitions
- * per site
- */
- unsigned multiple_partitions : 1;
-
- /**
- * Whether the adjustment method supports multiple CRTC:s
- * per partition per site
- */
- unsigned multiple_crtcs : 1;
-
- /**
- * Whether the partition to graphics card is a bijection
- */
- unsigned partitions_are_graphics_cards : 1;
-
- /**
- * Whether the adjustment method supports `libgamma_site_restore`
- */
- unsigned site_restore : 1;
-
- /**
- * Whether the adjustment method supports `libgamma_partition_restore`
- */
- unsigned partition_restore : 1;
-
- /**
- * Whether the adjustment method supports `libgamma_crtc_restore`
- */
- unsigned crtc_restore : 1;
-
- /**
- * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size`
- * fields in `libgamma_crtc_information_t` will always have the same
- * values as each other for the adjustment method
- */
- unsigned identical_gamma_sizes : 1;
-
- /**
- * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size`
- * fields in `libgamma_crtc_information_t` will always be filled with the
- * same value for the adjustment method
- */
- unsigned fixed_gamma_size : 1;
-
- /**
- * Whether the `gamma_depth` field in `libgamma_crtc_information_t`
- * will always be filled with the same value for the adjustment method
- */
- unsigned fixed_gamma_depth : 1;
-
- /**
- * Whether the adjustment method will actually perform adjustments
- */
- unsigned real : 1;
-
- /**
- * Whether the adjustment method is implement using a translation layer
- */
- unsigned fake : 1;
-
- /**
- * Whether adjustments are undone when the process disconnects from
- * the display server
- */
- unsigned auto_restore : 1;
-
-} libgamma_method_capabilities_t;
-
-
-
-/**
- * Site state
- *
- * On operating systems that integrate a graphical environment
- * there is usually just one site. However, one systems with
- * pluggable graphics, like Unix-like systems such as GNU/Linux
- * and the BSD:s, there can usually be any (feasible) number of
- * sites. In X.org parlance they are called displays.
- */
-typedef struct libgamma_site_state {
- /**
- * Adjustment method implementation specific data.
- * You as a user of this library should not touch this.
- */
- void *data;
-
- /**
- * This field specifies, for the methods if this library,
- * which adjustment method (display server and protocol)
- * is used to adjust the gamma ramps
- */
- int method;
-
- /**
- * The site identifier. It can either be `NULL` or a string.
- * `NULL` indicates the default site. On systems like the
- * Unix-like systems, where the graphics are pluggable, this
- * is usually resolved by an environment variable, such as
- * "DISPLAY" for X.org.
- */
- char *site;
-
- /**
- * The number of partitions that is available on this site.
- * Probably the majority of display server only one partition
- * per site. However, X.org can, and traditional used to have
- * on multi-headed environments, multiple partitions per site.
- * In X.org partitions are called 'screens'. It is not to be
- * confused with monitor. A screen is a collection of monitors,
- * and the mapping from monitors to screens is a surjection.
- * On hardware-level adjustment methods, such as Direct
- * Rendering Manager, a partition is a graphics card.
- */
- size_t partitions_available;
-
-} libgamma_site_state_t;
-
-
-/**
- * Partition state
- *
- * Probably the majority of display server only one partition
- * per site. However, X.org can, and traditional used to have
- * on multi-headed environments, multiple partitions per site.
- * In X.org partitions are called 'screens'. It is not to be
- * confused with monitor. A screen is a collection of monitors,
- * and the mapping from monitors to screens is a surjection.
- * On hardware-level adjustment methods, such as Direct
- * Rendering Manager, a partition is a graphics card.
- */
-typedef struct libgamma_partition_state {
- /**
- * Adjustment method implementation specific data
- *
- * You as a user of this library should not touch this
- */
- void *data;
-
- /**
- * The site this partition belongs to
- */
- libgamma_site_state_t *site;
-
- /**
- * The index of the partition
- */
- size_t partition;
-
- /**
- * The number of CRTC:s that are available
- * under this partition
- *
- * Note that the CRTC:s are not necessarily
- * online.
- */
- size_t crtcs_available;
-
-} libgamma_partition_state_t;
-
-
-/**
- * Cathode ray tube controller state
- *
- * The CRTC controls the gamma ramps for the
- * monitor that is plugged in to the connector
- * that the CRTC belongs to
- */
-typedef struct libgamma_crtc_state {
- /**
- * Adjustment method implementation specific data
- *
- * You as a user of this library should not touch this
- */
- void *data;
-
- /**
- * The partition this CRTC belongs to
- */
- libgamma_partition_state_t *partition;
-
- /**
- * The index of the CRTC within its partition
- */
- size_t crtc;
-
-} libgamma_crtc_state_t;
-
-
-/**
- * Types for connectors
- */
-typedef enum libgamma_connector_type {
- /**
- * The adjustment method does not know the connector's type
- *
- * (This could be considered an error)
- */
- LIBGAMMA_CONNECTOR_TYPE_Unknown = 0,
-
- /**
- * Video Graphics Array (VGA)
- */
- LIBGAMMA_CONNECTOR_TYPE_VGA,
-
- /**
- * Digital Visual Interface, unknown type
- */
- LIBGAMMA_CONNECTOR_TYPE_DVI,
-
- /**
- * Digital Visual Interface, integrated (DVI-I)
- */
- LIBGAMMA_CONNECTOR_TYPE_DVII,
-
- /**
- * Digital Visual Interface, digital only (DVI-D)
- */
- LIBGAMMA_CONNECTOR_TYPE_DVID,
-
- /**
- * Digital Visual Interface, analogue only (DVI-A)
- */
- LIBGAMMA_CONNECTOR_TYPE_DVIA,
-
- /**
- * Composite video
- */
- LIBGAMMA_CONNECTOR_TYPE_Composite,
-
- /**
- * Separate Video (S-video)
- */
- LIBGAMMA_CONNECTOR_TYPE_SVIDEO,
-
- /**
- * Low-voltage differential signaling (LVDS)
- */
- LIBGAMMA_CONNECTOR_TYPE_LVDS,
-
- /**
- * Component video, usually separate cables for each channel
- */
- LIBGAMMA_CONNECTOR_TYPE_Component,
-
- /**
- * 9 pin DIN (Deutsches Institut für Normung) connector
- */
- LIBGAMMA_CONNECTOR_TYPE_9PinDIN,
-
- /**
- * DisplayPort
- */
- LIBGAMMA_CONNECTOR_TYPE_DisplayPort,
-
- /**
- * High-Definition Multimedia Interface (HDMI), unknown type
- */
- LIBGAMMA_CONNECTOR_TYPE_HDMI,
-
- /**
- * High-Definition Multimedia Interface, type A (HDMI-A)
- */
- LIBGAMMA_CONNECTOR_TYPE_HDMIA,
-
- /**
- * High-Definition Multimedia Interface, type B (HDMI-B)
- */
- LIBGAMMA_CONNECTOR_TYPE_HDMIB,
-
- /**
- * Television, unknown connector
- */
- LIBGAMMA_CONNECTOR_TYPE_TV,
-
- /**
- * Embedded DisplayPort (eDP)
- */
- LIBGAMMA_CONNECTOR_TYPE_eDP,
-
- /**
- * A virtual connector
- */
- LIBGAMMA_CONNECTOR_TYPE_VIRTUAL,
-
- /**
- * Display Serial Interface (DSI)
- */
- LIBGAMMA_CONNECTOR_TYPE_DSI,
-
- /**
- * LFP connector
- *
- * (What is this?)
- */
- LIBGAMMA_CONNECTOR_TYPE_LFP
-
-} libgamma_connector_type_t;
-
-/**
- * The number of values defined in `libgamma_connector_type_t`
- */
-#define LIBGAMMA_CONNECTOR_TYPE_COUNT 20
-
-/**
- * Orders for subpixels
- *
- * Currently the possible values are very biased
- * to LCD, Plasma and monochrome monitors
- */
-typedef enum libgamma_subpixel_order {
- /**
- * The adjustment method does not know the order of the subpixels
- *
- * (This could be considered an error)
- */
- LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN = 0,
-
- /**
- * There are no subpixels in the monitor
- */
- LIBGAMMA_SUBPIXEL_ORDER_NONE,
-
- /**
- * The subpixels are ordered red, green and then blue, from left to right
- */
- LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB,
-
- /**
- * The subpixels are ordered blue, green and then red, from left to right
- */
- LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR,
-
- /**
- * The subpixels are ordered red, green and then blue, from the top down
- */
- LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB,
-
- /**
- * The subpixels are ordered blue, green and then red, from the top down
- */
- LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR
-
-} libgamma_subpixel_order_t;
-
-/**
- * The number of values defined in `libgamma_subpixel_order_t`
- */
-#define LIBGAMMA_SUBPIXEL_ORDER_COUNT 6
-
-
-/**
- * Answer enum to a decision problem
- */
-typedef enum libgamma_decision {
- /**
- * The answer is negative
- */
- LIBGAMMA_NO = 0,
-
- /**
- * The answer is unknown
- */
- LIBGAMMA_MAYBE = 1,
-
- /**
- * The answer is positive
- */
- LIBGAMMA_YES = 2
-
-} libgamma_decision_t;
-
-
-/**
- * For a `libgamma_crtc_information_t` fill in the values for
- * `edid` and `edid_length` and report errors to `edid_error`
- */
-#define LIBGAMMA_CRTC_INFO_EDID (1 << 0)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value
- * for `width_mm` and report errors to `width_mm_error`
- */
-#define LIBGAMMA_CRTC_INFO_WIDTH_MM (1 << 1)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value
- * for `height_mm` and report errors to `height_mm_error`
- */
-#define LIBGAMMA_CRTC_INFO_HEIGHT_MM (1 << 2)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `width_mm_edid` and report errors to `width_mm_edid_error`
- */
-#define LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID (1 << 3)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `height_mm_edid` and report errors to `height_mm_edid_error`
- */
-#define LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID (1 << 4)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the values for
- * `red_gamma_size`, `green_gamma_size`, and `blue_gamma_size`,
- * and report errors to `gamma_size_error`
- */
-#define LIBGAMMA_CRTC_INFO_GAMMA_SIZE (1 << 5)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `gamma_depth` and report errors to `gamma_depth_error`
- */
-#define LIBGAMMA_CRTC_INFO_GAMMA_DEPTH (1 << 6)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `gamma_support` and report errors to `gamma_support_error`
- */
-#define LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT (1 << 7)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `subpixel_order` and report errors to `subpixel_order_error`
- */
-#define LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER (1 << 8)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the
- * value for `active` and report errors to `active_error`
- */
-#define LIBGAMMA_CRTC_INFO_ACTIVE (1 << 9)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `connector_name` and report errors to `connector_name_error`
- */
-#define LIBGAMMA_CRTC_INFO_CONNECTOR_NAME (1 << 10)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the value for
- * `connector_type` and report errors to `connector_type_error`
- */
-#define LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE (1 << 11)
-
-/**
- * For a `libgamma_crtc_information_t` fill in the
- * values for `gamma_red`, `gamma_green`, and `gamma_blue`
- * and report errors to `gamma_error`
- */
-#define LIBGAMMA_CRTC_INFO_GAMMA (1 << 12)
-
-/**
- * The number of `LIBGAMMA_CRTC_INFO_*` values defined
- */
-#define LIBGAMMA_CRTC_INFO_COUNT 13
-
-/**
- * Macro for both `libgamma_crtc_information_t` fields
- * that can specify the size of the monitor's viewport
- * as specified in the monitor's Extended Display
- * Information Data
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT (LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID | LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID)
-
-/**
- * Macro for all `libgamma_crtc_information_t` fields
- * that can be filled if the adjustment method have
- * support for reading the monitors' Extended Display
- * Information Data
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_EDID (LIBGAMMA_CRTC_INFO_EDID | LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT | LIBGAMMA_CRTC_INFO_GAMMA)
-
-/**
- * Macro for both `libgamma_crtc_information_t` fields
- * that can specify the size of the monitor's viewport
- * as provided by the adjustment method without this
- * library having to parse the monitor's Extended Display
- * Information Data
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT (LIBGAMMA_CRTC_INFO_WIDTH_MM | LIBGAMMA_CRTC_INFO_HEIGHT_MM)
-
-/**
- * Macro for the `libgamma_crtc_information_t` fields
- * that specifies the CRTC's gamma ramp sizes and gamma
- * ramp depth
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_RAMP (LIBGAMMA_CRTC_INFO_GAMMA_SIZE | LIBGAMMA_CRTC_INFO_GAMMA_DEPTH)
-
-/**
- * Macro for the `libgamma_crtc_information_t` fields
- * that specifies the CRTC's connector type and the
- * partition unique name of the connector
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_CONNECTOR (LIBGAMMA_CRTC_INFO_CONNECTOR_NAME | LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE)
-
-/**
- * Macro for the `libgamma_crtc_information_t` fields
- * that required there is a monitor attached to the
- * connector, and that status itself
- */
-#define LIBGAMMA_CRTC_INFO_MACRO_ACTIVE (LIBGAMMA_CRTC_INFO_MACRO_EDID | LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT |\
- LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER | LIBGAMMA_CRTC_INFO_ACTIVE)
-
-
-
-/**
- * Cathode ray tube controller information data structure
- */
-typedef struct libgamma_crtc_information {
- /**
- * The Extended Display Identification Data associated with
- * the attached monitor.
- *
- * This is raw byte array that is usually 128 bytes long.
- * It is not NUL-terminate, rather its length is stored in
- * `edid_length`.
- */
- unsigned char *edid;
-
- /**
- * The length of `edid`
- */
- size_t edid_length;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int edid_error;
-
-
- /**
- * The phyical width, in millimetres, of the viewport of the
- * attached monitor, as reported by the adjustment method
- *
- * This value may be incorrect, which is a known issue with
- * the X server where it is the result of the X server
- * attempting the estimate the size on its own
- *
- * Zero means that its is not applicable, which is the case
- * for projectors
- */
- size_t width_mm;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int width_mm_error;
-
-
- /**
- * The phyical height, in millimetres, of the viewport of the
- * attached monitor, as reported by the adjustment method
- *
- * This value may be incorrect, which is a known issue with
- * the X server where it is the result of the X server
- * attempting the estimate the size on its own
- *
- * Zero means that its is not applicable, which is the case
- * for projectors
- */
- size_t height_mm;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int height_mm_error;
-
-
- /**
- * The phyical width, in millimetres, of the viewport of the
- * attached monitor, as reported by it the monitor's Extended
- * Display Information Data
- *
- * This value can only contain whole centimetres, which means
- * that the result is always zero modulus ten. However, this
- * could change with revisions of the EDID structure.
- *
- * Zero means that its is not applicable, which is the case
- * for projectors.
- */
- size_t width_mm_edid;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int width_mm_edid_error;
-
-
- /**
- * The phyical height, in millimetres, of the viewport of the
- * attached monitor, as reported by it the monitor's Extended
- * Display Information Data
- *
- * This value can only contain whole centimetres, which means
- * that the result is always zero modulus ten. However, this
- * could change with revisions of the EDID structure.
- *
- * Zero means that its is not applicable, which is the case
- * for projectors
- */
- size_t height_mm_edid;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int height_mm_edid_error;
-
-
- /**
- * The size of the encoding axis of the red gamma ramp
- */
- size_t red_gamma_size;
-
- /**
- * The size of the encoding axis of the green gamma ramp
- */
- size_t green_gamma_size;
-
- /**
- * The size of the encoding axis of the blue gamma ramp
- */
- size_t blue_gamma_size;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int gamma_size_error;
-
-
- /**
- * The bit-depth of the value axes of gamma ramps,
- * -1 for single precision floating point, and -2 for
- * double precision floating point
- */
- signed gamma_depth;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int gamma_depth_error;
-
-
- /**
- * `LIBGAMMA_NO` indicates that the CRTC does not support
- * gamma ramp adjustments. `LIBGAMMA_MAYBE` indicates that
- * the CRTC may or may not support gamma ramp adjustments,
- * meaning that the display server really does not know, but
- * the protocol is available. `LIBGAMMA_NO` indicates that
- * the CRTC does support gamma ramp adjustments.
- */
- libgamma_decision_t gamma_support;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int gamma_support_error;
-
-
- /**
- * The layout of the subpixels
- *
- * You cannot count on this value — especially for CRT:s —
- * but it is provided anyway as a means of distinguishing
- * monitors
- */
- libgamma_subpixel_order_t subpixel_order;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int subpixel_order_error;
-
-
- /**
- * Whether there is a monitor connected to the CRTC
- */
- int active;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int active_error;
-
-
- /**
- * The name of the connector as designated by the display
- * server or as give by this library in case the display
- * server lacks this feature.
- */
- char *connector_name;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library.
- */
- int connector_name_error;
-
-
- /**
- * The type of the connector that is associated with the CRTC.
- */
- libgamma_connector_type_t connector_type;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library.
- */
- int connector_type_error;
-
-
- /**
- * The gamma characteristics of the monitor as reported
- * in its Extended Display Information Data. The value
- * holds the value for the red channel.
- *
- * If you do not have and more accurate measurement of the
- * gamma for the monitor this could be used to give a rought
- * gamma correction; simply divide the value with 2.2 and use
- * the result for the red channel in the gamma correction.
- */
- float gamma_red;
-
- /**
- * The gamma characteristics of the monitor as reported
- * in its Extended Display Information Data. The value
- * holds the value for the green channel.
- *
- * If you do not have and more accurate measurement of the
- * gamma for the monitor this could be used to give a rought
- * gamma correction; simply divide the value with 2.2 and use
- * the result for the green channel in the gamma correction.
- */
- float gamma_green;
-
- /**
- * The gamma characteristics of the monitor as reported
- * in its Extended Display Information Data. The value
- * holds the value for the blue channel.
- *
- * If you do not have and more accurate measurement of the
- * gamma for the monitor this could be used to give a rought
- * gamma correction; simply divide the value with 2.2 and use
- * the result for the blue channel in the gamma correction.
- */
- float gamma_blue;
-
- /**
- * Zero on success, positive it holds the value `errno` had
- * when the reading failed, otherwise (negative) the value
- * of an error identifier provided by this library
- */
- int gamma_error;
-
-} libgamma_crtc_information_t;
-
-
-
-/**
- * Gamma ramp structure for 8-bit gamma ramps
- */
-typedef struct libgamma_gamma_ramps8 {
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- uint8_t *red;
-
- /**
- * The gamma ramp for the green channel
- */
- uint8_t *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- uint8_t *blue;
-
-} libgamma_gamma_ramps8_t;
-
-
-/**
- * Gamma ramp structure for 16-bit gamma ramps
- */
-typedef struct libgamma_gamma_ramps16
-{
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- uint16_t *red;
-
- /**
- * The gamma ramp for the green channel
- */
- uint16_t *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- uint16_t *blue;
-
-} libgamma_gamma_ramps16_t;
-
-
-/**
- * Gamma ramp structure for 32-bit gamma ramps
- */
-typedef struct libgamma_gamma_ramps32
-{
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- uint32_t *red;
-
- /**
- * The gamma ramp for the green channel
- */
- uint32_t *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- uint32_t *blue;
-
-} libgamma_gamma_ramps32_t;
-
-
-/**
- * Gamma ramp structure for 64-bit gamma ramps
- */
-typedef struct libgamma_gamma_ramps64
-{
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- uint64_t *red;
-
- /**
- * The gamma ramp for the green channel
- */
- uint64_t *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- uint64_t *blue;
-
-} libgamma_gamma_ramps64_t;
-
-
-/**
- * Gamma ramp structure for `float` gamma ramps
- */
-typedef struct libgamma_gamma_rampsf
-{
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- float *red;
-
- /**
- * The gamma ramp for the green channel
- */
- float *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- float *blue;
-
-} libgamma_gamma_rampsf_t;
-
-
-/**
- * Gamma ramp structure for `double` gamma ramps
- */
-typedef struct libgamma_gamma_rampsd
-{
- /**
- * The size of `red`
- */
- size_t red_size;
-
- /**
- * The size of `green`
- */
- size_t green_size;
-
- /**
- * The size of `blue`
- */
- size_t blue_size;
-
- /**
- * The gamma ramp for the red channel
- */
- double *red;
-
- /**
- * The gamma ramp for the green channel
- */
- double *green;
-
- /**
- * The gamma ramp for the blue channel
- */
- double *blue;
-
-} libgamma_gamma_rampsd_t;
-
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_ramps8_initialise(libgamma_gamma_ramps8_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps8_destroy(libgamma_gamma_ramps8_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps8_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps8_free(libgamma_gamma_ramps8_t *restrict);
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_ramps16_initialise(libgamma_gamma_ramps16_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps16_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps16_destroy(libgamma_gamma_ramps16_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps16_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps16_free(libgamma_gamma_ramps16_t *restrict);
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated.
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_ramps32_initialise(libgamma_gamma_ramps32_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps32_destroy(libgamma_gamma_ramps32_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps32_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps32_free(libgamma_gamma_ramps32_t *restrict);
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation.
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated.
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_ramps64_initialise(libgamma_gamma_ramps64_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps64_destroy(libgamma_gamma_ramps64_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_ramps64_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_ramps64_free(libgamma_gamma_ramps64_t *restrict);
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_rampsf_initialise(libgamma_gamma_rampsf_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_rampsf_destroy(libgamma_gamma_rampsf_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsf_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_rampsf_free(libgamma_gamma_rampsf_t *restrict);
-
-
-/**
- * Initialise a gamma ramp in the proper way that allows all adjustment
- * methods to read from and write to it without causing segmentation violation
- *
- * The input must have `red_size`, `green_size`, and `blue_size` set to the
- * sizes of the gamma ramps that should be allocated
- *
- * @param this The gamma ramps
- * @return Zero on success, -1 on allocation error, `errno` will be set accordingly
- */
-int libgamma_gamma_rampsd_initialise(libgamma_gamma_rampsd_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
- * initialised in the proper manner
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_rampsd_destroy(libgamma_gamma_rampsd_t *restrict);
-
-/**
- * Release resources that are held by a gamma ramp strcuture that
- * has been allocated by `libgamma_gamma_rampsd_initialise` or otherwise
- * initialised in the proper manner, as well as release the pointer
- * to the structure
- *
- * @param this The gamma ramps
- */
-void libgamma_gamma_rampsd_free(libgamma_gamma_rampsd_t *restrict);
-
-
-
-#ifndef __GNUC__
-# undef __attribute__
-#endif
-
-#endif
diff --git a/src/lib/libgamma.h b/src/lib/libgamma.h
deleted file mode 100644
index cc63fb8..0000000
--- a/src/lib/libgamma.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBGAMMA_H
-#define LIBGAMMA_H
-
-#include "libgamma-config.h" /* Must be first. */
-
-#include "libgamma-method.h"
-#include "libgamma-facade.h"
-#include "libgamma-error.h"
-
-#endif