diff options
Diffstat (limited to '')
-rw-r--r-- | xorg-xrandr/setres/get.py | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/xorg-xrandr/setres/get.py b/xorg-xrandr/setres/get.py new file mode 100644 index 0000000..47a6428 --- /dev/null +++ b/xorg-xrandr/setres/get.py @@ -0,0 +1,248 @@ +class XScreen: + def __init__(self, line): + self.number = int(line.split(':')[0].split(' ')[1]) + self.minimum = None + self.current = None + self.maximum = None + self.connectors = [] + for part in line.split(':')[1][1:].split(', '): + words = part.split(' ') + if words[0] == 'minimum': + self.minimum = (int(words[1]), int(words[3])) + elif words[0] == 'current': + self.minimum = (int(words[1]), int(words[3])) + elif words[0] == 'maximum': + self.minimum = (int(words[1]), int(words[3])) + + def __getitem__(self, value): + if isinstance(value, str): + for connector in self.connectors: + if connector.name == value: + return connector + elif value is True: + for connector in self.connectors: + if connector.primary: + return connector + else: + return self.connectors[value] + return None + + +class XConnector: + def __init__(self, line): + line = line.split(' ') + self.name = line[0] + self.connected = line[1] == 'connected' + self.primary = False + self.size = None + self.position = None + self.mode = None + self.rr = None + self.physsize = None + self.modes = [] + self.identifier = None + self.timestamp = None + self.subpixel = None + self.gamma = None + self.brightness = None + self.clones = None + self.crtc = None + self.crtcs = None + self.transform = None + self.filter = None # TODO + self.edid = None + # TODO BACKLIGHT + # TODO Backlight + # TODO scaling mode + # TODO Broadcast RGB + # TODO audio + + if not self.connected: + return + i = 2 + + if i == len(line): + return + if line[i] == 'primary': + self.primary = True + i += 1 + + if i == len(line): + return + word = line[i].replace('-', '+-').replace('+--', '+-') + if len(word.replace('+', '')) + 2 == len(word) and len(word.replace('x', '')) + 1 == len(word): + if word.replace('+', '').replace('x', '').isdigit(): + i += 1 + words = word.split('+') + self.position = (int(words[1]), int(words[2])) + words = words[0].split('x') + self.size = (int(words[0]), int(words[1])) + + if i == len(line): + return + if line[i].startswith('(0x') and line[i].endswith(')'): + self.mode = int(line[i][3 : -1], 16) + i += 1 + + while not line[i].startswith('('): + if self.rr is None: + self.rr = line[i] + else: + self.rr += ' ' + line[i] + i += 1 + while not line[i].endswith(')'): + i += 1 + i += 1 + + line = [word[:-2] for word in line[i:] if word.endswith('mm')] + if len(line) == 2: + self.physsize = (int(line[0]), int(line[1])) + + def __getitem__(self, name): + for mode in self.modes: + if mode.name == name: + return mode + return None + + def best_rate(self, mode): + best = None + if isinstance(mode, str): + mode = tuple(int(x) for x in mode.split('x')) + for m in self.modes: + if m.size == mode: + cand = m.vclock + if cand is None: + continue + if best is None or float(cand) > float(best): + best = cand + return best + + +class XMode: + def __init__(self, line): + line = line.split(' ') + [w, h] = line[0].split('x') + self.size = (int(w), int(h)) + self.name = int(line[1][3 : -1], 16) + self.tclock = line[2][:-3] # MHz + self.hsync = None + self.vsync = None + self.current = False + self.preferred = False + for word in line[3]: + if word.endswith('HSync'): + self.hsync = word[0] + elif word.endswith('VSync'): + self.vsync = word[0] + elif word == '*current': + self.current = True + elif word == '+preferred': + self.preferred = True + + def set_h(self, line): + line = line.split(' ') + self.width = int(line[2]) + self.hstart = int(line[4]) + self.hend = int(line[6]) + self.htotal = int(line[8]) + self.hskew = int(line[10]) + self.hclock = line[12][:-3] # KHz + + def set_v(self, line): + line = line.split(' ') + self.height = int(line[2]) + self.vstart = int(line[4]) + self.vend = int(line[6]) + self.vtotal = int(line[8]) + self.vclock = line[10][:-2] # Hz + + +def get_setup(): + from subprocess import Popen, PIPE + + def is_screen_line(line): + if ':' not in line: + return False + line = line.split(':')[0].split(' ') + if len(line) != 2: + return False + return line[0] == 'Screen' and line[1].isdigit() + + def is_connector_line(line): + return ' ' in line and line.split(' ')[1] in ('connected', 'disconnected') + + def is_mode_line(line): + words = line.split(' ') + if len(words) < 2: + return False + if len(words[0]) - 1 != len(words[0].replace('x', '')): + return False + if not words[0].replace('x', '').isdigit(): + return False + if words[0][0] == 'x' or words[0][-1] == 'x': + return False + if not words[1].startswith('(0x'): + return False + return words[1].endswith(')') + + screens = [] + screen = None + connector = None + mode = None + transx = None + on_edid = False + + xrandr_output = Popen('env LANG=C xrandr --verbose'.split(' '), stdout = PIPE) + xrandr_output = xrandr_output.communicate()[0].decode('utf-8', 'strict').split('\n') + + for line in xrandr_output: + if on_edid and line.startswith('\t\t') and ':' not in line: + connector.edid += line.replace(' ', '') + on_edid = None + elif transx is not None: + transx.append(line.strip()) + if len(transx) == 3: + connector.transform = tuple(tuple(float(x) for x in r.split(' ')) for r in transx) + transx = None + elif is_screen_line(line): + screen = XScreen(line) + screens.append(screen) + elif is_connector_line(line): + connector = XConnector(line) + screen.connectors.append(connector) + else: + line = line.replace('\t', ' ').strip() + while ' ' in line: + line = line.replace(' ', ' ') + words = line.split(' ') + if is_mode_line(line): + mode = XMode(line) + connector.modes.append(mode) + elif line.startswith('h: '): + mode.set_h(line) + elif line.startswith('v: '): + mode.set_v(line) + elif line.startswith('Identifier:'): + connector.identifier = int(words[1][2:], 16) + elif line.startswith('Timestamp:'): + connector.timestamp = int(words[1]) + elif line.startswith('Subpixel:'): + connector.subpixel = ' '.join(words[1:]) + elif line.startswith('Gamma:'): + connector.gamma = tuple(float(x) for x in words[1].split(':')) + elif line.startswith('Brightness:'): + connector.brightness = float(words[1]) + elif line.startswith('Clones:'): + connector.clones = words[1:] + elif line.startswith('CRTCs:'): + connector.crtc = int(words[1]) + elif line.startswith('CRTCs:'): + connector.crtcs = tuple(int(x) for x in words[1:]) + elif line.startswith('Transform:'): + transx = [' '.join(words[1:])] + elif line.startswith('EDID:'): + connector.edid = ''.join(words[1:]) + on_edid = None + on_edid = on_edid is None + + return screens |