From 7edd0ced5c8e45161cb655a36f05f2a90283bb9e Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 5 Mar 2021 20:59:13 +0100 Subject: Join test source files into test.c and update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .gitignore | 3 +- Makefile | 10 +- mk/method-dummy=yes.mk | 3 +- src/test/crtcinfo.c | 236 ------------- src/test/crtcinfo.h | 20 -- src/test/errors.c | 66 ---- src/test/errors.h | 18 - src/test/methods.c | 168 --------- src/test/methods.h | 63 ---- src/test/ramps.c | 104 ------ src/test/ramps.h | 85 ----- src/test/test.c | 157 --------- src/test/test.h | 20 -- src/test/update-warnings.h | 52 --- src/test/user.c | 143 -------- src/test/user.h | 28 -- test.c | 823 +++++++++++++++++++++++++++++++++++++++++++++ 17 files changed, 835 insertions(+), 1164 deletions(-) delete mode 100644 src/test/crtcinfo.c delete mode 100644 src/test/crtcinfo.h delete mode 100644 src/test/errors.c delete mode 100644 src/test/errors.h delete mode 100644 src/test/methods.c delete mode 100644 src/test/methods.h delete mode 100644 src/test/ramps.c delete mode 100644 src/test/ramps.h delete mode 100644 src/test/test.c delete mode 100644 src/test/test.h delete mode 100644 src/test/update-warnings.h delete mode 100644 src/test/user.c delete mode 100644 src/test/user.h create mode 100644 test.c diff --git a/.gitignore b/.gitignore index 0c969eb..0664eb9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ *.so.* *.dll *.dylib -config.h +/config.h +/test diff --git a/Makefile b/Makefile index 17f7774..41a9607 100644 --- a/Makefile +++ b/Makefile @@ -151,7 +151,7 @@ HDR =\ $(HDR_METHODS) -all: libgamma.a libgamma.$(LIBEXT) +all: libgamma.a libgamma.$(LIBEXT) test $(OBJ): $(@:.o=.c) $(HDR) $(LOBJ): $(@:.lo=.c) $(HDR) @@ -177,6 +177,12 @@ libgamma.$(LIBEXT): $(LOBJ) .c.lo: $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CFLAGS_METHODS) $(CPPFLAGS) $(CPPFLAGS_METHODS) +test.o: test.c libgamma.h + $(CC) -c -o $@ test.c $(CFLAGS) $(CPPFLAGS) + +test: test.o + $(CC) -o $@ test.o libgamma.a $(LDFLAGS_METHODS) $(LDFLAGS) + install: libgamma.a libgamma.$(LIBEXT) mkdir -p -- "$(DESTDIR)$(PREFIX)/lib/" mkdir -p -- "$(DESTDIR)$(PREFIX)/include/" @@ -194,7 +200,7 @@ uninstall: -rm -f -- "$(DESTDIR)$(PREFIX)/include/libgamma.h" clean: - -rm -f -- *.o *.lo *.su *.a *.$(LIBEXT) + -rm -f -- *.o *.lo *.su *.a *.$(LIBEXT) test config.h .SUFFIXES: .SUFFIXES: .lo .o .c diff --git a/mk/method-dummy=yes.mk b/mk/method-dummy=yes.mk index 3694cb3..88eb2aa 100644 --- a/mk/method-dummy=yes.mk +++ b/mk/method-dummy=yes.mk @@ -26,4 +26,5 @@ OBJ_DUMMY =\ libgamma_dummy_crtc_set_gamma_rampsf.o\ libgamma_dummy_crtc_get_gamma_rampsd.o\ libgamma_dummy_crtc_set_gamma_rampsd.o\ - libgamma_dummy_internal_configurations.o + libgamma_dummy_internal_configurations.o\ + libgamma_dummy_internal_crtc_restore_forced.o diff --git a/src/test/crtcinfo.c b/src/test/crtcinfo.c deleted file mode 100644 index 627559b..0000000 --- a/src/test/crtcinfo.c +++ /dev/null @@ -1,236 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "crtcinfo.h" - - -/** - * Conditionally print a CRTC information field - * - * @param type:data-type Data type for the value of the information field - * @param notation:string-literal %-pattern for `printf` (excluding the %) that is used for `type` - * @param do_print Whether the information should be included in the process's output - * @param description A description of the information field - * @param error The error of the information field - * @param value The value of the information field - */ -#define print_crtc_information_(type, notation)\ - static void\ - print_crtc_information_##type(int do_print, const char *description, int error, type value)\ - {\ - char buf[256];\ - if (do_print) {\ - if (error) {\ - snprintf(buf, sizeof(buf) / sizeof(char), " (error) %s", description);\ - libgamma_perror(buf, error);\ - } else {\ - printf(" %s: %" notation "\n", description, value);\ - }\ - }\ - } - - -/** - * A single [a-z] word alternative to `const char*`, we need it for the - * function name of the string variant of `print_crtc_information_*` - */ -typedef const char *str; -/* Create `print_crtc_information_*` variants */ -print_crtc_information_(size_t, "lu") -print_crtc_information_(signed, "i") -print_crtc_information_(int, "i") -#ifdef __GCC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdouble-promotion" -#endif -print_crtc_information_(float, "f") -#ifdef __GCC__ -# pragma GCC diagnostic pop -#endif -print_crtc_information_(str, "s") -#undef print_crtc_information_ - - -#define __case(VALUE) case VALUE: return #VALUE - -/** - * Get a string representation of a subpixel order - * - * @param value The subpixel order - * @return String representation - */ -static const char * -subpixel_order_str(libgamma_subpixel_order_t value) -{ - switch (value) { - __case (LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN); - __case (LIBGAMMA_SUBPIXEL_ORDER_NONE); - __case (LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB); - __case (LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR); - __case (LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB); - __case (LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR); - default: - return "(unknown)"; - } -} - - -/** - * Get a string representation of a connector type - * - * @param value The connector type - * @return String representation - */ -static const char * -connector_type_str(libgamma_connector_type_t value) -{ - switch (value) { - __case (LIBGAMMA_CONNECTOR_TYPE_Unknown); - __case (LIBGAMMA_CONNECTOR_TYPE_VGA); - __case (LIBGAMMA_CONNECTOR_TYPE_DVI); - __case (LIBGAMMA_CONNECTOR_TYPE_DVII); - __case (LIBGAMMA_CONNECTOR_TYPE_DVID); - __case (LIBGAMMA_CONNECTOR_TYPE_DVIA); - __case (LIBGAMMA_CONNECTOR_TYPE_Composite); - __case (LIBGAMMA_CONNECTOR_TYPE_SVIDEO); - __case (LIBGAMMA_CONNECTOR_TYPE_LVDS); - __case (LIBGAMMA_CONNECTOR_TYPE_Component); - __case (LIBGAMMA_CONNECTOR_TYPE_9PinDIN); - __case (LIBGAMMA_CONNECTOR_TYPE_DisplayPort); - __case (LIBGAMMA_CONNECTOR_TYPE_HDMI); - __case (LIBGAMMA_CONNECTOR_TYPE_HDMIA); - __case (LIBGAMMA_CONNECTOR_TYPE_HDMIB); - __case (LIBGAMMA_CONNECTOR_TYPE_TV); - __case (LIBGAMMA_CONNECTOR_TYPE_eDP); - __case (LIBGAMMA_CONNECTOR_TYPE_VIRTUAL); - __case (LIBGAMMA_CONNECTOR_TYPE_DSI); - __case (LIBGAMMA_CONNECTOR_TYPE_LFP); - default: - return "(unknown)"; - } -} - - -/** - * Get a string representation of a decision - * - * @param value The decision - * @return String representation - */ -static const char * -decision_str(libgamma_decision_t value) -{ - switch (value) { - __case (LIBGAMMA_NO); - __case (LIBGAMMA_MAYBE); - __case (LIBGAMMA_YES); - default: - return "(unknown)"; - } -} - -#undef __case - - -/** - * The CRTC information for a CRTC - * - * @param crtc The CRTC - */ -void -crtc_information(libgamma_crtc_state_t *restrict crtc) -{ - libgamma_method_capabilities_t caps; - libgamma_crtc_information_t info; - int fields, field; - char *edid_lc, *edid_uc; - unsigned char *edid_raw; - - /* Get supported CRTC informations fields */ - libgamma_method_capabilities(&caps, crtc->partition->site->method); - - /* List unsupport information fields by testing them one by one */ - for (fields = caps.crtc_information; field = fields & -fields, fields; fields ^= field) { - if (libgamma_get_crtc_information(&info, crtc, field)) - printf("Could not read CRTC information field %i\n", field); - free(info.edid); - free(info.connector_name); - } - - /* Get CRTC information, that is supported */ - fields = caps.crtc_information; - if (libgamma_get_crtc_information(&info, crtc, fields)) - printf("An error occurred while reading CRTC information\n"); - - /* Macros for printing CRTC information */ -#define print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, ERROR_VAR)\ - print_crtc_information_##TYPE(fields & FIELD_ID, DESCRIPTION, info.ERROR_VAR, info.FIELD_VAR); -#define print(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR)\ - print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, FIELD_VAR##_error); - - - /* Print CRTC information */ - - printf("CRTC information:\n"); - - /* Print the EDID field */ - if ((fields & LIBGAMMA_CRTC_INFO_EDID)) { - if (info.edid_error) { - libgamma_perror(" (error) EDID", info.edid_error); - } else { - edid_lc = libgamma_behex_edid(info.edid, info.edid_length); - edid_raw = libgamma_unhex_edid(edid_lc); - edid_uc = libgamma_behex_edid_uppercase(edid_raw, info.edid_length); - printf(" EDID: %s\n", edid_lc); - printf(" EDID (uppercase): %s\n", edid_uc); - printf(" EDID (length): %lu\n", info.edid_length); - free(edid_lc); - free(edid_raw); - free(edid_uc); - } - } - /* Print physical dimensions of the monitor */ - print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM, "width", width_mm); - print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM, "height", height_mm); - print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID, "width per EDID", width_mm_edid); - print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID, "height per EDID", height_mm_edid); - /* Print gamma ramp information */ - print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "red gamma ramp size", red_gamma_size, gamma_size_error); - print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "green gamma ramp size", green_gamma_size, gamma_size_error); - print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "blue gamma ramp size", blue_gamma_size, gamma_size_error); - print(signed, LIBGAMMA_CRTC_INFO_GAMMA_DEPTH, "gamma ramp depth", gamma_depth); - /* Print gamma ramp support */ - if (fields & LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT) { - if (info.gamma_support_error) - libgamma_perror(" (error) gamma support", info.gamma_support_error); - else - printf(" gamma support: %s\n", decision_str(info.gamma_support)); - } - /* Print subpixel order for the monitor */ - if (fields & LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER) { - if (info.subpixel_order_error) - libgamma_perror(" (error) subpixel order", info.subpixel_order_error); - else - printf(" subpixel order: %s\n", subpixel_order_str(info.subpixel_order)); - } - /* Print connector information */ - print(int, LIBGAMMA_CRTC_INFO_ACTIVE, "active", active); - print(str, LIBGAMMA_CRTC_INFO_CONNECTOR_NAME, "connector name", connector_name); - if (fields & LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE) { - if (info.connector_type_error) - libgamma_perror(" (error) subpixel order", info.connector_type_error); - else - printf(" subpixel order: %s\n", connector_type_str(info.connector_type)); - } - /* Print the gamma characteristics of the monitor */ - print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "red gamma characteristics", gamma_red, gamma_error); - print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "green gamma characteristics", gamma_green, gamma_error); - print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "blue gamma characteristics", gamma_blue, gamma_error); - printf("\n"); - - -#undef print -#undef print2 - - /* Release resouces */ - free(info.edid); - free(info.connector_name); -} diff --git a/src/test/crtcinfo.h b/src/test/crtcinfo.h deleted file mode 100644 index dc120e7..0000000 --- a/src/test/crtcinfo.h +++ /dev/null @@ -1,20 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_CRTCINFO_H -#define LIBGAMMA_TEST_CRTCINFO_H - - -#include - -#include -#include - - -/** - * The CRTC information for a CRTC - * - * @param crtc The CRTC - */ -void crtc_information(libgamma_crtc_state_t *restrict crtc); - - -#endif diff --git a/src/test/errors.c b/src/test/errors.c deleted file mode 100644 index ffe9bd2..0000000 --- a/src/test/errors.c +++ /dev/null @@ -1,66 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "errors.h" - - -/** - * The error API - */ -void -error_test(void) -{ - int i; - - /* Test that naming and name dereferencing - of errors work. Because the mappings in - these [`libgamma_value_of_error` and - `libgamma_name_of_error`] functions are - generated, it should work if and only if - one test passes, assumming the errors are - unique whihc is tested in the end of this - function. */ - printf("Testing error API using LIBGAMMA_STATE_UNKNOWN:\n"); - printf(" Expecting %i: %i\n", LIBGAMMA_STATE_UNKNOWN, libgamma_value_of_error("LIBGAMMA_STATE_UNKNOWN")); - printf(" Expecting %s: %s\n", "LIBGAMMA_STATE_UNKNOWN", libgamma_name_of_error(LIBGAMMA_STATE_UNKNOWN)); - printf("\n"); - - /* Test that `libgamma_perror` can print - libgamma errors and system errors, and - handle success in the same with as `perror`. */ - printf("Testing libgamma_perror:\n"); - libgamma_perror(" Expecting LIBGAMMA_STATE_UNKNOWN", LIBGAMMA_STATE_UNKNOWN); - libgamma_perror(" Expecting a description for ENOMEM", ENOMEM); - libgamma_perror(" Expecting a description for successfulness", 0); - /* Test that `libgamma_perror` handles - `LIBGAMMA_ERRNO_SET` correctly. */ - libgamma_perror(" Expecting a description for ENOMEM", (errno = ENOMEM, LIBGAMMA_ERRNO_SET)); - /* That that `libgamma_perror` handles - `LIBGAMMA_DEVICE_REQUIRE_GROUP` - correctly both when the required - group's name is known and when it - is unknown. */ - libgamma_group_gid = 10; - libgamma_group_name = "test"; - libgamma_perror(" Expecting 'LIBGAMMA_DEVICE_REQUIRE_GROUP: test (10)'", LIBGAMMA_DEVICE_REQUIRE_GROUP); - libgamma_group_name = NULL; - libgamma_perror(" Expecting 'LIBGAMMA_DEVICE_REQUIRE_GROUP: 10'", LIBGAMMA_DEVICE_REQUIRE_GROUP); - printf("\n"); - - /* That all libgamma error codes - are unique. This is done by - getting the name associated - with an error code and the getting - the error code associated that - name and test that the same - error code is returned as put in, - for each libgamma error code. */ - printf("Testing error code uniqueness: "); - for (i = -1; i >= LIBGAMMA_ERROR_MIN; i--) { - if (libgamma_value_of_error(libgamma_name_of_error(i)) != i) { - printf("failed\n"); - goto not_unique; - } - } - printf("passed\n"); -not_unique: - printf("\n"); -} diff --git a/src/test/errors.h b/src/test/errors.h deleted file mode 100644 index 1000a7d..0000000 --- a/src/test/errors.h +++ /dev/null @@ -1,18 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_ERRROS_H -#define LIBGAMMA_TEST_ERRROS_H - - -#include - -#include -#include - - -/** - * The error API - */ -void error_test(void); - - -#endif diff --git a/src/test/methods.c b/src/test/methods.c deleted file mode 100644 index 5cd8bd6..0000000 --- a/src/test/methods.c +++ /dev/null @@ -1,168 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "methods.h" - - -/** - * Get the name representation of an - * adjustment method by its identifier - * - * @param method The identifier of the adjustment method - * @return The name of the adjustment method, should not be `free`:d - */ -const char * -method_name(int method) -{ - switch (method) { - case LIBGAMMA_METHOD_DUMMY: return "dummy"; - case LIBGAMMA_METHOD_X_RANDR: return "RandR X extension"; - case LIBGAMMA_METHOD_X_VIDMODE: return "VidMode X extension"; - case LIBGAMMA_METHOD_LINUX_DRM: return "Linux DRM"; - case LIBGAMMA_METHOD_W32_GDI: return "Windows GDI"; - case LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS: return "Quartz using CoreGraphics"; - default: - return "(unknown)"; - } -} - - -/** - * Print a list of adjustment methods - * - * @param description Precursory text for the list - * @param methods An array allocated to fit all adjustment methods - * @param operation See the `operation` parameter for `libgamma_list_methods` - */ -void -list_methods(const char *description, int *methods, int operation) -{ - /* Get adjustment method list */ - size_t i, n = libgamma_list_methods(methods, LIBGAMMA_METHOD_COUNT, operation); - - /* Print adjustment method list */ - printf("%s:\n", description); - for (i = 0; i < n; i++) - printf(" %s\n", method_name(methods[i])); - printf("\n"); -} - - -/** - * Print all lists, of adjustments methods, that - * are made available by `libgamma_list_methods` - */ -void -list_methods_lists(void) -{ - /* Allocate a list for adjustment methods that is large - enough if the program is up to date with the library */ - int *methods = malloc(LIBGAMMA_METHOD_COUNT * sizeof(int)); - /* Get a list of all adjustment methods */ - size_t n = libgamma_list_methods(methods, LIBGAMMA_METHOD_COUNT, 4); - - /* If we got more adjustment methods than we expected - the program needs to be recompiled, and we need to - reallocate the list so it is large enough. */ - if (n > LIBGAMMA_METHOD_COUNT) { - printf("Warning: you should to recompile the program, libgamma has been updated.\n"); - methods = realloc(methods, n * sizeof(int)); - } - - /* Print adjustment method lists. */ - list_methods("Available adjustment methods", methods, 4); - list_methods("Available real adjustment methods", methods, 3); - list_methods("Available real non-fake adjustment methods", methods, 2); - list_methods("Recommended adjustment methods", methods, 1); - list_methods("Recommended non-fake adjustment methods", methods, 0); - - free(methods); -} - - -/** - * Test the availability (determined at - * compile-time) of all adjustment - * methods and one that does not exist - */ -void -method_availability(void) -{ - int method; - /* The availability of an adjustmen method whose identifier - is invalid. It should say it is not available. */ - printf("Testing the availability of a non-existing adjustment method: "); - printf("%s\n", libgamma_is_method_available(-1) ? "available" : "not available"); - - /* Test the availability of the adjustment methods that does exist */ - for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { - printf("Testing the availability of %s: ", method_name(method)); - printf("%s\n", libgamma_is_method_available(method) ? "available" : "not available"); - } - printf("\n"); -} - - -/** - * List the default site and the environment - * variable, if any, that determines the - * default site, for all availiable adjustment - * methods - */ -void -list_default_sites(void) -{ - int method; - for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { - /* Include only available adjustment methods. - If an adjustment method is not available - it should print "(null)", but as that can - be misguiding we exclude those methods. */ - if (libgamma_is_method_available(method)) { - printf("Default site for %s:\n", method_name(method)); - printf(" Variable: %s\n", libgamma_method_default_site_variable(method)); - printf(" Site name: %s\n", libgamma_method_default_site(method)); - printf("\n"); - } - } -} - - -/** - * Print the capabilities of all availiable - * adjustment methods. - */ -void -method_capabilities(void) -{ - libgamma_method_capabilities_t caps; - int method; - for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { - if (libgamma_is_method_available(method)) { - /* Print adjustment method name and get the - adjustment method's capabilities. */ - printf("Capabilities of %s:\n", method_name(method)); - libgamma_method_capabilities(&caps, method); - - /* Print capabilities. The CRTC information - capabilities is printed hexadecimal. See - the `LIBGAMMA_CRTC_INFO_*` definitions in - `src/lib/libgamma-method.h` for what each - bit represents. */ - printf(" %s: %X\n", "CRTC information", caps.crtc_information); - printf(" %s: %s\n", "Default site known", caps.default_site_known ? "yes" : "no"); - printf(" %s: %s\n", "Multiple sites", caps.multiple_sites ? "yes" : "no"); - printf(" %s: %s\n", "Multiple partitions", caps.multiple_partitions ? "yes" : "no"); - printf(" %s: %s\n", "Multiple crtcs", caps.multiple_crtcs ? "yes" : "no"); - printf(" %s: %s\n", "Graphics cards", caps.partitions_are_graphics_cards ? "yes" : "no"); - printf(" %s: %s\n", "Site restore", caps.site_restore ? "yes" : "no"); - printf(" %s: %s\n", "Partition restore", caps.partition_restore ? "yes" : "no"); - printf(" %s: %s\n", "CRTC restore", caps.crtc_restore ? "yes" : "no"); - printf(" %s: %s\n", "Identical gamma sizes", caps.identical_gamma_sizes ? "yes" : "no"); - printf(" %s: %s\n", "Fixed gamma size", caps.fixed_gamma_size ? "yes" : "no"); - printf(" %s: %s\n", "Fixed gamma depth", caps.fixed_gamma_depth ? "yes" : "no"); - printf(" %s: %s\n", "Real method", caps.real ? "yes" : "no"); - printf(" %s: %s\n", "Fake method", caps.fake ? "yes" : "no"); - printf(" %s: %s\n", "Auto restore", caps.auto_restore ? "yes" : "no"); - printf("\n"); - } - } -} diff --git a/src/test/methods.h b/src/test/methods.h deleted file mode 100644 index e7f53ab..0000000 --- a/src/test/methods.h +++ /dev/null @@ -1,63 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_METHODS_H -#define LIBGAMMA_TEST_METHODS_H - - -#include - -#include -#include - - -#ifndef __GCC__ -# define __attribute__(x) -#endif - - -/** - * Get the name representation of an - * adjustment method by its identifier - * - * @param method The identifier of the adjustment method - * @return The name of the adjustment method, should not be `free`:d - */ -const char *method_name(int method) __attribute__((const)); - -/** - * Print a list of adjustment methods - * - * @param description Precursory text for the list - * @param methods An array allocated to fit all adjustment methods - * @param operation See the `operation` parameter for `libgamma_list_methods` - */ -void list_methods(const char *description, int *methods, int operation); - -/** - * Print all lists, of adjustments methods, that - * are made available by `libgamma_list_methods` - */ -void list_methods_lists(void); - -/** - * Test the availability (determined - * at compile-time) of all adjustment - * methods and one that does not exist - */ -void method_availability(void); - -/** - * List the default site and the environment - * variable, if any, that determines the - * default site, for all availiable adjustment - * methods - */ -void list_default_sites(void); - -/** - * Print the capabilities of all availiable - * adjustment methods - */ -void method_capabilities(void); - - -#endif diff --git a/src/test/ramps.c b/src/test/ramps.c deleted file mode 100644 index 5303195..0000000 --- a/src/test/ramps.c +++ /dev/null @@ -1,104 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "ramps.h" - - -/** - * Test 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 - */ -uint8_t -invert_ramps8(float encoding) -{ - double i_encoding = (double)(1.f - encoding); - double f_output = (double)UINT8_MAX * i_encoding; - uint8_t output = (uint8_t)f_output; - if (i_encoding < (double)0.25f && output > UINT8_MAX / 2) - output = 0; - if (i_encoding > (double)0.75f && output < UINT8_MAX / 2) - output = UINT8_MAX; - return output; -} - -/** - * Test 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 - */ -uint16_t -invert_ramps16(float encoding) -{ - double i_encoding = (double)(1.f - encoding); - double f_output = (double)UINT16_MAX * i_encoding; - uint16_t output = (uint16_t)f_output; - if (i_encoding < (double)0.25f && output > UINT16_MAX / 2) - output = 0; - if (i_encoding > (double)0.75f && output < UINT16_MAX / 2) - output = UINT16_MAX; - return output; -} - -/** - * Test 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 - */ -uint32_t -invert_ramps32(float encoding) -{ - double i_encoding = (double)(1.f - encoding); - double f_output = (double)UINT32_MAX * i_encoding; - uint32_t output = (uint32_t)f_output; - if (i_encoding < (double)0.25f && output > UINT32_MAX / 2) - output = 0; - if (i_encoding > (double)0.75f && output < UINT32_MAX / 2) - output = UINT32_MAX; - return output; -} - -/** - * Test 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 - */ -uint64_t -invert_ramps64(float encoding) -{ - double i_encoding = (double)(1.f - encoding); - double f_output = (double)UINT64_MAX * i_encoding; - uint64_t output = (uint64_t)f_output; - if (i_encoding < (double)0.25f && output > UINT64_MAX / 2) - output = 0; - if (i_encoding > (double)0.75f && output < UINT64_MAX / 2) - output = UINT64_MAX; - return output; -} - -/** - * Test 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 - */ -float -invert_rampsf(float encoding) -{ - return 1.f - encoding; -} - -/** - * Test 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 - */ -double -invert_rampsd(double encoding) -{ - return (double)1.f - encoding; -} diff --git a/src/test/ramps.h b/src/test/ramps.h deleted file mode 100644 index 13c31b1..0000000 --- a/src/test/ramps.h +++ /dev/null @@ -1,85 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_RAMPS_H -#define LIBGAMMA_TEST_RAMPS_H - - -#include - - -#ifndef __GCC__ -# define __attribute__(x) -#endif - - -/** - * X macros of all integer gamma ramps - */ -#define LIST_INTEGER_RAMPS X(ramps8) X(ramps32) X(ramps64) X(ramps16) - -/** - * X macros of all floating-point gamma ramps - */ -#define LIST_FLOAT_RAMPS X(rampsf) X(rampsd) - -/** - * X macros of all gamma ramps - */ -#define LIST_RAMPS LIST_FLOAT_RAMPS LIST_INTEGER_RAMPS - - -/* ramps16 is last because we want to make sure that the gamma ramps are - preserved exactly on exit, and we assume RandR X is used. */ - - - -/** - * Test 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 - */ -uint8_t invert_ramps8(float encoding) __attribute__((const)); - -/** - * Test 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 - */ -uint16_t invert_ramps16(float encoding) __attribute__((const)); - -/** - * Test 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 - */ -uint32_t invert_ramps32(float encoding) __attribute__((const)); - -/** - * Test 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 - */ -uint64_t invert_ramps64(float encoding) __attribute__((const)); - -/** - * Test 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 - */ -float invert_rampsf(float encoding) __attribute__((const)); - -/** - * Test 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 - */ -double invert_rampsd(double encoding) __attribute__((const)); - - -#endif diff --git a/src/test/test.c b/src/test/test.c deleted file mode 100644 index 8cf0579..0000000 --- a/src/test/test.c +++ /dev/null @@ -1,157 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "test.h" - - -/** - * Test `libgamma` - * - * @return Non-zero on machine detectable error, this library - * may still be faulty if zero is returned - */ -int -main(void) -{ - libgamma_site_state_t *restrict site_state = malloc(sizeof(libgamma_site_state_t)); - libgamma_partition_state_t *restrict part_state = malloc(sizeof(libgamma_partition_state_t)); - libgamma_crtc_state_t *restrict crtc_state = malloc(sizeof(libgamma_crtc_state_t)); - libgamma_crtc_information_t info; -#define X(R)\ - libgamma_gamma_##R##_t old_##R, R;\ - libgamma_gamma_##R##_fun* f_##R = invert_##R; - LIST_RAMPS -#undef X - size_t i, n; - int r, rr = 0; - - /* Test miscellaneous parts of the library */ - list_methods_lists(); - method_availability(); - list_default_sites(); - method_capabilities(); - error_test(); - - /* Select monitor for tests over CRTC:s, partitions and sites */ - if (select_monitor(site_state, part_state, crtc_state)) - return 1; - - /* Test CRTC information functions. */ - crtc_information(crtc_state); - - /* Get the sizes of the gamma ramps for the selected CRTC */ - libgamma_get_crtc_information(&info, crtc_state, LIBGAMMA_CRTC_INFO_GAMMA_SIZE); - - /* Create gamma ramps for each depth */ -#define X(R)\ - old_##R.red_size = info.red_gamma_size;\ - old_##R.green_size = info.green_gamma_size;\ - old_##R.blue_size = info.blue_gamma_size;\ - R = old_##R;\ - libgamma_gamma_##R##_initialise(&old_##R);\ - libgamma_gamma_##R##_initialise(&R); - LIST_RAMPS -#undef X - - /* Fill gamma ramps, for each depth, with the CRTC:s current ramps */ -#define X(R)\ - if ((rr |= r = libgamma_crtc_get_gamma_##R(crtc_state, &old_##R))) {\ - libgamma_perror("libgamma_crtc_get_gamma_" #R, r);\ - goto done;\ - }\ - if ((rr |= r = libgamma_crtc_get_gamma_##R(crtc_state, &R))) {\ - libgamma_perror("libgamma_crtc_get_gamma_" #R, r);\ - goto done;\ - } - LIST_RAMPS -#undef X - - /* Test function assisted gamma ramps setting */ -#define X(R)\ - /* Dim the monitor for one second and the restore it. */\ - printf("Inverting monitor output for 1 second... (" #R ")\n");\ - if ((rr |= r = libgamma_crtc_set_gamma_##R##_f(crtc_state, f_##R, f_##R, f_##R)))\ - libgamma_perror("libgamma_crtc_set_gamma_" #R "_f", r);\ - sleep(1);\ - if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, old_##R)))\ - libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ - printf("Done!\n");\ - /* Sleep for one second, we have more depths to test */\ - printf("Sleeping for 1 second...\n");\ - sleep(1); - LIST_RAMPS -#undef X - - /* Test getting and setting gamma ramps */ -#define X(R)\ - /* Get the grand size of the gamma ramps */\ - n = R.red_size;\ - n = n > R.green_size ? n : R.green_size;\ - n = n > R.blue_size ? n : R.blue_size;\ - /* Print the current gamma ramps */\ - printf("Current gamma ramps (" #R "):\n");\ - for (i = 0; i < n; i++) {\ - if (i < R.red_size) Y(R.red, "1"); else printf(" ");\ - if (i < R.green_size) Y(R.green, "2"); else printf(" ");\ - if (i < R.blue_size) Y(R.blue, "4"); else printf(" ");\ - printf("\n");\ - }\ - printf("\n");\ - /* Adjust the gamma ramps for dimming the monitor */\ - for (i = 0; i < R.red_size + R.green_size + R.blue_size; i++)\ - R.red[i] /= 2;\ - /* Dim the monitor for one second and the restore it */\ - printf("Dimming monitor for 1 second...\n");\ - if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, R)))\ - libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ - sleep(1);\ - if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, old_##R)))\ - libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ - printf("Done!\n");\ - /* Sleep for one second, we have more depths to test */\ - printf("Sleeping for 1 second...\n");\ - sleep(1); -#define Y(R, C) printf(" \033[3" C "m%1.8lf\033[00m", (double)(R[i])) - LIST_FLOAT_RAMPS -#undef Y -#define Y(R, C) printf(" \033[3" C "m%16llX\033[00m", (uint64_t)(R[i])) - LIST_INTEGER_RAMPS -#undef Y -#undef X - - /* Test order of gamma ramps */ - memcpy(ramps16.red, old_ramps16.red, ramps16.red_size * sizeof(uint16_t)); - memset(ramps16.green, 0, ramps16.green_size * sizeof(uint16_t)); - memset(ramps16.blue, 0, ramps16.blue_size * sizeof(uint16_t)); - printf("Making the monitor red-only for 1 second...\n"); - if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, ramps16))) - libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); - sleep(1); - memset(ramps16.red, 0, ramps16.red_size * sizeof(uint16_t)); - memcpy(ramps16.green, old_ramps16.green, ramps16.green_size * sizeof(uint16_t)); - printf("Making the monitor green-only for 1 second...\n"); - if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, ramps16))) - libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); - sleep(1); - memset(ramps16.green, 0, ramps16.green_size * sizeof(uint16_t)); - memcpy(ramps16.blue, old_ramps16.blue, ramps16.blue_size * sizeof(uint16_t)); - printf("Making the monitor green-only for 1 second...\n"); - if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, ramps16))) - libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); - sleep(1); - if ((rr |= r = libgamma_crtc_set_gamma_ramps64(crtc_state, old_ramps64))) - libgamma_perror("libgamma_crtc_set_gamma_ramps64", r); - printf("Done!\n"); - - /* TODO Test gamma ramp restore functions */ - -done: - /* Release resouces */ -#define X(R)\ - libgamma_gamma_##R##_destroy(&R);\ - libgamma_gamma_##R##_destroy(&old_##R); - LIST_RAMPS -#undef X - libgamma_crtc_free(crtc_state); - libgamma_partition_free(part_state); - libgamma_site_free(site_state); - return rr; -} diff --git a/src/test/test.h b/src/test/test.h deleted file mode 100644 index f8fa9f5..0000000 --- a/src/test/test.h +++ /dev/null @@ -1,20 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_TEST_H -#define LIBGAMMA_TEST_TEST_H - -#include "update-warnings.h" -#include "methods.h" -#include "errors.h" -#include "crtcinfo.h" -#include "user.h" -#include "ramps.h" - -#include - -#include -#include -#include -#include -#include - -#endif diff --git a/src/test/update-warnings.h b/src/test/update-warnings.h deleted file mode 100644 index 4a1b027..0000000 --- a/src/test/update-warnings.h +++ /dev/null @@ -1,52 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_UPDATE_WARNINGS_H -#define LIBGAMMA_TEST_UPDATE_WARNINGS_H - -#include - - -/* - * This file testes whether the program is out of date - * when it is compiled. This is done by checking for newer - * values of constants that tells us how much there is of - * different things for which we may want to create - * descriptions or otherwise handle especially. - * - * To get the current value of for example `LIBGAMMA_ERROR_MIN` - * simply run the command - * - * cpp < - * LIBGAMMA_ERROR_MIN - * EOF - * - * However, we only do this for if GCC is used to - * compile the program because the #warning CPP - * directive is a GCC extension. If you are not - * using GNU you may want to find another way to - * accomplish this. - */ - -#ifdef __GCC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcpp" -# if LIBGAMMA_ERROR_MIN < -46 -# warning New error codes have been added to libgamma -# endif -# if LIBGAMMA_METHOD_COUNT > 6 -# warning New adjust methods has been added to libgamma -# endif -# if LIBGAMMA_CONNECTOR_TYPE_COUNT > 20 -# warning New connector types have been added to libgamma -# endif -# if LIBGAMMA_SUBPIXEL_ORDER_COUNT > 6 -# warning New subpixel orders have been added to libgamma -# endif -# if LIBGAMMA_CRTC_INFO_COUNT > 13 -# warning New CRTC information fields have been added to libgamma -# endif -# pragma GCC diagnostic pop -#endif - - -#endif diff --git a/src/test/user.c b/src/test/user.c deleted file mode 100644 index 7a1fd78..0000000 --- a/src/test/user.c +++ /dev/null @@ -1,143 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "user.h" - - -#ifdef __GCC__ -# include -#else -/* Hack to circumvent that the funcions are defined multiples */ -# define strlen strlen_ -# define memcpy memcpy_ -# define strchr strchr_ -static size_t -strlen_(const char *str) { - size_t n = 0; - while (str[n]) - n++; - return n; -} -static void * -memcpy_(void *restrict dest, const void *restrict src, size_t n) -{ - char *restrict d = dest; - const char *restrict s = src; - size_t i; - for (i = 0; i < n; i++) - d[i] = s[i]; - return dest; -} -static char *strchr_(const char *s, int c) -{ - char find = (char)c; - for (; *s; s++) - if (*s == find) - return s; - return NULL; -} -#endif - - -/** - * Let the user select adjustment method, site, partition and CRTC - * - * @param site_state Output slot for the site - * @param part_state Output slot for the partition - * @param crtc_state Output slot for the CRTC - * @return Zero on and only on success - */ -int -select_monitor(libgamma_site_state_t *restrict site_state, - libgamma_partition_state_t *restrict part_state, - libgamma_crtc_state_t *restrict crtc_state) -{ - int method; - char *site; - char *tmp; - char buf[256]; - int r; - - - /* -- Adjustment method -- */ - - /* Let the user select adjustment method */ - printf("Select adjustment method:\n"); - for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) - printf(" %i: %s\n", method, method_name(method)); - printf("> "); - fflush(stdout); - fgets(buf, sizeof(buf) / sizeof(char), stdin); - method = atoi(buf); - - - /* -- Site -- */ - - /* Let the user select site */ - printf("Select site: "); - fflush(stdout); - fgets(buf, sizeof(buf) / sizeof(char), stdin); - tmp = strchr(buf, '\n'); - if (tmp) - *tmp = '\0'; - if (!buf[0]) { - site = NULL; - } else { - site = malloc((strlen(buf) + 1) * sizeof(char)); - memcpy(site, buf, strlen(buf) + 1); - } - - /* Initialise site state */ - if ((r = libgamma_site_initialise(site_state, method, site))) { - free(site); - libgamma_perror("error", r); - return 1; - } - - - /* -- Partition -- */ - - /* Check that the site has at least one partition */ - if (!site_state->partitions_available) { - libgamma_site_free(site_state); - printf("No partitions found\n"); - return 1; - } - - /* Let the user select partition */ - printf("Select partition [0, %lu]: ", site_state->partitions_available - 1); - fflush(stdout); - fgets(buf, sizeof(buf) / sizeof(char), stdin); - - /* Initialise partition state */ - if ((r = libgamma_partition_initialise(part_state, site_state, (size_t)atoll(buf)))) { - libgamma_site_free(site_state); - libgamma_perror("error", r); - return 1; - } - - - /* -- CRTC -- */ - - /* Check that the partition has at least one CRTC */ - if (!part_state->crtcs_available) { - libgamma_partition_free(part_state); - libgamma_site_free(site_state); - printf("No CRTC:s found\n"); - return 1; - } - - /* Let the user select CRTC */ - printf("Select CRTC [0, %lu]: ", part_state->crtcs_available - 1); - fflush(stdout); - fgets(buf, sizeof(buf) / sizeof(char), stdin); - - /* Initialise CRTC state. */ - if ((r = libgamma_crtc_initialise(crtc_state, part_state, (size_t)atoll(buf)))) { - libgamma_partition_free(part_state); - libgamma_site_free(site_state); - libgamma_perror("error", r); - return 1; - } - - printf("\n"); - return 0; -} diff --git a/src/test/user.h b/src/test/user.h deleted file mode 100644 index 5a0c868..0000000 --- a/src/test/user.h +++ /dev/null @@ -1,28 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef LIBGAMMA_TEST_USER_H -#define LIBGAMMA_TEST_USER_H - - -#include "methods.h" - -#include - -#include -#include - - - -/** - * Let the user select adjustment method, site, partition and CRTC - * - * @param site_state Output slot for the site - * @param part_state Output slot for the partition - * @param crtc_state Output slot for the CRTC - * @return Zero on and only on success - */ -int select_monitor(libgamma_site_state_t *restrict site_state, - libgamma_partition_state_t *restrict part_state, - libgamma_crtc_state_t *restrict crtc_state); - - -#endif diff --git a/test.c b/test.c new file mode 100644 index 0000000..9dfa598 --- /dev/null +++ b/test.c @@ -0,0 +1,823 @@ +/* See LICENSE file for copyright and license details. */ +#include "libgamma.h" + +#include +#include +#include +#include +#include +#include + + +#if LIBGAMMA_CRTC_INFO_COUNT != 13 +# warning CRTC information fields have been updated +#endif + + + +/** + * X macro of all integer gamma ramps + * + * @param _:macro(identifer) Macro to expand + */ +#define LIST_INTEGER_RAMPS(_) _(ramps8) _(ramps32) _(ramps64) _(ramps16) + +/** + * X macro of all floating-point gamma ramps + * + * @param _:macro(identifer) Macro to expand + */ +#define LIST_FLOAT_RAMPS(_) _(rampsf) _(rampsd) + +/** + * X macro of all gamma ramps + * + * @param _:macro(identifer) Macro to expand + */ +#define LIST_RAMPS(_) LIST_FLOAT_RAMPS(_) LIST_INTEGER_RAMPS(_) + +/* ramps16 is last because we want to make sure that the gamma ramps are + preserved exactly on exit, and we assume X RandR is used. */ + + + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static uint8_t +dim_ramps8(float encoding) +{ + double i_encoding = (double)(encoding / 2.f); + double f_output = (double)UINT8_MAX * i_encoding; + uint8_t output = (uint8_t)f_output; + if (i_encoding < (double)0.25f && output > UINT8_MAX / 2) + output = 0; + if (i_encoding > (double)0.75f && output < UINT8_MAX / 2) + output = UINT8_MAX; + return output; +} + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static uint16_t +dim_ramps16(float encoding) +{ + double i_encoding = (double)(encoding / 2.f); + double f_output = (double)UINT16_MAX * i_encoding; + uint16_t output = (uint16_t)f_output; + if (i_encoding < (double)0.25f && output > UINT16_MAX / 2) + output = 0; + if (i_encoding > (double)0.75f && output < UINT16_MAX / 2) + output = UINT16_MAX; + return output; +} + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static uint32_t +dim_ramps32(float encoding) +{ + double i_encoding = (double)(encoding / 2.f); + double f_output = (double)UINT32_MAX * i_encoding; + uint32_t output = (uint32_t)f_output; + if (i_encoding < (double)0.25f && output > UINT32_MAX / 2) + output = 0; + if (i_encoding > (double)0.75f && output < UINT32_MAX / 2) + output = UINT32_MAX; + return output; +} + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static uint64_t +dim_ramps64(float encoding) +{ + double i_encoding = (double)(encoding / 2.f); + double f_output = (double)UINT64_MAX * i_encoding; + uint64_t output = (uint64_t)f_output; + if (i_encoding < (double)0.25f && output > UINT64_MAX / 2) + output = 0; + if (i_encoding > (double)0.75f && output < UINT64_MAX / 2) + output = UINT64_MAX; + return output; +} + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static float +dim_rampsf(float encoding) +{ + return encoding / 2.f; +} + +/** + * Test 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 + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static double +dim_rampsd(double encoding) +{ + return encoding / (double)2.f; +} + + +/** + * Get the name representation of an + * adjustment method by its identifier + * + * @param method The identifier of the adjustment method + * @return The name of the adjustment + */ +LIBGAMMA_GCC_ONLY__(__attribute__((__const__))) +static const char * +method_name(int method) +{ + const char *r = libgamma_name_of_method(method); + return r ? r : "(unknown)"; +} + + +/** + * Print a list of adjustment methods + * + * @param description Precursory text for the list + * @param methods An array allocated to fit all adjustment methods + * @param operation See the `operation` parameter for `libgamma_list_methods` + */ +static void +list_methods(const char *description, int *methods, int operation) +{ + /* Get adjustment method list */ + size_t i, n = libgamma_list_methods(methods, LIBGAMMA_METHOD_COUNT, operation); + + /* Print adjustment method list */ + printf("%s:\n", description); + for (i = 0; i < n; i++) + printf(" %s\n", method_name(methods[i])); + printf("\n"); +} + + +/** + * Print all lists, of adjustments methods, that + * are made available by `libgamma_list_methods` + */ +static void +list_methods_lists(void) +{ + /* Allocate a list for adjustment methods that is large + * enough if the program is up to date with the library */ + int methods[LIBGAMMA_METHOD_COUNT]; + /* Get a list of all adjustment methods */ + size_t n = libgamma_list_methods(methods, LIBGAMMA_METHOD_COUNT, 4); + + /* Print adjustment method lists. */ + list_methods("Available adjustment methods", methods, 4); + list_methods("Available real adjustment methods", methods, 3); + list_methods("Available real non-fake adjustment methods", methods, 2); + list_methods("Recommended adjustment methods", methods, 1); + list_methods("Recommended non-fake adjustment methods", methods, 0); +} + + +/** + * Test the availability (determined at + * compile-time) of all adjustment + * methods and one that does not exist + */ +static void +method_availability(void) +{ + int method; + /* The availability of an adjustmen method whose identifier + * is invalid. It should say it is not available. */ + printf("Testing the availability of a non-existing adjustment method: "); + printf("%s\n", libgamma_is_method_available(-1) ? "available" : "not available"); + + /* Test the availability of the adjustment methods that does exist */ + for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { + printf("Testing the availability of %s: ", method_name(method)); + printf("%s\n", libgamma_is_method_available(method) ? "available" : "not available"); + } + printf("\n"); +} + + +/** + * List the default site and the environment + * variable, if any, that determines the + * default site, for all availiable adjustment + * methods + */ +static void +list_default_sites(void) +{ + int method; + for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { + /* Include only available adjustment methods. + * If an adjustment method is not available + * it should print "(null)", but as that can + * be misguiding we exclude those methods. */ + if (libgamma_is_method_available(method)) { + printf("Default site for %s:\n", method_name(method)); + printf(" Variable: %s\n", libgamma_method_default_site_variable(method)); + printf(" Site name: %s\n", libgamma_method_default_site(method)); + printf("\n"); + } + } +} + + +/** + * Print the capabilities of all availiable + * adjustment methods. + */ +static void +method_capabilities(void) +{ + libgamma_method_capabilities_t caps; + int method; + for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) { + if (libgamma_is_method_available(method)) { + /* Print adjustment method name and get the + * adjustment method's capabilities. */ + printf("Capabilities of %s:\n", method_name(method)); + libgamma_method_capabilities(&caps, method); + + /* Print capabilities. The CRTC information + * capabilities is printed hexadecimal. See + * the `LIBGAMMA_CRTC_INFO_*` definitions in + * `libgamma.h` for what each bit represents. */ + printf(" %s: %X\n", "CRTC information", caps.crtc_information); + printf(" %s: %s\n", "Default site known", caps.default_site_known ? "yes" : "no"); + printf(" %s: %s\n", "Multiple sites", caps.multiple_sites ? "yes" : "no"); + printf(" %s: %s\n", "Multiple partitions", caps.multiple_partitions ? "yes" : "no"); + printf(" %s: %s\n", "Multiple crtcs", caps.multiple_crtcs ? "yes" : "no"); + printf(" %s: %s\n", "Graphics cards", caps.partitions_are_graphics_cards ? "yes" : "no"); + printf(" %s: %s\n", "Site restore", caps.site_restore ? "yes" : "no"); + printf(" %s: %s\n", "Partition restore", caps.partition_restore ? "yes" : "no"); + printf(" %s: %s\n", "CRTC restore", caps.crtc_restore ? "yes" : "no"); + printf(" %s: %s\n", "Identical gamma sizes", caps.identical_gamma_sizes ? "yes" : "no"); + printf(" %s: %s\n", "Fixed gamma size", caps.fixed_gamma_size ? "yes" : "no"); + printf(" %s: %s\n", "Fixed gamma depth", caps.fixed_gamma_depth ? "yes" : "no"); + printf(" %s: %s\n", "Real method", caps.real ? "yes" : "no"); + printf(" %s: %s\n", "Fake method", caps.fake ? "yes" : "no"); + printf(" %s: %s\n", "Auto restore", caps.auto_restore ? "yes" : "no"); + printf("\n"); + } + } +} + + + +/** + * Let the user select adjustment method, site, partition and CRTC + * + * @param site_state Output slot for the site + * @param part_state Output slot for the partition + * @param crtc_state Output slot for the CRTC + * @return Zero on and only on success + */ +static int +select_monitor(libgamma_site_state_t *site_state, libgamma_partition_state_t *part_state, libgamma_crtc_state_t *crtc_state) +{ + int method; + char *site; + char *tmp; + char buf[256]; + int r; + + + /* -- Adjustment method -- */ + + /* Let the user select adjustment method */ + printf("Select adjustment method:\n"); + for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) + printf(" %i: %s\n", method, method_name(method)); + printf("> "); + fflush(stdout); + fgets(buf, sizeof(buf) / sizeof(char), stdin); + method = atoi(buf); + + + /* -- Site -- */ + + /* Let the user select site */ + printf("Select site: "); + fflush(stdout); + fgets(buf, sizeof(buf) / sizeof(char), stdin); + tmp = strchr(buf, '\n'); + if (tmp) + *tmp = '\0'; + if (!buf[0]) { + site = NULL; + } else { + site = malloc((strlen(buf) + 1) * sizeof(char)); + memcpy(site, buf, strlen(buf) + 1); + } + + /* Initialise site state */ + if ((r = libgamma_site_initialise(site_state, method, site))) { + free(site); + libgamma_perror("error", r); + return 1; + } + + + /* -- Partition -- */ + + /* Check that the site has at least one partition */ + if (!site_state->partitions_available) { + libgamma_site_free(site_state); + printf("No partitions found\n"); + return 1; + } + + /* Let the user select partition */ + printf("Select partition [0, %lu]: ", site_state->partitions_available - 1); + fflush(stdout); + fgets(buf, sizeof(buf) / sizeof(char), stdin); + + /* Initialise partition state */ + if ((r = libgamma_partition_initialise(part_state, site_state, (size_t)atoll(buf)))) { + libgamma_site_free(site_state); + libgamma_perror("error", r); + return 1; + } + + + /* -- CRTC -- */ + + /* Check that the partition has at least one CRTC */ + if (!part_state->crtcs_available) { + libgamma_partition_free(part_state); + libgamma_site_free(site_state); + printf("No CRTC:s found\n"); + return 1; + } + + /* Let the user select CRTC */ + printf("Select CRTC [0, %lu]: ", part_state->crtcs_available - 1); + fflush(stdout); + fgets(buf, sizeof(buf) / sizeof(char), stdin); + + /* Initialise CRTC state. */ + if ((r = libgamma_crtc_initialise(crtc_state, part_state, (size_t)atoll(buf)))) { + libgamma_partition_free(part_state); + libgamma_site_free(site_state); + libgamma_perror("error", r); + return 1; + } + + printf("\n"); + return 0; +} + + + +/** + * Conditionally print a CRTC information field + * + * @param type:data-type Data type for the value of the information field + * @param notation:string-literal %-pattern for `printf` (excluding the %) that is used for `type` + * @param do_print Whether the information should be included in the process's output + * @param description A description of the information field + * @param error The error of the information field + * @param value The value of the information field + */ +#define print_crtc_information_(type, notation)\ + static void\ + print_crtc_information_##type(int do_print, const char *description, int error, type value)\ + {\ + char buf[256];\ + if (do_print) {\ + if (error) {\ + snprintf(buf, sizeof(buf) / sizeof(char), " (error) %s", description);\ + libgamma_perror(buf, error);\ + } else {\ + printf(" %s: %" notation "\n", description, value);\ + }\ + }\ + } + + +/** + * A single [a-z] word alternative to `const char *`, we need it for the + * function name of the string variant of `print_crtc_information_*` + */ +typedef const char *str; +/* Create `print_crtc_information_*` variants */ +print_crtc_information_(size_t, "lu") +print_crtc_information_(signed, "i") +print_crtc_information_(int, "i") +#ifdef __GCC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdouble-promotion" +#endif +print_crtc_information_(float, "f") +#ifdef __GCC__ +# pragma GCC diagnostic pop +#endif +print_crtc_information_(str, "s") +#undef print_crtc_information_ + + +/** + * Get a string representation of a subpixel order + * + * @param value The subpixel order + * @return String representation + */ +static const char * +subpixel_order_str(libgamma_subpixel_order_t value) +{ + const char *r = libgamma_name_of_subpixel_order(value); + return r ? r : "(unknown)"; +} + + +/** + * Get a string representation of a connector type + * + * @param value The connector type + * @return String representation + */ +static const char * +connector_type_str(libgamma_connector_type_t value) +{ + const char *r = libgamma_name_of_connector_type(value); + return r ? r : "(unknown)"; +} + + +/** + * Get a string representation of a decision + * + * @param value The decision + * @return String representation + */ +static const char * +decision_str(libgamma_decision_t value) +{ + switch (value) { + case LIBGAMMA_NO: return "LIBGAMMA_NO"; + case LIBGAMMA_MAYBE: return "LIBGAMMA_MAYBE"; + case LIBGAMMA_YES: return "LIBGAMMA_YES"; + default: + return "(unknown)"; + } +} + + +/** + * The CRTC information for a CRTC + * + * @param crtc The CRTC + */ +static void +crtc_information(libgamma_crtc_state_t *restrict crtc) +{ + libgamma_method_capabilities_t caps; + libgamma_crtc_information_t info; + int fields, field; + char *edid_lc, *edid_uc; + unsigned char *edid_raw; + + /* Get supported CRTC informations fields */ + libgamma_method_capabilities(&caps, crtc->partition->site->method); + + /* List unsupport information fields by testing them one by one */ + for (fields = caps.crtc_information; field = fields & -fields, fields; fields ^= field) { + if (libgamma_get_crtc_information(&info, crtc, field)) + printf("Could not read CRTC information field %i\n", field); + free(info.edid); + free(info.connector_name); + } + + /* Get CRTC information, that is supported */ + fields = caps.crtc_information; + if (libgamma_get_crtc_information(&info, crtc, fields)) + printf("An error occurred while reading CRTC information\n"); + + /* Macros for printing CRTC information */ +#define print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, ERROR_VAR)\ + print_crtc_information_##TYPE(fields & FIELD_ID, DESCRIPTION, info.ERROR_VAR, info.FIELD_VAR); +#define print(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR)\ + print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, FIELD_VAR##_error); + + + /* Print CRTC information */ + + printf("CRTC information:\n"); + + /* Print the EDID field */ + if ((fields & LIBGAMMA_CRTC_INFO_EDID)) { + if (info.edid_error) { + libgamma_perror(" (error) EDID", info.edid_error); + } else { + edid_lc = libgamma_behex_edid(info.edid, info.edid_length); + edid_raw = libgamma_unhex_edid(edid_lc); + edid_uc = libgamma_behex_edid_uppercase(edid_raw, info.edid_length); + printf(" EDID: %s\n", edid_lc); + printf(" EDID (uppercase): %s\n", edid_uc); + printf(" EDID (length): %lu\n", info.edid_length); + free(edid_lc); + free(edid_raw); + free(edid_uc); + } + } + /* Print physical dimensions of the monitor */ + print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM, "width", width_mm); + print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM, "height", height_mm); + print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID, "width per EDID", width_mm_edid); + print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID, "height per EDID", height_mm_edid); + /* Print gamma ramp information */ + print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "red gamma ramp size", red_gamma_size, gamma_size_error); + print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "green gamma ramp size", green_gamma_size, gamma_size_error); + print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "blue gamma ramp size", blue_gamma_size, gamma_size_error); + print(signed, LIBGAMMA_CRTC_INFO_GAMMA_DEPTH, "gamma ramp depth", gamma_depth); + /* Print gamma ramp support */ + if (fields & LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT) { + if (info.gamma_support_error) + libgamma_perror(" (error) gamma support", info.gamma_support_error); + else + printf(" gamma support: %s\n", decision_str(info.gamma_support)); + } + /* Print subpixel order for the monitor */ + if (fields & LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER) { + if (info.subpixel_order_error) + libgamma_perror(" (error) subpixel order", info.subpixel_order_error); + else + printf(" subpixel order: %s\n", subpixel_order_str(info.subpixel_order)); + } + /* Print connector information */ + print(int, LIBGAMMA_CRTC_INFO_ACTIVE, "active", active); + print(str, LIBGAMMA_CRTC_INFO_CONNECTOR_NAME, "connector name", connector_name); + if (fields & LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE) { + if (info.connector_type_error) + libgamma_perror(" (error) subpixel order", info.connector_type_error); + else + printf(" subpixel order: %s\n", connector_type_str(info.connector_type)); + } + /* Print the gamma characteristics of the monitor */ + print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "red gamma characteristics", gamma_red, gamma_error); + print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "green gamma characteristics", gamma_green, gamma_error); + print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "blue gamma characteristics", gamma_blue, gamma_error); + printf("\n"); + + +#undef print +#undef print2 + + /* Release resouces */ + free(info.edid); + free(info.connector_name); +} + + +/** + * The error API + */ +void +error_test(void) +{ + int i; + + /* Test that naming and name dereferencing + of errors work. Because the mappings in + these [`libgamma_value_of_error` and + `libgamma_name_of_error`] functions are + generated, it should work if and only if + one test passes, assumming the errors are + unique whihc is tested in the end of this + function. */ + printf("Testing error API using LIBGAMMA_STATE_UNKNOWN:\n"); + printf(" Expecting %i: %i\n", LIBGAMMA_STATE_UNKNOWN, libgamma_value_of_error("LIBGAMMA_STATE_UNKNOWN")); + printf(" Expecting %s: %s\n", "LIBGAMMA_STATE_UNKNOWN", libgamma_name_of_error(LIBGAMMA_STATE_UNKNOWN)); + printf("\n"); + + /* Test that `libgamma_perror` can print + libgamma errors and system errors, and + handle success in the same with as `perror`. */ + printf("Testing libgamma_perror:\n"); + libgamma_perror(" Expecting LIBGAMMA_STATE_UNKNOWN", LIBGAMMA_STATE_UNKNOWN); + libgamma_perror(" Expecting a description for ENOMEM", ENOMEM); + libgamma_perror(" Expecting a description for successfulness", 0); + /* Test that `libgamma_perror` handles + `LIBGAMMA_ERRNO_SET` correctly. */ + libgamma_perror(" Expecting a description for ENOMEM", (errno = ENOMEM, LIBGAMMA_ERRNO_SET)); + /* That that `libgamma_perror` handles + `LIBGAMMA_DEVICE_REQUIRE_GROUP` + correctly both when the required + group's name is known and when it + is unknown. */ + libgamma_group_gid_set(10); + libgamma_group_name_set("test"); + libgamma_perror(" Expecting 'LIBGAMMA_DEVICE_REQUIRE_GROUP: test (10)'", LIBGAMMA_DEVICE_REQUIRE_GROUP); + libgamma_group_name_set(NULL); + libgamma_perror(" Expecting 'LIBGAMMA_DEVICE_REQUIRE_GROUP: 10'", LIBGAMMA_DEVICE_REQUIRE_GROUP); + printf("\n"); + + /* That all libgamma error codes + are unique. This is done by + getting the name associated + with an error code and the getting + the error code associated that + name and test that the same + error code is returned as put in, + for each libgamma error code. */ + printf("Testing error code uniqueness: "); + for (i = -1; i >= LIBGAMMA_ERROR_MIN; i--) { + if (libgamma_value_of_error(libgamma_name_of_error(i)) != i) { + printf("failed\n"); + goto not_unique; + } + } + printf("passed\n"); +not_unique: + printf("\n"); +} + + + +/** + * Test libgamma + * + * @return Non-zero on machine detectable error, this library + * may still be faulty if zero is returned + */ +int +main(void) +{ + libgamma_site_state_t *site_state = malloc(sizeof(libgamma_site_state_t)); + libgamma_partition_state_t *part_state = malloc(sizeof(libgamma_partition_state_t)); + libgamma_crtc_state_t *crtc_state = malloc(sizeof(libgamma_crtc_state_t)); + libgamma_crtc_information_t info; +#define X(RAMPS)\ + libgamma_gamma_##RAMPS##_t old_##RAMPS, RAMPS;\ + libgamma_gamma_##RAMPS##_fun* f_##RAMPS = dim_##RAMPS; + LIST_RAMPS(X) +#undef X + size_t i, n; + int r, rr = 0; + + /* Test miscellaneous parts of the library */ + list_methods_lists(); + method_availability(); + list_default_sites(); + method_capabilities(); + error_test(); + + /* Select monitor for tests over CRTC:s, partitions and sites */ + if (select_monitor(site_state, part_state, crtc_state)) + return 1; + + /* Test CRTC information functions */ + crtc_information(crtc_state); + + /* Get the sizes of the gamma ramps for the selected CRTC */ + libgamma_get_crtc_information(&info, crtc_state, LIBGAMMA_CRTC_INFO_GAMMA_SIZE); + + /* Create gamma ramps for each depth */ +#define X(R)\ + old_##R.red_size = info.red_gamma_size;\ + old_##R.green_size = info.green_gamma_size;\ + old_##R.blue_size = info.blue_gamma_size;\ + R = old_##R;\ + libgamma_gamma_##R##_initialise(&old_##R);\ + libgamma_gamma_##R##_initialise(&R); + LIST_RAMPS(X) +#undef X + + /* Fill gamma ramps, for each depth, with the CRTC:s current ramps */ +#define X(R)\ + if ((rr |= r = libgamma_crtc_get_gamma_##R(crtc_state, &old_##R))) {\ + libgamma_perror("libgamma_crtc_get_gamma_" #R, r);\ + goto done;\ + }\ + if ((rr |= r = libgamma_crtc_get_gamma_##R(crtc_state, &R))) {\ + libgamma_perror("libgamma_crtc_get_gamma_" #R, r);\ + goto done;\ + } + LIST_RAMPS(X) +#undef X + + /* Test function assisted gamma ramps setting */ +#define X(R)\ + /* Dim the monitor for one second and the restore it. */\ + printf("Dimming monitor output for 1 second... (" #R ")\n");\ + if ((rr |= r = libgamma_crtc_set_gamma_##R##_f(crtc_state, f_##R, f_##R, f_##R)))\ + libgamma_perror("libgamma_crtc_set_gamma_" #R "_f", r);\ + sleep(1);\ + if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, &old_##R)))\ + libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ + printf("Done!\n");\ + /* Sleep for one second, we have more depths to test */\ + printf("Sleeping for 1 second...\n");\ + sleep(1); + LIST_RAMPS(X) +#undef X + + /* Test getting and setting gamma ramps */ +#define X(R)\ + /* Get the grand size of the gamma ramps */\ + n = R.red_size;\ + n = n > R.green_size ? n : R.green_size;\ + n = n > R.blue_size ? n : R.blue_size;\ + /* Print the current gamma ramps */\ + printf("Current gamma ramps (" #R "):\n");\ + for (i = 0; i < n; i++) {\ + if (i < R.red_size) Y(R.red, "1"); else printf(" ");\ + if (i < R.green_size) Y(R.green, "2"); else printf(" ");\ + if (i < R.blue_size) Y(R.blue, "4"); else printf(" ");\ + printf("\n");\ + }\ + printf("\n");\ + /* Adjust the gamma ramps for dimming the monitor */\ + for (i = 0; i < R.red_size + R.green_size + R.blue_size; i++)\ + R.red[i] /= 2;\ + /* Dim the monitor for one second and the restore it */\ + printf("Dimming monitor for 1 second...\n");\ + if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, &R)))\ + libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ + sleep(1);\ + if ((rr |= r = libgamma_crtc_set_gamma_##R(crtc_state, &old_##R)))\ + libgamma_perror("libgamma_crtc_set_gamma_" #R, r);\ + printf("Done!\n");\ + /* Sleep for one second, we have more depths to test */\ + printf("Sleeping for 1 second...\n");\ + sleep(1); +#define Y(R, C) printf(" \033[3" C "m%1.8lf\033[00m", (double)(R[i])) + LIST_FLOAT_RAMPS(X) +#undef Y +#define Y(R, C) printf(" \033[3" C "m%16llX\033[00m", (uint64_t)(R[i])) + LIST_INTEGER_RAMPS(X) +#undef Y +#undef X + + /* Test order of gamma ramps */ + memcpy(ramps16.red, old_ramps16.red, ramps16.red_size * sizeof(uint16_t)); + memset(ramps16.green, 0, ramps16.green_size * sizeof(uint16_t)); + memset(ramps16.blue, 0, ramps16.blue_size * sizeof(uint16_t)); + printf("Making the monitor red-only for 1 second...\n"); + if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, &ramps16))) + libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); + sleep(1); + memset(ramps16.red, 0, ramps16.red_size * sizeof(uint16_t)); + memcpy(ramps16.green, old_ramps16.green, ramps16.green_size * sizeof(uint16_t)); + printf("Making the monitor green-only for 1 second...\n"); + if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, &ramps16))) + libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); + sleep(1); + memset(ramps16.green, 0, ramps16.green_size * sizeof(uint16_t)); + memcpy(ramps16.blue, old_ramps16.blue, ramps16.blue_size * sizeof(uint16_t)); + printf("Making the monitor green-only for 1 second...\n"); + if ((rr |= r = libgamma_crtc_set_gamma_ramps16(crtc_state, &ramps16))) + libgamma_perror("libgamma_crtc_set_gamma_ramps16", r); + sleep(1); + if ((rr |= r = libgamma_crtc_set_gamma_ramps64(crtc_state, &old_ramps64))) + libgamma_perror("libgamma_crtc_set_gamma_ramps64", r); + printf("Done!\n"); + + /* TODO Test gamma ramp restore functions */ + +done: + /* Release resouces */ +#define X(R)\ + libgamma_gamma_##R##_destroy(&R);\ + libgamma_gamma_##R##_destroy(&old_##R); + LIST_RAMPS(X) +#undef X + libgamma_crtc_free(crtc_state); + libgamma_partition_free(part_state); + libgamma_site_free(site_state); + return rr; +} -- cgit v1.2.3-70-g09d2