-
-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement acceleration using an input_handler
modifying usbhid
input events directly
#5
base: master
Are you sure you want to change the base?
Conversation
input_handler
modifying usbhid
input events directly
Another follow-up, for my mice this doesn't seem to matter (as far as I can observe at least), but I've got some additional changes here in case we want to be more strict about This splits the batch of events into at most two parts. While it still applies the accelerated So, this is technically more correct, but might not be necessary in a lot of cases. Edit: I've tested this out and since it's not causing issues and is more correct, I'm picking these changes over to this branch |
3b4171f
to
d3f8f08
Compare
Hey, I tried to run this PR, and I had some issues with the udev rules (or the lack of them). I know they should not be necessary, but I added all the udev stuff back in and it worked. The most important change I think is that there is actually no Leetmouse driver, at least not in the Also, I had one small issue with the code. This is the declaration of static unsigned int usb_mouse_events(struct input_handle *handle,
struct input_value *vals, unsigned int count) while for me, the correct signature of the static void usb_mouse_events(struct input_handle *handle,
const struct input_value *vals, unsigned int count) the return type is void, and After this change the code compiled smoothly. Other than that, it looks great, I'll look a bit more into the code, and try to remove the |
Yup, that's by design for now and I've basically remove the driver entirely, as you've noticed here ✌️ If this works well though and we're happy to go ahead with this, what I'd suggest for implementation next is:
This should allow us to seamlessly bind devices to the driver with the GUI, while still having acceleration applied to all other devices (or if no devices are bound of course)
That's pretty odd! I've checked this against the latest kernel code, and this is a public API that shouldn't have changed. Odd!
Nice! I suppose if we want to have both a driver and this input handler approach in parallel, then if I build off of this, we'd be fine? |
Ah, alright, torvalds/linux@14498e9 |
I think something like this will work too: #if LINUX_VERSION_CODE <= KERNEL_VERSION(6,12,3)
static void usb_mouse_events(struct input_handle *handle, const struct input_value *vals, unsigned int count)
#else
static unsigned int usb_mouse_events(struct input_handle *handle, struct input_value *vals, unsigned int count)
#endif For me it uses the top (void with const version, so it's correct). I'm using version 6.8 |
Also, I think that
It caused errors for me, because there is no "udev_trigger" in the makefile. I tried suggesting this change for this PR, but it seems as though I can only edit the files that were already altered in some way. |
b82853e
to
d7b631c
Compare
@AndyFilter: Sorry 😅 Was having some issues getting the last version to compile on both kernel versions, but I just made some adjustments and it's working fine for me now. I'm choosing not to handle the |
It think the const's are fine either way. Current version builds for me just fine (using the |
sorry for dropping the ball here! I've been a little busy lately. I'll have to set up some virtual machines to test this a little more once I've got more time, e.g. on a clean Arch install, to make sure we're in a good state here. That should ultimately also help me resolve the build issues for you ❤️ |
Supersedes #2 (A prior draft of this PR)
Problem
Currently, the kernel module is a full driver, based on the boot-mode USB mouse driver in Linux. It then uses a slim USB HID descriptor parser (
util.c
) and creates a new driver to bind input devices to.However, Linux contains a lot of modifications and custom drivers for input devices as well, and there's quite a long list of problematic devices that misreport events or HID descriptors, which are patched upstream in the kernel.
These patches are only available to the built-in
usbhid
driver though.Likely, a combination of the USB HID descriptor parser being very slim and sacrificing accuracy for brevity, and missing device patches and workarounds, means that a lot of mice that'd usually work just don't 😞
While it's possible to improve the USB HID descriptor parser, it's also possible to find a new approach, with the goal of intercepting events and modifying them while still letting the
usbhid
driver handle the device. (This also has the benefit that it leaves outputs intact, i.e. on-device configuration would still work)Halfway Solution: Input handlers and virtual devices
The
maccel
project, which essentially started as yet another fork ofleetmouse
(but has diverged quite a lot), has a solution to this that I've seen replicated in a few other places.This approach uses regular
input_handler
s in the Linux Input subsystem implementation to filter outEV_REL
events and to replace them by sending them to a virtual input device.This is close to what we want but then comes with some drawbacks:
yeetmouse
projectFull(?) Solution: Intercepting and modifying events
input_handlers
are very powerful and theirfilter
callback concept is essentially just a template that uses the underlyingevents
API to omit events dynamically.However, this can also be used to modify events.
The new driver in this PR intercepts events, collects them, passes them to the
accelerate()
function, then modifies the original events. If we make sure that ourinput_handler
is registered at the front of the list of all handlers (which the kernel'sinput_register_handle()
function usually only does for filters, i.e. handlers with->filter
set rather than->events
), then we're able to intercept and mutate the events as we please.Further, we can also reach into the device and update the original events in a similar way, which makes sure that there's no residual data of the unaccelerated input (fwiw, I don't know if that's important, but who knows)
In theory this now means:
usbhid
's handling of devices, sub-drivers, and quirks which should blanket-support every device that works out of the box with LinuxNote
There's one gotcha I found, which is that I don't yet know how events are queued up.
This means I'm not waiting for an
EV_SYN
event and just consider a batch of events as "one input" that we should accelerate. Optimally, we'd handle this better, but I'm not sure if that means we have to shift around some state. TBDSet of changes
module_usb_driver
module implementation with amodule_init
/module_exit
moduleinput_handler
receivingevents
and updating themutil.c
USB HID descriptor parser codeudev
installation/code/etctemp
because this PR still requires testing, and I'm assuming we might want to work on a hybrid driver, that can function using bothinput_handler
s and as a driver to bind a device to.