On Tue, Feb 18, 2014 at 04:09:09PM +1000, Peter Hutterer wrote: > libevdev wraps the various peculiarities of the evdev kernel API into a > type-safe API. It also buffers the device so checking for specific features at > a later time is easier than re-issuing the ioctls. Plus, it gives us almost > free support for SYN_DROPPED events (in the following patch). > > This patch switches all the bit checks over to libevdev and leaves the event > processing as-is. Makes it easier to review. > > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
Looks good to me as well, with one comment inline. Reviewed-by: Jonas Ådahl <jad...@gmail.com> > --- > configure.ac | 7 ++--- > src/Makefile.am | 2 ++ > src/evdev-touchpad.c | 25 ++++++--------- > src/evdev.c | 87 > +++++++++++++++++++++------------------------------- > src/evdev.h | 14 ++------- > 5 files changed, 52 insertions(+), 83 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 44729a9..68e1d35 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -44,6 +44,7 @@ AC_CHECK_DECL(CLOCK_MONOTONIC,[], > PKG_PROG_PKG_CONFIG() > PKG_CHECK_MODULES(MTDEV, [mtdev >= 1.1.0]) > PKG_CHECK_MODULES(LIBUDEV, [libudev]) > +PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4]) > > if test "x$GCC" = "xyes"; then > GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes > -Wmissing-prototypes -fvisibility=hidden" > @@ -64,20 +65,16 @@ AC_ARG_ENABLE(tests, > [build_tests="$enableval"], > [build_tests="auto"]) > > -PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4], [HAVE_LIBEVDEV="yes"], > [HAVE_LIBEVDEV="no"]) > PKG_CHECK_MODULES(CHECK, [check >= 0.9.9], [HAVE_CHECK="yes"], > [HAVE_CHECK="no"]) > > if test "x$build_tests" = "xauto"; then > - if test "x$HAVE_CHECK" = "xyes" -a "x$HAVE_LIBEVDEV" = "xyes"; then > + if test "x$HAVE_CHECK" = "xyes"; then > build_tests="yes" > fi > fi > if test "x$build_tests" = "xyes" -a "x$HAVE_CHECK" = "xno"; then > AC_MSG_ERROR([Cannot build tests, check is missing]) > fi > -if test "x$build_tests" = "xyes" -a "x$HAVE_LIBEVDEV" = "xno"; then > - AC_MSG_ERROR([Cannot build tests, libevdev is missing]) > -fi > > AM_CONDITIONAL(BUILD_TESTS, [test "x$build_tests" = "xyes"]) > > diff --git a/src/Makefile.am b/src/Makefile.am > index 6e27b3b..f544ccd 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -20,9 +20,11 @@ libinput_la_SOURCES = \ > > libinput_la_LIBADD = $(MTDEV_LIBS) \ > $(LIBUDEV_LIBS) \ > + $(LIBEVDEV_LIBS) \ > -lm > libinput_la_CFLAGS = $(MTDEV_CFLAGS) \ > $(LIBUDEV_CFLAGS) \ > + $(LIBEVDEV_CFLAGS) \ > $(GCC_CFLAGS) > > pkgconfigdir = $(libdir)/pkgconfig > diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c > index d65ebb2..8185bf2 100644 > --- a/src/evdev-touchpad.c > +++ b/src/evdev-touchpad.c > @@ -170,16 +170,16 @@ struct touchpad_dispatch { > static enum touchpad_model > get_touchpad_model(struct evdev_device *device) > { > - struct input_id id; > + int vendor, product; > unsigned int i; > > - if (ioctl(device->fd, EVIOCGID, &id) < 0) > - return TOUCHPAD_MODEL_UNKNOWN; > + vendor = libevdev_get_id_vendor(device->evdev); > + product = libevdev_get_id_product(device->evdev); > > for (i = 0; i < ARRAY_LENGTH(touchpad_spec_table); i++) > - if (touchpad_spec_table[i].vendor == id.vendor && > + if (touchpad_spec_table[i].vendor == vendor && > (!touchpad_spec_table[i].product || > - touchpad_spec_table[i].product == id.product)) > + touchpad_spec_table[i].product == product)) > return touchpad_spec_table[i].model; > > return TOUCHPAD_MODEL_UNKNOWN; > @@ -730,9 +730,7 @@ touchpad_init(struct touchpad_dispatch *touchpad, > { > struct motion_filter *accel; > > - unsigned long prop_bits[INPUT_PROP_MAX]; > - struct input_absinfo absinfo; > - unsigned long abs_bits[NBITS(ABS_MAX)]; > + const struct input_absinfo *absinfo; > > bool has_buttonpad; > > @@ -746,16 +744,13 @@ touchpad_init(struct touchpad_dispatch *touchpad, > /* Detect model */ > touchpad->model = get_touchpad_model(device); > > - ioctl(device->fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits); > - has_buttonpad = TEST_BIT(prop_bits, INPUT_PROP_BUTTONPAD); > + has_buttonpad = libevdev_has_property(device->evdev, > INPUT_PROP_BUTTONPAD); > > /* Configure pressure */ > - ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits); > - if (TEST_BIT(abs_bits, ABS_PRESSURE)) { > - ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo); > + if ((absinfo = libevdev_get_abs_info(device->evdev, ABS_PRESSURE))) { > configure_touchpad_pressure(touchpad, > - absinfo.minimum, > - absinfo.maximum); > + absinfo->minimum, > + absinfo->maximum); > } > > /* Configure acceleration factor */ > diff --git a/src/evdev.c b/src/evdev.c > index d8dff65..ba28fc6 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -491,11 +491,7 @@ evdev_device_dispatch(void *data) > static int > evdev_configure_device(struct evdev_device *device) > { > - struct input_absinfo absinfo; > - unsigned long ev_bits[NBITS(EV_MAX)]; > - unsigned long abs_bits[NBITS(ABS_MAX)]; > - unsigned long rel_bits[NBITS(REL_MAX)]; > - unsigned long key_bits[NBITS(KEY_MAX)]; > + const struct input_absinfo *absinfo; > int has_abs, has_rel, has_mt; > int has_button, has_keyboard, has_touch; > unsigned int i; > @@ -507,84 +503,71 @@ evdev_configure_device(struct evdev_device *device) > has_keyboard = 0; > has_touch = 0; > > - ioctl(device->fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits); > - if (TEST_BIT(ev_bits, EV_ABS)) { > - ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), > - abs_bits); > + if (libevdev_has_event_type(device->evdev, EV_ABS)) { > > - if (TEST_BIT(abs_bits, ABS_X)) { > - ioctl(device->fd, EVIOCGABS(ABS_X), &absinfo); > - device->abs.min_x = absinfo.minimum; > - device->abs.max_x = absinfo.maximum; > + if ((absinfo = libevdev_get_abs_info(device->evdev, ABS_X))) { > + device->abs.min_x = absinfo->minimum; > + device->abs.max_x = absinfo->maximum; > has_abs = 1; > } > - if (TEST_BIT(abs_bits, ABS_Y)) { > - ioctl(device->fd, EVIOCGABS(ABS_Y), &absinfo); > - device->abs.min_y = absinfo.minimum; > - device->abs.max_y = absinfo.maximum; > + if ((absinfo = libevdev_get_abs_info(device->evdev, ABS_Y))) { > + device->abs.min_y = absinfo->minimum; > + device->abs.max_y = absinfo->maximum; > has_abs = 1; > } > /* We only handle the slotted Protocol B in weston. > Devices with ABS_MT_POSITION_* but not ABS_MT_SLOT > require mtdev for conversion. */ > - if (TEST_BIT(abs_bits, ABS_MT_POSITION_X) && > - TEST_BIT(abs_bits, ABS_MT_POSITION_Y)) { > - ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_X), > - &absinfo); > - device->abs.min_x = absinfo.minimum; > - device->abs.max_x = absinfo.maximum; > - ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_Y), > - &absinfo); > - device->abs.min_y = absinfo.minimum; > - device->abs.max_y = absinfo.maximum; > + if (libevdev_has_event_code(device->evdev, EV_ABS, > ABS_MT_POSITION_X) && > + libevdev_has_event_code(device->evdev, EV_ABS, > ABS_MT_POSITION_Y)) { > + absinfo = libevdev_get_abs_info(device->evdev, > ABS_MT_POSITION_X); > + device->abs.min_x = absinfo->minimum; > + device->abs.max_x = absinfo->maximum; > + absinfo = libevdev_get_abs_info(device->evdev, > ABS_MT_POSITION_Y); > + device->abs.min_y = absinfo->minimum; > + device->abs.max_y = absinfo->maximum; > device->is_mt = 1; > has_touch = 1; > has_mt = 1; > > - if (!TEST_BIT(abs_bits, ABS_MT_SLOT)) { > + if (!libevdev_has_event_code(device->evdev, EV_ABS, > ABS_MT_SLOT)) { > device->mtdev = mtdev_new_open(device->fd); > if (!device->mtdev) > return -1; > device->mt.slot = > device->mtdev->caps.slot.value; > } else { > - ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), > - &absinfo); > - device->mt.slot = absinfo.value; > + device->mt.slot = > libevdev_get_current_slot(device->evdev); > } > } > } > - if (TEST_BIT(ev_bits, EV_REL)) { > - ioctl(device->fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), > - rel_bits); > - if (TEST_BIT(rel_bits, REL_X) || TEST_BIT(rel_bits, REL_Y)) > + if (libevdev_has_event_code(device->evdev, EV_REL, REL_X) || > + libevdev_has_event_code(device->evdev, EV_REL, REL_Y)) > has_rel = 1; > - } > - if (TEST_BIT(ev_bits, EV_KEY)) { > - ioctl(device->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), > - key_bits); > - if (TEST_BIT(key_bits, BTN_TOOL_FINGER) && > - !TEST_BIT(key_bits, BTN_TOOL_PEN) && > + > + if (libevdev_has_event_type(device->evdev, EV_KEY)) { > + 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 || has_mt)) { > device->dispatch = evdev_touchpad_create(device); > } > for (i = KEY_ESC; i < KEY_MAX; i++) { > if (i >= BTN_MISC && i < KEY_OK) > continue; > - if (TEST_BIT(key_bits, i)) { > + if (libevdev_has_event_code(device->evdev, EV_KEY, i)) { > has_keyboard = 1; > break; > } > } > - if (TEST_BIT(key_bits, BTN_TOUCH)) > + if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOUCH)) > has_touch = 1; > for (i = BTN_MISC; i < BTN_JOYSTICK; i++) { > - if (TEST_BIT(key_bits, i)) { > + if (libevdev_has_event_code(device->evdev, EV_KEY, i)) { > has_button = 1; > break; > } > } > } > - if (TEST_BIT(ev_bits, EV_LED)) > + if (libevdev_has_event_type(device->evdev, EV_LED)) > has_keyboard = 1; > > if ((has_abs || has_rel) && has_button) > @@ -604,7 +587,7 @@ evdev_device_create(struct libinput_seat *seat, > { > struct libinput *libinput = seat->libinput; > struct evdev_device *device; > - char devname[256] = "unknown"; > + int rc; > int fd; > int unhandled_device = 0; > > @@ -624,6 +607,10 @@ evdev_device_create(struct libinput_seat *seat, > > libinput_device_init(&device->base, seat); > > + rc = libevdev_new_from_fd(fd, &device->evdev); > + if (rc != 0) > + return NULL; > + > device->seat_caps = 0; > device->is_mt = 0; > device->mtdev = NULL; > @@ -635,10 +622,7 @@ evdev_device_create(struct libinput_seat *seat, > device->dispatch = NULL; > device->fd = fd; > device->pending_event = EVDEV_NONE; > - > - ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname); > - devname[sizeof(devname) - 1] = '\0'; > - device->devname = strdup(devname); > + device->devname = libevdev_get_name(device->evdev); This makes the assumption that the const char * returned by libevdev_get_name() is valid until we destroy the device. Is this guaranteed anywhere by libevdev? > > libinput_seat_ref(seat); > > @@ -742,8 +726,7 @@ evdev_device_destroy(struct evdev_device *device) > dispatch->interface->destroy(dispatch); > > libinput_seat_unref(device->base.seat); > - > - free(device->devname); > + libevdev_free(device->evdev); > free(device->devnode); > free(device->sysname); > free(device); > diff --git a/src/evdev.h b/src/evdev.h > index 3c9f93a..a9e27bf 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -27,6 +27,7 @@ > #include "config.h" > > #include <linux/input.h> > +#include <libevdev/libevdev.h> > > #include "libinput-private.h" > > @@ -55,10 +56,11 @@ struct evdev_device { > struct libinput_source *source; > > struct evdev_dispatch *dispatch; > + struct libevdev *evdev; > char *output_name; > char *devnode; > char *sysname; > - char *devname; > + const char *devname; > int fd; > struct { > int min_x, max_x, min_y, max_y; > @@ -86,16 +88,6 @@ struct evdev_device { > int is_mt; > }; > > -/* copied from udev/extras/input_id/input_id.c */ > -/* we must use this kernel-compatible implementation */ > -#define BITS_PER_LONG (sizeof(unsigned long) * 8) > -#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) > -#define OFF(x) ((x)%BITS_PER_LONG) > -#define BIT(x) (1UL<<OFF(x)) > -#define LONG(x) ((x)/BITS_PER_LONG) > -#define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1) > -/* end copied */ > - > #define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1) > > struct evdev_dispatch; > -- > 1.8.4.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel