# SPDX-License-Identifier: MIT import xml.etree.ElementTree as ET import plistlib, base64, struct, os, logging from .img4 import img4p_extract from .core import FWFile log = logging.getLogger("asahi_firmware.multitouch") def load_plist_xml(d): root = ET.fromstring(d.decode("ascii")) idmap = {} def unmunge(el, idmap): if "ID" in el.attrib: idmap[el.attrib["ID"]] = el if "IDREF" in el.attrib: return idmap[el.attrib["IDREF"]] else: el2 = ET.Element(el.tag) el2.text = el.text el2.tag = el.tag el2.attrib = el.attrib for child in el: el2.append(unmunge(child, idmap)) return el2 pl = ET.Element("plist") pl.append(unmunge(root, idmap)) return plistlib.loads(ET.tostring(pl)) LOAD_COMMAND_INIT_PAYLOAD = 0 LOAD_COMMAND_SEND_BLOB = 1 LOAD_COMMAND_SEND_CALIBRATION = 2 def plist_to_bin_touchbar(plist): def serialize(plist): yield struct.pack("<4sI", b"Z2FW", 1) for i in plist: if i["Type"] == "Config": init = i["Config"]["SPI Config"]["Init Payload"] yield struct.pack("H", o) else: yield bytes([0x1a]) yield struct.pack(">I", o) elif isinstance(o, bytes): if len(o) <= 0xffff: yield (4, 3) yield struct.pack(">BH", 0x59, len(o)) else: raise Exception("Unsupported serializer case") yield b"?" + struct.pack(">I", len(o)) yield o else: raise Exception("Unsupported serializer case") yield b"?" + str(type(o)).encode("ascii") def add_padding(l): nonlocal iface_offset off = 0 for b in l: if b is None: assert iface_offset is None iface_offset = off b = b"\x00" if isinstance(b, tuple): align, i = b if (off + i) % align != 0: pad = align - ((off + i) % align) off += pad yield b"\xd3" * pad else: off += len(b) yield b blob = b"".join(add_padding(serialize(plist))) assert iface_offset is not None hdr = struct.pack("<4sIII", b"HIDF", 1, 32, len(blob)) hdr += struct.pack("