These devices will set the LIBINPUT_DEVICE_CAP_STYLUS flag, and may emit extra axis information, uncommon in mice and touchpads. These devices may also have different tool modes, notified in LIBINPUT_EVENT_POINTER_TOOL_UPDATE events.
In this commit, only (unfiltered) motion tracking is implemented. Signed-off-by: Carlos Garnacho <[email protected]> --- src/Makefile.am | 2 + src/evdev-tablet.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/evdev-tablet.h | 40 ++++++++++++++++ src/evdev.c | 12 ++++- src/evdev.h | 3 ++ 5 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src/evdev-tablet.c create mode 100644 src/evdev-tablet.h diff --git a/src/Makefile.am b/src/Makefile.am index 579ed25..ef6ae4b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,8 @@ libinput_la_SOURCES = \ libinput-util.h \ evdev.c \ evdev.h \ + evdev-tablet.c \ + evdev-tablet.h \ evdev-mt-touchpad.c \ evdev-mt-touchpad.h \ evdev-mt-touchpad-tap.c \ diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c new file mode 100644 index 0000000..02877d9 --- /dev/null +++ b/src/evdev-tablet.c @@ -0,0 +1,134 @@ +/* + * Copyright © 2014 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "config.h" + +#include <assert.h> +#include <math.h> +#include <stdbool.h> +#include "evdev-tablet.h" + +#define tablet_set_status(tablet,s) (tablet->status |= (s)); +#define tablet_unset_status(tablet,s) (tablet->status &= ~(s)); +#define tablet_has_status(tablet,s) (!!(tablet->status & s)) + +static void +tablet_process_absolute(struct tablet_dispatch *tablet, + struct evdev_device *device, + struct input_event *e, + uint32_t time) +{ + switch (e->code) { + case ABS_X: + device->abs.x = e->value; + tablet_set_status(tablet, TABLET_UPDATED); + break; + case ABS_Y: + device->abs.y = e->value; + tablet_set_status(tablet, TABLET_UPDATED); + break; + default: + log_info("Unhandled ABS event code 0x%x\n", e->code); + break; + } +} + +static void +tablet_flush(struct tablet_dispatch *tablet, + struct evdev_device *device, + uint32_t time) +{ + struct libinput_device *base = &device->base; + li_fixed_t x, y; + + if (tablet_has_status(tablet, TABLET_UPDATED)) { + /* FIXME: apply hysteresis, calibration */ + x = li_fixed_from_int(device->abs.x); + y = li_fixed_from_int(device->abs.y); + + pointer_notify_motion_absolute(base, time, x, y); + tablet_unset_status(tablet, TABLET_UPDATED); + } +} + +static void +tablet_process(struct evdev_dispatch *dispatch, + struct evdev_device *device, + struct input_event *e, + uint32_t time) +{ + struct tablet_dispatch *tablet = + (struct tablet_dispatch *)dispatch; + + switch (e->type) { + case EV_ABS: + tablet_process_absolute(tablet, device, e, time); + break; + case EV_SYN: + tablet_flush(tablet, device, time); + break; + default: + log_error("Unexpected event type 0x%x\n", e->type); + break; + } +} + +static void +tablet_destroy(struct evdev_dispatch *dispatch) +{ + struct tablet_dispatch *tablet = + (struct tablet_dispatch*)dispatch; + + free(tablet); +} + +static struct evdev_dispatch_interface tablet_interface = { + tablet_process, + tablet_destroy +}; + +static int +tablet_init(struct tablet_dispatch *tablet, + struct evdev_device *device) +{ + tablet->base.interface = &tablet_interface; + tablet->device = device; + tablet->status = TABLET_NONE; + + return 0; +} + +struct evdev_dispatch * +evdev_tablet_create(struct evdev_device *device) +{ + struct tablet_dispatch *tablet; + + tablet = zalloc(sizeof *tablet); + if (!tablet) + return NULL; + + if (tablet_init(tablet, device) != 0) { + tablet_destroy(&tablet->base); + return NULL; + } + + return &tablet->base; +} diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h new file mode 100644 index 0000000..e1479fa --- /dev/null +++ b/src/evdev-tablet.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2014 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef EVDEV_TABLET_H +#define EVDEV_TABLET_H + +#include "evdev.h" + +enum tablet_status { + TABLET_NONE = 0, + TABLET_UPDATED = 1 << 0, +}; + +struct tablet_dispatch { + struct evdev_dispatch base; + struct evdev_device *device; + enum tablet_status status; +}; + +#endif diff --git a/src/evdev.c b/src/evdev.c index 71da8f7..5f47571 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -609,7 +609,17 @@ evdev_configure_device(struct evdev_device *device) device->dispatch = evdev_mt_touchpad_create(device); log_info("input device '%s', %s is a touchpad\n", device->devname, device->devnode); + } else if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_FINGER) && + libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_PEN) && + has_abs) { + device->dispatch = evdev_tablet_create(device); + device->seat_caps |= EVDEV_DEVICE_TABLET; + log_info("input device '%s', %s is a tablet\n", + device->devname, device->devnode); + } else if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOUCH)) { + has_touch = 1; } + for (i = KEY_ESC; i < KEY_MAX; i++) { if (i >= BTN_MISC && i < KEY_OK) continue; @@ -618,8 +628,6 @@ evdev_configure_device(struct evdev_device *device) break; } } - if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOUCH)) - has_touch = 1; for (i = BTN_MISC; i < BTN_JOYSTICK; i++) { if (libevdev_has_event_code(device->evdev, EV_KEY, i)) { has_button = 1; diff --git a/src/evdev.h b/src/evdev.h index a798ab6..4db0385 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -122,6 +122,9 @@ evdev_touchpad_create(struct evdev_device *device); struct evdev_dispatch * evdev_mt_touchpad_create(struct evdev_device *device); +struct evdev_dispatch * +evdev_tablet_create(struct evdev_device *device); + void evdev_device_proces_event(struct libinput_event *event); -- 1.9.0 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
