From ba5df47c97428c1396b4233a28bcbb7bd1d37b69 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Wed, 12 Mar 2025 23:00:33 +0200 Subject: [PATCH] edidconf: Allow 128-byte edids for --import-display-ids --- kvmd/apps/edidconf/__init__.py | 2 +- kvmd/edid.py | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/kvmd/apps/edidconf/__init__.py b/kvmd/apps/edidconf/__init__.py index 2234b5a8..717f9e32 100644 --- a/kvmd/apps/edidconf/__init__.py +++ b/kvmd/apps/edidconf/__init__.py @@ -71,7 +71,7 @@ def _read_out2_edid() -> (Edid | None): data = file.read() if len(data) == 0: return None - return Edid.from_file(os.path.join(path, "edid")) + return Edid.from_file(os.path.join(path, "edid"), allow_short=True) def _adopt_out2_ids(dest: Edid) -> None: diff --git a/kvmd/edid.py b/kvmd/edid.py index bfa62e3c..8532a06b 100644 --- a/kvmd/edid.py +++ b/kvmd/edid.py @@ -69,6 +69,9 @@ class _CeaBlock: return _CeaBlock(tag, data) +_LONG = 256 +_SHORT = 128 + _CEA = 128 _CEA_AUDIO = 1 _CEA_SPEAKERS = 4 @@ -77,12 +80,18 @@ _CEA_SPEAKERS = 4 class Edid: # https://en.wikipedia.org/wiki/Extended_Display_Identification_Data - def __init__(self, data: bytes) -> None: - assert len(data) == 256 + def __init__(self, data: bytes, allow_short: bool=False) -> None: + if allow_short: + assert len(data) in [_SHORT, _LONG], f"Invalid EDID length: {len(data)}, should be {_SHORT} or {_LONG} bytes" + else: + assert len(data) == _LONG, f"Invalid EDID length: {len(data)}, should be {_LONG} bytes" + assert data[126] == 1, "Zero extensions number" + assert (data[_CEA + 0], data[_CEA + 1]) == (0x02, 0x03), "Can't find CEA extension" self.__data = list(data) + self.__long = (len(data) == _LONG) @classmethod - def from_file(cls, path: str) -> "Edid": + def from_file(cls, path: str, allow_short: bool=False) -> "Edid": with _smart_open(path, "rb") as file: data = file.read() if not data.startswith(b"\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00"): @@ -91,10 +100,7 @@ class Edid: int(text[index:index + 2], 16) for index in range(0, len(text), 2) ]) - assert len(data) == 256, f"Invalid EDID length: {len(data)}, should be 256 bytes" - assert data[126] == 1, "Zero extensions number" - assert (data[_CEA + 0], data[_CEA + 1]) == (0x02, 0x03), "Can't find CEA extension" - return Edid(data) + return Edid(data, allow_short) def write_hex(self, path: str) -> None: self.__update_checksums() @@ -115,7 +121,8 @@ class Edid: def __update_checksums(self) -> None: self.__data[127] = 256 - (sum(self.__data[:127]) % 256) - self.__data[255] = 256 - (sum(self.__data[128:255]) % 256) + if self.__long: + self.__data[255] = 256 - (sum(self.__data[128:255]) % 256) # ===== @@ -229,6 +236,8 @@ class Edid: self.__data[_CEA + 3] &= (0xFF - 0b01000000) # ~X def __parse_cea(self) -> tuple[list[_CeaBlock], bytes]: + assert self.__long, "This EDID does not contain any CEA blocks" + cea = self.__data[_CEA:] dtd_begin = cea[2] if dtd_begin == 0: