2

I have this weird multitouch issue on our embedded Linux product (based on Ångström). The short story is that our Qt app fails to detect TouchEnd events in certain cases when accidentally multitouching, which then "locks up" the app. We don't need multitouch support so I've already tried to disable multitouch by editing xorg.conf and adding:

Section "InputClass"
  Identifier "NoTouch1"
  MatchIsTouchscreen "on"
  MatchProduct "scf0700_ts1"
  Option "Ignore" "on"
EndSection

Section "InputClass"
  Identifier "NoTouch2"
  MatchIsTouchscreen "on"
  MatchProduct "scf0700_ts2"
  Option "Ignore" "on"
EndSection

and I can verify that X (xinput list) no longer "sees" more than one touch device:

xinput list
Virtual core pointer                         id=2    [master pointer  (3)]
 ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
 ↳ scf0700_ts0                               id=8    [slave  pointer  (2)]
Virtual core keyboard                        id=3    [master keyboard (2)]
 ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
 ↳ twl4030_pwrbutton                         id=6    [slave  keyboard (3)]
 ↳ TWL4030 Keypad                            id=7    [slave  keyboard (3)]

Qt, however, seems to disregard this (it's using evdev instead?).

So the ugly solution to this (in my mind) is to simply prevent /dev/input/event1 and 2 from being created and letting /dev/input/event0 be the only input device (1 and 2 are the other two "touch points").

I've tried to edit the udev rules but I haven't been able to prevent the "unwanted" event devices from being created. /libs/udev/rules.d/99-xf86-input-tslib.rules before edit:

SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{modalias}=="input:*-e0*,3,*a0,1,*18,*", SYMLINK+="input/touchscreen%n", ENV{x11_driver}="tslib"

and after trying to disable one of the event devices:

SUBSYSTEM=="input", KERNEL=="event1", ATTRS{name}=="scf0700_ts1", OPTIONS=="ignore_device"

Is this the right way to go? Can I do what I want using the rules or do I need to do something with the touchscreen driver instead?

I found a similar post here on SE where the solution was to use EVIOCGRAB to grab exclusive use of the device(s). Perhaps this is another solution? Grabbing the devices and drop all events that come in?

7
  • Yes, udev rules are the right way to prevent /dev/input/event files from being created. It may also to possible to do something in Qt, if it's using all XInput devices instead of just the core ones. Details of your xinput list after modification, and of your udev rule attempt would help us to figure out what went wrong. Debugging udev rules is notoriously hard, one trick is to attach strace to udevd.
    – dirkt
    Commented Feb 8, 2017 at 11:35
  • Hi! I just added the info you requested to my post. I'm reading up on if OPTIONS=="ignore_device is even supposed to work on anything else than USB devices (my ts is i2c). Commented Feb 8, 2017 at 12:16
  • Grabbing the device might work if that is really where Qt gets the events from (which I don't know, but your xorg.conf looks good to me). You can also grab devices with evtest --grab /dev/input/eventX > /dev/null or similar. Worth a try.
    – dirkt
    Commented Feb 8, 2017 at 14:06
  • ignore_device was apparently removed from udev in 2009 (release 148). I didn't realize there was a --grab flag for evtest. Will try it first thing tomorrow! Commented Feb 8, 2017 at 15:11
  • Apparently you can also blacklist USB devices in udev using the auhorized attribute; I didn't test myself if it still is valid, and don't know if it's restricted to USB devices, and you didn't say if your touch device is USB, so it may or may not work.
    – dirkt
    Commented Feb 9, 2017 at 10:34

1 Answer 1

1

Ok, so I managed to find a pretty simple way around this problem. The ideal solution would (in my opinion) had been to prevent /dev/input/event1 and 2 from being created but I didn't get the udev rules to work the way I wanted.

I ended up using EVIOCGRAB in my Qt app instead. I hava a "global" eventfilter at the top that detects if the user has touched the device, and dims the display after a couple of minutes of inactivity. By adding this to the constructor:

QString dev1 = QLatin1String("/dev/input/event1");
QString dev2 = QLatin1String("/dev/input/event2");

int fd1 = QT_OPEN(dev1.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if(fd1 >= 0)
{
    ::ioctl(fd1, EVIOCGRAB, 1);
    qDebug() << "Grabbed " << dev1;
}

int fd2 = QT_OPEN(dev2.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if(fd2 >= 0)
{
    ::ioctl(fd2, EVIOCGRAB, 1);
    qDebug() << "Grabbed " << dev2;
}

and not doing anything else I got the result I needed. Inputs from event1 and event2 are not showing up in my app anymore (and are not accessible by evtest), and if I exit the app then the event devices become "active" again.

Works like a charm!

//Anders

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .