From a5376d2de0df53cda8cc511e6b07d3e977f47a09 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Tue, 27 Jan 2026 20:26:46 +0100 Subject: [PATCH] xfree86: ddc: new entry point for EDID parsing The old ones didn't know the block size, so couldn't deduce the block type version. With upcoming new features, eg. HDR, we need to know the block type version in order to know what we can extract from it. This new function should now be used by all drivers, the old ones shall be phased out. That commit should be backported to 25.0 and 25.1 releases, so drivers can remain compatible with all existing release lines. Signed-off-by: Enrico Weigelt, metux IT consult --- hw/xfree86/ddc/interpret_edid.c | 44 +++++++++++++++++++++++++++------ hw/xfree86/ddc/xf86DDC.h | 13 ++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 808cabed44..4c3fbaaa64 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -28,6 +28,10 @@ #include #endif +#include +#include +#include + #include "misc.h" #include "xf86.h" #include "xf86_OSproc.h" @@ -164,15 +168,18 @@ encode_aspect_ratio(xf86MonPtr m) } } -xf86MonPtr -xf86InterpretEDID(int scrnIndex, Uchar * block) +static xf86MonPtr parseEDID(int scrnIndex, uint8_t *block, size_t size, bool copy) { - xf86MonPtr m; + xf86MonPtr m = calloc(1, sizeof(xf86Monitor) + (copy ? size : 0)); + if (!m) + return NULL; + + /* make a copy of the EDID block for later reference */ + if (copy) { + memcpy(&(m[1]), block, size); + block = (uint8_t*)&m[1]; + } - if (!block) - return NULL; - if (!(m = XNFcallocarray(1, sizeof(xf86Monitor)))) - return NULL; m->scrnIndex = scrnIndex; m->rawData = block; @@ -191,6 +198,11 @@ xf86InterpretEDID(int scrnIndex, Uchar * block) handle_edid_quirks(m); encode_aspect_ratio(m); + if (size > 128) + m->flags |= EDID_COMPLETE_RAWDATA; + + /* possibly add more extended parsing here, eg. HDR information */ + return m; error: @@ -198,6 +210,24 @@ xf86InterpretEDID(int scrnIndex, Uchar * block) return NULL; } +/* new entry point, should be used whenever possible */ +xf86MonPtr xf86ParseEDID(ScrnInfoPtr pScrn, uint8_t *block, size_t size) +{ + if (!pScrn || !block || !size) + return NULL; + + return parseEDID(pScrn->scrnIndex, block, size, true); +} + +/* old entry point, deprecated but still needed for backwards compat */ +xf86MonPtr xf86InterpretEDID(int scrnIndex, uint8_t *block) +{ + if (!block) + return NULL; + + return parseEDID(scrnIndex, block, EDID1_LEN, false); +} + static int get_cea_detail_timing(Uchar * blk, xf86MonPtr mon, struct detailed_monitor_section *det_mon) diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h index c750441fcb..17fc38ea5e 100644 --- a/hw/xfree86/ddc/xf86DDC.h +++ b/hw/xfree86/ddc/xf86DDC.h @@ -42,4 +42,17 @@ extern _X_EXPORT xf86MonPtr xf86InterpretEEDID(int screenIndex, Uchar * block); extern _X_EXPORT Bool xf86SetDDCproperties(ScrnInfoPtr pScreen, xf86MonPtr DDC); +/* + * parse EDID block and return a newly allocated xf86Monitor + * + * the data block will be copied into the structure (actually right after the struct) + * and thus automatically be freed when the returned struct is freed. + * + * @param screenIndex index of the screen, will be recorded in the xf86Monitor + * @param block the EDID block to parse + * @param size size of the EDID block (128 or larger for extended types) + * @return newly allocated xf86MonRec or NULL on failure + */ +_X_EXPORT xf86MonPtr xf86ParseEDID(ScrnInfoPtr pScreen, uint8_t *block, size_t size); + #endif