Debian in more depth: adding touch support
Published on July 23, 2010
There are two options for touchscreen support in X-Windows:
xserver-xorg-input-evtouch - Touchscreen-Driver for X.Org/XFree86 server xserver-xorg-input-tslib - tslib touchscreen driver for X.Org/XFree86 server
The first uses the input event layer of Linux to read directly from touchscreen devices. The second uses a library named tslib
to perform filtering and translation of raw coordinates from a touchscreen device in order to generate X-Windows events.
In this post, I'm going to walk through the details of tslib
, since I haven't yet had any success in getting evtouch
calibration to work.
Before we start, we'll need to add another package to our installation. The libts-bin
package contains the touchscreen calibration and test utilities for tslib
.
debian:~# apt-get install libts-bin
We'll also need to configure tslib
through the use of /etc/ts.conf
. The following is a pretty typical setup that tells tslib
to read from the input event layer, perform a little filtering, and translate the results into screen coordinates.
# Uncomment if you wish to use the linux input layer event interface
module_raw input
# Uncomment if you're using a Sharp Zaurus SL-5500/SL-5000d
# module_raw collie
# Uncomment if you're using a Sharp Zaurus SL-C700/C750/C760/C860
# module_raw corgi
# Uncomment if you're using a device with a UCB1200/1300/1400 TS interface
# module_raw ucb1x00
# Uncomment if you're using an HP iPaq h3600 or similar
# module_raw h3600
# Uncomment if you're using a Hitachi Webpad
# module_raw mk712
# Uncomment if you're using an IBM Arctic II
# module_raw arctic2
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
Once this file is created, we can use the ts_calibrate
and ts_test
utilities to calibrate and test the touchscreen. Note that you'll need to set the TSLIB_TSDEVICE environment variable to tell tslib
what input device is the touchscreen. It's typically /dev/input/event0
because the touchscreen driver is loaded early in platform initialization.
ts_calibrate
will prompt you to touch each of five points. This calibration routine helps it to determine how it should scale and translate raw input readings to produce screen locations.
debian:~# export TSLIB_TSDEVICE=/dev/input/event0 debian:~# ts_calibrate
After touching these points, you can see the set of coefficients it produced in /etc/pointercal
.
debian:~# cat /etc/pointercal 243 54107 -2786888 32553 -1 -1549556 6553636debian:~#
You can also test the touchscreen with the ts_test
utility. It will allow you to either drag a cross-hair icon around on the screen or draw lines between the points it reads:
debian:~# ts_test
The next step is to configure X-Windows to use the touchscreen driver. We do this by adding an InputDevice
section to /etc/X11/xorg.conf
:
Section "InputDevice"
Identifier "tslib"
Driver "tslib"
Option "ScreenNumber" "0"
Option "Width" "800"
Option "Height" "480"
Option "Rotate" "NONE"
Option "TslibDevice" "/dev/input/event3"
Option "CorePointer"
EndSection
Once you've done this, you can startx
and things will almost work. You should see the pointer move as you touch various points on the screen and move in the right directions, but the scaling won't work properly.
Many thanks to Ricardo Soza for figuring this one out. It's a known bug with a known fix. Here's the workaround:
debian:~# apt-get build-dep xserver-xorg-input-tslib && apt-get source xserver-xorg-input-tslib
... update xf86-input-tslib_0.0.4/src/tslib with the patch below
debian:~# cd xf86-input-tslib_0.0.4
debian:~/xf86-input-tslib-0.0.4# debian/rules binary
I got the patch by screen-scraping the bug report:
Index: src/tslib.c =================================================================== --- a/src/tslib.c (revision 28) +++ b/src/tslib.c (working copy) @@ -184,9 +184,11 @@ InputInfoPtr pInfo; unsigned char map[MAXBUTTONS + 1]; int i; + struct ts_priv *priv; ErrorF("%sn", __FUNCTION__); pInfo = device->public.devicePrivate; + priv = pInfo->private; switch (what) { case DEVICE_INIT: @@ -222,15 +224,17 @@ return !Success; } - InitValuatorAxisStruct(device, 0, 0, /* min val */ 1023, /* max val */ - 1024, /* resolution */ - 0, /* min_res */ - 1024); /* max_res */ + InitValuatorAxisStruct(device, 0, 0, /* min val */ + priv->width - 1, /* max val */ + priv->width, /* resolution */ + 0, /* min_res */ + priv->width); /* max_res */ - InitValuatorAxisStruct(device, 1, 0, /* min val */ 1023, /* max val */ - 1024, /* resolution */ - 0, /* min_res */ - 1024); /* max_res */ + InitValuatorAxisStruct(device, 1, 0, /* min val */ + priv->height - 1,/* max val */ + priv->height, /* resolution */ + 0, /* min_res */ + priv->height); /* max_res */
Once done, you can restart the X-server and move the mouse pointer around with the touchscreen!