Skip to content

Commit 24f9409

Browse files
authored
Add files via upload
wacom-gui.py * changed toggle to use MapToOutput next options.py * reworked screen detection; now supports more than 2 displays * uses MapToOutput HEAD-<displayID> vs generating a matrix; seems to support non-standard monitor layouts better * this breaks support for CentOS 6 as it requires a newer release of the wacom drivers to support
1 parent 85818f8 commit 24f9409

File tree

2 files changed

+159
-224
lines changed

2 files changed

+159
-224
lines changed

wacom-gui/options.py

+153-129
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#!/usr/bin/python
22

3-
from PyQt4 import QtCore,QtGui
4-
import sys, os, re
3+
from PyQt4 import QtCore, QtGui
4+
import sys
5+
import os
6+
import re
7+
import subprocess
58

69
class otherOptions(QtGui.QWidget):
710
def __init__(self, tabletName, parent=None):
811
QtGui.QWidget.__init__(self, parent)
9-
self.tabletName=tabletName
12+
self.tabletName = tabletName.replace('Pad', 'Pen')
1013

1114
self.initUI()
1215

@@ -19,29 +22,41 @@ def initUI(self):
1922
#layout code
2023
self.mainLayout = QtGui.QHBoxLayout()
2124
self.mainLayout.setAlignment(QtCore.Qt.AlignLeft)
22-
self.mainLayout.addWidget(self.screenOptions())
25+
screens = self.screenOptions()
26+
if screens:
27+
self.mainLayout.addWidget(screens)
2328
self.mainLayout.addWidget(self.flipOptions())
2429
self.setLayout(self.mainLayout)
2530

2631
#update current active screen area
2732
self.getCurrentScreen()
2833

2934
def screenOptions(self):
35+
if QtGui.QDesktopWidget().numScreens() == 1:
36+
return None
3037
groupBox = QtGui.QGroupBox("Screen Area")
3138
groupBox.setAlignment(QtCore.Qt.AlignHCenter)
3239
groupBox.setFixedHeight(120)
40+
displays = self.get_monitors()
3341
self.screenGroup = QtGui.QButtonGroup(groupBox)
34-
self.screenLeft = QtGui.QRadioButton("Left Monitor")
35-
self.screenRight = QtGui.QRadioButton("Right Monitor")
36-
self.screenFull = QtGui.QRadioButton("Both Monitors")
37-
38-
self.screenGroup.addButton(self.screenLeft)
39-
self.screenGroup.addButton(self.screenRight)
42+
self.displays = []
43+
for x in range(0, QtGui.QDesktopWidget().numScreens()):
44+
self.displays.append(QtGui.QRadioButton("Monitor %d" % x))
45+
#self.screenLeft = QtGui.QRadioButton("Left Monitor")
46+
#self.screenRight = QtGui.QRadioButton("Right Monitor")
47+
self.screenFull = QtGui.QRadioButton("All Monitors")
48+
49+
for screen in self.displays:
50+
self.screenGroup.addButton(screen)
51+
#self.screenGroup.addButton(self.screenLeft)
52+
#self.screenGroup.addButton(self.screenRight)
4053
self.screenGroup.addButton(self.screenFull)
4154

4255
screenLayout = QtGui.QVBoxLayout()
43-
screenLayout.addWidget(self.screenLeft)
44-
screenLayout.addWidget(self.screenRight)
56+
for screen in self.displays:
57+
screenLayout.addWidget(screen)
58+
#screenLayout.addWidget(self.screenLeft)
59+
#screenLayout.addWidget(self.screenRight)
4560
screenLayout.addWidget(self.screenFull)
4661
screenLayout.addStretch(1)
4762

@@ -50,7 +65,25 @@ def screenOptions(self):
5065
groupBox.setLayout(screenLayout)
5166

5267
return groupBox
53-
68+
69+
70+
def get_monitors(self):
71+
p = subprocess.Popen("xrandr | grep \" connected\"", shell=True, stdout=subprocess.PIPE)
72+
output = p.communicate()[0].split('\n')
73+
regex = r"^([\w-]+)(\D+)(\d+)x(\d+)\+(\d+)\+(\d+)"
74+
screens = {}
75+
for display in output:
76+
if display != '':
77+
match = re.search(regex, display)
78+
if match.group(5) not in screens.keys():
79+
screens[match.group(5)] = {}
80+
screens[match.group(5)][match.group(6)] = match.group(1)
81+
displays = []
82+
for x in sorted(screens.keys()):
83+
for y in sorted(screens[x].keys()):
84+
displays.append(screens[x][y])
85+
return displays
86+
5487
def flipOptions(self):
5588
groupBox = QtGui.QGroupBox("Tablet Orientation")
5689
groupBox.setAlignment(QtCore.Qt.AlignHCenter)
@@ -67,15 +100,15 @@ def flipOptions(self):
67100
flipLayout.addWidget(self.tabletLeft)
68101
flipLayout.addStretch(1)
69102

70-
getCommand = os.popen("xsetwacom --get \""+self.tabletName+" stylus\" Rotate").readlines()
71-
#check correct button for orientation
103+
getCommand = os.popen("xsetwacom --get \"%s stylus\" Rotate" % self.tabletName).readlines()
104+
# check correct button for orientation
72105
if getCommand[0] == "none\n":
73-
self.orient = "xsetwacom --set \""+self.tabletName+" stylus\" Rotate none"
74-
self.orient += "\nxsetwacom --set \"" + self.tabletName + " eraser\" Rotate none"
106+
self.orient = "xsetwacom --set \"%s stylus\" Rotate none" % self.tabletName
107+
self.orient += "\nxsetwacom --set \"%s eraser\" Rotate none" % self.tabletName
75108
self.tabletRight.setChecked(1)
76109
elif getCommand[0] == "half\n":
77-
self.orient = "xsetwacom --set \""+self.tabletName+" stylus\" Rotate half"
78-
self.orient += "\nxsetwacom --set \"" + self.tabletName + " eraser\" Rotate half"
110+
self.orient = "xsetwacom --set \"%s stylus\" Rotate half" % self.tabletName
111+
self.orient += "\nxsetwacom --set \"%s eraser\" Rotate half" % self.tabletName
79112
self.tabletLeft.setChecked(1)
80113

81114
self.tabletFlipGroup.buttonClicked.connect(self.tabletFlipChange)
@@ -86,140 +119,124 @@ def flipOptions(self):
86119

87120
def tabletFlipChange(self, buttonId):
88121
if buttonId.text() == "Right-Handed":
89-
self.orient = "xsetwacom --set \""+self.tabletName+" stylus\" Rotate none"
90-
self.orient +="\nxsetwacom --set \"" + self.tabletName + " eraser\" Rotate none"
122+
self.orient = "xsetwacom --set \"%s stylus\" Rotate none" % self.tabletName
123+
self.orient += "\nxsetwacom --set \"%s eraser\" Rotate none" % self.tabletName
91124
elif buttonId.text() == "Left-Handed":
92-
self.orient = "xsetwacom --set \""+self.tabletName+" stylus\" Rotate half"
93-
self.orient +="\nxsetwacom --set \"" + self.tabletName + " eraser\" Rotate half"
125+
self.orient = "xsetwacom --set \"%s stylus\" Rotate half" % self.tabletName
126+
self.orient += "\nxsetwacom --set \"%s eraser\" Rotate half" % self.tabletName
94127
flipTablet = os.popen(self.orient)
95128

96-
def screenChange(self,buttonId):
97-
screen = ""
98-
coords = ""
99-
if buttonId.text() == "Both Monitors":
129+
130+
def screenChange(self, buttonId):
131+
if buttonId.text() == "All Monitors":
100132
self.tabletActiveArea = "1 0 0 0 1 0 0 0 1"
101133
for device in self.devices:
102-
if device != self.tabletName+" pad":
103-
setCommand = os.popen("xinput set-prop \"" + self.tabletName+ " " + device + "\" --type=float \"Coordinate Transformation Matrix\" " + self.tabletActiveArea)
104-
#for i in range(len(self.otherOptionSettings)):
105-
# if self.otherOptionSettings[i].find("xinput set-prop") != -1 and self.otherOptionSettings[i].find(device) != -1:
106-
# self.otherOptionSettings[i] = "xinput set-prop \"" + device + "\" --type=float \"Coordinate Transformation Matrix\" 1 0 0 0 1 0 0 0 1"
107-
elif buttonId.text() == "Left Monitor":
108-
screen = QtGui.QDesktopWidget().screenGeometry(0)
109-
elif buttonId.text() == "Right Monitor":
110-
screen = QtGui.QDesktopWidget().screenGeometry(1)
111-
if screen != "":
112-
totalResolution = os.popen("xdpyinfo | grep dimensions | awk '{print $2}' | awk -Fx '{print $1, $2}'").read()
113-
totalResolution = totalResolution.split()
114-
115-
display = [[0 for x in xrange(3)] for x in xrange(3)]
116-
display[2][2]=1.0
117-
118-
display[0][0] = float(screen.width()) / float(totalResolution[0])
119-
display[1][1] = float(screen.height()) / float(totalResolution[1])
120-
if float(screen.topLeft().x())!=0:
121-
display[0][2] = float(screen.x()) / float(totalResolution[0])
122-
if float(screen.topLeft().y())!=0:
123-
display[1][2] = float(screen.y()) / float(totalResolution[1])
124-
125-
self.tabletActiveArea = ''
126-
for x in xrange(3):
127-
for y in xrange(3):
128-
self.tabletActiveArea = self.tabletActiveArea + " " + str(display[x][y])
129-
134+
if device != "pad":
135+
cmd = "xinput set-prop \"%s %s\" --type=float \"Coordinate Transformation Matrix\" %s" % \
136+
(self.tabletName, device, self.tabletActiveArea)
137+
setCommand = os.popen(cmd)
138+
else:
139+
self.tabletActiveArea = "HEAD-%s" % buttonId.text().split(' ')[1]
130140
for device in self.devices:
131-
if device != self.tabletName+" pad":
132-
setCommand = os.popen("xinput set-prop \"" + self.tabletName+ " " + device + "\" --type=float \"Coordinate Transformation Matrix\" " + self.tabletActiveArea)
133-
#for i in range(len(self.otherOptionSettings)):
134-
# if self.otherOptionSettings[i].find("xinput set-prop") != -1 and self.otherOptionSettings[i].find(device) != -1:
135-
# self.otherOptionSettings[i] = "xinput set-prop \"" + device + "\" " + coordset
141+
if device != "pad":
142+
cmd = "xsetwacom set \"%s %s\" MapToOutput %s" % (self.tabletName, device, self.tabletActiveArea)
143+
setCommand = os.popen(cmd)
144+
136145

137146
def getTabletArea(self):
138-
#get current tablet area
139-
tabletInfo = os.popen("xinput list-props \""+ self.tabletName+ " stylus\" | grep Coordinate").readlines()
147+
# get current tablet area
148+
tabletInfo = os.popen("xinput list-props \"%s stylus\" | grep Coordinate" % self.tabletName).readlines()
140149
tabletInfo[0] = tabletInfo[0][41:].rstrip('\n')
141-
tabletInfo[0] = re.sub(",","",tabletInfo[0])
150+
tabletInfo[0] = re.sub(",", "", tabletInfo[0])
142151
tabletScreenCoords = {}
143152
blarg = tabletInfo[0].split()
144153
count = 0
145-
for i in range(0,3):
146-
for j in range(0,3):
147-
tabletScreenCoords[(i,j)] = blarg[count]
154+
for i in range(0, 3):
155+
for j in range(0, 3):
156+
tabletScreenCoords[(i, j)] = blarg[count]
148157
self.tabletActiveArea = self.tabletActiveArea + " " + blarg[count]
149-
count+=1
158+
count += 1
150159

151-
#check if "full screen"
160+
# check if "full screen"
152161
fullScreen = True
153-
for i in range(0,3):
154-
for j in range(0,3):
155-
if i == j and float(tabletScreenCoords[(i,j)]) != 1.0:
162+
for i in range(0, 3):
163+
for j in range(0, 3):
164+
if i == j and float(tabletScreenCoords[(i, j)]) != 1.0:
156165
fullScreen = False
157166
break
158-
elif i != j and float(tabletScreenCoords[(i,j)]) != 0.0:
167+
elif i != j and float(tabletScreenCoords[(i, j)]) != 0.0:
159168
fullScreen = False
160169
break
161170
if fullScreen:
162171
self.screenFull.setChecked(1)
163-
#have to build array then compare... boo
172+
# have to build array then compare... boo
164173
else:
165-
screen1 = QtGui.QDesktopWidget().screenGeometry(0)
166-
screen2 = QtGui.QDesktopWidget().screenGeometry(1)
167-
totalResolution = os.popen("xdpyinfo | grep dimensions | awk '{print $2}' | awk -Fx '{print $1, $2}'").read()
168-
totalResolution = totalResolution.split()
169-
170-
171-
display = [[0 for x in xrange(3)] for x in xrange(3)]
172-
display[2][2]=1.0
173-
174-
display[0][0] = float(screen1.width()) / float(totalResolution[0])
175-
#percent of screen height
176-
display[1][1] = float(screen1.height()) / float(totalResolution[1])
177-
#offset in x
178-
if float(screen1.topLeft().x())!=0:
179-
display[0][2] = float(screen1.topLeft().x()) / float(totalResolution[0])
180-
#offset in y
181-
if float(screen1.topLeft().y())!=0:
182-
display[1][2] = float(screen1.topLeft().y()) / float(totalResolution[1])
183-
184-
isLeft = True
185-
for i in range(0,3):
186-
for j in range(0,3):
187-
if float(tabletScreenCoords[(i,j)]) != float(display[i][j]):
188-
isLeft = False
189-
break
190-
191-
if isLeft:
192-
self.screenLeft.setChecked(1)
193-
#crap... check if right
194-
else:
195-
display[0][0] = float(screen2.width()) / float(totalResolution[0])
196-
#percent of screen height
197-
display[1][1] = float(screen2.height()) / float(totalResolution[1])
198-
#offset in x
199-
if float(screen2.topLeft().x())!=0:
200-
display[0][2] = float(screen2.topLeft().x()) / float(totalResolution[0])
201-
#offset in y
202-
if float(screen2.topLeft().y())!=0:
203-
display[1][2] = float(screen2.topLeft().y()) / float(totalResolution[1])
204-
205-
isRight = True
206-
for i in range(0,3):
207-
for j in range(0,3):
208-
if float(tabletScreenCoords[(i,j)]) != float(display[i][j]):
209-
isRight = False
174+
for id in range(0, QtGui.QDesktopWidget().numScreens()):
175+
screen = QtGui.QDesktopWidget().screenGeometry(id)
176+
#screen1 = QtGui.QDesktopWidget().screenGeometry(0)
177+
#screen2 = QtGui.QDesktopWidget().screenGeometry(1)
178+
totalResolution = os.popen("xdpyinfo | grep dimensions | awk '{print $2}' | awk -Fx '{print $1, $2}'").read()
179+
totalResolution = totalResolution.split()
180+
181+
182+
display = [[0 for x in xrange(3)] for x in xrange(3)]
183+
display[2][2] = 1.0
184+
185+
display[0][0] = float(screen.width()) / float(totalResolution[0])
186+
# percent of screen height
187+
display[1][1] = float(screen.height()) / float(totalResolution[1])
188+
# offset in x
189+
if float(screen.topLeft().x()) != 0:
190+
display[0][2] = float(screen.topLeft().x()) / float(totalResolution[0])
191+
# offset in y
192+
if float(screen.topLeft().y()) != 0:
193+
display[1][2] = float(screen.topLeft().y()) / float(totalResolution[1])
194+
valid = True
195+
196+
#isLeft = True
197+
for i in range(0, 3):
198+
for j in range(0, 3):
199+
if float(tabletScreenCoords[(i, j)]) != float(display[i][j]):
200+
valid = False
210201
break
211-
if isRight:
212-
self.screenRight.setChecked(1)
202+
if valid:
203+
self.displays[id].setChecked(1)
204+
break
205+
206+
207+
#if isLeft:
208+
# self.screenLeft.setChecked(1)
209+
# crap... check if right
210+
#else:
211+
# display[0][0] = float(screen2.width()) / float(totalResolution[0])
212+
# # percent of screen height
213+
# display[1][1] = float(screen2.height()) / float(totalResolution[1])
214+
# # offset in x
215+
# if float(screen2.topLeft().x()) != 0:
216+
# display[0][2] = float(screen2.topLeft().x()) / float(totalResolution[0])
217+
# # offset in y
218+
# if float(screen2.topLeft().y()) != 0:
219+
# display[1][2] = float(screen2.topLeft().y()) / float(totalResolution[1])#
220+
221+
# isRight = True
222+
# for i in range(0,3):
223+
# for j in range(0,3):
224+
# if float(tabletScreenCoords[(i, j)]) != float(display[i][j]):
225+
# isRight = False
226+
# break
227+
# if isRight:
228+
# self.screenRight.setChecked(1)
229+
213230

214231
def getCurrentScreen(self):
215-
#check if we actually have more that 1 screen
232+
# check if we actually have more that 1 screen
216233
if QtGui.QDesktopWidget().numScreens() < 2 or QtGui.QDesktopWidget().numScreens() > 2:
217234
self.screenLeft.enabled = False
218235
self.screenRight.enabled = False
219236
self.screenFull.enabled = False
220237
if QtGui.QDesktopWidget().numScreens() > 2:
221238
print "More that 2 monitors; this isn't available yet. Disabling tablet area option"
222-
#set correct check box for active area... if it is valid
239+
# set correct check box for active area... if it is valid
223240
else:
224241
self.getTabletArea()
225242

@@ -231,23 +248,30 @@ def setDevices(self, devices):
231248
def getScreenArea(self):
232249
setCommands = []
233250
for device in self.devices:
234-
if device != "pad" and device !='touch':
235-
setCommands.append("xinput set-prop \""+self.tabletName+" " + device +
236-
"\" --type=float \"Coordinate Transformation Matrix\" " + self.tabletActiveArea)
251+
if device != "pad" and device != 'touch':
252+
if 'HEAD' in self.tabletActiveArea:
253+
setCommands.append("xsetwacom set \"%s %s\" MapToOutput %s" %
254+
(self.tabletName, device, self.tabletActiveArea))
255+
else:
256+
setCommands.append("xinput set-prop \"%s %s\" --type=float \"Coordinate Transformation Matrix\" %s"
257+
% (self.tabletName, device, self.tabletActiveArea))
237258
return setCommands
238259

260+
239261
def getFlip(self):
240262
return self.orient
241263

242264

243265
def resetDefaults(self):
244-
self.orient = "xsetwacom --set \"" + self.tabletName + " stylus\" Rotate none"
245-
self.orient += "\nxsetwacom --set \"" + self.tabletName + " eraser\" Rotate none"
266+
self.orient = "xsetwacom --set \"%s stylus\" Rotate none" % self.tabletName
267+
self.orient += "\nxsetwacom --set \"%s eraser\" Rotate none" % self.tabletName
246268
self.tabletRight.setChecked(1)
247269
os.popen(self.orient)
248270
for device in self.devices:
249-
if device != self.tabletName + " pad":
250-
setCommand = os.popen("xinput set-prop \"" + self.tabletName + " " + device + "\" --type=float \"Coordinate Transformation Matrix\" 1 0 0 0 1 0 0 0 1")
271+
if device != "pad":
272+
cmd = "xinput set-prop \"%s %s\" --type=float \"Coordinate Transformation Matrix\" 1 0 0 0 1 0 0 0 1" % \
273+
(self.tabletName, device)
274+
setCommand = os.popen(cmd)
251275
self.screenFull.setChecked(True)
252276

253277
if __name__ == '__main__':

0 commit comments

Comments
 (0)