[PATCH 1/3] xfree86: Add a xf86MonitorFindHDMIBlock()
walter harms
wharms at bfs.de
Thu Aug 22 00:11:47 PDT 2013
Am 21.08.2013 19:25, schrieb Damien Lespiau:
> The HDMI CEA vendor specific block has some interesting information,
> such as the maximum TMDS dot clock.
>
> v2: Don't parse CEA blocks with invalid offsets, remove spurious
> brackets (Chris Wilson)
>
> Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
> ---
> hw/xfree86/ddc/interpret_edid.c | 91 +++++++++++++++++++++++++++++++++++++++++
> hw/xfree86/ddc/xf86DDC.h | 2 +
> 2 files changed, 93 insertions(+)
>
> diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
> index e6b4d5b..eff928e 100644
> --- a/hw/xfree86/ddc/interpret_edid.c
> +++ b/hw/xfree86/ddc/interpret_edid.c
> @@ -332,6 +332,97 @@ xf86ForEachVideoBlock(xf86MonPtr mon, handle_video_fn fn, void *data)
> }
> }
>
> +static Bool
> +cea_db_offsets(Uchar *cea, int *start, int *end)
> +{
> + /* Data block offset in CEA extension block */
> + *start = CEA_EXT_MIN_DATA_OFFSET;
> + *end = cea[2];
> + if (*end == 0);
> + *end = CEA_EXT_MAX_DATA_OFFSET;
> + if (*end < CEA_EXT_MIN_DATA_OFFSET || *end > CEA_EXT_MAX_DATA_OFFSET)
> + return FALSE;
> + return TRUE;
> +}
> +
> +static int
> +cea_db_len(Uchar *db)
> +{
> + return db[0] & 0x1f;
> +}
> +
> +static int
> +cea_db_tag(Uchar *db)
> +{
> + return db[0] >> 5;
> +}
> +
> +typedef void (*handle_cea_db_fn) (Uchar *, void *);
> +
> +static void
> +cea_for_each_db(xf86MonPtr mon, handle_cea_db_fn fn, void *data)
> +{
> + int i;
> +
> + if (!mon)
> + return;
> +
> + if (!(mon->flags & EDID_COMPLETE_RAWDATA))
> + return;
> +
> + if (!mon->no_sections)
> + return;
> +
> + if (!mon->rawData)
> + return;
> +
> + for (i = 0; i < mon->no_sections; i++) {
> + int start, end, offset;
> + Uchar *ext;
> +
> + ext = mon->rawData + EDID1_LEN * (i + 1);
> + if (ext[EXT_TAG] != CEA_EXT)
> + continue;
> +
> + if (!cea_db_offsets(ext, &start, &end))
> + continue;
> +
> + for (offset = start;
> + offset < end && offset + cea_db_len(&ext[i]) < end;
> + offset += cea_db_len(&ext[offset]) + 1)
> + fn(&ext[offset], data);
> + }
> +}
> +
> +struct find_hdmi_block_data {
> + struct cea_data_block *hdmi;
> +};
> +
> +static void find_hdmi_block(Uchar *db, void *data)
> +{
> + struct find_hdmi_block_data *result = data;
> + int oui;
> +
> + if (cea_db_tag(db) != CEA_VENDOR_BLK)
> + return;
> +
> + if (cea_db_len(db) < 5)
> + return;
> +
> + oui = (db[3] << 16) + (db[2] << 8) + db[1];
> + if (oui == IEEE_ID_HDMI)
> + result->hdmi = (struct cea_data_block *)db;
> +}
result->hdmi could be undefined, is that intentional ?
re,
wh
> +
> +struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon)
> +{
> + struct find_hdmi_block_data result = { NULL };
> +
> + cea_for_each_db(mon, find_hdmi_block, &result);
> +
> + return result.hdmi;
> +}
> +
> xf86MonPtr
> xf86InterpretEEDID(int scrnIndex, Uchar * block)
> {
> diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
> index bdc7648..de8e718 100644
> --- a/hw/xfree86/ddc/xf86DDC.h
> +++ b/hw/xfree86/ddc/xf86DDC.h
> @@ -98,4 +98,6 @@ typedef void (*handle_video_fn) (struct cea_video_block *, void *);
>
> void xf86ForEachVideoBlock(xf86MonPtr, handle_video_fn, void *);
>
> +struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon);
> +
> #endif
More information about the xorg-devel
mailing list