--- /dev/null
+#!/usr/bin/python
+import sys, re, subprocess
+from PyQt4 import QtGui
+from selector_window import PositionSelection
+app = QtGui.QApplication(sys.argv)
+
+def getXrandrInformation():
+ p = subprocess.Popen(["xrandr", "-q"], stdout=subprocess.PIPE)
+ connectors = {} # map of connector names to a list of resolutions
+ connector = None # current connector
+ for line in p.stdout:
+ # new connector?
+ m = re.search('^([\w]+) connected ', line)
+ if m is not None:
+ connector = m.groups()[0]
+ assert connector not in connectors
+ connectors[connector] = []
+ continue
+ # new resolution?
+ m = re.search('^ ([\d]+x[\d]+) +', line)
+ if m is not None:
+ assert connector is not None
+ connectors[connector].append(int(m.groups()[0]))
+ return connectors
+
+# Check screen setup
+internalName = "LVDS"
+externalName = "CRT1"
+connectors = getXrandrInformation()
+internalResolutions = connectors[internalName] # there must be a screen assoicated to the internal connector
+externalResolutions = connectors.get(externalName)
+
+# Check what to do
+internalArgs = ["--mode", internalResolutions[0]] # there must be a resolution for the internal screen
+externalArgs = ["--off"]
+if externalResolutions is not None: # we need to ask what to do
+ extPosition = PositionSelection(externalResolutions)
+ extPosition.exec_()
+ if not extPosition.result(): sys.exit(1) # the user canceled
+ # build command-line
+ externalArgs = ["--mode", extPosition.resolution] # we definitely want an external screen
+ if extPosition.position == PositionSelection.EXTERNAL_ONLY:
+ internalArgs = ["--off"]
+ elif extPosition.position == PositionSelection.LEFT:
+ externalArgs += ["--left-of", internalName]
+ else:
+ externalArgs += ["--right-of", internalName]
+# and do it
+args = ["--output", internalName] + internalArgs + ["--output", externalName] + externalArgs
+print args
+subprocess.check_call(["xrandr"] + args)
--- /dev/null
+#!/usr/bin/python
+from PyQt4 import QtGui
+
+class PositionSelection(QtGui.QDialog):
+ LEFT = 10
+ RIGHT = 20
+ EXTERNAL_ONLY = 30
+
+ def __init__(self, resolutions):
+ super(PositionSelection, self).__init__()
+
+ mainBox = QtGui.QVBoxLayout()
+ posBox = QtGui.QHBoxLayout()
+ resBox = QtGui.QHBoxLayout()
+
+ # First row: Resolution selection
+ mainBox.addLayout(resBox)
+ resBox.addWidget(QtGui.QLabel('Select the resolution of the external screen:'))
+ self.resolutions = QtGui.QComboBox(self)
+ for res in resolutions:
+ self.resolutions.addItem(res)
+ self.resolutions.setCurrentIndex(0) # select first resolution
+ resBox.addWidget(self.resolutions)
+
+ # Next two rows: Position selection
+ mainBox.addWidget(QtGui.QLabel('Select the position of the external screen relative to the internal one:'))
+ mainBox.addLayout(posBox)
+
+ btn = QtGui.QPushButton('Left', self)
+ btn.clicked.connect(self.left)
+ posBox.addWidget(btn)
+
+ btn = QtGui.QPushButton('Right', self)
+ btn.clicked.connect(self.right)
+ btn.setFocus()
+ posBox.addWidget(btn)
+
+ btn = QtGui.QPushButton('External only', self)
+ btn.clicked.connect(self.externalOnly)
+ posBox.addWidget(btn)
+
+ # Finalization
+ self.setLayout(mainBox)
+ self.setWindowTitle('External screen setup')
+
+ def accept(self):
+ self.resolution = str(self.resolutions.currentText())
+ super(PositionSelection, self).accept()
+
+ def left(self):
+ self.position = PositionSelection.LEFT
+ self.accept()
+
+ def right(self):
+ self.position = PositionSelection.RIGHT
+ self.accept()
+
+ def externalOnly(self):
+ self.position = PositionSelection.EXTERNAL_ONLY
+ self.accept()