diff options
author | Mattias Andrée <maandree@kth.se> | 2021-03-06 16:52:22 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2021-03-06 16:52:22 +0100 |
commit | adb5b26bd94e0b90966307274f8fd6cada0fdb92 (patch) | |
tree | 423d934f23abd225213c4d1228de5249f0b2e43d | |
parent | Update todo (diff) | |
download | libgamma-adb5b26bd94e0b90966307274f8fd6cada0fdb92.tar.gz libgamma-adb5b26bd94e0b90966307274f8fd6cada0fdb92.tar.bz2 libgamma-adb5b26bd94e0b90966307274f8fd6cada0fdb92.tar.xz |
Add chroma and white point support from EDID, add version support to methods caps and CRTC info, support EDID 1.4, and support EDID with extensions
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | TODO | 10 | ||||
-rw-r--r-- | common.h | 2 | ||||
-rw-r--r-- | legacy.c | 18 | ||||
-rw-r--r-- | libgamma.h | 304 | ||||
-rw-r--r-- | libgamma_dummy_get_crtc_information.c | 4 | ||||
-rw-r--r-- | libgamma_get_crtc_information.c | 27 | ||||
-rw-r--r-- | libgamma_internal_parse_edid.c | 90 | ||||
-rw-r--r-- | libgamma_linux_drm_get_crtc_information.c | 4 | ||||
-rw-r--r-- | libgamma_list_methods.c | 2 | ||||
-rw-r--r-- | libgamma_method_capabilities.c | 26 | ||||
-rw-r--r-- | libgamma_quartz_cg_get_crtc_information.c | 8 | ||||
-rw-r--r-- | libgamma_w32_gdi_get_crtc_information.c | 4 | ||||
-rw-r--r-- | libgamma_x_randr_get_crtc_information.c | 12 | ||||
-rw-r--r-- | libgamma_x_vidmode_get_crtc_information.c | 4 | ||||
-rw-r--r-- | method-dummy.h | 2 | ||||
-rw-r--r-- | method-linux-drm.h | 3 | ||||
-rw-r--r-- | method-quartz-cg.h | 5 | ||||
-rw-r--r-- | method-w32-gdi.h | 4 | ||||
-rw-r--r-- | method-x-randr.h | 2 | ||||
-rw-r--r-- | method-x-vidmode.h | 3 | ||||
-rw-r--r-- | set_ramps_fun.h | 2 | ||||
-rw-r--r-- | test.c | 38 |
22 files changed, 474 insertions, 100 deletions
@@ -1,11 +1,3 @@ -Important functionality: - CRTC info. shall report the x and y (CIE xyY) values - of the monitor's red, green, and blue colour, as well - as the default white point. CRTC info shall also - report the colour space of the monitors (sRGB, other RGB, - non-RGB, and monochrome/greyscale). This information - is obtainable from the monitor's EDID. - Unsupported display servers: GNU Hurd TTY Does it have gamma ramp support? The BSD TTY:s Do they have gamma ramp support? @@ -16,5 +8,3 @@ Unsupported display servers: Add hotplug support. Generate librarian and pkg-config files. - -Add suport for EDID 1.4. @@ -380,4 +380,4 @@ int libgamma_internal_allocated_any_ramp(gamma_ramps_any_t *restrict, const gamm * @return Non-zero on error */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict, int32_t); +int libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict, unsigned long long); @@ -7,6 +7,8 @@ #undef libgamma_crtc_set_gamma_ramps64 #undef libgamma_crtc_set_gamma_rampsf #undef libgamma_crtc_set_gamma_rampsd +#undef libgamma_get_crtc_information +#undef libgamma_method_capabilities int libgamma_crtc_set_gamma_ramps8(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps8_t); @@ -15,6 +17,8 @@ int libgamma_crtc_set_gamma_ramps32(libgamma_crtc_state_t *restrict, libgamma_ga int libgamma_crtc_set_gamma_ramps64(libgamma_crtc_state_t *restrict, libgamma_gamma_ramps64_t); int libgamma_crtc_set_gamma_rampsf(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsf_t); int libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t *restrict, libgamma_gamma_rampsd_t); +int libgamma_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_method_capabilities(libgamma_method_capabilities_t *restrict, int); int @@ -52,3 +56,17 @@ libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t *restrict this, libgamma_ga { return libgamma_crtc_set_gamma_rampsd__new(this, &ramps); } + +int +libgamma_get_crtc_information(libgamma_crtc_information_t *restrict this, libgamma_crtc_state_t *restrict crtc, int32_t fields) +{ + return libgamma_get_crtc_information__new(this, offsetof(libgamma_crtc_information_t, gamma_error) + + sizeof(this->gamma_error), crtc, (unsigned long long int)fields); +} + +int +libgamma_method_capabilities(libgamma_method_capabilities_t *restrict this, int method) +{ + const size_t size = (_Alignof(unsigned) > sizeof(int32_t) ? _Alignof(unsigned) : sizeof(int32_t)) + sizeof(unsigned); + return libgamma_method_capabilities__new(this, size, method); +} @@ -631,50 +631,68 @@ typedef struct libgamma_method_capabilities { /** * OR of the CRTC information fields in `libgamma_crtc_information_t` * that may (but can fail) be read successfully + * + * @since Always, deprecated as of .struct_version==1, replaced by .crtc_information */ - int32_t crtc_information; + int32_t crtc_information__old; /** * Whether the default site is known, if true the site is integrated * to the system or can be determined using environment variables + * + * @since Always */ unsigned default_site_known : 1; /** * Whether the adjustment method supports multiple sites rather * than just the default site + * + * @since Always */ unsigned multiple_sites : 1; /** * Whether the adjustment method supports multiple partitions * per site + * + * @since Always */ unsigned multiple_partitions : 1; /** * Whether the adjustment method supports multiple CRTC:s * per partition per site + * + * @since Always */ unsigned multiple_crtcs : 1; /** * Whether the partition to graphics card is a bijection + * + * @since Always */ unsigned partitions_are_graphics_cards : 1; /** * Whether the adjustment method supports `libgamma_site_restore` + * + * @since Always */ unsigned site_restore : 1; /** * Whether the adjustment method supports `libgamma_partition_restore` + * + * @since Always */ unsigned partition_restore : 1; /** * Whether the adjustment method supports `libgamma_crtc_restore` + * + * @since Always */ unsigned crtc_restore : 1; @@ -682,6 +700,8 @@ typedef struct libgamma_method_capabilities { * 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 + * + * @since Always */ unsigned identical_gamma_sizes : 1; @@ -689,33 +709,69 @@ typedef struct libgamma_method_capabilities { * 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 + * + * @since Always */ 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 + * + * @since Always */ unsigned fixed_gamma_depth : 1; /** * Whether the adjustment method will actually perform adjustments + * + * @since Always */ unsigned real : 1; /** * Whether the adjustment method is implement using a translation layer + * + * @since Always */ unsigned fake : 1; /** * Whether adjustments are undone when the process disconnects from * the display server + * + * @since Always */ unsigned auto_restore : 1; + /** + * Set by the library to inform the program which fields + * have been set + * + * @since .struct_version==1 (version 0.8 of the library, which made + * `libgamma_method_capabilities` a 3-parameter function) + */ + int struct_version; + + /** + * OR of the CRTC information fields in `libgamma_crtc_information_t` + * that may (but can fail) be read successfully + * + * @since .struct_version==1, replaces .crtc_information__old (previously named .crtc_information) + */ + unsigned long long crtc_information; + } libgamma_method_capabilities_t; +/** + * The number the version of the library the program is + * compiled against will set the `struct_version` field + * in `libgamma_method_capabilities_t` to; note that the + * version of the library the program is linked against + * may set it to another value + */ +#define LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION 1 + /** * Site state @@ -845,7 +901,7 @@ 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) +#define LIBGAMMA_CRTC_INFO_EDID (1ULL << 0) /** * The Extended Display Identification Data associated with @@ -854,11 +910,15 @@ typedef struct libgamma_crtc_information { * This is raw byte array that is usually 128 bytes long. * It is not NUL-terminate, rather its length is stored in * `edid_length`. + * + * @since Always */ unsigned char *edid; /** * The length of `edid` + * + * @since Always */ size_t edid_length; @@ -866,6 +926,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int edid_error; @@ -874,7 +936,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_WIDTH_MM (1ULL << 1) /** * The phyical width, in millimetres, of the viewport of the @@ -886,6 +948,8 @@ typedef struct libgamma_crtc_information { * * Zero means that its is not applicable, which is the case * for projectors + * + * @since Always */ size_t width_mm; @@ -893,6 +957,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int width_mm_error; @@ -901,7 +967,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_HEIGHT_MM (1ULL << 2) /** * The phyical height, in millimetres, of the viewport of the @@ -913,6 +979,8 @@ typedef struct libgamma_crtc_information { * * Zero means that its is not applicable, which is the case * for projectors + * + * @since Always */ size_t height_mm; @@ -920,6 +988,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int height_mm_error; @@ -928,7 +998,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID (1ULL << 3) /** * The phyical width, in millimetres, of the viewport of the @@ -941,6 +1011,8 @@ typedef struct libgamma_crtc_information { * * Zero means that its is not applicable, which is the case * for projectors. + * + * @since Always */ size_t width_mm_edid; @@ -948,6 +1020,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int width_mm_edid_error; @@ -956,7 +1030,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID (1ULL << 4) /** * The phyical height, in millimetres, of the viewport of the @@ -969,6 +1043,8 @@ typedef struct libgamma_crtc_information { * * Zero means that its is not applicable, which is the case * for projectors + * + * @since Always */ size_t height_mm_edid; @@ -976,6 +1052,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int height_mm_edid_error; @@ -985,20 +1063,26 @@ typedef struct libgamma_crtc_information { * `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) +#define LIBGAMMA_CRTC_INFO_GAMMA_SIZE (1ULL << 5) /** * The size of the encoding axis of the red gamma ramp + * + * @since Always */ size_t red_gamma_size; /** * The size of the encoding axis of the green gamma ramp + * + * @since Always */ size_t green_gamma_size; /** * The size of the encoding axis of the blue gamma ramp + * + * @since Always */ size_t blue_gamma_size; @@ -1006,6 +1090,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int gamma_size_error; @@ -1014,12 +1100,14 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_GAMMA_DEPTH (1ULL << 6) /** * The bit-depth of the value axes of gamma ramps, * -1 for single precision floating point, and -2 for * double precision floating point + * + * @since Always */ signed gamma_depth; @@ -1027,6 +1115,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int gamma_depth_error; @@ -1035,7 +1125,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT (1ULL << 7) /** * `LIBGAMMA_NO` indicates that the CRTC does not support @@ -1044,6 +1134,8 @@ typedef struct libgamma_crtc_information { * 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. + * + * @since Always */ libgamma_decision_t gamma_support; @@ -1051,6 +1143,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int gamma_support_error; @@ -1059,7 +1153,7 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER (1ULL << 8) /** * The layout of the subpixels @@ -1067,6 +1161,8 @@ typedef struct libgamma_crtc_information { * You cannot count on this value — especially for CRT:s — * but it is provided anyway as a means of distinguishing * monitors + * + * @since Always */ libgamma_subpixel_order_t subpixel_order; @@ -1074,6 +1170,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int subpixel_order_error; @@ -1082,10 +1180,12 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_ACTIVE (1ULL << 9) /** * Whether there is a monitor connected to the CRTC + * + * @since Always */ int active; @@ -1093,6 +1193,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int active_error; @@ -1101,12 +1203,14 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_CONNECTOR_NAME (1ULL << 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. + * + * @since Always */ char *connector_name; @@ -1114,6 +1218,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int connector_name_error; @@ -1122,10 +1228,12 @@ typedef struct libgamma_crtc_information { * 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) +#define LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE (1ULL << 11) /** * The type of the connector that is associated with the CRTC + * + * @since Always */ libgamma_connector_type_t connector_type; @@ -1133,6 +1241,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ int connector_type_error; @@ -1142,7 +1252,7 @@ typedef struct libgamma_crtc_information { * values for `gamma_red`, `gamma_green`, and `gamma_blue` * and report errors to `gamma_error` */ -#define LIBGAMMA_CRTC_INFO_GAMMA (1 << 12) +#define LIBGAMMA_CRTC_INFO_GAMMA (1ULL << 12) /** * The gamma characteristics of the monitor as reported @@ -1153,6 +1263,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ float gamma_red; @@ -1165,6 +1277,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ float gamma_green; @@ -1177,6 +1291,8 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ float gamma_blue; @@ -1184,21 +1300,146 @@ typedef struct libgamma_crtc_information { * 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 + * + * @since Always */ 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 */ + + + /** + * Set by the library to inform the program which fields + * have been set + * + * @since .struct_version==1 (version 0.8 of the library, which made + * `libgamma_get_crtc_information` a 4-parameter function) + */ + int struct_version; + + +/** + * For a `libgamma_crtc_information_t` fill in the values + * for `red_chroma_x`, `red_chroma_y`, `green_chroma_x`, + * `green_chroma_y`, `blue_chroma_x`, and `blue_chroma_y` + * and report errors to `gamma_error` + */ +#define LIBGAMMA_CRTC_INFO_CHROMA (1ULL << 13) + + /** + * The x coordinate of the red subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float red_chroma_x; + + /** + * The y coordinate of the red subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float red_chroma_y; + + /** + * The x coordinate of the green subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float green_chroma_x; + + /** + * The y coordinate of the green subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float green_chroma_y; + + /** + * The x coordinate of the blue subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float blue_chroma_x; + + /** + * The y coordinate of the blue subpixels chroma + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float blue_chroma_y; + + /** + * 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 + * + * @since .struct_version==1 + */ + int chroma_error; + + +/** + * For a `libgamma_crtc_information_t` fill in the values + * for `white_point_x`, `white_point_y` and report errors + * to `white_point_error` + */ +#define LIBGAMMA_CRTC_INFO_WHITE_POINT (1ULL << 14) + + /** + * The x coordinate of the white point + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float white_point_x; + + /** + * The y coordinate of the white point + * + * 2° CIE 1931 xy coordinates are used + * + * @since .struct_version==1 + */ + float white_point_y; + + /** + * 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 + * + * @since .struct_version==1 + */ + int white_point_error; + + + + /* DEVELOPERS: Remember to update LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION, + * LIBGAMMA_CRTC_INFO_COUNT, and LIBGAMMA_CRTC_INFO_MACRO_EDID + * macros below and may add additional LIBGAMMA_CRTC_INFO_MACRO_* + * 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 +#define LIBGAMMA_CRTC_INFO_COUNT 15 /** * The number of `LIBGAMMA_CRTC_INFO_*` values defined in @@ -1207,6 +1448,15 @@ typedef struct libgamma_crtc_information { extern const int libgamma_crtc_info_count; /** + * The number the version of the library the program is + * compiled against will set the `struct_version` field + * in `libgamma_crtc_information_t` to; note that the + * version of the library the program is linked against + * may set it to another value + */ +#define LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION 1 + +/** * 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 @@ -1220,7 +1470,14 @@ extern const int libgamma_crtc_info_count; * 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) +#define LIBGAMMA_CRTC_INFO_MACRO_EDID (LIBGAMMA_CRTC_INFO_EDID | LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT |\ + LIBGAMMA_CRTC_INFO_GAMMA | LIBGAMMA_CRTC_INFO_MACRO_COLOUR_SPACE) + +/** + * Macro for the `libgamma_crtc_information_t` fields + * that specifies the monitors colour space + */ +#define LIBGAMMA_CRTC_INFO_MACRO_COLOUR_SPACE (LIBGAMMA_CRTC_INFO_CHROMA | LIBGAMMA_CRTC_INFO_WHITE_POINT) /** * Macro for both `libgamma_crtc_information_t` fields @@ -2007,12 +2264,15 @@ 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 size Should be `sizeof(*this)`, used to let the library know which version + * of the structure is used so that it does not write outside of it * @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 */ LIBGAMMA_GCC_ONLY__(__attribute__((__access__(__write_only__, 1)))) -int libgamma_method_capabilities(libgamma_method_capabilities_t *restrict, int); +int libgamma_method_capabilities__new(libgamma_method_capabilities_t *restrict, size_t, int); +#define libgamma_method_capabilities libgamma_method_capabilities__new /** * Return the default site for an adjustment method @@ -2185,12 +2445,16 @@ 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 size Should be `sizeof(*this)`, used to let the library know which version + * of the structure is used so that it does not write outside of it * @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__, __access__(__write_only__, 1)))) -int libgamma_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_get_crtc_information__new(libgamma_crtc_information_t *restrict, size_t, + libgamma_crtc_state_t *restrict, unsigned long long); +#define libgamma_get_crtc_information libgamma_get_crtc_information__new /** * Release all resources in an information data structure for a CRTC diff --git a/libgamma_dummy_get_crtc_information.c b/libgamma_dummy_get_crtc_information.c index 2fb4ec6..f8f885e 100644 --- a/libgamma_dummy_get_crtc_information.c +++ b/libgamma_dummy_get_crtc_information.c @@ -9,11 +9,11 @@ * @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` + * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ int libgamma_dummy_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { libgamma_dummy_crtc_t *restrict data = crtc->data; int supported = libgamma_dummy_internal_configurations.capabilities.crtc_information; diff --git a/libgamma_get_crtc_information.c b/libgamma_get_crtc_information.c index 5c7e2fe..58011dd 100644 --- a/libgamma_get_crtc_information.c +++ b/libgamma_get_crtc_information.c @@ -6,23 +6,46 @@ * Read information about a CRTC * * @param this Instance of a data structure to fill with the information about the CRTC + * @param size Should be `sizeof(*this)`, used to let the library know which version + * of the structure is used so that it does not write outside of it * @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) +libgamma_get_crtc_information(libgamma_crtc_information_t *restrict this, size_t size, + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { + libgamma_crtc_information_t info_; + int r, (*func)(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, unsigned long long); + this->edid = NULL; this->connector_name = NULL; switch (crtc->partition->site->method) { #define X(CONST, CNAME, ...)\ case CONST:\ - return libgamma_##CNAME##_get_crtc_information(this, crtc, fields); + func = libgamma_##CNAME##_get_crtc_information;\ + break; LIST_AVAILABLE_METHODS(X) #undef X default: return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD; } + + if (size == sizeof(info_)) { + r = func(this, crtc, fields); + this->struct_version = LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION; + return r; + } else { + info_.struct_version = LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION; + r = func(&info_, crtc, fields); + if (size < sizeof(info_)) { + memcpy(this, &info_, size); + } else { + memcpy(this, &info_, sizeof(info_)); + memset(&((char *)this)[size], 0, size - sizeof(info_)); + } + return r; + } } diff --git a/libgamma_internal_parse_edid.c b/libgamma_internal_parse_edid.c index aa1b87c..32641c1 100644 --- a/libgamma_internal_parse_edid.c +++ b/libgamma_internal_parse_edid.c @@ -7,6 +7,9 @@ * http://en.wikipedia.org/w/index.php?title=Extended_display_identification_data&oldid=46295569 * * EDID structure revision 1.3: + * https://en.wikipedia.org/w/index.php?title=Extended_Display_Identification_Data&oldid=805561402#EDID_1.3_data_format + * + * EDID structure revision 1.4: * http://en.wikipedia.org/wiki/Extended_display_identification_data */ @@ -21,47 +24,54 @@ * @return Non-zero on error */ int -libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict this, int32_t fields) +libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict this, unsigned long long fields) { #define __test_version(edid, major, minor_min, minor_max)\ ((edid)[18] == (major) && (minor_min) <= (edid)[19] && (edid)[19] <= (minor_max)) #define __m(value)\ (this->edid[index++] != (value)) + uint16_t red_x, green_x, blue_x, white_x; + uint16_t red_y, green_y, blue_y, white_y; int error = 0, checksum = 0; size_t i, index = 0; - /* If the length of the EDID is not 128 bytes, we know that it is not of EDID - structure revision 1.0–1.3, and thus we do not support it. Additionally - this make sure we do not do segmentation violation on the next test. */ - if (this->edid_length != 128) + /* If the length of the EDID is less than 128 bytes, we know that it is + * not of EDID structure revision 1.0–1.4, and thus we do not support it; + * however, extensions allows it to be longer tha 128 bytes */ + if (this->edid_length < 128) error = LIBGAMMA_EDID_LENGTH_UNSUPPORTED; - /* Check that the magic number of that of the EDID structure. */ + /* Check that the magic number of that of the EDID structure */ else if (__m(0x00) || __m(0xFF) || __m(0xFF) || __m(0xFF) || __m(0xFF) || __m(0xFF) || __m(0xFF) || __m(0x00)) error = LIBGAMMA_EDID_WRONG_MAGIC_NUMBER; - /* Check that EDID structure revision 1.1–1.3 is used, those are the only - version we support. EDID structure revision 1.3 is also by far the most - commonly use revision and it is currently the newest revision. We know - that parsing works for both revision 1.1 and revision 1.3, because of - this we assume it is also correct for revision 1.2. However, we are not - assuming this for revision 1.0 which appeared in August 1994 and was - replaced by revision 1.1 in April 1996. */ - else if (!__test_version(this->edid, 1, 1, 3)) + /* Check that EDID structure revision 1.1–1.4 is used, those are the only + * version we support. EDID structure revisions 1.3 and 1.4 is also by far + * the most commonly use revision and it is currently the newest revisions. + * We know that parsing works for revisions 1.1, 1.3, and 1.4, because of + * this we assume it is also correct for revision 1.2. However, we are not + * assuming this for revision 1.0 which appeared in August 1994 and was + * replaced by revision 1.1 in April 1996. */ + else if (!__test_version(this->edid, 1, 1, 4)) error = LIBGAMMA_EDID_REVISION_UNSUPPORTED; /* If we have encountered an error, report it for the fields that require - the EDID to be parsed. Note that it is not stored for the EDID field - itself because it is not considered an error just because we do not - support the used version. */ + * the EDID to be parsed. Note that it is not stored for the EDID field + * itself because it is not considered an error just because we do not + * support the used version. */ this->width_mm_edid_error = this->height_mm_edid_error = this->gamma_error = error; + this->chroma_error = this->white_point_error = error; + + /* Set errors and exit if we have error, especially important if this->edid_length < 128 */ + if (error) + goto out; /* Retrieve the size of the viewport. This is done even if it is not - requested because it is not worth it branch. */ + * requested because it is not worth it to branch. */ this->width_mm_edid = (size_t)this->edid[21] * 10; this->height_mm_edid = (size_t)this->edid[22] * 10; - /* Retrieve the monitor's gamma characteristics. */ - if ((fields & LIBGAMMA_CRTC_INFO_GAMMA) && !error) { + /* Retrieve the monitor's gamma characteristics */ + if (fields & LIBGAMMA_CRTC_INFO_GAMMA) { if (this->edid[23] == 0xFF) { /* If the gamma charactistics is FFh (3,55) it should be interpreted as not specified. */ this->gamma_error = LIBGAMMA_GAMMA_NOT_SPECIFIED; @@ -71,27 +81,49 @@ libgamma_internal_parse_edid(libgamma_crtc_information_t *restrict this, int32_t } } - /* 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. */ + /* Retrieve the monitor's subpixel chromas */ + if (fields & (LIBGAMMA_CRTC_INFO_CHROMA | LIBGAMMA_CRTC_INFO_WHITE_POINT)) { + red_x = (((uint16_t)this->edid[25] >> 6) & 2) | ((uint16_t)this->edid[27] << 2); + red_y = (((uint16_t)this->edid[25] >> 4) & 2) | ((uint16_t)this->edid[28] << 2); + green_x = (((uint16_t)this->edid[25] >> 2) & 2) | ((uint16_t)this->edid[29] << 2); + green_y = (((uint16_t)this->edid[25] >> 0) & 2) | ((uint16_t)this->edid[30] << 2); + blue_x = (((uint16_t)this->edid[26] >> 6) & 2) | ((uint16_t)this->edid[31] << 2); + blue_y = (((uint16_t)this->edid[26] >> 4) & 2) | ((uint16_t)this->edid[32] << 2); + white_x = (((uint16_t)this->edid[26] >> 2) & 2) | ((uint16_t)this->edid[33] << 2); + white_y = (((uint16_t)this->edid[26] >> 6) & 2) | ((uint16_t)this->edid[34] << 2); + /* Even though the maximum value as encoded is 1023, the values should be divided by 1024 */ + this->red_chroma_x = (float)red_x / 1024.f; + this->red_chroma_y = (float)red_y / 1024.f; + this->green_chroma_x = (float)green_x / 1024.f; + this->green_chroma_y = (float)green_y / 1024.f; + this->blue_chroma_x = (float)blue_x / 1024.f; + this->blue_chroma_y = (float)blue_y / 1024.f; + this->white_point_x = (float)white_x / 1024.f; + this->white_point_y = (float)white_y / 1024.f; + } + + /* Calculate and test the checksum. It is not considered + * an error that the gamma characteristics is left + * unspecified in the EDID. */ if (!error) - for (i = 0; i < this->edid_length; i++) + for (i = 0; i < 128; i++) checksum += (int)this->edid[i]; - /* The checksum should be zero. */ + /* The checksum should be zero */ if (checksum & 255) { /* Store the error in all fields that require the EDID to be parsed, - as well as the EDID field itself. */ + * as well as the EDID field itself */ error = LIBGAMMA_EDID_CHECKSUM_ERROR; + out: this->edid_error = this->width_mm_edid_error = this->height_mm_edid_error = error; /* If the gamma characteristics is not specified, that is kept, - and the checksum error is augmented. */ + * and the checksum error is augmented. */ this->gamma_error = this->gamma_error == LIBGAMMA_GAMMA_NOT_SPECIFIED ? LIBGAMMA_GAMMA_NOT_SPECIFIED_AND_EDID_CHECKSUM_ERROR : error; } /* Return whether or not we encountered an error or if - the gamma characteristics was requested but is not - specified in the monitor's EDID. */ + * the gamma characteristics was requested but is not + * specified in the monitor's EDID */ return error | this->gamma_error; #undef __m diff --git a/libgamma_linux_drm_get_crtc_information.c b/libgamma_linux_drm_get_crtc_information.c index 2927702..39ec116 100644 --- a/libgamma_linux_drm_get_crtc_information.c +++ b/libgamma_linux_drm_get_crtc_information.c @@ -189,7 +189,7 @@ get_connector_type(libgamma_crtc_information_t *restrict out, const drmModeConne */ static int read_connector_data(libgamma_crtc_state_t *restrict crtc, libgamma_crtc_information_t *restrict out, - const drmModeConnector *restrict connector, int32_t fields) + const drmModeConnector *restrict connector, unsigned long long int fields) { const char *connector_name_base = NULL; libgamma_drm_card_data_t *restrict card; @@ -314,7 +314,7 @@ get_edid(libgamma_crtc_state_t *restrict crtc, libgamma_crtc_information_t *rest */ int libgamma_linux_drm_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { #define _E(FIELD) ((fields & FIELD) ? LIBGAMMA_CRTC_INFO_NOT_SUPPORTED : 0) diff --git a/libgamma_list_methods.c b/libgamma_list_methods.c index 7c923f1..45faff4 100644 --- a/libgamma_list_methods.c +++ b/libgamma_list_methods.c @@ -48,7 +48,7 @@ list_method_test(int method, int operation) libgamma_method_capabilities_t caps; int fd, r, saved_errno; - libgamma_method_capabilities(&caps, method); + libgamma_method_capabilities(&caps, sizeof(caps), method); switch (operation) { case 0: diff --git a/libgamma_method_capabilities.c b/libgamma_method_capabilities.c index d5bdb93..6c44056 100644 --- a/libgamma_method_capabilities.c +++ b/libgamma_method_capabilities.c @@ -6,23 +6,43 @@ * Return the capabilities of an adjustment method * * @param this The data structure to fill with the method's capabilities + * @param size Should be `sizeof(*this)`, used to let the library know which version + * of the structure is used so that it does not write outside of it * @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) +libgamma_method_capabilities(libgamma_method_capabilities_t *restrict this, size_t size, int method) { + libgamma_method_capabilities_t caps_; + void (*func)(libgamma_method_capabilities_t *restrict); + memset(this, 0, sizeof(*this)); switch (method) { #define X(CONST, CNAME, ...)\ case CONST:\ - libgamma_##CNAME##_method_capabilities(this);\ - return 0; + func = libgamma_##CNAME##_method_capabilities;\ + break; LIST_AVAILABLE_METHODS(X) #undef X default: return LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD; } + + if (size == sizeof(caps_)) { + func(this); + this->struct_version = LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION; + } else { + func(&caps_); + caps_.struct_version = LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION; + if (size < sizeof(caps_)) { + memcpy(this, &caps_, size); + } else { + memcpy(this, &caps_, sizeof(caps_)); + memset(&((char *)this)[size], 0, size - sizeof(caps_)); + } + } + this->crtc_information__old = (int32_t)this->crtc_information; } diff --git a/libgamma_quartz_cg_get_crtc_information.c b/libgamma_quartz_cg_get_crtc_information.c index 185c3f5..8104075 100644 --- a/libgamma_quartz_cg_get_crtc_information.c +++ b/libgamma_quartz_cg_get_crtc_information.c @@ -9,12 +9,12 @@ * * @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` + * @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_quartz_cg_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { #define SUPPORTED_FIELDS (LIBGAMMA_CRTC_INFO_GAMMA_SIZE | LIBGAMMA_CRTC_INFO_GAMMA_DEPTH) #define _E(FIELD) ((fields & FIELD) ? LIBGAMMA_CRTC_INFO_NOT_SUPPORTED : 0) @@ -29,7 +29,7 @@ libgamma_quartz_cg_get_crtc_information(libgamma_crtc_information_t *restrict th this->width_mm_edid_error = _E(LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID); this->height_mm_edid_error = _E(LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID); /* Quartz/CoreGraphics does support gamma ramp size query - The gamma ramps are identical but not fixed, and the query can fail */ + * The gamma ramps are identical but not fixed, and the query can fail */ this->gamma_size_error = 0; if ((fields & LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) { crtcs = crtc->partition->data; diff --git a/libgamma_w32_gdi_get_crtc_information.c b/libgamma_w32_gdi_get_crtc_information.c index 7ffb0e2..d7bda38 100644 --- a/libgamma_w32_gdi_get_crtc_information.c +++ b/libgamma_w32_gdi_get_crtc_information.c @@ -10,11 +10,11 @@ * @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` + * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ int libgamma_w32_gdi_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { #define KNOWN_FIELDS (LIBGAMMA_CRTC_INFO_GAMMA_SIZE | LIBGAMMA_CRTC_INFO_GAMMA_DEPTH) #define _E(FIELD) ((fields & FIELD) ? LIBGAMMA_CRTC_INFO_NOT_SUPPORTED : 0) diff --git a/libgamma_x_randr_get_crtc_information.c b/libgamma_x_randr_get_crtc_information.c index 29abd8b..c457bd6 100644 --- a/libgamma_x_randr_get_crtc_information.c +++ b/libgamma_x_randr_get_crtc_information.c @@ -95,8 +95,8 @@ static int get_connector_type(libgamma_crtc_information_t *restrict this) { /* Since we require the name of the output of get the type of the connected, - copy any reported error on the output's name to the connector's type, - and report failure if there was an error */ + * copy any reported error on the output's name to the connector's type, + * and report failure if there was an error */ if ((this->connector_type_error = this->connector_name_error)) return -1; @@ -198,8 +198,10 @@ get_edid(libgamma_crtc_information_t *restrict out, libgamma_crtc_state_t *restr /* Acquire a list of all properties of the output */ prop_cookie = xcb_randr_list_output_properties(connection, output); prop_reply = xcb_randr_list_output_properties_reply(connection, prop_cookie, &error); - if (error) - return out->edid_error = libgamma_x_randr_internal_translate_error(error->error_code, LIBGAMMA_LIST_PROPERTIES_FAILED, 1); + if (error) { + return out->edid_error = libgamma_x_randr_internal_translate_error(error->error_code, + LIBGAMMA_LIST_PROPERTIES_FAILED, 1); + } /* Extract the properties form the data structure that holds them, */ atoms = xcb_randr_list_output_properties_atoms(prop_reply); @@ -289,7 +291,7 @@ get_edid(libgamma_crtc_information_t *restrict out, libgamma_crtc_state_t *restr */ int libgamma_x_randr_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { #define _E(FIELD) ((fields & FIELD) ? LIBGAMMA_CRTC_INFO_NOT_SUPPORTED : 0) diff --git a/libgamma_x_vidmode_get_crtc_information.c b/libgamma_x_vidmode_get_crtc_information.c index c3cc367..60b0a89 100644 --- a/libgamma_x_vidmode_get_crtc_information.c +++ b/libgamma_x_vidmode_get_crtc_information.c @@ -9,11 +9,11 @@ * @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; oOn error refer to the error reports in `this` + * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ int libgamma_x_vidmode_get_crtc_information(libgamma_crtc_information_t *restrict this, - libgamma_crtc_state_t *restrict crtc, int32_t fields) + libgamma_crtc_state_t *restrict crtc, unsigned long long fields) { #define _E(FIELD) ((fields & FIELD) ? LIBGAMMA_CRTC_INFO_NOT_SUPPORTED : 0) diff --git a/method-dummy.h b/method-dummy.h index 9fa1df6..8d84f05 100644 --- a/method-dummy.h +++ b/method-dummy.h @@ -301,7 +301,7 @@ int libgamma_dummy_crtc_restore(libgamma_crtc_state_t *restrict); * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_dummy_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_dummy_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, unsigned long long); /** diff --git a/method-linux-drm.h b/method-linux-drm.h index b30341d..1e8de08 100644 --- a/method-linux-drm.h +++ b/method-linux-drm.h @@ -147,7 +147,8 @@ int libgamma_linux_drm_crtc_restore(libgamma_crtc_state_t *restrict); * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_linux_drm_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_linux_drm_get_crtc_information(libgamma_crtc_information_t *restrict, + libgamma_crtc_state_t *restrict, unsigned long long); /** * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version diff --git a/method-quartz-cg.h b/method-quartz-cg.h index 96effa5..177378e 100644 --- a/method-quartz-cg.h +++ b/method-quartz-cg.h @@ -121,10 +121,11 @@ int libgamma_quartz_cg_crtc_restore(libgamma_crtc_state_t *restrict); * @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` + * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_quartz_cg_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_quartz_cg_get_crtc_information(libgamma_crtc_information_t *restrict, + libgamma_crtc_state_t *restrict, unsigned long long); /** * Get the current gamma ramps for a CRTC, `float` version diff --git a/method-w32-gdi.h b/method-w32-gdi.h index 811c546..43f1dcc 100644 --- a/method-w32-gdi.h +++ b/method-w32-gdi.h @@ -131,10 +131,10 @@ int libgamma_w32_gdi_crtc_restore(libgamma_crtc_state_t *restrict); * @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` + * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_w32_gdi_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_w32_gdi_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, unsigned long long); /** * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version diff --git a/method-x-randr.h b/method-x-randr.h index 51dc0bf..047498b 100644 --- a/method-x-randr.h +++ b/method-x-randr.h @@ -168,7 +168,7 @@ int libgamma_x_randr_crtc_restore(libgamma_crtc_state_t *restrict); * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_x_randr_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_x_randr_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, unsigned long long); /** * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version diff --git a/method-x-vidmode.h b/method-x-vidmode.h index 8370e86..0fe3d09 100644 --- a/method-x-vidmode.h +++ b/method-x-vidmode.h @@ -120,7 +120,8 @@ int libgamma_x_vidmode_crtc_restore(libgamma_crtc_state_t *restrict); * @return Zero on success, -1 on error; on error refer to the error reports in `this` */ LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__))) -int libgamma_x_vidmode_get_crtc_information(libgamma_crtc_information_t *restrict, libgamma_crtc_state_t *restrict, int32_t); +int libgamma_x_vidmode_get_crtc_information(libgamma_crtc_information_t *restrict, + libgamma_crtc_state_t *restrict, unsigned long long); /** * Get the current gamma ramps for a CRTC, 16-bit gamma-depth version diff --git a/set_ramps_fun.h b/set_ramps_fun.h index 5a3b541..a177568 100644 --- a/set_ramps_fun.h +++ b/set_ramps_fun.h @@ -12,7 +12,7 @@ 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)) { +if (libgamma_get_crtc_information(&info, sizeof(info), this, LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) { e = info.gamma_size_error; if (e < 0) return e; @@ -16,8 +16,8 @@ #endif -#if LIBGAMMA_CRTC_INFO_COUNT != 13 -# warning CRTC information fields have been updated +#if LIBGAMMA_CRTC_INFO_COUNT != 15 +# error CRTC information fields have been updated #endif @@ -278,7 +278,11 @@ method_capabilities(void) /* Print adjustment method name and get the * adjustment method's capabilities. */ printf("Capabilities of %s:\n", method_name(method)); - libgamma_method_capabilities(&caps, method); + libgamma_method_capabilities(&caps, sizeof(caps), method); + if (caps.struct_version != LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION) { + fprintf(stderr, "LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION must be updated\n"); + exit(1); + } /* Print capabilities. The CRTC information * capabilities is printed hexadecimal. See @@ -515,16 +519,20 @@ crtc_information(libgamma_crtc_state_t *restrict crtc) { libgamma_method_capabilities_t caps; libgamma_crtc_information_t info; - int fields, field; + unsigned long long 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); + libgamma_method_capabilities(&caps, sizeof(caps), crtc->partition->site->method); + if (caps.struct_version != LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION) { + fprintf(stderr, "LIBGAMMA_METHOD_CAPABILITIES_STRUCT_VERSION must be updated\n"); + exit(1); + } /* 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)) + if (libgamma_get_crtc_information(&info, sizeof(info), crtc, field)) printf("Could not read CRTC information field %i\n", field); free(info.edid); free(info.connector_name); @@ -532,8 +540,12 @@ crtc_information(libgamma_crtc_state_t *restrict crtc) /* Get CRTC information, that is supported */ fields = caps.crtc_information; - if (libgamma_get_crtc_information(&info, crtc, fields)) + if (libgamma_get_crtc_information(&info, sizeof(info), crtc, fields)) printf("An error occurred while reading CRTC information\n"); + if (info.struct_version != LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION) { + fprintf(stderr, "LIBGAMMA_CRTC_INFORMATION_STRUCT_VERSION must be updated\n"); + exit(1); + } /* Macros for printing CRTC information */ #define print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, ERROR_VAR)\ @@ -599,6 +611,16 @@ crtc_information(libgamma_crtc_state_t *restrict crtc) 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); + /* Print the colour space of the monitor */ + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "red chroma x", red_chroma_x, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "red chroma y", red_chroma_y, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "green chroma x", green_chroma_x, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "green chroma y", green_chroma_y, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "blue chroma x", blue_chroma_x, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_CHROMA, "blue chroma y", blue_chroma_y, chroma_error); + print2(float, LIBGAMMA_CRTC_INFO_WHITE_POINT, "white point x", white_point_x, white_point_error); + print2(float, LIBGAMMA_CRTC_INFO_WHITE_POINT, "white point y", white_point_y, white_point_error); + printf("\n"); @@ -1380,7 +1402,7 @@ main(void) 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); + libgamma_get_crtc_information(&info, sizeof(info), crtc_state, LIBGAMMA_CRTC_INFO_GAMMA_SIZE); /* Create gamma ramps for each depth */ #define X(R)\ |