[RFC v2 libinput 0/2] Buttonset interface - numbered axes

Peter Hutterer peter.hutterer at who-t.net
Thu Mar 19 17:19:06 PDT 2015


On Thu, Mar 19, 2015 at 01:15:01PM +0100, David Herrmann wrote:
> Hi
> 
> On Wed, Mar 18, 2015 at 7:58 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> >
> > This is a re-vamped version of the buttonset interface. Still WIP but I'd
> > like to get some comments on the API.
> >
> > Changes to the last version:
> > This version now uses numbered axes instead of typed axes. Previously the
> > interface used a unique axis type to deal with axes (e.g.
> > LIBINPUT_BUTTONSET_AXIS_RING_LEFT). This approach was ditched, instead a
> > device has a number of axes, each with a type. A caller can check how many
> > axes are there and the type for each axis. In the event interface, the axis
> > number is used, not the type.
> >
> > A whole bunch of axes have been added too though the wacom pad interface
> > doesn't expose them, only wheel and ring.
> >
> > Branch is available here:
> > https://github.com/whot/libinput/tree/wip/buttonbox-interface
> >
> > It's still missing a couple of details, tests, checks, etc. but it should
> > show the interface well enough.
> 
> Awesome! Really appreciated!
> 
> Few assorted comments:
> 
> 1) You introduce an enum for axis-types, instead of using the ABS_*
> and REL_* values. On purpose? What's the reason? You don't do this for
> buttons. I can come up with several reasons, but a clear statement
> would be nice:
>  - you want to merge ABS_* and REL_* into a single namespace
>  - you want to get rid of the ABS_X/Y/Z and ABS_HAT* misuse for
> anything that doesn't have its own ABS_* type
>  - ABS2_* still didn't land upstream, so there's no way to introduce
> new ABS_* values, but we really need them (yeah, my bad, I know!)
>  - the kernel ABS_* values just never made any sense

all of the above, pretty much. the kernel uses the axis types as
identifiers, so once you have two identical axes you need to either add a
new constant (delays, ABS_MAX limit) or escape onto a different meaningless
axis (ABS_THROTTLE for the second ring). Not to even mention the fake MT
devices that we need to check for everywhere (when the ABS_ range runs into
the ABS_MT_* range)
so the libinput types are pretty much a list of axes that we know enough
about to specify the details.

fwiw, this is pretty much the same we do in the tablet-support branch. I
admit that this patchset and the documentation requires some pre-existing
knowledge of the decisions there. That'll be fixed up in the final
documentation.

> 2) Mapping from ABS_*/REL_* to axis-types is static? That is, we do
> this based on the devices we know, instead of a magic translation
> table for all types. I really like this, as we can get rid of the
> crappy mappings we used to have for gamepads and so on. I just wonder
> why this isn't done for buttons. Yeah, the namespace is bigger for
> buttons and it used to have less bad mappings, but they still exist.

mostly historical. having said that, I think we can use a button enum
without breaking API or ABI, as long as we copy the linux/input.h
codes in the KEY_MAX range.

We just haven't yet had the real use-case for it, but if we need strictly
numbered buttons we can set them at some offset + index.

> 3) What is an axis-source? I don't get it. What else should I use to
> control an axis, but my finger? My tongue? :) Ok, seriously, the
> description is a bit short. Is this meant to distinguish between
> touch-based input and other input? So you get release-events for the
> 'finger'-based input?

the axis source is best explained in the scrolling patches where we use the
same concept:
http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
the main information about the "finger" is that we'll send you an event when
the finger lifts off the scroll source so that you can implement kinetics.

again, here too it probably relies too much on the other documentation.

> 4) Why hard-code 'relative' in the axis-name, instead of making it a
> property? AXIS_X/Y/Z and ROTATION_X/Y/Z already are two examples that
> can be absolute _and_ relative. Wouldn't it make sense to make
> 'relative' a boolean attribute of an axis on a device? I don't know
> what RING and STRIP is, so cannot comment on that.
> A lot of other axes have this implicit (accelerometer/gyro/compass are
> always absolute, for instance), so not sure it's a good idea. Just
> wanted to bring it up and see whether you have any input on it.

fwiw, ring and strip are on the Intuos 4/5/Pro and the Intuos 3,
respectively, a quick image search will make it obvious.

the distinction is intentional, it (hopefully) reduces confusion. But since
libinput tries to provide physical values where possible the distinction is
needed - a true abs axis can give you true mm, but a rel axis is always
normalized to our 1000dpi.

> 5) If a device has multiple axes of the same type, is the order
> supposed to be ABI? Example: gamepads tend to have two analog-sticks.
> How do applications reliably find the left and right stick?

well, our promise is that the same device will come up in the same order of
axes. so once you figure out that the left stick is the first, you can rely
on it always being the first on that device.

if the kernel driver changes out from underneath us that could be
interesting but then again that'd be an argument for a kernel regression :)

> 6) *_get_*_transformed() is linear? Can you mention that in the
> description? It's not clear just from the name 'transform' and a
> min/max range.

yeah, straightforward mapping, same as
libinput_pointer_get_absolute_x_transformed(), i.e. it's effectively a mm to
magic axis range conversion.

> 7) libinput_event_buttonset_get_axis_delta_transformed()?
> What is that thing doing? libinput_event_buttonset_get_axis_delta()
> returns data for relative axes, but the *_transformed() version says
> it always returns 0 for relative axes? There's a big FIXME, but the
> function description doesn't make sense to me. Can you elaborate?

whoops. copy/paste error. it's supposed to be like get_axis_delta, with a
axis scale supplied...

... uhm, come to think of it, this function makes no sense. last minute
addition (hence the fixme), will be removed.

> 8) What is libinput_event_buttonset_get_seat_button_count() good for?
> Not that I care much, but it made me curious :)

libinput is per-device, but compositors merge multiple devices into a seat.
if you hold button X down on the mouse and the touchpad,
get_seat_button_count() gives you 2 for that button. On a release event, the
compositor checks for the seat button count and then decides whether to send
a release event to the client or not. again, same as in the pointer/keyboard
interface, the touch interface has a similar one with the seat_slot concept.
libinput doesn't use it, but since every compositor will have to we added
the code here to reduce duplication.
 
> 9) There's only libinput_device_buttonset_has_button(), but no way to
> get a list of buttons enabled on that device. Do you expect
> applications to iterate all 2^32 buttons or are applications not
> supposed to retrieve the set of buttons on a device?

good point. I don't know. While we stick to linux/input.h the button range
is significantly lower but my (possibly naive) view was that rather than
checking for every button possible a caller would check for specific buttons
that are required for some functionality. So you'd check for e.g.
BTN_LEFT/BTN_RIGHT, or BTN_STYLUS/BTN_STYLUS2 on the pen. or BTN_SOUTH
through to BTN_WEST for a gamepad.

after all, knowing that a misc button exists doesn't mean you'll be able to
handle it. This may be a overly simplified or optimistic view though...

> Last point: Will there be some generic type for libinput-devices so
> applications can select them? For instance: "this is a
> wacom-tablet-style-thing" or "this is a gamepad", .. etc. Or are
> applications supposed to look exactly at the capabilities of a device
> and say "Hey, this has two analog-sticks, a dpad, 4 action-buttons and
> a bit more; lets use it as gamepad input"? I like the latter, but
> wanna be sure what the plans are.

yeah, that. I'm struggling to figure out a good device identification system
that won't end up like a pile of hacks and issues. e.g. you may tag
something as gamepad today, but that may not be accurate enough tomorrow (is
the wiimote a joystick, a gamepad, an "other"?). X's struggle to clamp
everything into "this is a keyboard or a mouse" has shown that devices tend
to avoid any meaningful categorization. e.g. the MS touch mouse is both a
mouse and a touchpad.

so any identification system would have to allow for multiple tags, but you
still have the same issues long-term. Intuos and Cintiqs are both tablets,
but one of them is also a screen, the other is also a touchpad. Tomorrow
that may not be detailed enough anymore, so punting the device
identification to the part that actually needs to know what a device is
seems the only long-term workable solution.

And in some cases it doesn't matter: if the device has X/Y/Z axes and
a couple of buttons you can use it as joystick, regardless what the device
actually is.

> Again, much appreciated! If this lands upstream, it'd be definitely
> worth a look to add gamepad/etc. support.

fwiw, the buttonset interface is a generic interface for "things that are
auxiliary devices that don't move the pointer". I think there' merit to
move any gamepad/joystick/... support into a separate interface where you'd
then have more flexibility in defining the rules. e.g. absolute coordinates
on a joystick/gamepad don't really make sense.

Thanks for the comments, I'll fix the bits and pieces up as mentioned above
but I think we'll need more discussions on some of the details too :)

Cheers,
   Peter



More information about the wayland-devel mailing list