[PATCH xf86-input-libinput] Add tablet pad support

Peter Hutterer peter.hutterer at who-t.net
Fri Apr 22 02:07:27 UTC 2016


On Wed, Apr 20, 2016 at 04:05:14PM -0700, Jason Gerecke wrote:
> On Sun, Apr 17, 2016 at 9:18 PM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > Modelled to be mostly compatible to the xf86-input-wacom driver behavior. The
> > pad gets 7 axes, the first three of which are mute and the others are always
> > available but obviously only send events when the axis is there.
> >
> > The strip axes are incompatible, the wacom driver merely forwards the device
> > events (which are a bitshifted value), libinput normalizes it and we just
> > expand this back into an integer range. Let's see how we go with this.
> >
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> >  src/xf86libinput.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 151 insertions(+)
> >
> > diff --git a/src/xf86libinput.c b/src/xf86libinput.c
> > index dd3250c..59ff44d 100644
> > --- a/src/xf86libinput.c
> > +++ b/src/xf86libinput.c
> > @@ -70,12 +70,15 @@
> >  #define TABLET_AXIS_MAX 0xffffff
> >  #define TABLET_PRESSURE_AXIS_MAX 2047
> >  #define TABLET_TILT_AXIS_MAX 64
> > +#define TABLET_STRIP_AXIS_MAX 4096
> > +#define TABLET_RING_AXIS_MAX 71
> >
> >  #define CAP_KEYBOARD   0x1
> >  #define CAP_POINTER    0x2
> >  #define CAP_TOUCH      0x4
> >  #define CAP_TABLET     0x8
> >  #define CAP_TABLET_TOOL        0x10
> > +#define CAP_TABLET_PAD 0x20
> >
> >  struct xf86libinput_driver {
> >         struct libinput *libinput;
> > @@ -957,6 +960,66 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
> >         InitProximityClassDeviceStruct(dev);
> >  }
> >
> > +static void
> > +xf86libinput_init_tablet_pad(InputInfoPtr pInfo)
> > +{
> > +       DeviceIntPtr dev = pInfo->dev;
> > +       struct xf86libinput *driver_data = pInfo->private;
> > +       struct libinput_device *device = driver_data->shared_device->device;
> > +       int min, max, res;
> > +       unsigned char btnmap[MAX_BUTTONS];
> > +       Atom btnlabels[MAX_BUTTONS] = {0};
> > +       Atom axislabels[TOUCHPAD_NUM_AXES] = {0};
> > +       int nbuttons;
> > +       int naxes = 7;
> > +
> > +       nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
> > +       init_button_map(btnmap, nbuttons);
> > +
> > +       InitPointerDeviceStruct((DevicePtr)dev,
> > +                               driver_data->options.btnmap,
> > +                               nbuttons,
> > +                               btnlabels,
> > +                               xf86libinput_ptr_ctl,
> > +                               GetMotionHistorySize(),
> > +                               naxes,
> > +                               axislabels);
> > +
> > +       /* For compat with xf86-input-wacom we init x, y, pressure, followed
> > +        * by strip x, strip y, ring, ring2*/
> > +       min = 0;
> > +       max = TABLET_AXIS_MAX;
> > +       res = 0;
> 
> I'm not sure what the point of initializing the valuators below with
> "res * 1000" when this is just zero, but if it's intentional... It
> looks like xf86-input-wacom sets the resolution to "0" or "1"
> depending on the axis, but I would be extraordinarily surprised if any
> client actually relied on those values since they're clearly bogus.

copy/paste ease mostly. All the calls to xf86InitValuatorAxisStruct are the
same, it's easer to just set the res to 0 than having subtle differences
here.
 
> > +       xf86InitValuatorAxisStruct(dev, 0,
> > +                                  XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +       xf86InitValuatorAxisStruct(dev, 1,
> > +                                  XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +       xf86InitValuatorAxisStruct(dev, 2,
> > +                                  XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE),
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +
> > +       /* strip x */
> > +       max = TABLET_STRIP_AXIS_MAX;
> > +       xf86InitValuatorAxisStruct(dev, 3,
> > +                                  None,
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +       /* strip y */
> > +       xf86InitValuatorAxisStruct(dev, 4,
> > +                                  None,
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +       /* first ring */
> > +       max = TABLET_RING_AXIS_MAX;
> > +       xf86InitValuatorAxisStruct(dev, 5,
> > +                                  XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL),
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +       /* second ring */
> > +       xf86InitValuatorAxisStruct(dev, 6,
> > +                                  None,
> > +                                  min, max, res * 1000, 0, res * 1000, Absolute);
> > +}
> > +
> >  static int
> >  xf86libinput_init(DeviceIntPtr dev)
> >  {
> > @@ -982,6 +1045,8 @@ xf86libinput_init(DeviceIntPtr dev)
> >                 xf86libinput_init_touch(pInfo);
> >         if (driver_data->capabilities & CAP_TABLET_TOOL)
> >                 xf86libinput_init_tablet(pInfo);
> > +       if (driver_data->capabilities & CAP_TABLET_PAD)
> > +               xf86libinput_init_tablet_pad(pInfo);
> >
> >         LibinputApplyConfig(dev);
> >         LibinputInitProperty(dev);
> > @@ -1476,6 +1541,74 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
> >  }
> >
> >  static void
> > +xf86libinput_handle_tablet_pad_button(InputInfoPtr pInfo,
> > +                                     struct libinput_event_tablet_pad *event)
> > +{
> > +       DeviceIntPtr dev = pInfo->dev;
> > +       struct xf86libinput *driver_data = pInfo->private;
> > +       int button;
> > +       int is_press;
> > +
> > +       if ((driver_data->capabilities & CAP_TABLET_PAD) == 0)
> > +               return;
> > +
> > +       button = 1 + libinput_event_tablet_pad_get_button_number(event);
> > +       is_press = (libinput_event_tablet_pad_get_button_state(event) == LIBINPUT_BUTTON_STATE_PRESSED);
> > +
> > +       xf86PostButtonEvent(dev, Relative, button, is_press, 0, 0);
> > +}
> > +
> > +static void
> > +xf86libinput_handle_tablet_pad_strip(InputInfoPtr pInfo,
> > +                                    struct libinput_event_tablet_pad *event)
> > +{
> > +       DeviceIntPtr dev = pInfo->dev;
> > +       struct xf86libinput *driver_data = pInfo->private;
> > +       ValuatorMask *mask = driver_data->valuators;
> > +       double value;
> > +       int axis = 3;
> > +       int v;
> > +
> > +       if ((driver_data->capabilities & CAP_TABLET_PAD) == 0)
> > +               return;
> > +
> > +       /* this isn't compatible with the wacom driver which just forwards
> > +        * the values and lets the clients handle them with log2. */
> > +       axis += libinput_event_tablet_pad_get_strip_number(event);
> > +       value = libinput_event_tablet_pad_get_strip_position(event);
> > +       v = TABLET_STRIP_AXIS_MAX * value;
> 
> If you're interested, I believe compatibility could be achieved with
> something like `v = round(pow(TABLET_STRIP_AXIS_MAX, value))`

yeah, but I really question if that is a sensible thing long-term.
the libinput driver won't be compatible to the wacom driver for
configuration, so over time things will need to change anyway. So I'm
wondering if mangling up the strip values is worth it, especially given that
IIRC only few devices have strips at this point.

> Also, on a somewhat-related note: I'm noticing that having
> xf86-input-libinput and xf86-input-wacom installed alongside each
> other results in some pretty annoying driver priority issues. I've got
> 0.17.0 installed at the moment and it ends up grabbing the pad on my
> 24HDT since udev tags it as a keyboard (probably because it has
> KEY_PROG1 through KEY_PROG3) and since libinput's xorg.conf.d file has
> a '90' prefix. The libinput driver later drops the device since udev
> also tags it as a buttonset, preventing the buttons from being usable
> under X at all (let alone usable by GNOME). If simultaneous
> installation of the libinput and wacom drivers is supposed to work,
> there might be some work to do...

yes, we'll have to use the new-ish NoMatch bits for that. unfortunately,
there is little way around this and I haven't gotten to it yet. I'll bump
this up in the todo list.

Cheers,
   Peter


More information about the xorg-devel mailing list