aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-03-06 16:52:22 +0100
committerMattias Andrée <maandree@kth.se>2021-03-06 16:52:22 +0100
commitadb5b26bd94e0b90966307274f8fd6cada0fdb92 (patch)
tree423d934f23abd225213c4d1228de5249f0b2e43d
parentUpdate todo (diff)
downloadlibgamma-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--TODO10
-rw-r--r--common.h2
-rw-r--r--legacy.c18
-rw-r--r--libgamma.h304
-rw-r--r--libgamma_dummy_get_crtc_information.c4
-rw-r--r--libgamma_get_crtc_information.c27
-rw-r--r--libgamma_internal_parse_edid.c90
-rw-r--r--libgamma_linux_drm_get_crtc_information.c4
-rw-r--r--libgamma_list_methods.c2
-rw-r--r--libgamma_method_capabilities.c26
-rw-r--r--libgamma_quartz_cg_get_crtc_information.c8
-rw-r--r--libgamma_w32_gdi_get_crtc_information.c4
-rw-r--r--libgamma_x_randr_get_crtc_information.c12
-rw-r--r--libgamma_x_vidmode_get_crtc_information.c4
-rw-r--r--method-dummy.h2
-rw-r--r--method-linux-drm.h3
-rw-r--r--method-quartz-cg.h5
-rw-r--r--method-w32-gdi.h4
-rw-r--r--method-x-randr.h2
-rw-r--r--method-x-vidmode.h3
-rw-r--r--set_ramps_fun.h2
-rw-r--r--test.c38
22 files changed, 474 insertions, 100 deletions
diff --git a/TODO b/TODO
index 4cbb180..e8fcc7c 100644
--- a/TODO
+++ b/TODO
@@ -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.
diff --git a/common.h b/common.h
index 8cad179..2235c33 100644
--- a/common.h
+++ b/common.h
@@ -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);
diff --git a/legacy.c b/legacy.c
index d4d1cf1..c53a3fe 100644
--- a/legacy.c
+++ b/legacy.c
@@ -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);
+}
diff --git a/libgamma.h b/libgamma.h
index f1aa0ce..aa18bde 100644
--- a/libgamma.h
+++ b/libgamma.h
@@ -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;
diff --git a/test.c b/test.c
index c5ec4ea..650e2fa 100644
--- a/test.c
+++ b/test.c
@@ -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)\