]> oss.titaniummirror.com Git - dispcfg.git/blobdiff - configure_displays
Change name, set x bit
[dispcfg.git] / configure_displays
diff --git a/configure_displays b/configure_displays
new file mode 100755 (executable)
index 0000000..40a3ff2
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/python
+"""
+Parse xrandr current information
+
+TODO:
+* Cannot seem to undock notebook then recover displays without causing a logout
+  event.  Could it be that i3 is finding there are no displays?
+"""
+
+import sys
+import subprocess
+import re
+
+dry_run = False
+
+class OutputInfo():
+    def __init__(self):
+        self.clear()
+
+    def clear(self):
+        self.name = None
+        self.connected = False
+        self.enabled = False
+        self.width = -1
+        self.height = -1
+        self.posx = -1
+        self.posy = -1
+
+    def complete(self):
+        if self.name and (self.connected == False or self.width != -1):
+            return True
+        else:
+            return False
+
+    def asDict(self):
+        if self.complete():
+            return {'name':self.name, 'enabled':self.enabled,
+                    'connected':self.connected, 'width':self.width,
+                    'height':self.height, 'posx':self.posx, 'posy':self.posy,
+                    'use':False, 'done':False}
+        else:
+            raise ValueError
+
+    def parse(self, line):
+        tokens = line.split()
+        if len(tokens):
+            if tokens[1] == 'connected' or tokens[1] == 'disconnected':
+                self.clear()
+                self.name = tokens[0]
+                if tokens[1] == 'connected':
+                    self.connected = True
+                token = 2
+                size = []
+                while token < len(tokens) and len(size) != 4:
+                    # skip other tokens like 'primary'
+                    size = re.split('[x+]', tokens[token])
+                    token += 1
+                if len(size) == 4:
+                    self.enabled = True
+                    #self.width = int(size[0])
+                    #self.height = int(size[1])
+                    #self.posx = int(size[2])
+                    #self.posy = int(size[3])
+            elif self.connected and self.width < 0:
+                size = re.split('x', tokens[0])
+                if len(size) == 2:
+                    self.width = int(size[0])
+                    self.height = int(size[1])
+
+
+def parse():
+    outputs = []
+    output = OutputInfo()
+    p = subprocess.check_output('xrandr')
+    for line in p.split('\n'):
+        output.parse(line)
+        if output.complete():
+            outputs.append(output.asDict())
+            output.clear()
+    return outputs
+
+
+def xrandr_on(output):
+    command = ['xrandr', '--output', output['name'], '--auto', '--pos',
+            '%dx0' % output['posx']]
+    if output['posx'] == 0:
+        command += ['--primary']
+    if not dry_run:
+        print 'xrandr_on:', command
+        subprocess.call(command)
+    else:
+        print '(dry-run) xrandr_on:', command
+
+
+def xrandr_off(output):
+    command = ['xrandr', '--output', output['name'], '--off']
+    if not dry_run:
+        subprocess.call(command)
+        print 'xrandr_off:', command
+    else:
+        print '(dry-run) xrandr_off:', command
+
+
+def output_by_name(outputs, name):
+    for output in outputs:
+        if output['name'] == name:
+            return output
+    return None
+
+
+if __name__ == '__main__':
+    def print_output(output):
+        print 'name:%s  connected:%r  enabled:%r  width:%d  height:%d pos:%dx%d' % (
+                output['name'], output['connected'], output['enabled'],
+                output['width'], output['height'], output['posx'],
+                output['posy'])
+
+    def print_outputs(header, outputs):
+        print '%s:' % header
+        for output in outputs:
+            print_output(output)
+        print
+
+    def all_done(outputs):
+        for output in outputs:
+            if not output['done']:
+                return False
+        return True
+
+    def disable_an_entry(outputs):
+        for output in outputs:
+            if not output['done'] and not output['use'] and output['enabled']:
+                xrandr_off(output)
+                output['done'] = True
+                return 1
+        return 0
+
+    def enable_an_entry(outputs):
+        enables = 0
+        for output in reversed(outputs):
+            if not output['done'] and output['use']:
+                xrandr_on(output)
+                output['done'] = True
+                return 1
+        return 0
+
+    def main(argv):
+        global dry_run
+        if len(argv) >= 2 and argv[1] == '--dry-run':
+            dry_run = True
+
+        outputs = parse()
+        print_outputs('Outputs', outputs)
+
+        # Find the first two connected devices, in reverse list order.  On the
+        # Thinkpad X201, the reversed list order is the preferred order of
+        # precedence, highest quality external display first, down to internal
+        # LVDS panel used as a last resort.  Also find new posx values.
+        use_count = 0
+        posx = 0
+        for output in reversed(outputs):
+            if output['connected']:
+                print 'use', output['name']
+                output['use'] = True
+                output['posx'] = posx
+                posx += output['width']
+                use_count += 1
+                if use_count >= 2:
+                    break
+
+        # How many outputs are currently enabled?
+        enabled_count = 0
+        for output in outputs:
+            if output['enabled']:
+                enabled_count += 1
+
+        # Mark outputs that receive no change as done
+        for output in outputs:
+            if not output['use'] and not output['enabled']:
+                # Nothing to do for this output, mark as done
+                output['done'] = True
+
+        while not all_done(outputs):
+            if enabled_count > 1:
+                enabled_count -= disable_an_entry(outputs)
+            if enabled_count < 2:
+                enabled_count += enable_an_entry(outputs)
+
+
+    main(sys.argv)