add options to select primary screen and internal screen resolution
[lilass.git] / external_screen.py
1 #!/usr/bin/python
2 import sys, re, subprocess
3 from PyQt4 import QtGui
4 from selector_window import PositionSelection
5 app = QtGui.QApplication(sys.argv)
6
7 def getXrandrInformation():
8         p = subprocess.Popen(["xrandr", "-q"], stdout=subprocess.PIPE)
9         connectors = {} # map of connector names to a list of resolutions
10         connector = None # current connector
11         for line in p.stdout:
12                 # new connector?
13                 m = re.search(r'^([\w]+) connected ', line)
14                 if m is not None:
15                         connector = m.groups()[0]
16                         assert connector not in connectors
17                         connectors[connector] = []
18                         continue
19                 # new resolution?
20                 m = re.search(r'^   ([\d]+)x([\d]+) +', line)
21                 if m is not None:
22                         assert connector is not None
23                         connectors[connector].append((int(m.groups()[0]), int(m.groups()[1])))
24         p.communicate()
25         if p.returncode != 0: raise Exception("Querying xrandr for data failed")
26         return connectors
27
28 def res2str(res):
29         (w, h) = res
30         return str(w)+'x'+str(h)
31
32 # Check screen setup
33 internalName = "LVDS"
34 externalName = "CRT1"
35 connectors = getXrandrInformation()
36 internalResolutions = connectors[internalName] # there must be a screen assoicated to the internal connector
37 externalResolutions = connectors.get(externalName)
38
39 # Check what to do
40 if externalResolutions is not None: # we need to ask what to do
41         extPosition = PositionSelection(map(res2str, internalResolutions), map(res2str, externalResolutions))
42         extPosition.exec_()
43         if not extPosition.result(): sys.exit(1) # the user canceled
44         extResolution = res2str(externalResolutions[extPosition.extResolutions.currentIndex()])
45         intResolution = res2str(internalResolutions[extPosition.intResolutions.currentIndex()])
46         # build command-line
47         externalArgs = ["--mode", extResolution] # we definitely want an external screen
48         if extPosition.extOnly.isChecked():
49                 internalArgs = ["--off"]
50                 externalArgs += ["--primary"]
51         else:
52                 # there are two screens
53                 internalArgs = ["--mode", intResolution]
54                 if extPosition.posLeft.isChecked():
55                         externalArgs += ["--left-of", internalName]
56                 else:
57                         externalArgs += ["--right-of", internalName]
58                 if extPosition.primExt.isChecked():
59                         externalArgs += ["--primary"]
60                 else:
61                         internalArgs += ["--primary"]
62 else:
63         internalArgs = ["--mode", res2str(internalResolutions[0]), "--primary"] # there must be a resolution for the internal screen
64         externalArgs = ["--off"]
65 # and do it
66 call = ["xrandr", "--output", internalName] + internalArgs + ["--output", externalName] + externalArgs
67 print "Call that will be made:",call
68 subprocess.check_call(call)