Qt and DirectFB - linux_input events handling
I am using DFB 1.4.3 on a embedded device together with Qt 4.6.3. and I have some issues with a device that I need to get working with this setup.
I have an input device (touch working as HID mouse) that sends linux input events in the following sequence:
evbug.c: Event. Dev: input1, Type: 4, Code: 4, Value: 589825
evbug.c: Event. Dev: input1, Type: 1, Code: 272, Value: 1 (click)
evbug.c: Event. Dev: input1, Type: 3, Code: 0, Value: 5216 (ABS X)
evbug.c: Event. Dev: input1, Type: 3, Code: 1, Value: 2816 (ABS Y)
evbug.c: Event. Dev: input1, Type: 0, Code: 0, Value: 0 (SYN)
evbug.c: Event. Dev: input1, Type: 1, Code: 272, Value: 0 (release)
evbug.c: Event. Dev: input1, Type: 0, Code: 0, Value: 0 (SYN)
Due to the Button press being dispatched before the XY ABS move, and the Button release on the new position, Qt does not detect a Button click and instead is marking the area.
These is the sequence of events Qt gets:
Touch/Mouse event type: 2 at 1078, 667 (click)
Touch/Mouse event type: 5 at 203, 68 (move)
Touch/Mouse event type: 3 at 203, 68 (release)
I got the idea that this is due to the fact that DFB linux_input does not handle EV_SYN synchronization. For the proof of this I modified DFB linux_input to:
- Buffer/update last ABS position instead of directly dispatching ABS AXISMOTION events
- Buffer all other events
- Dispatch X and Y ABS, and all buffered other events upon reception of the EV_SYN in this reordered sequence
Basically, it does exactly what it is supposed to – I have checked that with various printf’s for debugging.
dfb_input_dispatch() does dispatch the events in the reordered sequence as expected.
However, In Qt I still receive the very same sequence of events as before and therefore still have the same issue.
If someone has any idea or a hint how to solve this or why even with reordered dispatching in DFB Qt still shows the old sequence ... I'd highly appreciate every idea.
Nobody an idea over which path or why Qt is still getting the events in the old order?
Funny thing, if I stop dispatching where I have changed the order, Qt stops receiving the events. To me, this means that I changed the order at the right place. The more I am amazed that Qt reorders or still shows the order the events come in from the device.
Did you try to take a look at the qlinuxinput.cpp file ?
Thanks for your response.
I don't have a qlinuxinput.cpp on my system.
As far as I could see the following is the event sequence (instance) of modules in Qt4.6.3 with DFB1.4.3:
- Input Event (OS)
- linux_input.c (DFB)
- qdirectfbmouse.c (Qt)
- qmouse_qws.cpp (Qt)
- qwindowsystem_qws.c (Qt)
- MyApplication (Qt)
If you feel that that this is wrong, please let me know.
For testing, I attached a different type of touch screen controller that generates the correct event sequence in the controller. With this touch, everything works OK without any code patch.
With the touch controller I need to have working, even with patched linux_input.c to have the same, corrected sequence, it does not work.
I must miss something in the event queue between the OS input event and the event being dispatched to MyApplication.
I currently don't have all the Qt sources on my Linux dev-VM - only compiled version/libraries needed fro the application development. Therefore, I cannot easily place debug output everywhere.
Many thanks for any hint how to track down this.
No it doesn't look wrong, I was checking the 4.8.7 sources.
Might be a silly question but does the other touchscreen you the same kernel module ?
I definitely don't understand what is happening here.
They use the same kernel module.
Just for testing I connected the controller that usually works and was very amazed that it now showed the same behavior. To find out the cause - and to have a working base - I reverted my mods step by step. Even after I reverted all changes I made to the DFB code - it still did not work with the controller it usually does.
I ended up in making a make clear to have it build everything new, and that was when it was back working.
I have no clue what makes the difference - before and after the make clean all the sources are the same after I reverted my changes.
I currently have no clue how to solve this nor do I understand the behavior of my project/compiler.
There is something I completely did not get/understand in how the events are propagated in the combination linux_input / DFB / Qt.
To sum up: same kernel driver, same input handler and different results ?
Do you see any difference if you e.g. hexdump the input device ?
The only difference between the 2 controllers is the firmware version - the sequence it outputs the events.
A typical click on a new location of the old one:
17:00:49.418029: EV_ABS ABS_X 5024
17:00:49.418063: EV_ABS ABS_Y 6560
17:00:49.418086: EV_SYN code=0 value=0
17:00:49.505969: EV_MSC MSC_SCAN 589825
17:00:49.505995: EV_KEY BTN_LEFT pressed
17:00:49.506045: EV_SYN code=0 value=0
17:00:49.513981: EV_MSC MSC_SCAN 589825
17:00:49.514008: EV_KEY BTN_LEFT released
17:00:49.514058: EV_SYN code=0 value=0
It first sends the new location, then the click and then the release.
Now the click on a new location with the new one:
17:01:27.386117: EV_MSC MSC_SCAN 589825
17:01:27.386144: EV_KEY BTN_LEFT pressed
17:01:27.386184: EV_ABS ABS_X 6336
17:01:27.386204: EV_ABS ABS_Y 7040
17:01:27.386227: EV_SYN code=0 value=0
17:01:27.514085: EV_MSC MSC_SCAN 589825
17:01:27.514112: EV_KEY BTN_LEFT released
17:01:27.514162: EV_SYN code=0 value=0
It sends the click first, then the new position and then the release. For every desktop linux, windows or whatever, this seems not to be an issue because they use the EV_SYN and are intelligent enough to proceed as follows on a EV_SYN and both controllers work perfect:
-- update XY position
-- Evaluate button/click event
If I use tslib with DFB instead of the linux_input with DFB, it works as well. However, tslib shows some other issues and first of all does not feature Hot-Plug which I need.
It is confirmed, that the linux_input module of DFB does not support the EV_SYN event to synchronize evaluation of input event packets. This is what I added to this module and the dfb_input_dispatch shows that the dispatch in DFB now is reordered.
This is where Qt comes in. Even though DFB now dispatches the events reordered, Qt still show the same, wrong sequence as shown in my first post in this thread.
Moreover - and I absolutely don't understand this - the old controller that has worked before now also shows the wrong sequence in Qt and as described before, it doesn't even recover when resetting changes, needing a clean before recovering.
It must be something with how Qt gets the XY event that it somehow gets before the click even if DFB dispatches the click first - but fro the life of me, I just don't find the cause/issue.
I am more than thankful for every tiny hint on this. I spent days now to fix this - to no avail.
Cheers, Franz (... all my best from central Switzerland id's Wallis)
And I guess you are locked to that old version of Qt ?
A later Version of Qt and/or DFB may run as well. However, this integration has been supplied by the SoC manufacturer "as is" and I somehow fear what it takes to have a later version run smoothly in this SDK.
DFB has been extended and uses custom-made drivers by the SoC supplier to use the SoC's Graphic device. There has been a a lot of modifications to Linux as well as DFB to support the Hardware.
I suspect that Qt (QWS) does not get the XY event and the click event from DFB over the exact same path. That may be the source of the effect I am seeing, a timing issue in the end.
bump ... bump
Cross-compiling Qt 4 is really not hard especially if you have the toolchain ready to use. From your description it seems that there's two different behavior between two devices that uses two different firmware, so there might be a clue there.
That doesn't really help. I know the difference between the 2 devices.
The issue seems to be in the path and maybe the resulting timing Qt (QWS to be more precise) gets the XY position compared to the path over which it gets the click events. This seems not to travel the same way from DFB to QWS.
Still have no solution for this.