Multitouch touch point id, evdev, and MT_TRACKING_ID on Linux
-
I am working on a Linux evdev driver for a digital pen, and I am generating multitouch events using MT_TRACKING_ID to set a unique ID for each pen (there can be several active and in use on the screen at the same time). As I know the identity of each pen, I wish to treat them as type B devices, so that I can keep track of them between touches (in practice, each pen will be operated by a different person, all working on a whiteboard application on a common, large screen, and I wish to be able to keep state per person, for example pen color, tip size, etc).
Is it possible to get hold of the actual ID I set (with the MT_TRACKING_ID event) in a TouchPoint, and not only the sequentially generated int that seems geared towards "multiple fingers on a touch screen"?
I have thus far been unable to get my unique IDs, and I worry that Qt "suffers" from the same behavior as e.g. touch events in major browser, i.e. the MT_TRACKING_ID is not carried through, but instead being replaced by an int, monotonically increasing for each new touch point detected, effectively treating all devices as type A. (I know that it is possible to get this to work, as e.g. Kivy distinguishes between type A and type B devices, and correctly report the MT_TRACKING_ID for type B.)
Cheers,
/johan
-
@superjudge said:
Hi and welcome
You already seems far more knowledge in this area that I am,
but i wonder if
you go have a look at
int TouchPoint::id() const
in the source code as see where it gets the id from as docs says
"Returns the id number of this touch point.
Do not assume that id numbers start at zero or that they are sequential. Such an assumption is often false due to the way the underlying drivers work."And since you are the driver , maybe it can do what you want and the source code should/might give a hint of how to make sure it reads it as you want.
Sorry if you already tried. -
Hi and welcome to devnet,
Adding to @mrjj, you should take a look at the the evdev plugins in Qt's sources. There are several plugins to handle different aspects of evdev e.g. touch, keyboard etc. You might find there what you are looking for or need to modify in order to achieve what you want.
Hope it helps
-
@mrjj said:
@superjudge said:
Hi and welcomeThanks, it feels good to be here! :-)
You already seems far more knowledge in this area that I am,
but i wonder if
you go have a look at
int TouchPoint::id() const
in the source code as see where it gets the id from as docs says
"Returns the id number of this touch point.
Do not assume that id numbers start at zero or that they are sequential. Such an assumption is often false due to the way the underlying drivers work."And since you are the driver , maybe it can do what you want and the source code should/might give a hint of how to make sure it reads it as you want.
Sorry if you already tried.Thank you! Following your advice, together with the hints from @SGaist, I believe I was able to solve my problem!
Please find additional details in my answer to @SGaist.
Cheers,
/johan
-
@SGaist said:
Hi and welcome to devnet,
Thank you!
Adding to @mrjj, you should take a look at the the evdev plugins in Qt's sources. There are several plugins to handle different aspects of evdev e.g. touch, keyboard etc. You might find there what you are looking for or need to modify in order to achieve what you want.
Hope it helps
It sure did help! I am very new to Qt (I did dabble a little with it many, many years ago), so I am still trying to find my way around.
tl;dr
Following your advice, I found the EvdevTouch plugin, and by adding it to the command line (e.g. "./myQtApp -plugin EvdevTouch"), my device was detected and started working!
For those interested, I will give some additional detail. Note that I am by no means an expert in Linux driver development, so read this with a somewhat critical eye.
When creating a Linux driver for a pointer device, there are several choices you need to make.
First, does the device report absolute or relative coordinates? A mouse type device will normally report relative coordinates, that is, coordinates relative to the pointers previous position. A touch screen or tablet stylus type device will normally report absolute screen coordinates.
Second, is the device a single touch or multi touch device? In my case, I actually have multiple pens that will be operated by different persons, and as the pens can be in contact with the writing surface at the same time, I will set it up as a multi touch device. It seems that the most common case for multi touch is "fingers on a touch screen", which usually (but not necessarily) means one person placing one or several fingers on a touch screen to perform some form of multi touch gesture.
Third, if you are dealing with a multi touch device, you need to decide whether it has "anonymous" touch points, as in the case of fingers on a touch screen (you cannot really identify which fingers are on the surface, only their relative identity as long as they are on the surface), or if the individual touch points are "uniquely" identifiable. The former is called a "type A" device and the latter is a "type B" device in Linux device driver jargon.
In my case, each pen connects over Bluetooth and thus has a unique Bluetooth address (very similar to e.g. an ethernet MAC address).
When setting up your device, you will have to specify what types of events it will generate. I will not go through all the events my driver uses here, but the most interesting ones are ABS_MT_TRACKING_ID, ABS_X/Y, and ABS_MT_POSITION_X/Y.
Actually, the ABS_X/Y events SHOULD not be needed for an MT device, they are actually for single touch devices, but I have noted that in some situations, they may be needed for the device to be correctly identified by applications. If they are available, it seems that your MT device will also be interpreted as a mouse pointer by the operating system (actually the FIRST MT device to touch the surface will double as the mouse).
Without getting too detailed, one interesting thing I noted with Qt and the EvdevTouch plugin is how my MT device gets detected. When giving the "-plugin EvdevToch" flag to the application, Qt will try to auto-detect any MT devices present. If I include the ABS_X/Y events in my MT device driver (I do not actually have to emit such events, only add them to the device specification), Qt will auto-detect my device, and the touch events will end up in the Qt application. However, if I do NOT include the ABS_X/Y, Qt will NOT auto-detect my device.
As I would like my device to be purely MT, and not double as mouse, I would like to NOT have ABS_X/Y in my device specification. It turns out you can give Qt additional information on the command line, so by explicitly specifying the device (something like "-plugin EvdevTouch:/dev/input/eventX", where X depends on your local HW setup), Qt will detect an MT device without ABS_X/Y events.
I hope this was not totally incomprehensible, and that someone find it useful.
Anyway, thanks a lot for the helpful pointers!
Cheers,
/johan
-
Very interesting and detailed explanation, thanks !
I wonder wether Qt should automatically detect or not your multiple devices… That's a question you should bring to either the interest mailing list or the #qt IRC channel. You'll find there Qt's developers/maintainers (this forum is more user oriented)
-
@SGaist said:
Very interesting and detailed explanation, thanks !
I wonder wether Qt should automatically detect or not your multiple devices… That's a question you should bring to either the interest mailing list or the #qt IRC channel. You'll find there Qt's developers/maintainers (this forum is more user oriented)
Ah, thanks for the info! I will check out the mailing list and the IRC channel!
For my purposes, auto-detect is probably not necessary, but I am unsure about "the general case". Anyway, it would be interesting to get the developers input on why there is a difference in auto-detect behavior depending on driver capabilities, and whether that is intentional or a bug.
Thanks!
Cheers,
/johan