2011/4/1 Mike Blumenkrantz <[email protected]>:
> On Fri, 1 Apr 2011 22:19:19 +0200
> Leif Middelschulte <[email protected]> wrote:
>
>> Hello everyone,
>>
>> find attached a patch for EDID data extraction. My display's
>> manufacturer didn't comply with the standard too much, so I can't test
>> it entirely. But it should work.
>>
>> Review, comments and commit are welcome ;-)
>>
>> BR,
>>
>> Leif
>>
> Thanks for sending! I'll review it immediately!
>
> April fool's, it'll languish on the mailing list for months! :D
Oh,

I forgot.... it's not april 1st anymore in .kr :-/

So then.. here you go

> --
> Mike Blumenkrantz
> Zentific: NULL pointer dereferences now 50% off!
>
From a866c1f84c0ef44e85fc7c10abf7deff23e1fa08 Mon Sep 17 00:00:00 2001
From: Leif Middelschulte <[email protected]>
Date: Fri, 1 Apr 2011 02:40:09 +0200
Subject: [PATCH] Added data extraction for raw EDID version >= 1.3

---
 trunk/ecore/ChangeLog                              |    4 +
 trunk/ecore/src/lib/ecore_x/Ecore_X.h              |  204 ++++++++
 trunk/ecore/src/lib/ecore_x/xlib/Makefile.am       |    1 +
 .../src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c   |  486 ++++++++++++++++++++
 4 files changed, 695 insertions(+), 0 deletions(-)
 create mode 100644 trunk/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c

diff --git a/trunk/ecore/ChangeLog b/trunk/ecore/ChangeLog
index 31f5fe1..03479f3 100644
--- a/trunk/ecore/ChangeLog
+++ b/trunk/ecore/ChangeLog
@@ -113,3 +113,7 @@
 
 	* Add ecore_con_url_pipeline_set and ecore_con_url_pipeline_get for HTTP 1.1
 	pipelining support.
+
+2011-04-01  Leif Middelschulte
+
+	* Add ecore_x_randr_edid_* data extraction and validation functions for EDID structures.
diff --git a/trunk/ecore/src/lib/ecore_x/Ecore_X.h b/trunk/ecore/src/lib/ecore_x/Ecore_X.h
index 0e21770..a9232fc 100644
--- a/trunk/ecore/src/lib/ecore_x/Ecore_X.h
+++ b/trunk/ecore/src/lib/ecore_x/Ecore_X.h
@@ -207,6 +207,35 @@ typedef enum _Ecore_X_Render_Subpixel_Order {
    ECORE_X_RENDER_SUBPIXEL_ORDER_NONE = 5
 } Ecore_X_Render_Subpixel_Order;
 
+typedef enum _Ecore_X_Randr_Edid_Display_Interface_Type {
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_UNDEFINED,
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DVI,
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_A,
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_B,
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_MDDI,
+     ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT
+} Ecore_X_Randr_Edid_Display_Interface_Type;
+
+typedef enum _Ecore_X_Randr_Edid_Display_Colorscheme {
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_MONOCHROME_GRAYSCALE = 0x00,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB = 0x08,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_NON_RGB = 0x10,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_UNDEFINED = 0x18,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4 = 0x444000,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4 = 0x444,
+     ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2 = 0x422
+} Ecore_X_Randr_Edid_Display_Colorscheme;
+
+typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio {
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3 = 0x0,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9 = 0x1,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10 = 0x2,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4 = 0x4,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9 = 0x8
+} Ecore_X_Randr_Edid_Aspect_Ratio;
+
+#define ECORE_X_RANDR_EDID_UNKNOWN_VALUE -1
+
 #define ECORE_X_SELECTION_TARGET_TARGETS       "TARGETS"
 #define ECORE_X_SELECTION_TARGET_TEXT          "TEXT"
 #define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT"
@@ -2668,6 +2697,181 @@ ecore_x_randr_output_crtc_set(Ecore_X_Window root,
                               Ecore_X_Randr_Output output,
                               const Ecore_X_Randr_Crtc crtc);
 
+/* ecore_x_randr_12_edid.c */
+
+/*
+ * @brief Validates the header from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if the header is valid. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_valid_header(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Checks whether a display's EDID has a valid checksum.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if the checksum is valid. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the encoded version from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded major and minor version encasuplated a single short.
+ */
+EAPI short ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the encoded manufacturer from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded manufacturer identifier.
+ */
+EAPI const char *ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the encoded name from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded manufacturer identifier.
+ */
+EAPI const char *ecore_x_randr_edid_display_name_get(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the encoded ASCII from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded ASCII display identifier.
+ */
+EAPI const char *ecore_x_randr_edid_display_ascii_get(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the encoded serial identifier from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded serial identifier.
+ */
+EAPI const char *ecore_x_randr_edid_display_serial_get(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the encoded model number from raw EDID data.
+ *
+ * The manufacturer ID table is necessary for a useful description.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded model number.
+ */
+EAPI short ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the manufacturer serial number from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded serial manufacturer serial number.
+ */
+EAPI int ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the manufacturer model number from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The manufacturer's model number.
+ */
+EAPI short ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Looks up the DPMS support from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if DPMS is supported in some way. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Looks up the DPMS Standby support from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if DPMS Standby is supported. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Looks up the DPMS Suspend support from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if DPMS Suspend is supported. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Looks up the DPMS Off support from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if DPMS Off is supported. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the preferred aspect ratio from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The preferred aspect ratio.
+ */
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio_Preferred ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the supported aspect ratios from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The supported aspect ratios.
+ */
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, long edid_length);
+
+/*
+ * @brief Get the supported colorschemes from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The supported colorschemes.
+ */
+EAPI Ecore_X_Randr_Edid_Display_Colorscheme ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the display type from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return EINA_TRUE, if the display is a digital one. Else EINA_FALSE.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length);
+
+/*
+ * @brief Get the display interface type from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The interface type.
+ */
+EAPI Ecore_X_Randr_Edid_Display_Interface_Type ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length);
+
 /* ecore_x_randr_13.c */
 EAPI void
 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level);
diff --git a/trunk/ecore/src/lib/ecore_x/xlib/Makefile.am b/trunk/ecore/src/lib/ecore_x/xlib/Makefile.am
index c75f4a5..71990ec 100644
--- a/trunk/ecore/src/lib/ecore_x/xlib/Makefile.am
+++ b/trunk/ecore/src/lib/ecore_x/xlib/Makefile.am
@@ -36,6 +36,7 @@ ecore_x_sync.c \
 ecore_x_randr.c \
 ecore_x_randr_11.c \
 ecore_x_randr_12.c \
+ecore_x_randr_12_edid.c \
 ecore_x_randr_13.c \
 ecore_x_fixes.c \
 ecore_x_damage.c \
diff --git a/trunk/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/trunk/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c
new file mode 100644
index 0000000..85582dd
--- /dev/null
+++ b/trunk/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2006-2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Original Author: Adam Jackson <[email protected]> */
+/* Heavily modified by: Leif Middelschulte <[email protected]> */
+
+#include "Ecore_X.h"
+
+/* TODO:
+ * - see other TODO's within this file.
+ */
+
+#define ECORE_X_RANDR_EDID_VERSION_10 ((1 << 8) | 0)
+#define ECORE_X_RANDR_EDID_VERSION_11 ((1 << 8) | 1)
+#define ECORE_X_RANDR_EDID_VERSION_12 ((1 << 8) | 2)
+#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3)
+#define ECORE_X_RANDR_EDID_VERSION_14 ((1 << 8) | 4)
+
+#define _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER 0x08
+#define _ECORE_X_RANDR_EDID_OFFSET_TYPE 0x14
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13
+#define _ECORE_X_RANDR_EDID_OFFSET_DPMS 0x18
+#define _ECORE_X_RANDR_EDID_OFFSET_COLORSPACE 0x18
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5
+#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED 15
+#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO 14
+
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL 0x80
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_INTERFACE 0x0f
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_TMDS_DFP_10 0x01
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS 0x18
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444 0x10
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422 0x08
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED 0xe0
+#define _ECORE_X_RANDR_EDID_MASK_DPMS 0xE0
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY 0x80
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND 0x40
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_OFF 0x20
+#define _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE 0x0f
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3 0x80
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9 0x40
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10 0x20
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4 0x10
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9 0x08
+
+#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13
+
+typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred {
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03,
+     ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04
+} Ecore_X_Randr_Edid_Aspect_Ratio_Preferred;
+
+/* Some convenience loops */
+#define _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, extension_block_iter) \
+   for (extension_block_iter = edid; extension_block_iter < (edid + edid_length); extension_block_iter += 128)
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \
+   _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, cea_block_iter) \
+if (cea_block_iter[0] == 0x02)
+
+/* The following macro is to be used with caution as it inherits another loop.
+ * Therefore using a 'break;' statement will lead to continuation in the
+ * inherent 'Extension block'-loop.
+ */
+#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_DETAILED_BLOCK(edid, edid_length, cea_block_iter, detailed_block_iter) \
+   _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \
+for (detailed_block_iter = cea_block_iter + cea_block_iter[2]; detailed_block_iter + 18 < cea_block_iter + 127; detailed_block_iter += 18) \
+if (detailed_block_iter[0])
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+   for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3*18)); block += 18)
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \
+   _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+if ((block[0] == 0) && (block[1] == 0))
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool is_valid = EINA_FALSE;
+
+   if (!edid) return EINA_FALSE;
+
+   if (!memcmp(edid, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8))
+     {
+        is_valid = EINA_TRUE;
+     }
+
+   return is_valid;
+}
+
+   EAPI short
+ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
+{
+   short version;
+   version = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+
+   if (edid && ecore_x_randr_edid_has_valid_header(edid, edid_length))
+     version = (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR];
+
+   return version;
+}
+
+   EAPI short
+ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length)
+{
+   short model = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+
+   if (edid && ecore_x_randr_edid_has_valid_header(edid, edid_length))
+     model = (short)(edid[0x0A] + (edid[0x0B] << 8));
+
+   return model;
+}
+
+   EAPI int
+ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length)
+{
+   int serial_number = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+
+   if (edid && ecore_x_randr_edid_has_valid_header(edid, edid_length))
+     serial_number = (int)(edid[0x0C] + (edid[0x0D] << 8) + (edid[0x0E] << 16) + (edid[0x0F] << 24));
+
+   return serial_number;
+}
+
+   EAPI const char
+*ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length)
+{
+   unsigned char *x;
+   char *name = NULL;
+
+   if (edid && ecore_x_randr_edid_has_valid_header(edid, edid_length))
+     {
+        x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER);
+
+        name = malloc(sizeof(char) * 4);
+
+        name[0] = ((x[0] & 0x7C) >> 2) + '@';
+        name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
+        name[2] = (x[1] & 0x1F) + '@';
+        name[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] = '\0';
+
+        /*
+         * if (isupper(name[0]) && isupper(name[1]) && isupper(name[2]))
+         * info->manufacturer_name_well_formed = EINA_TRUE;
+         */
+     }
+
+   return name;
+}
+
+   EAPI const char
+*ecore_x_randr_edid_display_name_get(unsigned char *edid, long edid_length)
+{
+   unsigned char *block = NULL;
+   char *name = NULL;
+   const char *edid_name;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
+
+   _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+     {
+        if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xFC) {
+             edid_name = (const char*)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+             name = malloc(sizeof(*name) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+             strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+             return name;
+        }
+     }
+   return name;
+}
+
+   EAPI Ecore_X_Randr_Edid_Aspect_Ratio
+ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, long edid_length)
+{
+   Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+   Ecore_X_Randr_Edid_Aspect_Ratio_Preferred preferred_ratio;
+   unsigned char *block = NULL;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return ret;
+
+   _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+     {
+        if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xFD) && (block[10] == 0x04))
+          {
+             preferred_ratio = (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred)((block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED) >> 5);
+             switch (preferred_ratio)
+               {
+                case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3:
+                   ret = ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
+                   break;
+                case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9:
+                   ret = ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
+                   break;
+                case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10:
+                   ret = ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
+                   break;
+                case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4:
+                   ret = ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
+                   break;
+                case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9:
+                   ret = ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
+                   break;
+                default:
+                   ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+               }
+          }
+        return ret;
+     }
+
+   return ret;
+}
+
+   EAPI Ecore_X_Randr_Edid_Aspect_Ratio
+ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, long edid_length)
+{
+   Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+   unsigned char *block = NULL;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return ret;
+
+   _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+     {
+        if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xFD) && (block[10] == 0x04))
+          {
+             if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3)
+               ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
+             if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9)
+               ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
+             if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10)
+               ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
+             if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4)
+               ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
+             if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9)
+               ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
+          }
+     }
+
+   return ret;
+}
+
+   EAPI const char
+*ecore_x_randr_edid_display_ascii_get(unsigned char *edid, long edid_length)
+{
+   unsigned char *block = NULL;
+   char *ascii = NULL;
+   const char *edid_ascii;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return ascii;
+
+   _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+     {
+        if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xFE)
+          {
+             edid_ascii = (const char*)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+             /*
+              * TODO: Two of these in a row, in the third and fouth slots,
+              * seems to be specified by SPWG: http://www.spwg.org/
+              */
+             ascii = malloc(sizeof(*ascii) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+             strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+             return ascii;
+          }
+     }
+
+   return ascii;
+}
+
+   EAPI const char
+*ecore_x_randr_edid_display_serial_get(unsigned char *edid, long edid_length)
+{
+   unsigned char *block = NULL;
+   char *serial = NULL;
+   const char *edid_serial;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return serial;
+
+   _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+     {
+        if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xFF)
+          {
+             edid_serial = (const char*)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+             /*
+              * TODO: Two of these in a row, in the third and fouth slots,
+              * seems to be specified by SPWG: http://www.spwg.org/
+              */
+             serial = malloc(sizeof(*serial) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+             strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+          }
+     }
+
+   return serial;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, long edid_length)
+{
+   unsigned char *cea_block_iter = NULL;
+   char sum;
+   int i;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+
+   /* Check the EDID block itself */
+   for (i = 0, sum = 0; i < 128; i++)
+     sum += edid[i];
+   if (sum) return EINA_FALSE;
+
+   /* Check the cea extension blocks */
+   _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter)
+     {
+        for (i = 0, sum = 0; i < 128; i++)
+          sum += cea_block_iter[i];
+        /*
+         * printf("Checksum: 0x%hx", x[0x7f]);
+         * printf(" (should be 0x%hx)\n", (char)(x[0x7f] - sum));
+         */
+     }
+
+   if (sum)
+     return EINA_FALSE;
+   else
+     return EINA_TRUE;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool ret = EINA_FALSE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+
+   ret = (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS);
+
+   return ret;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool ret = EINA_FALSE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+
+   if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+     ret = (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY);
+
+   return ret;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool ret = EINA_FALSE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+
+   if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+     ret = (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND);
+
+   return ret;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool ret = EINA_FALSE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+
+   if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+     ret = (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS_OFF);
+
+   return ret;
+}
+
+   EAPI Eina_Bool
+ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length)
+{
+   Eina_Bool ret = EINA_FALSE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return ret;
+
+   ret = (edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & _ECORE_X_RANDR_EDID_MASK_DIGITAL);
+
+   return ret;
+}
+
+   EAPI Ecore_X_Randr_Edid_Display_Colorscheme
+ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length)
+{
+   Ecore_X_Randr_Edid_Display_Colorscheme colorscheme = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return colorscheme;
+
+   if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length))
+     {
+        colorscheme = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4;
+        if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444)
+          colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4;
+        if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422)
+          colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2;
+     }
+   else
+     {
+        colorscheme = edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS;
+     }
+
+   return colorscheme;
+}
+
+   EAPI Ecore_X_Randr_Edid_Display_Interface_Type
+ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length)
+{
+   Ecore_X_Randr_Edid_Display_Interface_Type type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+   static short version;
+
+   version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+   if (version < ECORE_X_RANDR_EDID_VERSION_13) return type;
+
+   type = edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE;
+
+   if ((type < ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_UNDEFINED) || (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT))
+     type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+
+   return type;
+}
-- 
1.7.1

------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to