forked from enlightenment/efl
From: Leif Middelschulte <leif.middelschulte@gmail.com>
Subject: [E-devel] [PATCH] EDID decoding functionality 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. ... with modifications to make it actually compile and api be cleaner, code more robust etc. SVN revision: 58348
This commit is contained in:
parent
7adaac4b7e
commit
6755f0c4c6
|
@ -109,6 +109,11 @@
|
|||
now uses the netwm sync protocol to get wm's to only configure
|
||||
as fast as it can keep drawing.
|
||||
|
||||
2011-04-05 Leif Middelschulte
|
||||
|
||||
* Add ecore_x_randr_edid_* data extraction and validation functions
|
||||
for EDID structures.
|
||||
|
||||
2011-04-01 Cedric Bail
|
||||
|
||||
* Add ecore_con_url_pipeline_set and ecore_con_url_pipeline_get for HTTP 1.1
|
||||
|
|
|
@ -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"
|
||||
|
@ -2662,6 +2691,225 @@ 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,
|
||||
unsigned long edid_length);
|
||||
|
||||
/*
|
||||
* @brief Get the encoded version from raw EDID data.
|
||||
*
|
||||
* The return value has the minor version in the lowest 8 bits, and the major
|
||||
* version in all the rest of the bits. i.e.
|
||||
*
|
||||
* minor = (version & 0x000000ff);
|
||||
* major = (version & 0xffffff00) >> 8;
|
||||
*
|
||||
* @param edid the edid structure
|
||||
* @param edid_length length of the edid structure
|
||||
* @return The encoded major and minor version encasuplated an int.
|
||||
*/
|
||||
EAPI int
|
||||
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 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 char *
|
||||
ecore_x_randr_edid_display_name_get(unsigned char *edid,
|
||||
unsigned 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 char *
|
||||
ecore_x_randr_edid_display_ascii_get(unsigned char *edid,
|
||||
unsigned 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 char *
|
||||
ecore_x_randr_edid_display_serial_get(unsigned char *edid,
|
||||
unsigned 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 int
|
||||
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 int
|
||||
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
|
||||
ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid,
|
||||
unsigned 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,
|
||||
unsigned 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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
* 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 <ajax@nwnk.net> */
|
||||
/* Heavily modified by: Leif Middelschulte <leif.middelschulte@gmail.com> */
|
||||
|
||||
#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)
|
||||
{
|
||||
const unsigned char header[] =
|
||||
{ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
||||
if (!edid) return EINA_FALSE;
|
||||
if (edid_length < 8) return EINA_FALSE;
|
||||
if (!memcmp(edid, header, 8)) return EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) &&
|
||||
(ecore_x_randr_edid_has_valid_header(edid, edid_length)))
|
||||
return ((edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) |
|
||||
edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]);
|
||||
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
if ((edid_length > 0x0b) &&
|
||||
(ecore_x_randr_edid_has_valid_header(edid, edid_length)))
|
||||
return (int)(edid[0x0a] + (edid[0x0b] << 8));
|
||||
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
if ((edid_length > 0x0f) &&
|
||||
(ecore_x_randr_edid_has_valid_header(edid, edid_length)))
|
||||
return (int)(edid[0x0c] + (edid[0x0d] << 8) +
|
||||
(edid[0x0e] << 16) + (edid[0x0f] << 24));
|
||||
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
if ((edid_length > (_ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER + 1)) &&
|
||||
(ecore_x_randr_edid_has_valid_header(edid, edid_length)))
|
||||
{
|
||||
unsigned char *x;
|
||||
char *name;
|
||||
|
||||
x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER);
|
||||
name = malloc(sizeof(char) * 4);
|
||||
if (!name) return NULL;
|
||||
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;
|
||||
return name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
unsigned char *block = NULL;
|
||||
int 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)
|
||||
{
|
||||
char *name, *p;
|
||||
const char *edid_name;
|
||||
|
||||
edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
|
||||
name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
|
||||
if (!name) return NULL;
|
||||
strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
|
||||
name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
|
||||
for (p = name; *p; p++)
|
||||
{
|
||||
if ((*p < ' ') || (*p > '~')) *p = 0;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Ecore_X_Randr_Edid_Aspect_Ratio
|
||||
ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
unsigned char *block = NULL;
|
||||
int version = ecore_x_randr_edid_version_get(edid, edid_length);
|
||||
|
||||
if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
_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))
|
||||
{
|
||||
Ecore_X_Randr_Edid_Aspect_Ratio_Preferred 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:
|
||||
return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
|
||||
case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9:
|
||||
return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
|
||||
case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10:
|
||||
return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
|
||||
case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4:
|
||||
return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
|
||||
case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9:
|
||||
return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
|
||||
default:
|
||||
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
}
|
||||
|
||||
EAPI Ecore_X_Randr_Edid_Aspect_Ratio
|
||||
ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
unsigned char *block = NULL;
|
||||
int version = ecore_x_randr_edid_version_get(edid, edid_length);
|
||||
|
||||
if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
_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 char *
|
||||
ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
unsigned char *block = NULL;
|
||||
int 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] == 0xfe)
|
||||
{
|
||||
char *ascii, *p;
|
||||
const char *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(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
|
||||
if (!ascii) return NULL;
|
||||
strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
|
||||
ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
|
||||
for (p = ascii; *p; p++)
|
||||
{
|
||||
if ((*p < ' ') || (*p > '~')) *p = 0;
|
||||
}
|
||||
return ascii;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
unsigned char *block = NULL;
|
||||
int 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] == 0xff)
|
||||
{
|
||||
char *serial, *p;
|
||||
const char *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(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
|
||||
if (!serial) return NULL;
|
||||
strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
|
||||
serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
|
||||
for (p = serial; *p; p++)
|
||||
{
|
||||
if ((*p < ' ') || (*p > '~')) *p = 0;
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
unsigned char *cea_block_iter = NULL;
|
||||
char sum = 0;
|
||||
int i;
|
||||
int version = ecore_x_randr_edid_version_get(edid, edid_length);
|
||||
|
||||
if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
|
||||
if (edid_length < 128) return EINA_FALSE;
|
||||
|
||||
/* Check the EDID block itself */
|
||||
for (i = 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];
|
||||
}
|
||||
if (sum) return EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
int version = ecore_x_randr_edid_version_get(edid, edid_length);
|
||||
|
||||
if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
|
||||
return (!!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
|
||||
_ECORE_X_RANDR_EDID_MASK_DPMS));
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
int 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)
|
||||
return (!!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
|
||||
_ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
int 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)
|
||||
return (!!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
|
||||
_ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
int 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)
|
||||
return (!!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
|
||||
_ECORE_X_RANDR_EDID_MASK_DPMS_OFF));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length)
|
||||
{
|
||||
int version = ecore_x_randr_edid_version_get(edid, edid_length);
|
||||
|
||||
if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
|
||||
return (!!(edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] &
|
||||
_ECORE_X_RANDR_EDID_MASK_DIGITAL));
|
||||
}
|
||||
|
||||
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;
|
||||
int 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;
|
||||
int 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_DISPLAY_PORT)
|
||||
type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
||||
return type;
|
||||
}
|
Loading…
Reference in New Issue