Commit 823ad33e authored by Peter Hutterer's avatar Peter Hutterer Committed by Pekka Paalanen

compositor: Drop legacy backends in favor of libinput

Reviewed-by: Pekka Paalanen's avatarPekka Paalanen <pekka.paalanen@collabora.co.uk>
parent a4bac9e0
......@@ -184,25 +184,12 @@ x11_backend_la_CFLAGS = \
x11_backend_la_SOURCES = src/compositor-x11.c
endif
INPUT_BACKEND_SOURCES = src/udev-input.h
if ENABLE_LIBINPUT_BACKEND
INPUT_BACKEND_LIBS = $(LIBINPUT_BACKEND_LIBS)
INPUT_BACKEND_SOURCES += \
INPUT_BACKEND_SOURCES = \
src/libinput-seat.c \
src/libinput-seat.h \
src/libinput-device.c \
src/libinput-device.h
else
INPUT_BACKEND_SOURCES += \
src/filter.c \
src/filter.h \
src/udev-seat.c \
src/udev-seat.h \
src/evdev.c \
src/evdev.h \
src/evdev-touchpad.c
endif
if ENABLE_DRM_COMPOSITOR
module_LTLIBRARIES += drm-backend.la
......
......@@ -155,15 +155,7 @@ if test x$enable_drm_compositor = xyes; then
fi
AC_ARG_ENABLE(libinput-backend, [ --disable-libinput-backend],,
enable_libinput_backend=yes)
AM_CONDITIONAL([ENABLE_LIBINPUT_BACKEND], [test x$enable_libinput_backend = xyes])
if test x$enable_libinput_backend = xyes; then
AC_DEFINE([BUILD_LIBINPUT_BACKEND], [1], [Build the libinput input device backend])
PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.6.0])
fi
PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.6.0])
PKG_CHECK_MODULES(COMPOSITOR, [$COMPOSITOR_MODULES])
AC_ARG_ENABLE(wayland-compositor, [ --enable-wayland-compositor],,
......
......@@ -47,7 +47,7 @@
#include "compositor.h"
#include "gl-renderer.h"
#include "pixman-renderer.h"
#include "udev-input.h"
#include "libinput-seat.h"
#include "launcher-util.h"
#include "vaapi-recorder.h"
......
......@@ -42,7 +42,7 @@
#include "compositor.h"
#include "launcher-util.h"
#include "pixman-renderer.h"
#include "udev-input.h"
#include "libinput-seat.h"
#include "gl-renderer.h"
struct fbdev_compositor {
......
......@@ -46,7 +46,7 @@
#include "compositor.h"
#include "rpi-renderer.h"
#include "launcher-util.h"
#include "udev-input.h"
#include "libinput-seat.h"
#if 0
#define DBG(...) \
......
This diff is collapsed.
This diff is collapsed.
/*
* Copyright © 2011, 2012 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef EVDEV_H
#define EVDEV_H
#include "config.h"
#include <linux/input.h>
#include <wayland-util.h>
#define MAX_SLOTS 16
enum evdev_event_type {
EVDEV_NONE,
EVDEV_ABSOLUTE_TOUCH_DOWN,
EVDEV_ABSOLUTE_MOTION,
EVDEV_ABSOLUTE_TOUCH_UP,
EVDEV_ABSOLUTE_MT_DOWN,
EVDEV_ABSOLUTE_MT_MOTION,
EVDEV_ABSOLUTE_MT_UP,
EVDEV_RELATIVE_MOTION,
};
enum evdev_device_seat_capability {
EVDEV_SEAT_POINTER = (1 << 0),
EVDEV_SEAT_KEYBOARD = (1 << 1),
EVDEV_SEAT_TOUCH = (1 << 2)
};
struct evdev_device {
struct weston_seat *seat;
struct wl_list link;
struct wl_event_source *source;
struct weston_output *output;
struct evdev_dispatch *dispatch;
struct wl_listener output_destroy_listener;
char *devnode;
char *devname;
char *output_name;
int fd;
struct {
int min_x, max_x, min_y, max_y;
uint32_t seat_slot;
int32_t x, y;
int apply_calibration;
float calibration[6];
} abs;
struct {
int slot;
struct {
int32_t x, y;
uint32_t seat_slot;
} slots[MAX_SLOTS];
} mt;
struct mtdev *mtdev;
struct {
wl_fixed_t dx, dy;
} rel;
enum evdev_event_type pending_event;
enum evdev_device_seat_capability seat_caps;
int is_mt;
};
/* copied from udev/extras/input_id/input_id.c */
/* we must use this kernel-compatible implementation */
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1)
/* end copied */
#define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
struct evdev_dispatch;
struct evdev_dispatch_interface {
/* Process an evdev input event. */
void (*process)(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct input_event *event,
uint32_t time);
/* Destroy an event dispatch handler and free all its resources. */
void (*destroy)(struct evdev_dispatch *dispatch);
};
struct evdev_dispatch {
struct evdev_dispatch_interface *interface;
};
struct evdev_dispatch *
evdev_touchpad_create(struct evdev_device *device);
void
evdev_led_update(struct evdev_device *device, enum weston_led leds);
struct evdev_device *
evdev_device_create(struct weston_seat *seat, const char *path, int device_fd);
void
evdev_device_set_output(struct evdev_device *device,
struct weston_output *output);
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 */
/*
* Copyright © 2012 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 <stdint.h>
#include <limits.h>
#include <math.h>
#include <wayland-util.h>
#include "compositor.h"
#include "filter.h"
WL_EXPORT void
weston_filter_dispatch(struct weston_motion_filter *filter,
struct weston_motion_params *motion,
void *data, uint32_t time)
{
filter->interface->filter(filter, motion, data, time);
}
/*
* Pointer acceleration filter
*/
#define MAX_VELOCITY_DIFF 1.0
#define MOTION_TIMEOUT 300 /* (ms) */
#define NUM_POINTER_TRACKERS 16
struct pointer_tracker {
double dx;
double dy;
uint32_t time;
int dir;
};
struct pointer_accelerator;
struct pointer_accelerator {
struct weston_motion_filter base;
accel_profile_func_t profile;
double velocity;
double last_velocity;
int last_dx;
int last_dy;
struct pointer_tracker *trackers;
int cur_tracker;
};
enum directions {
N = 1 << 0,
NE = 1 << 1,
E = 1 << 2,
SE = 1 << 3,
S = 1 << 4,
SW = 1 << 5,
W = 1 << 6,
NW = 1 << 7,
UNDEFINED_DIRECTION = 0xff
};
static int
get_direction(int dx, int dy)
{
int dir = UNDEFINED_DIRECTION;
int d1, d2;
double r;
if (abs(dx) < 2 && abs(dy) < 2) {
if (dx > 0 && dy > 0)
dir = S | SE | E;
else if (dx > 0 && dy < 0)
dir = N | NE | E;
else if (dx < 0 && dy > 0)
dir = S | SW | W;
else if (dx < 0 && dy < 0)
dir = N | NW | W;
else if (dx > 0)
dir = NW | W | SW;
else if (dx < 0)
dir = NE | E | SE;
else if (dy > 0)
dir = SE | S | SW;
else if (dy < 0)
dir = NE | N | NW;
}
else {
/* Calculate r within the interval [0 to 8)
*
* r = [0 .. 2π] where 0 is North
* d_f = r / 2π ([0 .. 1))
* d_8 = 8 * d_f
*/
r = atan2(dy, dx);
r = fmod(r + 2.5*M_PI, 2*M_PI);
r *= 4*M_1_PI;
/* Mark one or two close enough octants */
d1 = (int)(r + 0.9) % 8;
d2 = (int)(r + 0.1) % 8;
dir = (1 << d1) | (1 << d2);
}
return dir;
}
static void
feed_trackers(struct pointer_accelerator *accel,
double dx, double dy,
uint32_t time)
{
int i, current;
struct pointer_tracker *trackers = accel->trackers;
for (i = 0; i < NUM_POINTER_TRACKERS; i++) {
trackers[i].dx += dx;
trackers[i].dy += dy;
}
current = (accel->cur_tracker + 1) % NUM_POINTER_TRACKERS;
accel->cur_tracker = current;
trackers[current].dx = 0.0;
trackers[current].dy = 0.0;
trackers[current].time = time;
trackers[current].dir = get_direction(dx, dy);
}
static struct pointer_tracker *
tracker_by_offset(struct pointer_accelerator *accel, unsigned int offset)
{
unsigned int index =
(accel->cur_tracker + NUM_POINTER_TRACKERS - offset)
% NUM_POINTER_TRACKERS;
return &accel->trackers[index];
}
static double
calculate_tracker_velocity(struct pointer_tracker *tracker, uint32_t time)
{
int dx;
int dy;
double distance;
dx = tracker->dx;
dy = tracker->dy;
distance = sqrt(dx*dx + dy*dy);
return distance / (double)(time - tracker->time);
}
static double
calculate_velocity(struct pointer_accelerator *accel, uint32_t time)
{
struct pointer_tracker *tracker;
double velocity;
double result = 0.0;
double initial_velocity;
double velocity_diff;
unsigned int offset;
unsigned int dir = tracker_by_offset(accel, 0)->dir;
/* Find first velocity */
for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
tracker = tracker_by_offset(accel, offset);
if (time <= tracker->time)
continue;
result = initial_velocity =
calculate_tracker_velocity(tracker, time);
if (initial_velocity > 0.0)
break;
}
/* Find least recent vector within a timelimit, maximum velocity diff
* and direction threshold. */
for (; offset < NUM_POINTER_TRACKERS; offset++) {
tracker = tracker_by_offset(accel, offset);
/* Stop if too far away in time */
if (time - tracker->time > MOTION_TIMEOUT ||
tracker->time > time)
break;
/* Stop if direction changed */
dir &= tracker->dir;
if (dir == 0)
break;
velocity = calculate_tracker_velocity(tracker, time);
/* Stop if velocity differs too much from initial */
velocity_diff = fabs(initial_velocity - velocity);
if (velocity_diff > MAX_VELOCITY_DIFF)
break;
result = velocity;
}
return result;
}
static double
acceleration_profile(struct pointer_accelerator *accel,
void *data, double velocity, uint32_t time)
{
return accel->profile(&accel->base, data, velocity, time);
}
static double
calculate_acceleration(struct pointer_accelerator *accel,
void *data, double velocity, uint32_t time)
{
double factor;
/* Use Simpson's rule to calculate the avarage acceleration between
* the previous motion and the most recent. */
factor = acceleration_profile(accel, data, velocity, time);
factor += acceleration_profile(accel, data, accel->last_velocity, time);
factor += 4.0 *
acceleration_profile(accel, data,
(accel->last_velocity + velocity) / 2,
time);
factor = factor / 6.0;
return factor;
}
static double
soften_delta(double last_delta, double delta)
{
if (delta < -1.0 || delta > 1.0) {
if (delta > last_delta)
return delta - 0.5;
else if (delta < last_delta)
return delta + 0.5;
}
return delta;
}
static void
apply_softening(struct pointer_accelerator *accel,
struct weston_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,
void *data, uint32_t time)
{
struct pointer_accelerator *accel =
(struct pointer_accelerator *) filter;
double velocity;
double accel_value;
feed_trackers(accel, motion->dx, motion->dy, time);
velocity = calculate_velocity(accel, time);
accel_value = calculate_acceleration(accel, data, velocity, time);
motion->dx = accel_value * motion->dx;
motion->dy = accel_value * motion->dy;
apply_softening(accel, motion);
accel->last_dx = motion->dx;
accel->last_dy = motion->dy;
accel->last_velocity = velocity;
}
static void
accelerator_destroy(struct weston_motion_filter *filter)
{
struct pointer_accelerator *accel =
(struct pointer_accelerator *) filter;
free(accel->trackers);
free(accel);
}
struct weston_motion_filter_interface accelerator_interface = {
accelerator_filter,
accelerator_destroy
};
WL_EXPORT struct weston_motion_filter *
create_pointer_accelator_filter(accel_profile_func_t profile)
{
struct pointer_accelerator *filter;
filter = malloc(sizeof *filter);
if (filter == NULL)
return NULL;
filter->base.interface = &accelerator_interface;
filter->profile = profile;
filter->last_velocity = 0.0;
filter->last_dx = 0;
filter->last_dy = 0;
filter->trackers =
calloc(NUM_POINTER_TRACKERS, sizeof *filter->trackers);
filter->cur_tracker = 0;
return &filter->base;
}
/*
* Copyright © 2012 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 _FILTER_H_
#define _FILTER_H_
#include "config.h"
#include <wayland-util.h>
#include "compositor.h"
struct weston_motion_params {
double dx, dy;
};
struct weston_motion_filter;
void
weston_filter_dispatch(struct weston_motion_filter *filter,
struct weston_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);
};
struct weston_motion_filter {
struct weston_motion_filter_interface *interface;
};
typedef double (*accel_profile_func_t)(struct weston_motion_filter *filter,
void *data,
double velocity,
uint32_t time);
struct weston_motion_filter *
create_pointer_accelator_filter(accel_profile_func_t filter);
#endif // _FILTER_H_
/*
* Copyright © 2014 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 _UDEV_INPUT_H_
#define _UDEV_INPUT_H_
#include "config.h"
#ifdef BUILD_LIBINPUT_BACKEND
#include "libinput-seat.h"
#else
#include "udev-seat.h"
#endif
#endif
This diff is collapsed.
/*
* Copyright © 2013 Intel Corporation
*
* 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 _UDEV_SEAT_H_
#define _UDEV_SEAT_H_
#include "config.h"
#include <libudev.h>
#include "compositor.h"
struct udev_seat {
struct weston_seat base;
struct wl_list devices_list;
struct wl_listener output_create_listener;
};
struct udev_input {
struct udev *udev;
struct udev_monitor *udev_monitor;
struct wl_event_source *udev_monitor_source;
char *seat_id;
struct weston_compositor *compositor;
int enabled;
};
int udev_input_enable(struct udev_input *input);
void udev_input_disable(struct udev_input *input);
int udev_input_init(struct udev_input *input,
struct weston_compositor *c,
struct udev *udev,
const char *seat_id);
void udev_input_destroy(struct udev_input *input);
struct udev_seat *udev_seat_get_named(struct udev_input *input,
const char *seat_name);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment