From bd4db1c2a21fddd9b1135a41c5adaff3db0f8b3a Mon Sep 17 00:00:00 2001 From: Jonas Ådahl Date: Sun, 10 Nov 2013 17:55:40 +0100 Subject: Port evdev code to be used as a shared library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces build script configuration for building a shared library 'libinput.so' containing the evdev input device functionality from weston. evdev.c, evdev.h and evdev-touchpad.c are ported to not use the data structures and API in weston and libwayland-server in order to minimize dependencies. The API of filter.c and filter.h are renamed to not include the 'weston_' prefix. Signed-off-by: Jonas Ådahl --- .gitignore | 26 ++++ Makefile.am | 3 + README | 9 ++ autogen.sh | 9 ++ configure.ac | 53 +++++++ m4/.gitignore | 5 + src/Makefile.am | 26 ++++ src/evdev-touchpad.c | 215 +++++++++++++++++------------ src/evdev.c | 342 ++++++++++++++++++++++------------------------ src/evdev.h | 33 +++-- src/filter.c | 23 ++-- src/filter.h | 40 +++--- src/libinput-private.h | 102 ++++++++++++++ src/libinput-version.h.in | 31 +++++ src/libinput.c | 168 +++++++++++++++++++++++ src/libinput.h | 173 +++++++++++++++++++++++ src/libinput.pc.in | 12 ++ 17 files changed, 955 insertions(+), 315 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile.am create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 m4/.gitignore create mode 100644 src/Makefile.am create mode 100644 src/libinput-private.h create mode 100644 src/libinput-version.h.in create mode 100644 src/libinput.c create mode 100644 src/libinput.h create mode 100644 src/libinput.pc.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..30a27dc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +*.o +*.pc +*.la +*.lo +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 +src/.libs/ +src/.deps/ +src/Makefile +src/Makefile.in +src/libinput-version.h diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..3a7ce7e8 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} diff --git a/README b/README new file mode 100644 index 00000000..06c30923 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +This library does processing on input device events while providing an API +to the the user used for delegating more useful input events. + +Input event processing includes scaling touch coordinates, generating +pointer events from touchpads, pointer acceleration, etc. + +It is based on the input code from the weston Wayland reference compositor. + +It has no other dependencies than libmtdev and supports only evdev devices. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..b08bc831 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. +( + cd "$srcdir" && + autoreconf --force -v --install +) || exit +test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..8e0f1c93 --- /dev/null +++ b/configure.ac @@ -0,0 +1,53 @@ +AC_PREREQ([2.64]) + +m4_define([libinput_major_version], [0]) +m4_define([libinput_minor_version], [0]) +m4_define([libinput_micro_version], [90]) +m4_define([libinput_version], + [libinput_major_version.libinput_minor_version.libinput_micro_version]) + +AC_INIT([libinput], + [libinput_version], + [http://nobugtracker], + [libinput], + [http://nohomepage]) + +AC_SUBST([LIBINPUT_VERSION_MAJOR], [libinput_major_version]) +AC_SUBST([LIBINPUT_VERSION_MINOR], [libinput_minor_version]) +AC_SUBST([LIBINPUT_VERSION_MICRO], [libinput_micro_version]) +AC_SUBST([LIBINPUT_VERSION], [libinput_version]) + +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) + +AM_SILENT_RULES([yes]) + +# Check for programs +AC_PROG_CC + +# Initialize libtool +LT_PREREQ([2.2]) +LT_INIT + +AC_CHECK_DECL(TFD_CLOEXEC,[], + [AC_MSG_ERROR("TFD_CLOEXEC is needed to compile libinput")], + [[#include ]]) +AC_CHECK_DECL(CLOCK_MONOTONIC,[], + [AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile libinput")], + [[#include ]]) + +PKG_PROG_PKG_CONFIG() +PKG_CHECK_MODULES(MTDEV, [mtdev >= 1.1.0]) + +if test "x$GCC" = "xyes"; then + GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden" +fi +AC_SUBST(GCC_CFLAGS) + +AC_CONFIG_FILES([Makefile + src/Makefile + src/libinput.pc + src/libinput-version.h]) +AC_OUTPUT diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..38066ddf --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,5 @@ +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..00b052e2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,26 @@ +lib_LTLIBRARIES = libinput.la + +include_HEADERS = \ + libinput.h + +libinput_la_SOURCES = \ + libinput.c \ + libinput.h \ + evdev.c \ + evdev.h \ + evdev-touchpad.c \ + filter.c \ + filter.h + +libinput_la_LIBADD = $(MTDEV_LIBS) +libinput_la_CFLAGS = $(MTDEV_CFLAGS) \ + $(GCC_CFLAGS) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libinput.pc + +AM_CPPFLAGS = $(FFI_CFLAGS) +AM_CFLAGS = $(GCC_CFLAGS) + +DISTCLEANFILES = libinput-version.h +EXTRA_DIST = libinput-version.h.in diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c index 69f913ac..6268dffa 100644 --- a/src/evdev-touchpad.c +++ b/src/evdev-touchpad.c @@ -22,16 +22,19 @@ #include "config.h" +#include #include #include #include #include +#include #include #include +#include -#include "filter.h" #include "evdev.h" -#include "../shared/config-parser.h" +#include "filter.h" +#include "libinput-private.h" /* Default values */ #define DEFAULT_CONSTANT_ACCEL_NUMERATOR 50 @@ -127,9 +130,15 @@ struct touchpad_dispatch { struct { bool enable; - struct wl_array events; + + enum fsm_event *events; + size_t events_len; + size_t events_count; enum fsm_state state; - struct wl_event_source *timer_source; + struct { + int fd; + struct libinput_fd_handle *fd_handle; + } timer; } fsm; struct { @@ -154,7 +163,7 @@ struct touchpad_dispatch { int motion_index; unsigned int motion_count; - struct weston_motion_filter *filter; + struct motion_filter *filter; }; static enum touchpad_model @@ -198,7 +207,7 @@ configure_touchpad_pressure(struct touchpad_dispatch *touchpad, } static double -touchpad_profile(struct weston_motion_filter *filter, +touchpad_profile(struct motion_filter *filter, void *data, double velocity, uint32_t time) @@ -265,12 +274,12 @@ static void filter_motion(struct touchpad_dispatch *touchpad, double *dx, double *dy, uint32_t time) { - struct weston_motion_params motion; + struct motion_params motion; motion.dx = *dx; motion.dy = *dy; - weston_filter_dispatch(touchpad->filter, &motion, touchpad, time); + filter_dispatch(touchpad->filter, &motion, touchpad, time); *dx = motion.dx; *dy = motion.dy; @@ -279,17 +288,21 @@ filter_motion(struct touchpad_dispatch *touchpad, static void notify_button_pressed(struct touchpad_dispatch *touchpad, uint32_t time) { - notify_button(touchpad->device->seat, time, - DEFAULT_TOUCHPAD_SINGLE_TAP_BUTTON, - WL_POINTER_BUTTON_STATE_PRESSED); + pointer_notify_button( + &touchpad->device->base, + time, + DEFAULT_TOUCHPAD_SINGLE_TAP_BUTTON, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); } static void notify_button_released(struct touchpad_dispatch *touchpad, uint32_t time) { - notify_button(touchpad->device->seat, time, - DEFAULT_TOUCHPAD_SINGLE_TAP_BUTTON, - WL_POINTER_BUTTON_STATE_RELEASED); + pointer_notify_button( + &touchpad->device->base, + time, + DEFAULT_TOUCHPAD_SINGLE_TAP_BUTTON, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); } static void @@ -303,17 +316,17 @@ static void process_fsm_events(struct touchpad_dispatch *touchpad, uint32_t time) { uint32_t timeout = UINT32_MAX; - enum fsm_event *pevent; enum fsm_event event; + unsigned int i; if (!touchpad->fsm.enable) return; - if (touchpad->fsm.events.size == 0) + if (touchpad->fsm.events_count == 0) return; - wl_array_for_each(pevent, &touchpad->fsm.events) { - event = *pevent; + for (i = 0; i < touchpad->fsm.events_count; ++i) { + event = touchpad->fsm.events[i]; timeout = 0; switch (touchpad->fsm.state) { @@ -379,48 +392,78 @@ process_fsm_events(struct touchpad_dispatch *touchpad, uint32_t time) } break; default: - weston_log("evdev-touchpad: Unknown state %d", - touchpad->fsm.state); touchpad->fsm.state = FSM_IDLE; break; } } - if (timeout != UINT32_MAX) - wl_event_source_timer_update(touchpad->fsm.timer_source, - timeout); + if (timeout != UINT32_MAX) { + struct itimerspec its; - wl_array_release(&touchpad->fsm.events); - wl_array_init(&touchpad->fsm.events); + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + its.it_value.tv_sec = timeout / 1000; + its.it_value.tv_nsec = (timeout % 1000) * 1000 * 1000; + timerfd_settime(touchpad->fsm.timer.fd, 0, &its, NULL); + } + + touchpad->fsm.events_count = 0; } static void push_fsm_event(struct touchpad_dispatch *touchpad, enum fsm_event event) { - enum fsm_event *pevent; + enum fsm_event *events; + size_t new_len = touchpad->fsm.events_len; if (!touchpad->fsm.enable) return; - pevent = wl_array_add(&touchpad->fsm.events, sizeof event); - if (pevent) - *pevent = event; - else - touchpad->fsm.state = FSM_IDLE; + if (touchpad->fsm.events_count + 1 >= touchpad->fsm.events_len) { + if (new_len == 0) + new_len = 4; + else + new_len *= 2; + events = realloc(touchpad->fsm.events, + sizeof(enum fsm_event) * new_len); + if (!events) { + touchpad->fsm.state = FSM_IDLE; + return; + } + + touchpad->fsm.events = events; + touchpad->fsm.events_len = new_len; + } + + touchpad->fsm.events[touchpad->fsm.events_count++] = event; } -static int -fsm_timout_handler(void *data) +static void +fsm_timeout_handler(int fd, void *data) { - struct touchpad_dispatch *touchpad = data; + struct evdev_device *device = data; + struct touchpad_dispatch *touchpad = + (struct touchpad_dispatch *) device->dispatch; + uint64_t expires; + int len; + struct timespec ts; + uint32_t now; + + len = read(fd, &expires, sizeof expires); + if (len != sizeof expires) + /* This will only happen if the application made the fd + * non-blocking, but this function should only be called + * upon the timeout, so lets continue anyway. */ + fprintf(stderr, "timerfd read error: %m\n"); + + if (touchpad->fsm.events_count == 0) { + clock_gettime(CLOCK_MONOTONIC, &ts); + now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; - if (touchpad->fsm.events.size == 0) { push_fsm_event(touchpad, FSM_EVENT_TIMEOUT); - process_fsm_events(touchpad, weston_compositor_get_time()); + process_fsm_events(touchpad, now); } - - return 1; } static void @@ -429,6 +472,7 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time) int motion_index; int center_x, center_y; double dx = 0.0, dy = 0.0; + struct libinput_device *base = &touchpad->device->base; if (touchpad->reset || touchpad->last_finger_state != touchpad->finger_state) { @@ -490,20 +534,24 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time) filter_motion(touchpad, &dx, &dy, time); if (touchpad->finger_state == TOUCHPAD_FINGERS_ONE) { - notify_motion(touchpad->device->seat, time, - wl_fixed_from_double(dx), - wl_fixed_from_double(dy)); + pointer_notify_motion( + base, + time, + li_fixed_from_double(dx), + li_fixed_from_double(dy)); } else if (touchpad->finger_state == TOUCHPAD_FINGERS_TWO) { if (dx != 0.0) - notify_axis(touchpad->device->seat, - time, - WL_POINTER_AXIS_HORIZONTAL_SCROLL, - wl_fixed_from_double(dx)); + pointer_notify_axis( + base, + time, + LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, + li_fixed_from_double(dx)); if (dy != 0.0) - notify_axis(touchpad->device->seat, - time, - WL_POINTER_AXIS_VERTICAL_SCROLL, - wl_fixed_from_double(dy)); + pointer_notify_axis( + base, + time, + LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, + li_fixed_from_double(dy)); } } @@ -596,9 +644,12 @@ process_key(struct touchpad_dispatch *touchpad, code = BTN_RIGHT; else code = e->code; - notify_button(device->seat, time, code, - e->value ? WL_POINTER_BUTTON_STATE_PRESSED : - WL_POINTER_BUTTON_STATE_RELEASED); + pointer_notify_button( + &touchpad->device->base, + time, + code, + e->value ? LIBINPUT_POINTER_BUTTON_STATE_PRESSED : + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); break; case BTN_TOOL_PEN: case BTN_TOOL_RUBBER: @@ -662,7 +713,11 @@ touchpad_destroy(struct evdev_dispatch *dispatch) (struct touchpad_dispatch *) dispatch; touchpad->filter->interface->destroy(touchpad->filter); - wl_event_source_remove(touchpad->fsm.timer_source); + touchpad->device->base.device_interface->remove_fd( + touchpad->fsm.timer.fd_handle, + touchpad->device->base.device_interface_data); + close(touchpad->fsm.timer.fd); + free(touchpad->fsm.events); free(dispatch); } @@ -671,40 +726,11 @@ struct evdev_dispatch_interface touchpad_interface = { touchpad_destroy }; -static void -touchpad_parse_config(struct touchpad_dispatch *touchpad, double diagonal) -{ - struct weston_compositor *compositor = - touchpad->device->seat->compositor; - struct weston_config_section *s; - double constant_accel_factor; - double min_accel_factor; - double max_accel_factor; - - s = weston_config_get_section(compositor->config, - "touchpad", NULL, NULL); - weston_config_section_get_double(s, "constant_accel_factor", - &constant_accel_factor, - DEFAULT_CONSTANT_ACCEL_NUMERATOR); - weston_config_section_get_double(s, "min_accel_factor", - &min_accel_factor, - DEFAULT_MIN_ACCEL_FACTOR); - weston_config_section_get_double(s, "max_accel_factor", - &max_accel_factor, - DEFAULT_MAX_ACCEL_FACTOR); - - touchpad->constant_accel_factor = - constant_accel_factor / diagonal; - touchpad->min_accel_factor = min_accel_factor; - touchpad->max_accel_factor = max_accel_factor; -} - static int touchpad_init(struct touchpad_dispatch *touchpad, struct evdev_device *device) { - struct weston_motion_filter *accel; - struct wl_event_loop *loop; + struct motion_filter *accel; unsigned long prop_bits[INPUT_PROP_MAX]; struct input_absinfo absinfo; @@ -739,7 +765,11 @@ touchpad_init(struct touchpad_dispatch *touchpad, height = abs(device->abs.max_y - device->abs.min_y); diagonal = sqrt(width*width + height*height); - touchpad_parse_config(touchpad, diagonal); + /* Set default parameters */ + touchpad->constant_accel_factor = + DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal; + touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR; + touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR; touchpad->hysteresis.margin_x = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; @@ -765,13 +795,20 @@ touchpad_init(struct touchpad_dispatch *touchpad, touchpad->last_finger_state = 0; touchpad->finger_state = 0; - wl_array_init(&touchpad->fsm.events); + touchpad->fsm.events = NULL; + touchpad->fsm.events_count = 0; + touchpad->fsm.events_len = 0; touchpad->fsm.state = FSM_IDLE; - loop = wl_display_get_event_loop(device->seat->compositor->wl_display); - touchpad->fsm.timer_source = - wl_event_loop_add_timer(loop, fsm_timout_handler, touchpad); - if (touchpad->fsm.timer_source == NULL) { + touchpad->fsm.timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + touchpad->fsm.timer.fd_handle = + touchpad->device->base.device_interface->add_fd( + touchpad->fsm.timer.fd, + fsm_timeout_handler, + touchpad->device->base.device_interface_data); + + if (touchpad->fsm.timer.fd_handle == NULL) { + close(touchpad->fsm.timer.fd); accel->interface->destroy(accel); return -1; } diff --git a/src/evdev.c b/src/evdev.c index 327a93fa..aa2ffa99 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1,5 +1,6 @@ /* * Copyright © 2010 Intel Corporation + * Copyright © 2013 Jonas Ådahl * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided @@ -31,21 +32,22 @@ #include #include -#include "compositor.h" +#include "libinput.h" #include "evdev.h" +#include "libinput-private.h" -#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10) +#define DEFAULT_AXIS_STEP_DISTANCE li_fixed_from_int(10) void -evdev_led_update(struct evdev_device *device, enum weston_led leds) +evdev_device_led_update(struct evdev_device *device, enum libinput_led leds) { static const struct { - enum weston_led weston; + enum libinput_led weston; int evdev; } map[] = { - { LED_NUM_LOCK, LED_NUML }, - { LED_CAPS_LOCK, LED_CAPSL }, - { LED_SCROLL_LOCK, LED_SCROLLL }, + { LIBINPUT_LED_NUM_LOCK, LED_NUML }, + { LIBINPUT_LED_CAPS_LOCK, LED_CAPSL }, + { LIBINPUT_LED_SCROLL_LOCK, LED_SCROLLL }, }; struct input_event ev[ARRAY_LENGTH(map) + 1]; unsigned int i; @@ -69,28 +71,27 @@ evdev_led_update(struct evdev_device *device, enum weston_led leds) static void transform_absolute(struct evdev_device *device, int32_t *x, int32_t *y) { - if (!device->abs.apply_calibration) { - *x = device->abs.x; - *y = device->abs.y; - return; - } else { - *x = device->abs.x * device->abs.calibration[0] + - device->abs.y * device->abs.calibration[1] + - device->abs.calibration[2]; - - *y = device->abs.x * device->abs.calibration[3] + - device->abs.y * device->abs.calibration[4] + - device->abs.calibration[5]; - } + if (!device->abs.apply_calibration) { + *x = device->abs.x; + *y = device->abs.y; + return; + } else { + *x = device->abs.x * device->abs.calibration[0] + + device->abs.y * device->abs.calibration[1] + + device->abs.calibration[2]; + + *y = device->abs.x * device->abs.calibration[3] + + device->abs.y * device->abs.calibration[4] + + device->abs.calibration[5]; + } } static void evdev_flush_pending_event(struct evdev_device *device, uint32_t time) { - struct weston_seat *master = device->seat; - wl_fixed_t x, y; int32_t cx, cy; int slot; + struct libinput_device *base = &device->base; slot = device->mt.slot; @@ -98,52 +99,65 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) case EVDEV_NONE: return; case EVDEV_RELATIVE_MOTION: - notify_motion(master, time, device->rel.dx, device->rel.dy); + pointer_notify_motion(base, + time, + device->rel.dx, + device->rel.dy); device->rel.dx = 0; device->rel.dy = 0; goto handled; case EVDEV_ABSOLUTE_MT_DOWN: - x = wl_fixed_from_int(device->mt.slots[slot].x); - y = wl_fixed_from_int(device->mt.slots[slot].y); - weston_output_transform_coordinate(device->output, - x, y, &x, &y); - notify_touch(master, time, - slot, x, y, WL_TOUCH_DOWN); + touch_notify_touch(base, + time, + slot, + li_fixed_from_int(device->mt.slots[slot].x), + li_fixed_from_int(device->mt.slots[slot].y), + LIBINPUT_TOUCH_TYPE_DOWN); goto handled; case EVDEV_ABSOLUTE_MT_MOTION: - x = wl_fixed_from_int(device->mt.slots[slot].x); - y = wl_fixed_from_int(device->mt.slots[slot].y); - weston_output_transform_coordinate(device->output, - x, y, &x, &y); - notify_touch(master, time, - slot, x, y, WL_TOUCH_MOTION); + touch_notify_touch(base, + time, + slot, + li_fixed_from_int(device->mt.slots[slot].x), + li_fixed_from_int(device->mt.slots[slot].y), + LIBINPUT_TOUCH_TYPE_MOTION); goto handled; case EVDEV_ABSOLUTE_MT_UP: - notify_touch(master, time, slot, 0, 0, - WL_TOUCH_UP); + touch_notify_touch(base, + time, + slot, + 0, 0, + LIBINPUT_TOUCH_TYPE_UP); goto handled; case EVDEV_ABSOLUTE_TOUCH_DOWN: transform_absolute(device, &cx, &cy); - x = wl_fixed_from_int(cx); - y = wl_fixed_from_int(cy); - weston_output_transform_coordinate(device->output, - x, y, &x, &y); - notify_touch(master, time, 0, x, y, WL_TOUCH_DOWN); + touch_notify_touch(base, + time, + slot, + li_fixed_from_int(cx), + li_fixed_from_int(cy), + LIBINPUT_TOUCH_TYPE_DOWN); goto handled; case EVDEV_ABSOLUTE_MOTION: transform_absolute(device, &cx, &cy); - x = wl_fixed_from_int(cx); - y = wl_fixed_from_int(cy); - weston_output_transform_coordinate(device->output, - x, y, &x, &y); - - if (device->caps & EVDEV_TOUCH) - notify_touch(master, time, 0, x, y, WL_TOUCH_MOTION); - else - notify_motion_absolute(master, time, x, y); + if (device->caps & EVDEV_TOUCH) { + touch_notify_touch(base, + time, + slot, + li_fixed_from_int(cx), + li_fixed_from_int(cy), + LIBINPUT_TOUCH_TYPE_DOWN); + } else { + pointer_notify_motion_absolute(base, + time, + li_fixed_from_int(cx), + li_fixed_from_int(cy)); + } goto handled; case EVDEV_ABSOLUTE_TOUCH_UP: - notify_touch(master, time, 0, 0, 0, WL_TOUCH_UP); + touch_notify_touch(base, + time, + 0, 0, 0, LIBINPUT_TOUCH_TYPE_UP); goto handled; } @@ -189,18 +203,21 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) case BTN_FORWARD: case BTN_BACK: case BTN_TASK: - notify_button(device->seat, - time, e->code, - e->value ? WL_POINTER_BUTTON_STATE_PRESSED : - WL_POINTER_BUTTON_STATE_RELEASED); + pointer_notify_button( + &device->base, + time, + e->code, + e->value ? LIBINPUT_POINTER_BUTTON_STATE_PRESSED : + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); break; default: - notify_key(device->seat, - time, e->code, - e->value ? WL_KEYBOARD_KEY_STATE_PRESSED : - WL_KEYBOARD_KEY_STATE_RELEASED, - STATE_UPDATE_AUTOMATIC); + keyboard_notify_key( + &device->base, + time, + e->code, + e->value ? LIBINPUT_KEYBOARD_KEY_STATE_PRESSED : + LIBINPUT_KEYBOARD_KEY_STATE_RELEASED); break; } } @@ -210,8 +227,13 @@ evdev_process_touch(struct evdev_device *device, struct input_event *e, uint32_t time) { - const int screen_width = device->output->current_mode->width; - const int screen_height = device->output->current_mode->height; + int screen_width; + int screen_height; + + device->base.device_interface->get_current_screen_dimensions( + &screen_width, + &screen_height, + device->base.device_interface_data); switch (e->code) { case ABS_MT_SLOT: @@ -248,8 +270,13 @@ static inline void evdev_process_absolute_motion(struct evdev_device *device, struct input_event *e) { - const int screen_width = device->output->current_mode->width; - const int screen_height = device->output->current_mode->height; + int screen_width; + int screen_height; + + device->base.device_interface->get_current_screen_dimensions( + &screen_width, + &screen_height, + device->base.device_interface_data); switch (e->code) { case ABS_X: @@ -273,17 +300,19 @@ static inline void evdev_process_relative(struct evdev_device *device, struct input_event *e, uint32_t time) { + struct libinput_device *base = &device->base; + switch (e->code) { case REL_X: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); - device->rel.dx += wl_fixed_from_int(e->value); + device->rel.dx += li_fixed_from_int(e->value); device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_Y: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); - device->rel.dy += wl_fixed_from_int(e->value); + device->rel.dy += li_fixed_from_int(e->value); device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_WHEEL: @@ -293,10 +322,11 @@ evdev_process_relative(struct evdev_device *device, /* Scroll down */ case 1: /* Scroll up */ - notify_axis(device->seat, - time, - WL_POINTER_AXIS_VERTICAL_SCROLL, - -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); + pointer_notify_axis( + base, + time, + LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, + -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); break; default: break; @@ -309,10 +339,11 @@ evdev_process_relative(struct evdev_device *device, /* Scroll left */ case 1: /* Scroll right */ - notify_axis(device->seat, - time, - WL_POINTER_AXIS_HORIZONTAL_SCROLL, - e->value * DEFAULT_AXIS_STEP_DISTANCE); + pointer_notify_axis( + base, + time, + LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, + e->value * DEFAULT_AXIS_STEP_DISTANCE); break; default: break; @@ -395,18 +426,13 @@ evdev_process_events(struct evdev_device *device, } } -static int -evdev_device_data(int fd, uint32_t mask, void *data) +int +evdev_device_dispatch(struct evdev_device *device) { - struct weston_compositor *ec; - struct evdev_device *device = data; + int fd = device->fd; struct input_event ev[32]; int len; - ec = device->seat->compositor; - if (!ec->session_active) - return 1; - /* If the compositor is repainting, this function is called only once * per frame and we have to process all the events available on the * fd, otherwise there will be input lag. */ @@ -420,10 +446,8 @@ evdev_device_data(int fd, uint32_t mask, void *data) if (len < 0 || len % sizeof ev[0] != 0) { if (len < 0 && errno != EAGAIN && errno != EINTR) { - weston_log("device %s died\n", - device->devnode); - wl_event_source_remove(device->source); - device->source = NULL; + device->base.device_interface->device_lost( + device->base.device_interface_data); } return 1; @@ -462,8 +486,7 @@ evdev_handle_device(struct evdev_device *device) TEST_BIT(abs_bits, ABS_GAS) || TEST_BIT(abs_bits, ABS_BRAKE) || TEST_BIT(abs_bits, ABS_HAT0X)) { - weston_log("device %s is a joystick, ignoring\n", - device->devnode); + /* Device %s is a joystick, ignoring. */ return 0; } @@ -498,8 +521,7 @@ evdev_handle_device(struct evdev_device *device) if (!TEST_BIT(abs_bits, ABS_MT_SLOT)) { device->mtdev = mtdev_new_open(device->fd); if (!device->mtdev) { - weston_log("mtdev required but failed to open for %s\n", - device->devnode); + /* mtdev required but failed to open. */ return 0; } device->mt.slot = device->mtdev->caps.slot.value; @@ -524,8 +546,6 @@ evdev_handle_device(struct evdev_device *device) !TEST_BIT(key_bits, BTN_TOOL_PEN) && has_abs) { device->dispatch = evdev_touchpad_create(device); - weston_log("input device %s, %s is a touchpad\n", - device->devname, device->devnode); } for (i = KEY_ESC; i < KEY_MAX; i++) { if (i >= BTN_MISC && i < KEY_OK) @@ -554,9 +574,6 @@ evdev_handle_device(struct evdev_device *device) * want to adjust the protocol later adding a proper event for dealing * with accelerometers and implement here accordingly */ if (has_abs && !has_key && !device->is_mt) { - weston_log("input device %s, %s " - "ignored: unsupported device type\n", - device->devname, device->devnode); return 0; } @@ -568,58 +585,54 @@ evdev_configure_device(struct evdev_device *device) { if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL)) && (device->caps & EVDEV_BUTTON)) { - weston_seat_init_pointer(device->seat); + device->base.device_interface->register_capability( + LIBINPUT_SEAT_CAP_POINTER, + device->base.device_interface_data); device->seat_caps |= EVDEV_SEAT_POINTER; - weston_log("input device %s, %s is a pointer caps =%s%s%s\n", - device->devname, device->devnode, - device->caps & EVDEV_MOTION_ABS ? " absolute-motion" : "", - device->caps & EVDEV_MOTION_REL ? " relative-motion": "", - device->caps & EVDEV_BUTTON ? " button" : ""); } if ((device->caps & EVDEV_KEYBOARD)) { - if (weston_seat_init_keyboard(device->seat, NULL) < 0) - return -1; + device->base.device_interface->register_capability( + LIBINPUT_SEAT_CAP_KEYBOARD, + device->base.device_interface_data); device->seat_caps |= EVDEV_SEAT_KEYBOARD; - weston_log("input device %s, %s is a keyboard\n", - device->devname, device->devnode); } if ((device->caps & EVDEV_TOUCH)) { - weston_seat_init_touch(device->seat); + device->base.device_interface->register_capability( + LIBINPUT_SEAT_CAP_TOUCH, + device->base.device_interface_data); device->seat_caps |= EVDEV_SEAT_TOUCH; - weston_log("input device %s, %s is a touch device\n", - device->devname, device->devnode); } return 0; } -struct evdev_device * -evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) +LIBINPUT_EXPORT struct libinput_device * +libinput_device_create_evdev( + const char *devnode, + int fd, + const struct libinput_device_interface *device_interface, + void *user_data) { struct evdev_device *device; - struct weston_compositor *ec; char devname[256] = "unknown"; device = zalloc(sizeof *device); if (device == NULL) return NULL; - ec = seat->compositor; - device->output = - container_of(ec->output_list.next, struct weston_output, link); + device->base.device_interface = device_interface; + device->base.device_interface_data = user_data; - device->seat = seat; device->seat_caps = 0; device->is_mt = 0; device->mtdev = NULL; - device->devnode = strdup(path); + device->devnode = strdup(devnode); device->mt.slot = -1; device->rel.dx = 0; device->rel.dy = 0; device->dispatch = NULL; - device->fd = device_fd; + device->fd = fd; device->pending_event = EVDEV_NONE; - wl_list_init(&device->link); ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname); devname[sizeof(devname) - 1] = '\0'; @@ -627,7 +640,7 @@ evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) if (!evdev_handle_device(device)) { evdev_device_destroy(device); - return EVDEV_UNHANDLED_DEVICE; + return NULL; } if (evdev_configure_device(device) == -1) @@ -639,38 +652,52 @@ evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) if (device->dispatch == NULL) goto err; - device->source = wl_event_loop_add_fd(ec->input_loop, device->fd, - WL_EVENT_READABLE, - evdev_device_data, device); - if (device->source == NULL) - goto err; - - return device; + return &device->base; err: evdev_device_destroy(device); return NULL; } +int +evdev_device_get_keys(struct evdev_device *device, char *keys, size_t size) +{ + memset(keys, 0, size); + return ioctl(device->fd, EVIOCGKEY(size), keys); +} + +void +evdev_device_calibrate(struct evdev_device *device, float calibration[6]) +{ + device->abs.apply_calibration = 1; + memcpy(device->abs.calibration, calibration, sizeof calibration); +} + void evdev_device_destroy(struct evdev_device *device) { struct evdev_dispatch *dispatch; - if (device->seat_caps & EVDEV_SEAT_POINTER) - weston_seat_release_pointer(device->seat); - if (device->seat_caps & EVDEV_SEAT_KEYBOARD) - weston_seat_release_keyboard(device->seat); - if (device->seat_caps & EVDEV_SEAT_TOUCH) - weston_seat_release_touch(device->seat); + if (device->seat_caps & EVDEV_SEAT_POINTER) { + device->base.device_interface->unregister_capability( + LIBINPUT_SEAT_CAP_POINTER, + device->base.device_interface_data); + } + if (device->seat_caps & EVDEV_SEAT_KEYBOARD) { + device->base.device_interface->unregister_capability( + LIBINPUT_SEAT_CAP_KEYBOARD, + device->base.device_interface_data); + } + if (device->seat_caps & EVDEV_SEAT_TOUCH) { + device->base.device_interface->unregister_capability( + LIBINPUT_SEAT_CAP_TOUCH, + device->base.device_interface_data); + } dispatch = device->dispatch; if (dispatch) dispatch->interface->destroy(dispatch); - if (device->source) - wl_event_source_remove(device->source); - wl_list_remove(&device->link); if (device->mtdev) mtdev_close_delete(device->mtdev); close(device->fd); @@ -678,46 +705,3 @@ evdev_device_destroy(struct evdev_device *device) free(device->devnode); free(device); } - -void -evdev_notify_keyboard_focus(struct weston_seat *seat, - struct wl_list *evdev_devices) -{ - struct evdev_device *device; - struct wl_array keys; - unsigned int i, set; - char evdev_keys[(KEY_CNT + 7) / 8]; - char all_keys[(KEY_CNT + 7) / 8]; - uint32_t *k; - int ret; - - if (!seat->keyboard_device_count > 0) - return; - - memset(all_keys, 0, sizeof all_keys); - wl_list_for_each(device, evdev_devices, link) { - memset(evdev_keys, 0, sizeof evdev_keys); - ret = ioctl(device->fd, - EVIOCGKEY(sizeof evdev_keys), evdev_keys); - if (ret < 0) { - weston_log("failed to get keys for device %s\n", - device->devnode); - continue; - } - for (i = 0; i < ARRAY_LENGTH(evdev_keys); i++) - all_keys[i] |= evdev_keys[i]; - } - - wl_array_init(&keys); - for (i = 0; i < KEY_CNT; i++) { - set = all_keys[i >> 3] & (1 << (i & 7)); - if (set) { - k = wl_array_add(&keys, sizeof *k); - *k = i; - } - } - - notify_keyboard_focus_in(seat, &keys, STATE_UPDATE_AUTOMATIC); - - wl_array_release(&keys); -} diff --git a/src/evdev.h b/src/evdev.h index e146d1a4..5efb5369 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -1,5 +1,6 @@ /* * Copyright © 2011, 2012 Intel Corporation + * Copyright © 2013 Jonas Ådahl * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided @@ -26,7 +27,15 @@ #include "config.h" #include -#include + +#include "evdev.h" +#include "libinput-private.h" + +static inline void * +zalloc(size_t size) +{ + return calloc(1, size); +} #define MAX_SLOTS 16 @@ -56,10 +65,8 @@ enum evdev_device_seat_capability { }; struct evdev_device { - struct weston_seat *seat; - struct wl_list link; - struct wl_event_source *source; - struct weston_output *output; + struct libinput_device base; + struct evdev_dispatch *dispatch; char *devnode; char *devname; @@ -81,7 +88,7 @@ struct evdev_device { struct mtdev *mtdev; struct { - wl_fixed_t dx, dy; + li_fixed_t dx, dy; } rel; enum evdev_event_type pending_event; @@ -123,17 +130,19 @@ struct evdev_dispatch { struct evdev_dispatch * evdev_touchpad_create(struct evdev_device *device); +int +evdev_device_dispatch(struct evdev_device *device); + void -evdev_led_update(struct evdev_device *device, enum weston_led leds); +evdev_device_led_update(struct evdev_device *device, enum libinput_led leds); -struct evdev_device * -evdev_device_create(struct weston_seat *seat, const char *path, int device_fd); +int +evdev_device_get_keys(struct evdev_device *device, char *keys, size_t size); void -evdev_device_destroy(struct evdev_device *device); +evdev_device_calibrate(struct evdev_device *device, float calibration[6]); void -evdev_notify_keyboard_focus(struct weston_seat *seat, - struct wl_list *evdev_devices); +evdev_device_destroy(struct evdev_device *device); #endif /* EVDEV_H */ diff --git a/src/filter.c b/src/filter.c index 89237bf8..397e0f63 100644 --- a/src/filter.c +++ b/src/filter.c @@ -27,15 +27,12 @@ #include #include -#include - -#include "compositor.h" #include "filter.h" void -weston_filter_dispatch(struct weston_motion_filter *filter, - struct weston_motion_params *motion, - void *data, uint32_t time) +filter_dispatch(struct motion_filter *filter, + struct motion_params *motion, + void *data, uint32_t time) { filter->interface->filter(filter, motion, data, time); } @@ -57,7 +54,7 @@ struct pointer_tracker { struct pointer_accelerator; struct pointer_accelerator { - struct weston_motion_filter base; + struct motion_filter base; accel_profile_func_t profile; @@ -267,15 +264,15 @@ soften_delta(double last_delta, double delta) static void apply_softening(struct pointer_accelerator *accel, - struct weston_motion_params *motion) + struct motion_params *motion) { motion->dx = soften_delta(accel->last_dx, motion->dx); motion->dy = soften_delta(accel->last_dy, motion->dy); } static void -accelerator_filter(struct weston_motion_filter *filter, - struct weston_motion_params *motion, +accelerator_filter(struct motion_filter *filter, + struct motion_params *motion, void *data, uint32_t time) { struct pointer_accelerator *accel = @@ -299,7 +296,7 @@ accelerator_filter(struct weston_motion_filter *filter, } static void -accelerator_destroy(struct weston_motion_filter *filter) +accelerator_destroy(struct motion_filter *filter) { struct pointer_accelerator *accel = (struct pointer_accelerator *) filter; @@ -308,12 +305,12 @@ accelerator_destroy(struct weston_motion_filter *filter) free(accel); } -struct weston_motion_filter_interface accelerator_interface = { +struct motion_filter_interface accelerator_interface = { accelerator_filter, accelerator_destroy }; -struct weston_motion_filter * +struct motion_filter * create_pointer_accelator_filter(accel_profile_func_t profile) { struct pointer_accelerator *filter; diff --git a/src/filter.h b/src/filter.h index dad538b2..6b2a1d20 100644 --- a/src/filter.h +++ b/src/filter.h @@ -20,47 +20,43 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _FILTER_H_ -#define _FILTER_H_ +#ifndef FILTER_H +#define FILTER_H #include "config.h" -#include - -#include "compositor.h" - -struct weston_motion_params { +struct motion_params { double dx, dy; }; -struct weston_motion_filter; +struct motion_filter; -WL_EXPORT void -weston_filter_dispatch(struct weston_motion_filter *filter, - struct weston_motion_params *motion, - void *data, uint32_t time); +void +filter_dispatch(struct motion_filter *filter, + struct motion_params *motion, + void *data, uint32_t time); -struct weston_motion_filter_interface { - void (*filter)(struct weston_motion_filter *filter, - struct weston_motion_params *motion, +struct motion_filter_interface { + void (*filter)(struct motion_filter *filter, + struct motion_params *motion, void *data, uint32_t time); - void (*destroy)(struct weston_motion_filter *filter); + void (*destroy)(struct motion_filter *filter); }; -struct weston_motion_filter { - struct weston_motion_filter_interface *interface; +struct motion_filter { + struct motion_filter_interface *interface; }; -WL_EXPORT struct weston_motion_filter * +struct motion_filter * create_linear_acceleration_filter(double speed); -typedef double (*accel_profile_func_t)(struct weston_motion_filter *filter, +typedef double (*accel_profile_func_t)(struct motion_filter *filter, void *data, double velocity, uint32_t time); -WL_EXPORT struct weston_motion_filter * +struct motion_filter * create_pointer_accelator_filter(accel_profile_func_t filter); -#endif // _FILTER_H_ +#endif /* FILTER_H */ diff --git a/src/libinput-private.h b/src/libinput-private.h new file mode 100644 index 00000000..8a7970c8 --- /dev/null +++ b/src/libinput-private.h @@ -0,0 +1,102 @@ +/* + * Copyright © 2013 Jonas Ådahl + * + * 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 LIBINPUT_PRIVATE_H +#define LIBINPUT_PRIVATE_H + +#include "libinput.h" + +struct libinput_device { + const struct libinput_device_interface *device_interface; + void *device_interface_data; + + const struct libinput_keyboard_listener *keyboard_listener; + void *keyboard_listener_data; + + const struct libinput_pointer_listener *pointer_listener; + void *pointer_listener_data; + + const struct libinput_touch_listener *touch_listener; + void *touch_listener_data; +}; + +void +keyboard_notify_key(struct libinput_device *device, + uint32_t time, + uint32_t key, + enum libinput_keyboard_key_state state); + +void +pointer_notify_motion(struct libinput_device *device, + uint32_t time, + li_fixed_t dx, + li_fixed_t dy); + +void +pointer_notify_motion_absolute(struct libinput_device *device, + uint32_t time, + li_fixed_t x, + li_fixed_t y); + +void +pointer_notify_button(struct libinput_device *device, + uint32_t time, + int32_t button, + enum libinput_pointer_button_state state); + +void +pointer_notify_axis(struct libinput_device *device, + uint32_t time, + enum libinput_pointer_axis axis, + li_fixed_t value); + +void +touch_notify_touch(struct libinput_device *device, + uint32_t time, + int32_t slot, + li_fixed_t x, + li_fixed_t y, + enum libinput_touch_type touch_type); + +static inline li_fixed_t li_fixed_from_int(int i) +{ + return i * 256; +} + +static inline li_fixed_t +li_fixed_from_double(double d) +{ + union { + double d; + int64_t i; + } u; + + u.d = d + (3LL << (51 - 8)); + + return u.i; +} + +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) + +#define LIBINPUT_EXPORT __attribute__ ((visibility("default"))) + +#endif /* LIBINPUT_PRIVATE_H */ diff --git a/src/libinput-version.h.in b/src/libinput-version.h.in new file mode 100644 index 00000000..2b1c4ea2 --- /dev/null +++ b/src/libinput-version.h.in @@ -0,0 +1,31 @@ +/* + * Copyright © 2013 Jonas Ådahl + * + * 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 LIBINPUT_VERSION_H +#define LIBINPUT_VERSION_H + +#define LIBINPUT_VERSION_MAJOR @LIBINPUT_VERSION_MAJOR@ +#define LIBINPUT_VERSION_MINOR @LIBINPUT_VERSION_MINOR@ +#define LIBINPUT_VERSION_MICRO @LIBINPUT_VERSION_MICRO@ +#define LIBINPUT_VERSION "@LIBINPUT_VERSION@" + +#endif diff --git a/src/libinput.c b/src/libinput.c new file mode 100644 index 00000000..10baf265 --- /dev/null +++ b/src/libinput.c @@ -0,0 +1,168 @@ +/* + * Copyright © 2013 Jonas Ådahl + * + * 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 + +#include "libinput.h" +#include "evdev.h" +#include "libinput-private.h" + +void +keyboard_notify_key(struct libinput_device *device, + uint32_t time, + uint32_t key, + enum libinput_keyboard_key_state state) +{ + if (device->keyboard_listener) + device->keyboard_listener->notify_key( + time, key, state, + device->keyboard_listener_data); +} + +void +pointer_notify_motion(struct libinput_device *device, + uint32_t time, + li_fixed_t dx, + li_fixed_t dy) +{ + if (device->pointer_listener) + device->pointer_listener->notify_motion( + time, dx, dy, + device->pointer_listener_data); +} + +void +pointer_notify_motion_absolute(struct libinput_device *device, + uint32_t time, + li_fixed_t x, + li_fixed_t y) +{ + if (device->pointer_listener) + device->pointer_listener->notify_motion_absolute( + time, x, y, + device->pointer_listener_data); +} + +void +pointer_notify_button(struct libinput_device *device, + uint32_t time, + int32_t button, + enum libinput_pointer_button_state state) +{ + if (device->pointer_listener) + device->pointer_listener->notify_button( + time, button, state, + device->pointer_listener_data); +} + +void +pointer_notify_axis(struct libinput_device *device, + uint32_t time, + enum libinput_pointer_axis axis, + li_fixed_t value) +{ + if (device->pointer_listener) + device->pointer_listener->notify_axis( + time, axis, value, + device->pointer_listener_data); +} + +void +touch_notify_touch(struct libinput_device *device, + uint32_t time, + int32_t slot, + li_fixed_t x, + li_fixed_t y, + enum libinput_touch_type touch_type) +{ + if (device->touch_listener) + device->touch_listener->notify_touch( + time, slot, x, y, touch_type, + device->touch_listener_data); +} + +LIBINPUT_EXPORT void +libinput_device_set_keyboard_listener( + struct libinput_device *device, + const struct libinput_keyboard_listener *listener, + void *data) +{ + device->keyboard_listener = listener; + device->keyboard_listener_data = data; +} + +LIBINPUT_EXPORT void +libinput_device_set_pointer_listener( + struct libinput_device *device, + const struct libinput_pointer_listener *listener, + void *data) +{ + device->pointer_listener = listener; + device->pointer_listener_data = data; +} + +LIBINPUT_EXPORT void +libinput_device_set_touch_listener( + struct libinput_device *device, + const struct libinput_touch_listener *listener, + void *data) +{ + device->touch_listener = listener; + device->touch_listener_data = data; +} + +LIBINPUT_EXPORT int +libinput_device_dispatch(struct libinput_device *device) +{ + return evdev_device_dispatch((struct evdev_device *) device); +} + +LIBINPUT_EXPORT void +libinput_device_destroy(struct libinput_device *device) +{ + evdev_device_destroy((struct evdev_device *) device); +} + +LIBINPUT_EXPORT void +libinput_device_led_update(struct libinput_device *device, + enum libinput_led leds) +{ + evdev_device_led_update((struct evdev_device *) device, leds); +} + +LIBINPUT_EXPORT int +libinput_device_get_keys(struct libinput_device *device, + char *keys, size_t size) +{ + return evdev_device_get_keys((struct evdev_device *) device, + keys, + size); +} + +LIBINPUT_EXPORT void +libinput_device_calibrate(struct libinput_device *device, + float calibration[6]) +{ + evdev_device_calibrate((struct evdev_device *) device, calibration); +} diff --git a/src/libinput.h b/src/libinput.h new file mode 100644 index 00000000..6b1f3aff --- /dev/null +++ b/src/libinput.h @@ -0,0 +1,173 @@ +/* + * Copyright © 2013 Jonas Ådahl + * + * 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 LIBINPUT_H +#define LIBINPUT_H + +#include +#include + +typedef int32_t li_fixed_t; + +enum libinput_seat_capability { + LIBINPUT_SEAT_CAP_KEYBOARD = 0, + LIBINPUT_SEAT_CAP_POINTER = 1, + LIBINPUT_SEAT_CAP_TOUCH = 2, +}; + +enum libinput_keyboard_key_state { + LIBINPUT_KEYBOARD_KEY_STATE_RELEASED = 0, + LIBINPUT_KEYBOARD_KEY_STATE_PRESSED = 1, +}; + +enum libinput_led { + LIBINPUT_LED_NUM_LOCK = (1 << 0), + LIBINPUT_LED_CAPS_LOCK = (1 << 1), + LIBINPUT_LED_SCROLL_LOCK = (1 << 2), +}; + +enum libinput_pointer_button_state { + LIBINPUT_POINTER_BUTTON_STATE_RELEASED = 0, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED = 1, +}; + +enum libinput_pointer_axis { + LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL = 0, + LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL = 1, +}; + +enum libinput_touch_type { + LIBINPUT_TOUCH_TYPE_DOWN = 0, + LIBINPUT_TOUCH_TYPE_UP = 1, + LIBINPUT_TOUCH_TYPE_MOTION = 2, + LIBINPUT_TOUCH_TYPE_FRAME = 3, + LIBINPUT_TOUCH_TYPE_CANCEL = 4, +}; + +struct libinput_fd_handle; + +typedef void (*libinput_fd_callback)(int fd, void *data); + +struct libinput_device_interface { + /* */ + void (*register_capability)(enum libinput_seat_capability capability, + void *data); + void (*unregister_capability)(enum libinput_seat_capability capability, + void *data); + + /* */ + void (*get_current_screen_dimensions)(int *width, + int *height, + void *data); + + /* */ + struct libinput_fd_handle * (*add_fd)(int fd, + libinput_fd_callback callback, + void *data); + void (*remove_fd)(struct libinput_fd_handle *fd_container, + void *data); + + /* */ + void (*device_lost)(void *data); +}; + +struct libinput_keyboard_listener { + void (*notify_key)(uint32_t time, + uint32_t key, + enum libinput_keyboard_key_state state, + void *data); +}; + +struct libinput_pointer_listener { + void (*notify_motion)(uint32_t time, + li_fixed_t dx, + li_fixed_t dy, + void *data); + void (*notify_motion_absolute)(uint32_t time, + li_fixed_t x, + li_fixed_t y, + void *data); + void (*notify_button)(uint32_t time, + int32_t button, + enum libinput_pointer_button_state state, + void *data); + void (*notify_axis)(uint32_t time, + enum libinput_pointer_axis axis, + li_fixed_t value, + void *data); +}; + +struct libinput_touch_listener { + void (*notify_touch)(uint32_t time, + int32_t slot, + li_fixed_t x, + li_fixed_t y, + enum libinput_touch_type touch_type, + void *data); +}; + +struct libinput_seat; +struct libinput_device; + +struct libinput_device * +libinput_device_create_evdev(const char *devnode, + int fd, + const struct libinput_device_interface *interface, + void *user_data); + +void +libinput_device_set_keyboard_listener( + struct libinput_device *device, + const struct libinput_keyboard_listener *listener, + void *data); + +void +libinput_device_set_pointer_listener( + struct libinput_device *device, + const struct libinput_pointer_listener *listener, + void *data); + +void +libinput_device_set_touch_listener( + struct libinput_device *device, + const struct libinput_touch_listener *listener, + void *data); + +int +libinput_device_dispatch(struct libinput_device *device); + +void +libinput_device_destroy(struct libinput_device *device); + +void +libinput_device_led_update(struct libinput_device *device, + enum libinput_led leds); + +int +libinput_device_get_keys(struct libinput_device *device, + char *keys, size_t size); + +void +libinput_device_calibrate(struct libinput_device *device, + float calibration[6]); + +#endif /* LIBINPUT_H */ diff --git a/src/libinput.pc.in b/src/libinput.pc.in new file mode 100644 index 00000000..ed51acc9 --- /dev/null +++ b/src/libinput.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +datarootdir=@datarootdir@ +pkgdatadir=@datadir@/@PACKAGE@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Libinput +Description: Input device library +Version: @LIBINPUT_VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -linput -- cgit v1.2.3