#!/usr/bin/env python3 """Reads hex-framed display data from stdin, writes PBM, auto-launches feh.""" import sys import os import signal import subprocess import time WIDTH = 200 HEIGHT = 200 BUFSIZE = (WIDTH * HEIGHT) // 8 OUT = "/tmp/nrfwarch.pbm" FRAME_START = "!F!" FRAME_END = "!E!" feh_proc = None def write_pbm(data): header = f"P4\n{WIDTH} {HEIGHT}\n".encode() inverted = bytes((~b) & 0xFF for b in data) tmp = OUT + ".tmp" with open(tmp, "wb") as f: f.write(header) f.write(inverted) os.replace(tmp, OUT) def launch_feh(): global feh_proc if feh_proc is not None and feh_proc.poll() is None: return try: feh_proc = subprocess.Popen( [ "feh", "--force-aliasing", "--scale", "auto", "--auto-reload", "--title", "nrfwarch sim", OUT, ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) except FileNotFoundError: print("feh not found, writing PBM to " + OUT) def cleanup(*_): global feh_proc if feh_proc and feh_proc.poll() is None: feh_proc.terminate() sys.exit(0) def main(): signal.signal(signal.SIGTERM, cleanup) signal.signal(signal.SIGINT, cleanup) write_pbm(bytes([0xFF] * BUFSIZE)) launch_feh() capturing = False hex_buf = "" frame_count = 0 for line in sys.stdin: line = line.strip() if line == FRAME_START: capturing = True hex_buf = "" elif line == FRAME_END: if capturing and hex_buf: try: data = bytes.fromhex(hex_buf) if len(data) == BUFSIZE: write_pbm(data) frame_count += 1 print(f" frame {frame_count}", file=sys.stderr) except ValueError: pass capturing = False hex_buf = "" elif capturing: hex_buf += line if __name__ == "__main__": main()