summaryrefslogtreecommitdiff
path: root/src/evdev-touchpad.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evdev-touchpad.c')
-rw-r--r--src/evdev-touchpad.c215
1 files changed, 126 insertions, 89 deletions
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;
}