edidconf: Allow 128-byte edids for --import-display-ids

This commit is contained in:
Maxim Devaev 2025-03-12 23:00:33 +02:00
parent 20a7206b0f
commit ba5df47c97
2 changed files with 18 additions and 9 deletions

View File

@ -71,7 +71,7 @@ def _read_out2_edid() -> (Edid | None):
data = file.read() data = file.read()
if len(data) == 0: if len(data) == 0:
return None 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: def _adopt_out2_ids(dest: Edid) -> None:

View File

@ -69,6 +69,9 @@ class _CeaBlock:
return _CeaBlock(tag, data) return _CeaBlock(tag, data)
_LONG = 256
_SHORT = 128
_CEA = 128 _CEA = 128
_CEA_AUDIO = 1 _CEA_AUDIO = 1
_CEA_SPEAKERS = 4 _CEA_SPEAKERS = 4
@ -77,12 +80,18 @@ _CEA_SPEAKERS = 4
class Edid: class Edid:
# https://en.wikipedia.org/wiki/Extended_Display_Identification_Data # https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
def __init__(self, data: bytes) -> None: def __init__(self, data: bytes, allow_short: bool=False) -> None:
assert len(data) == 256 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.__data = list(data)
self.__long = (len(data) == _LONG)
@classmethod @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: with _smart_open(path, "rb") as file:
data = file.read() data = file.read()
if not data.startswith(b"\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00"): 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) int(text[index:index + 2], 16)
for index in range(0, len(text), 2) for index in range(0, len(text), 2)
]) ])
assert len(data) == 256, f"Invalid EDID length: {len(data)}, should be 256 bytes" return Edid(data, allow_short)
assert data[126] == 1, "Zero extensions number"
assert (data[_CEA + 0], data[_CEA + 1]) == (0x02, 0x03), "Can't find CEA extension"
return Edid(data)
def write_hex(self, path: str) -> None: def write_hex(self, path: str) -> None:
self.__update_checksums() self.__update_checksums()
@ -115,7 +121,8 @@ class Edid:
def __update_checksums(self) -> None: def __update_checksums(self) -> None:
self.__data[127] = 256 - (sum(self.__data[:127]) % 256) 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 self.__data[_CEA + 3] &= (0xFF - 0b01000000) # ~X
def __parse_cea(self) -> tuple[list[_CeaBlock], bytes]: def __parse_cea(self) -> tuple[list[_CeaBlock], bytes]:
assert self.__long, "This EDID does not contain any CEA blocks"
cea = self.__data[_CEA:] cea = self.__data[_CEA:]
dtd_begin = cea[2] dtd_begin = cea[2]
if dtd_begin == 0: if dtd_begin == 0: