InputCoordinateTransformation
Contents
Introduction
Recent X.org servers have incorporated a property for setting how input device events are translated to screen coordinates. This property can be used to ensure a touchscreen is not stretched across a multi-monitor setup or to rotate the touch screen input when you rotate the physical device.
Printing the Coordinate Transformation Matrix
First, we need to determine the name of the input device. Run the following:
$ xinput list
You will see output like:
⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ SynPS/2 Synaptics TouchPad id=11 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Video Bus id=7 [slave keyboard (3)] ↳ Power Button id=8 [slave keyboard (3)] ↳ HID 413c:8161 id=9 [slave keyboard (3)] ↳ AT Translated Set 2 keyboard id=10 [slave keyboard (3)]
We'll operate on the "SynPS/2 Synaptics TouchPad". To print the Coordinate Transformation Matrix (CTM), run the following:
$ xinput list-props 'SynPS/2 Synaptics TouchPad' | grep "Coordinate Transformation Matrix"
By default, this will output:
Coordinate Transformation Matrix (137): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
This is a 3x3 coordinate transformation matrix. It's encoded in row-major order, so the matrix would look like the following in a text book:
⎡ 1 0 0 ⎤ ⎜ 0 1 0 ⎥ ⎣ 0 0 1 ⎦
Astute readers will recognize that this is the identity matrix.
Using the Coordinate Transformation Matrix
By default, the CTM for every input device in X is the identity matrix. As an example, lets say you touch a touchscreen at point (400, 197) on the screen:
⎡ 1 0 0 ⎤ ⎡ 400 ⎤ ⎡ 400 ⎤ ⎜ 0 1 0 ⎥ · ⎜ 197 ⎥ = ⎜ 197 ⎥ ⎣ 0 0 1 ⎦ ⎣ 1 ⎦ ⎣ 1 ⎦
The X and Y coordinates of the device event are input in the second matrix of the calculation. The result of the calculation is where the X and Y coordinates of the event are mapped to the screen. As shown, the identity matrix maps the device coordinates to the screen coordinates without any changes.
The transformation matrix used is called an affine transformation matrix. Note that the translation values are in normalized floating point coordinates.
Left rotate (clockwise 90°)
Lets say we physically rotate the screen by 90° (from left) to the right. The X server screen can be rotated so that the display output matches the new orientation:
$ xrandr -o left
Not all graphics drivers support rotation
Now we want to map our touchscreen to the new orientation (90° (from left) to the right) as well. Using the affine transformation rules we would want our transformation matrix to be:
⎡ 0 -1 1 ⎤ ⎜ 1 0 0 ⎥ ⎣ 0 0 1 ⎦
Right rotate (counterclockwise 90°)
For 90° (from right) to the left.
$ xrandr -o right
Not all graphics drivers support rotation
with a transformation matrix of:
⎡ 0 1 0 ⎤ ⎜ -1 0 1 ⎥ ⎣ 0 0 1 ⎦
Invert rotate (clockwise or counterclockwise 180°)
$ xrandr -o inverted
Not all graphics drivers support rotation
with a transformation matrix of:
⎡ -1 0 1 ⎤ ⎜ 0 -1 1 ⎥ ⎣ 0 0 1 ⎦
Limit Range
Instead, lets say we have two monitors side by side, and our touchscreen is on the right monitor. They have the same resolution in the X direction. We don't want our touchscreen mapped across both monitors, so we need to map the device coordinates to only the right half of the screen. Again, using the affine transformation rules we would want our transformation matrix to be:
⎡ 0.5 0 1 ⎤ ⎜ 0 1 0 ⎥ ⎣ 0 0 1 ⎦
Setting the Coordinate Transformation Matrix
Once we have determined the CTM, we need to set the matrix for the input device. We'll assume the device name has been retrieved using 'xinput list' as described above. To set the matrix, run:
$ xinput set-prop '<device name>' 'Coordinate Transformation Matrix' <matrix in row-order>
For example, to set the CTM to:
⎡ 0.5 0 1 ⎤ ⎜ 0 1 0 ⎥ ⎣ 0 0 1 ⎦
run:
xinput set-prop '<device name>' 'Coordinate Transformation Matrix' 0.5 0 1 0 1 0 0 0 1
X/InputCoordinateTransformation (last edited 2014-09-04 02:33:09 by li200-146)