There is an annoying bug in the sequence of code that manages the wacom rotation / sleep / resume and stylus calibration right now. (Where "right now" is Ubuntu Intrepid, with the 0.8.2-1 wacom drivers.)
This is a document bug over at the ubuntu launchpad, and the poster there does a fine job of describing the intricacies of reproducing the bug, so I'll only give a brief explanation here to help get indexed.
If you rotate the screen any amount, even returning to the original rotation, and then sleep the machine, when it wakes up, the stylus will not be calibrated properly -- the cursor will be off to the side of the stylus point. It doesn't seem to matter how it was calibrated when the machine slept, nor does it matter what rotation you're in when you put the machine to sleep.
There is one straightforward workaround: When you wake the machine, run wacomcpl, click on stylus, click calibrate (the mouse should now be under the stylus again), and exit wacomcpl. This is incredibly cumbersome, but at least it's better than restarting X, which is what I have been doing.
Further inspection (based largely on the thread of comments on that launchpad bug) reveals that the problem is actually related to bad values for the TopX, TopY, BottomX and BottomY settings on the wacom devices after a resume. By resetting these to their proper values for the current rotation, we can reestablish the proper calibration. First off, we need to know the proper values, and the easiest way to get them is with `xsetwacom`:
[cc lang="bash"]
#!/bin/bash
# wacomSettings
echo "TopX=" `xsetwacom get stylus TopX`
echo "TopY=" `xsetwacom get stylus TopY`
echo "BottomX=" `xsetwacom get stylus BottomX`
echo "BottomY=" `xsetwacom get stylus BottomY`
[/cc]
Now, we'll run this for each rotation, and save the results. You should end up with something like the following:
[cc lang="bash"]
|rogue on bach |AC 70% | @ 00:02:26 ~|
$ xrotate 1 && wacomSettings
xrandr to left, xsetwacom to 2
TopX= -46
TopY= -3
BottomX= 18605
BottomY= 24518
|rogue on bach |AC 70% | @ 00:02:28 ~|
$ xrotate 2 && wacomSettings
xrandr to inverted, xsetwacom to 3
TopX= 58
TopY= -46
BottomX= 24579
BottomY= 18605
|rogue on bach |AC 70% | @ 00:02:35 ~|
$ xrotate 3 && wacomSettings
xrandr to right, xsetwacom to 1
TopX= -173
TopY= 58
BottomX= 18478
BottomY= 24579
|rogue on bach |AC 70% | @ 00:02:41 ~|
$ xrotate 0 && wacomSettings
xrandr to normal, xsetwacom to 0
TopX= -3
TopY= -173
BottomX= 24518
BottomY= 18478
[/cc]
(Note that my bash prompt looks like & command lines above are indented, and the output is left-aligned)
That gives us enough information to script the calibration when we resume. For example, when resuming to a "normal" rotation, I need to run:
[cc lang="bash"]
xsetwacom set stylus TopX -3
xsetwacom set stylus TopY -173
xsetwacom set stylus BottomX 24518
xsetwacom set stylus BottomY 18478
[/cc]
(Wrap that in a bash script and give it a shot!)
Here's the full script that gets the current orientation and then calibrates the common wacom devices:
[cc lang="bash"]
#!/bin/bash
#
# waCalibrate.sh: recalibrates the wacom stylus
#
# Author: Rogan Creswick
# License: just be nice
# Set LOG to something reasonable:
# (The file does not need to exist, but the *directory* does)
LOG=/home/rogue/calibration.out
XSETWACOM=/usr/local/bin/xsetwacom
#
# Calibrates the wacom devices {stylus, eraser, cursor} with the
# given offsets:
#
# Usage:
# calibrate
#
function calibrate {
${XSETWACOM} --display :0.0 set stylus TopX $1 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set stylus TopY $2 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set stylus BottomX $3 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set stylus BottomY $4 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set eraser TopX $1 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set eraser TopY $2 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set eraser BottomX $3 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set eraser BottomY $4 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set cursor TopX $1 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set cursor TopY $2 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set cursor BottomX $3 >> ${LOG} 2>&1
${XSETWACOM} --display :0.0 set cursor BottomY $4 >> ${LOG} 2>&1
}
function fixCalibration {
# get the current orientation:
ORIENTATION=`xrandr --verbose --query | grep " connected" | awk '{print $5}'`
echo "Orientation: ${ORIENTATION}" >> ${LOG}
case "${ORIENTATION}" in
normal)
calibrate -3 -173 24518 18478
;;
left)
calibrate -46 -3 18605 24518
;;
right)
calibrate -173 58 18478 24579
;;
inverted)
calibrate 58 -46 24579 18605
;;
*)
calibrate -3 -173 24518 18478
echo "ERROR!! unknown orientation! ${ORIENTATION}" >> ${LOG}
;;
esac
}
case "$1" in
resume|thaw)
date >> ${LOG}
fixCalibration
whoami >> ${LOG}
;;
*)
echo "not a resum|thaw event: $1" >> ${LOG}
;;
esac
[/cc]
Stick that in `/etc/pm/sleep.d/40wacomCalibrate` (or some similarly named file), make it executable by all (`chmod a+x /etc/pm/sleep.d/40wacomCalibrate`) and it should be run when the system resumes.
Update: I found that the logging of the old script didn't work, so I've updated the script to reflect that. There were also some problems with how I was testing the first script, and the actions I was taking didn't actually trigger the bug. (The bug seems to be quite state-dependent, and markovian assumption was wrong.) To get this to work, root will need to have access to the display that xsetwacom uses. The simplest way to do this is to add `xhost +` to you x startup. (I put it in my ~/.xsession just before `exec enlightenment-start`).
9 comments:
[...] Update: There were some issues with the wacom calibration after a sleep/resume cycle if the laptop screen had been rotated during that prior wake cycle (this happens a lot more than it seems, given how complex that description is.) I’ve written up a workaround here. [...]
Hey the script calibrate works perfectly for me but I can't get the automatic one sleep.d/40wacomCalibrate to work at all. I think it runs it just doesn't do anything. Help?
@Kinst:
I've updated the post with some details re: using xhost, and an updated script that has better error output. If you still can't get it to work, please post the log with some details of what actions you're taking. (I've found it's simplest to test from a "fresh" X start-up--that is, log out, log in, clear the log, rotate the screen, rotate back, verify the stylus is calibrated, sleep, resume, then look at the log if it's not working.
--Rogan
Okay...the script isn't running when I resume. It only runs if I do it manually and then it says 'this is not a resume'. Can you help me make it run on resume? I put it in /etc/pm/sleep.d made it executable by everyone, I don't understand the xhost thing because I don't seem to have a hidden .xsession file.
hm.. so it's not writing a log anywhere?
Can you create another similar (simpler) script and put it in /etc/pm/sleep.d/ and see if it gets run? (maybe just have it touch a file in your home dir, or something...)
xhost controls who can connect to your xsession. you can run `xhost +` from a terminal after starting up X, and it should do what you need, but only for that xsession. Once you get this working then we can figure out how to make it run each time you log in.
Okay I got it to run by making it owned by root (instead of owned by me). Then I fixed xsetwacom because mine is in /usr/bin/xsetwacom, not /usr/local/bin/xsetwacom.
Now it runs but it says this:
not a resum|thaw event: suspend
Thu Feb 12 19:09:48 EST 2009
Orientation:
ERROR!! unknown orientation!
root
It seems to work only on the second time I suspend. I can't get the xrandr -verbose -query thing to work.
It says:
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
No protocol specified
Failed to open display (:0.0)
I'm not sure if that fixed it. I don't think it worked but I don't know. And I don't know how to make xhost + run on startup, maybe I can try that?
Post a Comment