aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/edid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/edid.c')
-rw-r--r--src/lib/edid.c177
1 files changed, 81 insertions, 96 deletions
diff --git a/src/lib/edid.c b/src/lib/edid.c
index 2a9f3f9..fc7b498 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -1,20 +1,4 @@
-/**
- * libgamma -- Display server abstraction layer for gamma ramp adjustments
- * Copyright (C) 2014, 2015 Mattias Andrée (maandree@member.fsf.org)
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
+/* See LICENSE file for copyright and license details. */
#include "edid.h"
#include "libgamma-method.h"
@@ -33,88 +17,89 @@
/**
- * Parse the EDID of a monitor.
+ * Parse the EDID of a monitor
*
- * @param this Instance of a data structure to fill with the information about the EDID.
- * It must contain the EDID and its length.
- * @param feilds OR:ed identifiers for the information about the EDID that should be parsed.
- * Fields that do not have to do with EDID are ignored.
- * @return Non-zero on error.
+ * @param this Instance of a data structure to fill with the information about the EDID;
+ * it must contain the EDID and its length
+ * @param fields OR:ed identifiers for the information about the EDID that should be parsed;
+ * fields that do not have to do with EDID are ignored
+ * @return Non-zero on error
*/
-int libgamma_parse_edid(libgamma_crtc_information_t* restrict this, int32_t fields)
+int
+libgamma_parse_edid(libgamma_crtc_information_t *restrict this, int32_t fields)
{
-#define __test_version(edid, major, minor_min, minor_max) \
- (((edid)[18] == major) && (minor_min <= (edid)[19]) && ((edid)[19] <= minor_max))
-#define __m(value) (this->edid[index++] != value)
-
- int error = 0;
- int 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)
- error = LIBGAMMA_EDID_LENGTH_UNSUPPORTED;
- /* 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) == 0)
- 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. */
- this->width_mm_edid_error = this->height_mm_edid_error = this->gamma_error = error;
-
- /* Retrieve the size of the viewport. This is done even if it is not
- requested because it is not worth it 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 == 0))
- {
- 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;
- else
- this->gamma_red = this->gamma_green = this->gamma_blue = (float)((int)(this->edid[23]) + 100) / 100.f;
- }
-
- /* If not error has occurred, calculate and test the checksum.
- It is not considered an error that the gamma characteristics
- is left unspecified in the EDID. */
- if (error == 0)
- for (i = 0; i < this->edid_length; i++)
- checksum += (int)(this->edid[i]);
- /* The checksum should be zero. */
- if ((checksum & 255))
- {
- /* Store the error in all fields that require the EDID to be parsed,
- as well as the EDID field itself. */
- error = LIBGAMMA_EDID_CHECKSUM_ERROR;
- 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. */
- 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. */
- return error | this->gamma_error;
-
+#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))
+
+ 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)
+ error = LIBGAMMA_EDID_LENGTH_UNSUPPORTED;
+ /* 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))
+ 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. */
+ this->width_mm_edid_error = this->height_mm_edid_error = this->gamma_error = error;
+
+ /* Retrieve the size of the viewport. This is done even if it is not
+ requested because it is not worth it 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) {
+ 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;
+ } else {
+ this->gamma_blue = (float)((int)this->edid[23] + 100) / 100.f;
+ this->gamma_red = this->gamma_green = this->gamma_blue;
+ }
+ }
+
+ /* If not error has occurred, calculate and test the checksum.
+ It is not considered an error that the gamma characteristics
+ is left unspecified in the EDID. */
+ if (!error) {
+ for (i = 0; i < this->edid_length; i++)
+ checksum += (int)this->edid[i];
+ }
+ /* The checksum should be zero. */
+ if (checksum & 255) {
+ /* Store the error in all fields that require the EDID to be parsed,
+ as well as the EDID field itself. */
+ error = LIBGAMMA_EDID_CHECKSUM_ERROR;
+ 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. */
+ 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. */
+ return error | this->gamma_error;
+
#undef __m
#undef __test_version
}
-