summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore26
-rw-r--r--Makefile.am3
-rw-r--r--README9
-rwxr-xr-xautogen.sh9
-rw-r--r--configure.ac53
-rw-r--r--m4/.gitignore5
-rw-r--r--src/Makefile.am26
-rw-r--r--src/evdev-touchpad.c215
-rw-r--r--src/evdev.c342
-rw-r--r--src/evdev.h33
-rw-r--r--src/filter.c23
-rw-r--r--src/filter.h40
-rw-r--r--src/libinput-private.h102
-rw-r--r--src/libinput-version.h.in31
-rw-r--r--src/libinput.c168
-rw-r--r--src/libinput.h173
-rw-r--r--src/libinput.pc.in12
17 files changed, 955 insertions, 315 deletions
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 <sys/timerfd.h>]])
+AC_CHECK_DECL(CLOCK_MONOTONIC,[],
+ [AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile libinput")],
+ [[#include <time.h>]])
+
+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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
+#include <time.h>
#include <unistd.h>
#include <linux/input.h>
+#include <sys/timerfd.h>
-#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 <mtdev.h>
#include <assert.h>
-#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 <linux/input.h>
-#include <wayland-util.h>
+
+#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 <limits.h>
#include <math.h>
-#include <wayland-util.h>
-
-#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 <wayland-util.h>
-
-#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 <stdlib.h>
+
+#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 <stdlib.h>
+#include <stdint.h>
+
+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