Port evdev code to be used as a shared library

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 <jadahl@gmail.com>
This commit is contained in:
Jonas Ådahl 2013-11-10 17:55:40 +01:00
parent fdf50bc34b
commit bd4db1c2a2
17 changed files with 961 additions and 321 deletions

26
.gitignore vendored Normal file
View file

@ -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

3
Makefile.am Normal file
View file

@ -0,0 +1,3 @@
SUBDIRS = src
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}

9
README Normal file
View file

@ -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.

9
autogen.sh Executable file
View file

@ -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" "$@"

53
configure.ac Normal file
View file

@ -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

5
m4/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4

26
src/Makefile.am Normal file
View file

@ -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

View file

@ -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;
}
static int
fsm_timout_handler(void *data)
{
struct touchpad_dispatch *touchpad = data;
if (touchpad->fsm.events.size == 0) {
push_fsm_event(touchpad, FSM_EVENT_TIMEOUT);
process_fsm_events(touchpad, weston_compositor_get_time());
touchpad->fsm.events = events;
touchpad->fsm.events_len = new_len;
}
return 1;
touchpad->fsm.events[touchpad->fsm.events_count++] = event;
}
static void
fsm_timeout_handler(int fd, void *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;
push_fsm_event(touchpad, FSM_EVENT_TIMEOUT);
process_fsm_events(touchpad, now);
}
}
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;
}

View file

@ -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];
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];
}
*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);
}

View file

@ -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);
void
evdev_led_update(struct evdev_device *device, enum weston_led leds);
int
evdev_device_dispatch(struct evdev_device *device);
struct evdev_device *
evdev_device_create(struct weston_seat *seat, const char *path, int device_fd);
void
evdev_device_led_update(struct evdev_device *device, enum libinput_led leds);
int
evdev_device_get_keys(struct evdev_device *device, char *keys, size_t size);
void
evdev_device_calibrate(struct evdev_device *device, float calibration[6]);
void
evdev_device_destroy(struct evdev_device *device);
void
evdev_notify_keyboard_focus(struct weston_seat *seat,
struct wl_list *evdev_devices);
#endif /* EVDEV_H */

View file

@ -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;

View file

@ -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
filter_dispatch(struct motion_filter *filter,
struct motion_params *motion,
void *data, uint32_t time);
struct motion_filter_interface {
void (*filter)(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,
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 */

102
src/libinput-private.h Normal file
View file

@ -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 */

31
src/libinput-version.h.in Normal file
View file

@ -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

168
src/libinput.c Normal file
View file

@ -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);
}

173
src/libinput.h Normal file
View file

@ -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 */

12
src/libinput.pc.in Normal file
View file

@ -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