Closed flacer closed 7 years ago
Thank you for the issue report, I am glad to see that relabsd is being of use. I have started working on implementing your suggestion in a separate branch.
The timeout will be set in the configuration file, so that users may choose whether they want it or not: if the option is absent, the feature is disabled. It takes the time limit (in milliseconds) as a parameter.
I am rather busy during the week, but I think I can finish the implementation this week-end.
There is now an implementation of the timeout option in the aforementioned branch. It is still too crude for a merging with the main branch, however. I'll work on the user-friendliness aspects tomorrow.
As of https://github.com/nsensfel/relabsd/commit/e9b84b7e4612da198576c7b7e64e0c72674597cf, it is now possible to set a timeout (in milliseconds) by editing src/config.h
.
I intend to have this as an run-time option, but the way I set up invocation parameters was short-sighted, making the addition of a new optional parameter require some changes in the way relabsd is called.
Thank you very much for your effort!
Unfortunately it doesn't work as expected. The whole input is delayed, whether the timeout is enabled or not. As I see there is no correlation with the timeout set in the config file in terms of duration. The delay seems to be in count of events, so the whole input is delayed approx. 200 - 300 events. This doesn't affect only the converted ones, but every event sent from that device.
But as far I can see, sesitivity is great now! : )
Btw: Are you (or someone else) interested in a description how I have set it up to work as a mouse?
Woops, that's my bad: I tested the build by making sudden taps on the knob and seeing that it did indeed reset properly, that hid the issue from me.
It should be fixed now, can you confirm it works as intended?
I am interested in how you set it up to be a mouse, as this would give me an example of configuration & use to put in the Wiki.
Thank you! The knob works as intended! The sensitivity is great! : )
But there is another bug: After releasing the knob and the timeout ran out, there are no BUTTON_RELEASED events emitted anymore, resulting e.g. in acting the mouse as the button is still pressed and dragging objects or selecting text. When touching the knob, the event is reported. The BUTTON_PRESSED events are handled normally.
BTW the timeout of 100ms seems to be too much, a value of 10ms works pretty good.
I have to find a good setting for the pointer acceleration. After that I will write an how-to and provide you a link when done.
I can confirm the same thing is happening here, and I'll admit I have no idea why it is so. From what I can tell, the way I implemented the timeout option should not consume any events, meaning that they all should be retransmitted by the virtual device. Despite this, enabling the timeout option seems to make the event that should follow a button press (which is an event that, AFAIK, says "There's an sequence of events ready to be read.") disappear: it is apparently not picked up by libevdev, so relabsd can't do much.
I've made a quick-and-dirty fix for this: whenever a button press event occurs, the appropriate synchronization event is also sent. This is not a good long term solution however, as it only cures the symptom and not the cause. It is possible other types of events are also affected.
Thank you, it works! I'm satisfied! ; ) But I'm willing to test coming releases.
BTW: Starting relabsd without a timeout causes it using 100% of CPU, strace says:
poll([{fd=3, events=POLLIN}], 1, 0) = 0 (Timeout)
@flacer did you manage to get BUTTON_RELEASED
working? I am having the problem, that if I press the button without moving the knob, the button sticks until i press another button or move the knob.
That's a looong time ago since I have used that setup, so I can't recall completely how I made it work, but IIRC it worked well. I assume that you have used the code from the "timeout" branch and set a parameter for timeout? Out of curiosity: Are you using a 3D Connexion device?
Off topic: I tried using a 3D mouse as a pointer device, but using a force relative pointing device is more unconvenient than using a way relative pointing device. I could not get used to that even after using it for 2 - 3 weeks or more whitout having large overshoots, although I am using a Trackpoint on my laptop. Maybe a smart algorithm could be go in between to make it more usable. (Heard somewhere about "negative inertia") Having so many buttons and plenty of degrees of freedom was great tough, so it was possible to scroll in both directions while zooming and moving the cursor! xD
Am Fr, 30. Apr, 2021 um 2:55 P. M. schrieb Herman Fries @.***>:
@flacer https://github.com/flacer did you manage to get BUTTON_RELEASED working? I am having the problem, that if I press the button without moving the knob, the button sticks until i press another button or move the knob.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nsensfel/relabsd/issues/1#issuecomment-830421621, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACJ3PDKY6RO3I3ZE4S5LFADTLMRNTANCNFSM4D3LSORA.
I've made a quick-and-dirty fix for this: whenever a button press event occurs, the appropriate synchronization event is also sent. This is not a good long term solution however, as it only cures the symptom and not the cause. It is possible other types of events are also affected.
I don't have my device at hand to test things out, but I suspect I failed to properly comment in my code why I had this put in place and just removed it in a later revision. Oops. I'll get my device back on Monday. I should be able to fix this fairly quickly (or at least put back the previous fix).
Thank you @flacer and @nsensfel for the responses. I have picked up a used 3DConnexion SpaceMouse Pro as I am curious to try using it in Elite Dangerous (space sim game). That is where I have come across this project.
Some details: I used the code from the master branch, tested with this code block uncommented: https://github.com/nsensfel/relabsd/blob/master/src/device/virtual/virtual_device.c#L380 but did not unstick the buttons. My C is pretty rusty and I never looked into input handling before, so I don't really know what I am doing there :see_no_evil:
-> Here I press and release a button without moving the knob
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_MSC; code = MSC_SCAN; value = 589825}.
[D] Sending event: {type = EV_MSC; code = MSC_SCAN; value = 589825}.
[D] Valid event received: {type = EV_KEY; code = BTN_0; value = 1}.
[D] Sending event: {type = EV_KEY; code = BTN_0; value = 1}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_MSC; code = MSC_SCAN; value = 589825}.
[D] Sending event: {type = EV_MSC; code = MSC_SCAN; value = 589825}.
-> Then move the knob a bit
[D] Valid event received: {type = EV_KEY; code = BTN_0; value = 0}.
[D] Sending event: {type = EV_KEY; code = BTN_0; value = 0}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -5}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -5}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -27}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -27}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -23}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -23}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -33}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -33}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -35}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -35}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -32}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -32}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -32}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -32}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -27}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -27}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -35}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -35}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -14}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -14}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -27}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -27}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_Y; value = -1}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = -1}.
[D] Valid event received: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
[D] Valid event received: {type = EV_REL; code = REL_RX; value = -8}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = -8}.
[D] Sending event: {type = EV_ABS; code = ABS_X; value = 0}.
[D] Sending event: {type = EV_ABS; code = ABS_Y; value = 0}.
[D] Sending event: {type = EV_ABS; code = ABS_Z; value = 0}.
[D] Sending event: {type = EV_ABS; code = ABS_RX; value = 0}.
[D] Sending event: {type = EV_ABS; code = ABS_RY; value = 0}.
[D] Sending event: {type = EV_ABS; code = ABS_RZ; value = 0}.
[D] Sending event: {type = EV_SYN; code = SYN_REPORT; value = 0}.
it is as if the button event only arrives, after the knob is used again. Maybe it gets stuck in a buffer?
Indeed. Could you check with the evtest
utility if this behavior is also present when relabsd
isn't being used?
evtest /dev/input/by-id/usb-3Dconnexion_SpaceMouse_Pro-event-mouse
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x46d product 0xc62b version 0x111
Input device name: "3Dconnexion SpaceMouse Pro"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 256 (BTN_0)
Event code 257 (BTN_1)
Event code 258 (BTN_2)
Event code 260 (BTN_4)
Event code 261 (BTN_5)
Event code 264 (BTN_8)
Event code 268 (?)
Event code 269 (?)
Event code 270 (?)
Event code 271 (?)
Event code 278 (BTN_BACK)
Event code 279 (BTN_TASK)
Event code 280 (?)
Event code 281 (?)
Event code 282 (?)
Event type 2 (EV_REL)
Event code 0 (REL_X)
Event code 1 (REL_Y)
Event code 2 (REL_Z)
Event code 3 (REL_RX)
Event code 4 (REL_RY)
Event code 5 (REL_RZ)
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Event type 17 (EV_LED)
Event code 8 (LED_MISC) state 0
Properties:
Testing ... (interrupt to exit)
Event: time 1619897887.357889, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1619897887.357889, type 1 (EV_KEY), code 256 (BTN_0), value 1
Event: time 1619897887.357889, -------------- SYN_REPORT ------------
Event: time 1619897887.653893, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1619897887.653893, type 1 (EV_KEY), code 256 (BTN_0), value 0
Event: time 1619897887.653893, -------------- SYN_REPORT ------------
The value 0 is reported immediately when I release the button. There is no difference if relabsd
is running or not.
Good to know, this confirms it as a bug in relabsd. Hopefully I'll be able to reproduce it with my device next week.
I've given it a shot on my computer at work (Ubuntu 18, with libevdev-dev
1.5.8+dfsg-1ubuntu0.1
). It seems to work just fine.
I'll try on another setup at home. Could you please tell me more about your setup (which distribution and which version of libevdev
)? Thanks.
Edit:
I appear to have been mistaken: evtest
doesn't let you test if libevdev
works (they access the device directly, not through libevdev
). I'll also try to find another program that can confirm this is indeed an issue from relabsd or not.
It is NixOS unstable with libevdev-1.11.0
running relabsd like this:
./relabsd -1 /dev/input/by-id/usb-3Dconnexion_SpaceMouse_Pro-event-mouse -f ../conf/space_navigator.conf -t 45 -v
I have tried quickly a modified version of this example code on https://www.freedesktop.org/wiki/Software/libevdev/
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <libevdev/libevdev.h>
#include <stdio.h>
int main ()
{
struct libevdev *dev = NULL;
int fd;
int rc = 1;
fd = open("/dev/input/by-id/usb-3Dconnexion_SpaceMouse_Pro-event-mouse", O_RDONLY|O_NONBLOCK);
rc = libevdev_new_from_fd(fd, &dev);
if (rc < 0) {
fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
exit(1);
}
printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
printf("Input device ID: bus %#x vendor %#x product %#x\n",
libevdev_get_id_bustype(dev),
libevdev_get_id_vendor(dev),
libevdev_get_id_product(dev));
do {
struct input_event ev;
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (rc == 0)
printf("Event: %s %s %d\n",
libevdev_event_type_get_name(ev.type),
libevdev_event_code_get_name(ev.type, ev.code),
ev.value);
} while (rc == 1 || rc == 0 || rc == -EAGAIN);
return 0;
}
The event Event: EV_KEY BTN_0 0
is reported without delay
Output
Input device name: "3Dconnexion SpaceMouse Pro"
Input device ID: bus 0x3 vendor 0x46d product 0xc62b
Event: EV_REL REL_RY 1
Event: EV_SYN SYN_REPORT 0
Event: EV_REL REL_RY 12
Event: EV_SYN SYN_REPORT 0
Event: EV_MSC MSC_SCAN 589848
Event: EV_KEY BTN_TASK 1
Event: EV_SYN SYN_REPORT 0
Event: EV_MSC MSC_SCAN 589848
Event: EV_KEY BTN_TASK 0
Event: EV_SYN SYN_REPORT 0
Event: EV_MSC MSC_SCAN 589848
Event: EV_KEY BTN_TASK 1
Event: EV_SYN SYN_REPORT 0
Event: EV_MSC MSC_SCAN 589848
Event: EV_KEY BTN_TASK 0
Event: EV_SYN SYN_REPORT 0
Event: EV_MSC MSC_SCAN 589848
Got the bug at home (also libevdev-1.11). I might even have had it at work and not read the event type correctly. Thanks for the testing, I'll try to fix it.
Edit: Current hypothesis: I'm using the physical device's file descriptor to detect that there are events to be read. libevdev might already have read and buffered those, meaning that they would not show up on that.
https://github.com/nsensfel/relabsd/commit/b3d9e2e69163ff17a0023d08daa5ab0f3e1551a0 https://github.com/nsensfel/relabsd/commit/44b297ad7eb33cb988592a80e97c4b9753a6c47f fixes the issue for me (that first commit broke interruption handling).
If this is indeed the solution, the issue was that I was expecting the device's file descriptor to tell me about awaiting events and only reading when it told me there was some to read. However, libevdev buffered events and that doesn't make the file descriptor indicate that events are ready to be processed.
Thank you for your time. The buttons now behave correctly. But it looks like the recenter to
option has lost effect :see_no_evil:
Woops. https://github.com/nsensfel/relabsd/commit/3e76054f937f471e352233f00a5c8ccfee8a78b9 fixes it. I didn't expect the libevdev read to block (the blocking with timeout is handled somewhere else).
Yes, this fixed it, thank you
Thank you for that nifty piece of software! This enables me (in combination with xboxdrv) to use my 3Dconnexion device as a mouse input device.
There is one issue which I'm facing. Sometimes after releasing the knob the pointer keeps moving. This could be handled with a deadzone, but it is decreasing sensitivity in the low movement area.
In my perception it has to do with the builtin deadzone in the 3Dconnexion devices. After the knob was released and entered the hardware deadzone the device stops reporting events and so does relabsd. The application relying on relabsd (xboxdrv in this case) is using then the last event, wich has not the value of zero but an arbitary one, depending on how fast releasing the knob. If that value is greater than the software deadzone (which is set as low as possible as described above), it is resulting in pointer movement.
In my opinion the way to go would be:
I would be very happy to see some results on that! : )