[PATCH v2 xserver 4/9] xwayland: Handle wp_tablet events

Jason Gerecke killertofu at gmail.com
Thu Feb 9 19:21:40 UTC 2017


On Tue, Feb 7, 2017 at 6:42 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> From: Jason Gerecke <killertofu at gmail.com>
>
> Creates and maintains the canonical trio of X devices (stylus, eraser,
> and cursor) to be shared by all connected tablets. A per-tablet trio
> could be created instead, but there are very few benefits to such a
> configuration since all tablets still ultimately share control of a
> single master pointer.
>
> The three X devices are modeled after those created by xf86-input-wacom
> but use a generic maximum X and Y that should be large enough to
> accurately represent values from even the largest currently-available
> tablets.
>
> Signed-off-by: Jason Gerecke <jason.gerecke at wacom.com>
> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Changes to v1:
> - extra comments for clarity
>
>  hw/xwayland/xwayland-input.c | 142 +++++++++++++++++++++++++++++++++++++++++++
>  hw/xwayland/xwayland.h       |   3 +
>  2 files changed, 145 insertions(+)
>
> diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
> index 3eac40f..97cc4d7 100644
> --- a/hw/xwayland/xwayland-input.c
> +++ b/hw/xwayland/xwayland-input.c
> @@ -288,6 +288,75 @@ xwl_touch_proc(DeviceIntPtr device, int what)
>  #undef NTOUCHPOINTS
>  }
>
> +static int
> +xwl_tablet_proc(DeviceIntPtr device, int what)
> +{
> +#define NBUTTONS 9
> +#define NAXES 6
> +    Atom btn_labels[NBUTTONS] = { 0 };
> +    Atom axes_labels[NAXES] = { 0 };
> +    BYTE map[NBUTTONS + 1] = { 0 };
> +    int i;
> +
> +    switch (what) {
> +    case DEVICE_INIT:
> +        device->public.on = FALSE;
> +
> +        for (i = 1; i <= NBUTTONS; i++)
> +            map[i] = i;
> +
> +        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
> +        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
> +        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
> +        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
> +        axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
> +        axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL);
> +
> +        if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
> +                                           GetMotionHistorySize(), Absolute))
> +            return BadValue;
> +
> +        /* Valuators - match the xf86-input-wacom ranges */
> +        InitValuatorAxisStruct(device, 0, axes_labels[0],
> +                               0, 262143, 10000, 0, 10000, Absolute);
> +        InitValuatorAxisStruct(device, 1, axes_labels[1],
> +                               0, 262143, 10000, 0, 10000, Absolute);
> +        /* pressure */
> +        InitValuatorAxisStruct(device, 2, axes_labels[2],
> +                               0, 2048, 1, 0, 1, Absolute);

The latest-generation of Wacom hardware supports 8192 pressure levels.
The xf86-input-wacom-0.34.0 driver changes this range to max out at
65536 instead of 2048 to avoid having to continually bump it upwards.
You'll need to change the 'tablet_tool_pressure' function in the
following patch to change (remove) the scaling factor.

Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one  /
(That is to say, eight) to the two,     /
But you can’t take seven from three,    /
So you look at the sixty-fours....

> +        /* tilt x */
> +        InitValuatorAxisStruct(device, 3, axes_labels[3],
> +                               -64, 63, 57, 0, 57, Absolute);
> +        /* tilt y */
> +        InitValuatorAxisStruct(device, 4, axes_labels[4],
> +                               -64, 63, 57, 0, 57, Absolute);
> +        /* abs wheel (airbrush) or rotation (artpen) */
> +        InitValuatorAxisStruct(device, 5, axes_labels[5],
> +                               -900, 899, 1, 0, 1, Absolute);
> +
> +        if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
> +            return BadValue;
> +
> +        if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
> +            return BadValue;
> +
> +        return Success;
> +
> +    case DEVICE_ON:
> +        device->public.on = TRUE;
> +        return Success;
> +
> +    case DEVICE_OFF:
> +    case DEVICE_CLOSE:
> +        device->public.on = FALSE;
> +        return Success;
> +    }
> +
> +    return BadMatch;
> +#undef NAXES
> +#undef NBUTTONS
> +}
> +
>  static void
>  pointer_handle_enter(void *data, struct wl_pointer *pointer,
>                       uint32_t serial, struct wl_surface *surface,
> @@ -1182,6 +1251,77 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
>      free(xwl_seat);
>  }
>
> +static void
> +tablet_handle_name(void *data, struct zwp_tablet_v2 *tablet, const char *name)
> +{
> +}
> +
> +static void
> +tablet_handle_id(void *data, struct zwp_tablet_v2 *tablet, uint32_t vid,
> +                  uint32_t pid)
> +{
> +}
> +
> +static void
> +tablet_handle_path(void *data, struct zwp_tablet_v2 *tablet, const char *path)
> +{
> +}
> +
> +static void
> +tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet)
> +{
> +    struct xwl_tablet *xwl_tablet = data;
> +    struct xwl_seat *xwl_seat = xwl_tablet->seat;
> +
> +    if (xwl_seat->stylus == NULL) {
> +        xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc);
> +        ActivateDevice(xwl_seat->stylus, TRUE);
> +    }
> +    EnableDevice(xwl_seat->stylus, TRUE);
> +
> +    if (xwl_seat->eraser == NULL) {
> +        xwl_seat->eraser = add_device(xwl_seat, "xwayland-eraser", xwl_tablet_proc);
> +        ActivateDevice(xwl_seat->eraser, TRUE);
> +    }
> +    EnableDevice(xwl_seat->eraser, TRUE);
> +
> +    if (xwl_seat->puck == NULL) {
> +        xwl_seat->puck = add_device(xwl_seat, "xwayland-cursor", xwl_tablet_proc);
> +        ActivateDevice(xwl_seat->puck, TRUE);
> +    }
> +    EnableDevice(xwl_seat->puck, TRUE);
> +}
> +
> +static void
> +tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet)
> +{
> +    struct xwl_tablet *xwl_tablet = data;
> +    struct xwl_seat *xwl_seat = xwl_tablet->seat;
> +
> +    xorg_list_del(&xwl_tablet->link);
> +
> +    /* The tablet is merely disabled, not removed. The next tablet
> +       will re-use the same X devices */
> +    if (xorg_list_is_empty(&xwl_seat->tablets)) {
> +        if (xwl_seat->stylus)
> +            DisableDevice(xwl_seat->stylus, TRUE);
> +        if (xwl_seat->eraser)
> +            DisableDevice(xwl_seat->eraser, TRUE);
> +        if (xwl_seat->puck)
> +            DisableDevice(xwl_seat->puck, TRUE);
> +    }
> +
> +    zwp_tablet_v2_destroy(tablet);
> +    free(xwl_tablet);
> +}
> +
> +static const struct zwp_tablet_v2_listener tablet_listener = {
> +    tablet_handle_name,
> +    tablet_handle_id,
> +    tablet_handle_path,
> +    tablet_handle_done,
> +    tablet_handle_removed
> +};
>
>  static void
>  tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
> @@ -1200,6 +1340,8 @@ tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat
>      xwl_tablet->seat = xwl_seat;
>
>      xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets);
> +
> +    zwp_tablet_v2_add_listener(tablet, &tablet_listener, xwl_tablet);
>  }
>
>  static void
> diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
> index a7f30b3..e7e6288 100644
> --- a/hw/xwayland/xwayland.h
> +++ b/hw/xwayland/xwayland.h
> @@ -132,6 +132,9 @@ struct xwl_seat {
>      DeviceIntPtr relative_pointer;
>      DeviceIntPtr keyboard;
>      DeviceIntPtr touch;
> +    DeviceIntPtr stylus;
> +    DeviceIntPtr eraser;
> +    DeviceIntPtr puck;
>      struct xwl_screen *xwl_screen;
>      struct wl_seat *seat;
>      struct wl_pointer *wl_pointer;
> --
> 2.9.3
>


More information about the xorg-devel mailing list