开发者社区> sky-heaven> 正文


简介: 转自:https://github.com/kergoth/tslib C library for filtering touchscreen events tslib consists of the library libts and tools that help you calibrate and use it in your environment.


logo Coverity Scan Build Status CII Best Practices

C library for filtering touchscreen events

tslib consists of the library libts and tools that help you calibrate and use it in your environment.


If you have problems, questions, ideas or suggestions, please contact us by writing an email to tslib@lists.infradead.org, which is our mailing list.


Visit the tslib website for an overview of the project.

table of contents

setup and configure tslib

install tslib

tslib runs on various hardware architectures and operating systems, including GNU/Linux, FreeBSD or Android/Linux. See building tslib for details. Apart from building the latest tarball release, running ./configure, make and make install, tslib is available from distributors like Arch Linux / Arch Linux ARM, Buildroot, Debian / Ubuntu, Fedora or OpenSUSE and their package management.

configure tslib

This is just an example /etc/ts.conf file. Touch samples flow from top to bottom. Each line specifies one module and it's parameters. Modules are processed in order. Use one module_raw on top, that accesses your device, followed by any combination of filter modules.

module_raw input
module median depth=3
module dejitter delta=100
module linear

see the section below for available filters and their parameters. On Linux, your first commented-in line should always be module_raw input which offers one optional parameter: grab_events=1 if you want it to execute EVIOCGRAB on the device.

With this configuration file, we end up with the following data flow through the library:

driver --> raw read --> median  --> dejitter --> linear --> application (using ts_read_mt())
           module       module      module       module

calibrate the touch screen

Calibration is done by the linear plugin, which uses it's own config file /etc/pointercal. Don't edit this file manually. It is created by the ts_calibrate program:

# ts_calibrate

The calibration procedure simply requires you to touch the cross on screen, where is appears, as accurate as possible.


test the filtered input behaviour

You may quickly test the touch behaviour that results from the configured filters, using ts_test_mt:

# ts_test_mt


On the bottom left of the screen, you see the available concurrent touch contacts supported, and whether it's because the driver says so, or ts_test_mt was started with the -j commandline option to overwrite it.

environment variables (optional)

You may override defaults. In most cases you won't need to do so though:

TSLIB_TSDEVICE          Touchscreen device file name.
                        Default:                automatic detection (on Linux)

TSLIB_CALIBFILE         Calibration file.
                        Default:                ${sysconfdir}/pointercal

TSLIB_CONFFILE          Config file.
                        Default:                ${sysconfdir}/ts.conf

TSLIB_PLUGINDIR         Plugin directory.
                        Default:                ${datadir}/plugins

TSLIB_CONSOLEDEVICE     Console device. (not needed when using --with-sdl2)
                        Default:                /dev/tty

TSLIB_FBDEVICE          Framebuffer device.
                        Default:                /dev/fb0

use the filtered result in your system (X.org method)

If you're using X.org graphical X server, things should be very easy. Install tslib and xf86-input-tslib, reboot, and you should instantly have your ts.conf filters running, without configuring anything else yourself.

use the filtered result in your system (ts_uinput method)

TL;DR: Run tools/ts_uinput_start.sh during startup and use /dev/input/ts_uinput as your evdev input device.

tslib tries to automatically find your touchscreen device in /dev/input/event* on Linux. Now make ts_uinput use it, instead of your graphical environment directly:

# ts_uinput -d -v

-d makes the program return and run as a daemon in the background. -v makes it print the new /dev/input/eventX device node before returning.

Now make your graphical environmen use that new event device, using evdev drivers.

  • For Qt5 for example you'd probably set something like this:

    QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/eventX QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/eventX:rotate=0

  • For X11 you'd probably edit your xorg.conf Section "InputDevice" for your touchscreen to have

    Option "Device" "/dev/input/eventX"

  • For Wayland, you'd make libinput use the new /dev/input/eventX and so on. Please see your system's documentation on how to use a specific evdev input device.

Let's recap the data flow here:

driver --> raw read --> filter(s) ... --> ts_uinput --> libevdev read  --> GUI app/toolkit
           module       module(s) ...     daemon        e.g. in libinput

symlink /dev/input/ts_uinput to the new event file

/dev/input/event numbers are not persistent. In order to know in advance, what enumerated input device file is created by ts_uinput, you can use a symlink:

  • use the included tools/ts_uinput_start.sh script that starts ts_uinput -d -v and creates the symlink called /dev/input/ts_uinput for you, or

  • if you're using systemd, create the following udev rule, for example /etc/udev/rules.d/98-touchscreen.rules:

    SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{name}=="ts_uinput", SYMLINK+="input/ts_uinput"

running as systemd service (optional)

in case you have to use non-default paths, create a file containing the environment for tslib, like /etc/ts.env


and create a systemd service file, like /usr/lib/systemd/system/ts_uinput.service

  Description=touchscreen input

  ExecStart=/bin/sh -c 'exec /usr/bin/ts_uinput &> /var/log/ts_uinput.log'



  #systemctl enable ts_uinput

will enable it permanently.

other operating systems

There is no tool that we know of that reads tslib samples and uses the Windows touch injection API, for example (yet).

filter modules

module: linear

Linear scaling - calibration - module, primerily used for conversion of touch screen co-ordinates to screen co-ordinates. It applies the corrections as recorded and saved by the ts_calibrate tool. It's the only module that reads a configuration file.

Parameters (usually not needed):

  • xyswap

    interchange the X and Y co-ordinates -- no longer used or needed if the linear calibration utility ts_calibrate is used.

  • pressure_offset

    offset applied to the pressure value. Default: 0

  • pressure_mul

    factor to multiply the pressure value with. Default: 1.

  • pressure_div

    value to divide the pressure value by. Default: 1.

Example: module linear

module: invert

Invert values in X and/or Y direction around the given value. There are no default values. If specified, a value has to be set. If one axis is not specified, it's simply untouched.


  • x0

    X-axis (horizontal) value around which to invert.

  • y0

    Y-axis (vertical) value around which to invert.

Example: module invert y0=640 (Y-axis inverted for 640 screen height, X-axis untouched)

module: median

The median filter reduces noise in the samples' coordinate values. It is able to filter undesired single large jumps in the signal. For some theory, see Wikipedia


  • depth

    Number of samples to apply the median filter to. Default: 3.

Example: module median depth=5

module: pthres

Pressure threshold filter. Given a release is always pressure 0 and a press is always >= 1, this discards samples below / above the specified pressure threshold.


  • pmin

    Minimum pressure value for a sample to be valid. Default: 1.

  • pmax

    Maximum pressure value for a sample to be valid. Default: (INT_MAX).

Example: pthres pmin=10

module: iir

Infinite impulse response filter. This is a smoothing filter to remove low-level noise. There is a trade-off between noise removal (smoothing) and responsiveness. The parameters N and D specify the level of smoothing in the form of a fraction (N/D).

Wikipedia has some theory.


  • N

    numerator of the smoothing fraction. Default: 0.

  • D

    denominator of the smoothing fraction. Default: 1.

Example: module iir N=6 D=10

module: dejitter

Removes jitter on the X and Y co-ordinates. This is achieved by applying a weighted smoothing filter. The latest samples have most weight; earlier samples have less weight. This allows to achieve 1:1 input->output rate. See Wikipedia for some theory.


  • delta

    Squared distance between two samples ((X2-X1)^2 + (Y2-Y1)^2) that defines the 'quick motion' threshold. If the pen moves quick, it is not feasible to smooth pen motion, besides quick motion is not precise anyway; so if quick motion is detected the module just discards the backlog and simply copies input to output. Default: 100.

Example: module dejitter delta=100

module: debounce

Simple debounce mechanism that drops input events for the specified time after a touch gesture stopped. Wikipedia has more theory.


  • drop_threshold

    drop events up to this number of milliseconds after the last release event. Default: 0.

Example: module debounce drop_threshold=40

module: skip

Skip nhead samples after press and ntail samples before release. This should help if for the device the first or last samples are unreliable.


  • nhead

    Number of events to drop after pressure. Default: 1.

  • ntail

    Number of events to drop before release. Default: 1.

Example: module skip nhead=2 ntail=1

module: lowpass

Simple lowpass exponential averaging filtering module.


  • factor

    floating point value between 0 and 1; for example 0.2 for more smoothing or 0.8 for less. Default: 0.4.

  • threshold

    x or y minimum distance between two samples to start applying the filter. Default: 2.

Example: module lowpass factor=0.5 threshold=1

module: variance

Variance filter. Tries to do it's best in order to filter out random noise coming from touchscreen ADC's. This is achieved by limiting the sample movement speed to some value (e.g. the pen is not supposed to move quicker than some threshold).

There is no multitouch support for this filter (yet). ts_read_mt() will limit your input to one slot when this filter is used. Try using the median filter instead.


  • delta

    Set the squared distance in touchscreen units between previous and current pen position (e.g. (X2-X1)^2 + (Y2-Y1)^2). This defines the criteria for determining whenever two samples are 'near' or 'far' to each other.

    Now if the distance between previous and current sample is 'far', the sample is marked as 'potential noise'. This doesn't mean yet that it will be discarded; if the next reading will be close to it, this will be considered just a regular 'quick motion' event, and it will sneak to the next layer. Also, if the sample after the 'potential noise' is 'far' from both previously discussed samples, this is also considered a 'quick motion' event and the sample sneaks into the output stream.

The following example setup

       |--------|       |-----|      |--------------|
x ---> | median | ----> | IIR | ---> |              | ---> x'
       |--------|    -> |-----|      |    screen    |
                    |                |  transform   |
                    |                | (calibrate)  |
       |--------|   |   |-----|      |              |
y ---> | median | ----> | IIR | ---> |              | ---> y'
       |--------|   |-> |-----|      |--------------|
p ---------> | debounce | -------------------------------> p'

would be achieved by the following ts.conf:

module_raw input
module debounce drop_threshold=40
module median depth=5
module iir N=6 D=10
module linear

while you are free to play with the parameter values.

screen rotation

The graphical tools support rotating the screen, see ts_calibrate --help or the man pages for the details. Note that this only rotates the framebuffer output. Rotating the input samples is a different task that has to be done by the linear filter module (re-calibrating or re-loading with different parameters).

the libts library

the libts API

The API is documented in our man pages in the doc directory. Check out our tests directory for examples how to use it.

int (*ts_error_fn)(const char *fmt, va_list ap)
int (*ts_open_restricted)(const char *path, int flags, void *user_data)
void (*ts_close_restricted)(int fd, void *user_data)

using libts

To use the library from C or C++, include the following preprocessor directive in your source files:

#include <tslib.h>

To link with with library, specify -lts as an argument to the linker.

compiling using autoconf and pkg-config

On UNIX systems you can use pkg-config to automatically select the appropriate compiler and linker switches for libts. The PKG_CHECK_MODULES m4 macro may be used to automatically set the appropriate Makefile variables:

PKG_CHECK_MODULES([TSLIB], [tslib >= 1.10],,
  AC_MSG_ERROR([libts 1.10 or newer not found.])

If you want to support tslib < 1.2, while still support multitouch and all recent versions of tslib, you'd do something like this:

#include <tslib.h>

        /* ts_read() as before (due to old tslib) */
        /* new ts_setup() and ret = ts_read_mt() */
        if (ret == -ENOSYS)
                /* ts_read() as before (due to user config) */

This is a complete example program, similar to ts_print_mt.c:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>

#include <tslib.h>

#define SLOTS 5
#define SAMPLES 1

int main(int argc, char **argv)
    struct tsdev *ts;
    char *tsdevice = NULL;
    struct ts_sample_mt **samp_mt = NULL;
    struct input_absinfo slot;
    int ret, i, j;

    ts = ts_setup(tsdevice, 0);
    if (!ts) {
            return -1;

    samp_mt = malloc(SAMPLES * sizeof(struct ts_sample_mt *));
    if (!samp_mt) {
            return -ENOMEM;
    for (i = 0; i < SAMPLES; i++) {
            samp_mt[i] = calloc(SLOTS, sizeof(struct ts_sample_mt));
            if (!samp_mt[i]) {
                    return -ENOMEM;

    while (1) {
            ret = ts_read_mt(ts, samp_mt, SLOTS, SAMPLES);
            if (ret < 0) {

            for (j = 0; j < ret; j++) {
            	for (i = 0; i < SLOTS; i++) {
			if (!(samp_mt[j][i].valid & TSLIB_MT_VALID)
			if (samp_mt[j][i].valid < 1)

			printf("%ld.%06ld: (slot %d) %6d %6d %6d\n",


If you know how many slots your device can handle, you could avoid malloc:

struct ts_sample_mt TouchScreenSamples[SAMPLES][SLOTS];

struct ts_sample_mt (*pTouchScreenSamples)[SLOTS] = TouchScreenSamples;
struct ts_sample_mt *ts_samp[SAMPLES];
for (i = 0; i < SAMPLES; i++)
        ts_samp[i] = pTouchScreenSamples[i];

and call ts_read_mt() like so

ts_read_mt(ts, ts_samp, SLOTS, SAMPLES);

ABI - Application Binary Interface

Wikipedia has background information.

libts Soname versions

Usually, and every time until now, libts does not break the ABI and your application can continue using libts after upgrading. Specifically this is indicated by the libts library version's major number, which should always stay the same. According to our versioning scheme, the major number is incremented only if we break backwards compatibility. The second or third minor version will increase with releases. In the following example

libts.so -> libts.so.0.7.0
libts.so.0 -> libts.so.0.7.0

use libts.so for using tslib unconditionally and libts.so.0 to make sure your current application never breaks.

If a release includes changes like added features, the second number is incremented and the third is set to zero. If a release includes mostly just bugfixes, only the third number is incremented.

tslib package version

A tslib tarball version number doesn't tell you anything about it's backwards compatibility.


  • libc (with libdl only when building dynamically linked)
  • libsdl2-dev (only when using --with-sdl2 for SDL2 graphical applications)

related libraries

libts users

This lists the programs for the every day use of tslib, facing the outside world. For testing purposes there are tools like ts_test_mt too.

shipped as part of tslib

  • ts_calibrate - graphical calibration tool. Configures the linear filter module.
  • ts_uinput - userspace evdev driver for the tslib-filtered samples.

third party applications

  • xf86-input-tslib - direct tslib input driver for X11
  • qtslib - direct Qt5 tslib input plugin
  • enlightenment - A Window Manager (direct support in framebuffer mode, X11 via xf86-input-tslib)
  • DirectFB - Graphics library on top of framebuffer

tslib module API

struct tslib_module_info
struct tslib_vars
struct tslib_ops
tslib_parse_vars(struct tslib_module_info *,const struct tslib_vars *, int, const char *);

tslib modules (filter or driver/raw module) in the plugins directory need to implement mod_init(). If the module takes parameters, it has to declare a const struct tslib_vars and pass that, it's lengths and the params string that is passed to mod_init to tslib_parse_vars() during mod_init().

Furthermore a const struct tslib_ops has to be declared, with it's members pointing to the module's implementation of module-operations like read_mt that get called in the chain of filters.

Symbols in Versions

Name Introduced
ts_libversion 1.10
ts_close 1.0
ts_config 1.0
ts_reconfig 1.3
ts_setup 1.4
ts_error_fn 1.0
ts_open_restricted 1.13
ts_close_restricted 1.13
ts_fd 1.0
ts_load_module 1.0
ts_open 1.0
ts_option 1.1
ts_read 1.0
ts_read_mt 1.3
ts_read_raw 1.0
ts_read_raw_mt 1.3
tslib_parse_vars 1.0
ts_get_eventpath 1.15

building tslib

shared vs. static builds

libts can be built to fit your needs. Use the configure script to enable only the modules you need. By default, libts is built as a shared library, with each module being a shared library object itself. You can, however, configure tslib to build libts statically linked, and the needed modules compiled inside of libts. Here's an example for this:

./configure --enable-static --disable-shared --enable-input=static --enable-linear=static --enable-iir=static

This should result in a libts.a of roughly 50 kilobytes, ready for using calibration (linear filter) and the infinite impulse response filter in ts.conf.

portable ts_calibrate and ts_test_mt using SDL2

In case you cannot draw to the framebuffer directly, there is an experimental implentation of the necessary graphical tools using SDL2. They are more portable but require more resources to run. To use them, make sure you have SDL2 and the development headers installed and use ./configure --with-sdl2.


tslib is cross-platform; you should be able to build it on a large variety of operating systems.

libts and filter plugins (module)

This is the hardware independent core part: libts and all filter modules as shared libraries, build on the following operating systems and probably more.

  • GNU / Linux
  • Android / Linux
  • FreeBSD
  • GNU / Hurd
  • Haiku
  • Windows
  • Mac OS X

input plugins (module_raw)

This makes the thing usable in the real world because it accesses your device. See hardware support for the currently possible configuration for your platform.

The libts default configuration currently has the following input modules disabled:

  • cy8mrln-palmpre
  • dmc_dus3000
  • galax
  • arctic2
  • corgi
  • collie
  • dmc
  • h3600
  • mk712
  • ucb1x00

Please note that this list may grow over time. If you rely on a particular input plugin, you should enable it explicitely. On Linux you should only need input though.

  • GNU / Linux - all (most importantly input)
    • ./configure
  • Android / Linux - all (most importantly input)
    • ./configure
  • FreeBSD - almost all (most importantly input)
    • ./configure --disable-waveshare
  • GNU / Hurd - some, see hardware support
    • ./configure --disable-input --disable-waveshare
  • Haiku - some, see hardware support
    • ./configure --disable-input --disable-touchkit --disable-waveshare
  • Windows - no tslib module for the Windows touchscreen API (yet)
    • ./configure --with-sdl2 --disable-tatung --disable-input --disable-touchkit --disable-waveshare

Writing your own plugin is quite easy, in case an existing one doesn't fit.

test programs and tools

  • GNU / Linux - all
  • Android / Linux - all (?)
  • FreeBSD - all (?)
  • GNU / Hurd - ts_print_mt, ts_print, ts_print_raw, ts_finddev
  • Haiku - ts_print_mt, ts_print, ts_print_raw, ts_finddev
  • Windows - ts_print.exe, ts_print_raw.exe ts_print_mt.exe ts_test_mt.exe ts_calibrate.exe

download binaries?

For GNU/Linux all architectures are very well covered, thanks to Debian or Arch Linux or others.

If you're lucky, you'll find some unofficial testing builds for Windows or other platforms here.

Please help porting missing programs!

touchscreen hardware support

TL;DR: On Linux, use module_raw input

For mostly historical reasons, tslib includes device specific module_raw userspace drivers. The ts.conf man page has details on the available module_raw drivers; not all of them are listed in the default etc/ts.conf config file. Those are to be considered workarounds and may get disabled in the default configuration in the future. If you use one of those, please ./configure --enable-... it explicitely.

It is strongly recommended to have a real device driver for your system and use a generic access module_raw of tslib. For Linux (evdev) this is called input.

【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua


11452 0
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
11700 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
8149 0
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
10958 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4480 0
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
6415 0