diff options
142 files changed, 5628 insertions, 5034 deletions
@@ -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 @@ -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 @@ -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 |