[ANNOUNCE] libinputmapper - Linux input-event mapping library

Peter Hutterer peter.hutterer at who-t.net
Tue Aug 27 14:47:54 PDT 2013


On Tue, Aug 27, 2013 at 12:36:33PM +0200, David Herrmann wrote:
> Hi
> 
> On Thu, Aug 22, 2013 at 8:53 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > On Thu, Aug 15, 2013 at 07:07:01PM +0200, David Herrmann wrote:
> >> Hi
> >>
> >> Following previous discussions, I pushed some initial work for the
> >> libinputmapper library to github. You can find the repository at:
> >>   https://github.com/dvdhrm/libinputmapper
> >>
> >> At the library's core, there is one important function:
> >>   void inmap_mapping_map(struct inmap_mapping *mapping,
> >>                                      const struct input_event *in,
> >>                                      struct input_event *out,
> >>                                      enum inmap_mapping_map_flags flags);
> >> As one might guess, this function takes a linux "struct input_event",
> >> performs some conversions/translations/.. and outputs it again. The
> >> supported operations are currently limited to simple "ev->code" to
> >> "ev->code" conversions. So for instance KEY_UNKNOWN can be remapped to
> >> KEY_BACKSPACE. But this is not limited to keys, you can also remap
> >> ABS_X to ABS_Y.
> >
> > I strongly recommend to do this as a N:M mapping, to allow for a set of
> > events in and a set of events out. this would allow more complex conversion
> > of events than just a simple 1:1 mapping. The real use-case I can see here
> > is hiding mtdev behind libinputmapper, a theoretical use-case is a known
> > broken device that requires adding e.g. BTN_TOOL_FINGER before the actual
> > converted event.
> 
> How do you think N:M mappings work? A 1:N mapping is possible, but if
> I have more than one source value, which value do I copy to the
> destination? Note that libinputmapper is really just a trivial mapper
> so far. It just maps input_event "code" entries from one to another.
> 
> I am open for suggestions, I can change the mapping function to:
> 
> unsigned int inmap_mapping_map(struct inmap_mapping *mapping,
>                                       const struct input_event *in,
>                                       size_t in_num,
>                                       struct input_event *out,
>                                       size_t out_num,
>                                       enum inmap_mapping_map_flags flags);
> 
> This allows a caller to collect input_events until the next
> SYN_REPORT. These are then passed to inmap_mapping_map() with "in_num"
> set to the number of events. It then writes the corresponding events
> to @out and returns the number of events written. Obviously, there
> must be a way for the caller to calculate a sane @out_num value so we
> don't need any dynamic allocation here.
> I want the standard event-path to work without any allocations or
> error-codes. It should be fail-safe and fast.

look at mtdev-plumbing.h. the lower layer of mtdev has an api in the form
of:

    struct input_event ev;
    read(fd, &ev, sizeof(ev));

    mtdev_put_event(mtdev, &ev);

    /* do we have converted events to process? */
    if (!mtdev_empty(mtdev)) {
        struct input_event converted;
        while (mtdev_get_event(mtdev, &converted))
             process(&converted);
    }

the main gripe I have with this API is that mtdev_put_event should return a
status code whether events are pending to save the mtdev_empty() call, and
the number of events pending. 

both could take more than one event at a time, though the current libevdev
API would make this rather pointless for mtdev_put_event, and in the end
callers still need to process events one-by-one anyway, so I'm not sure
that's much of a benefit here.

obviously that requires two event buffers inside mtdev, same would be true
for libinputmapper.

> Note that I don't think passing more events than until the next
> SYN_REPORT makes sense. I guess we agree here?

yes, I agree.

> Furthermore, I can imagine 1:N mappings which just generates N events
> out of 1. Though, I currently lack any proper use-case for that.

there are a few devices that provide us with ABS_MT_POSITION_X/Y, but not
ABS_X/Y. the xorg evdev driver can't handle these atm and technically
they're against the spec. however, that's a use-case where 1:N would be
possible, and completely transparent to the user process. these devices
could be fixed in the hwdb until the kernel is fixed properly and even that
transition would be transparent.

Cheers,
   Peter




More information about the Input-tools mailing list