From 367c9ac02a76b3d2b55a0e155828117c2386b231 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Fri, 22 Feb 2019 10:47:42 -0800 Subject: Rewrite enumerate-displays in python Looking at the /sys filesystem gets the mapping wrong for some reason. XRandr sees DP-2-8 whereas /sys sees DP-5 or DP-3 (for which there are no physical analogs) and doesn't contain any file mapping the two. The long-term correct answer is to rewrite this in C and use the XRandr APIs directly but I need this to work right now for some presentations so Python it is. --- bin/enumerate-displays | 91 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 16 deletions(-) (limited to 'bin') diff --git a/bin/enumerate-displays b/bin/enumerate-displays index 996a135..40aea68 100755 --- a/bin/enumerate-displays +++ b/bin/enumerate-displays @@ -1,21 +1,80 @@ -#!/bin/bash +#!/usr/bin/env python3 # -# Simple script to do all the ugly munging or connected displays on a Dell XPS -# 13. Is used by a Lua function within Awesome that actually determines what to -# do with those displays. +# TODO: Rewrite this in C and just use the XRandr APIs directly # -for output in /sys/class/drm/card*-*; do - if [ "$(cat $output/status)" == "connected" ]; then - card=$(basename $output); card=${card##card?-} - edid=$(cat $output/edid | parse-edid 2>&1 | grep Identifier | cut -d '"' -f2) - edid_sum=$(md5sum -b $output/edid | cut -f1 -d' ') +import re +import sys +import subprocess - # The EDID data is corrupt on the Dell XPS panels for some reason - if [ "$edid_sum" == "99030a11512deeb0371adf0a6c6a8a06" ] || [ "$edid_sum" == "31a6481b493cdfcd9e50c67290644eed" ]; then - edid="DELL_XPS_13" - fi - echo "$card:$edid" - fi -done +def is_host_xps(): + try: + with open("/sys/class/dmi/id/product_name", "r") as fp: + product = fp.read() + + return bool(re.match("XPS 13 93[78]0", product)) + except FileNotFoundError: + return False + + +def parse_edid(hex_list): + proc = subprocess.Popen( + ["parse-edid"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + out, _ = proc.communicate(bytes.fromhex("".join(hex_list))) + + identifier = re.findall( + '\tIdentifier "([^"]+)"\n', + out.decode("us-ascii", errors="backslashreplace")) + + if identifier: + return identifier[0] + else: + return None + + +def get_connected_displays(): + out = subprocess.check_output(["xrandr", "--verbose", "--query"]) + + current_display = None + in_edid = False + current_edid = [] + + all_edids = {} + + for line in out.decode("us-ascii").split("\n"): + if ' connected ' in line: + current_display = line.split(" ")[0] + + if current_display and 'EDID:' in line: + in_edid = True + continue + + if in_edid and line[:2] == "\t\t": + current_edid.append(line.strip()) + elif in_edid and line[:2] != "\t\t": + all_edids[current_display] = parse_edid(current_edid) + in_edid = False + current_display = None + current_edid = [] + + return all_edids + + +def main(): + is_xps = is_host_xps() + + for display, edid in get_connected_displays().items(): + # The EDID data is corrupted on all Dell XPSes + if is_xps and display == "eDP-1": + edid = "DELL_XPS_13" + + print("{display}:{edid}".format(**locals())) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) -- cgit v1.2.3