commit c617c3751ff65b7be847c70e8c01c1b6f26cce1f
parent 94322e53bbd2f827f5c3733812381ef698e0aeac
Author: Michael Forney <mforney@mforney.org>
Date: Thu, 29 Dec 2016 20:34:34 -0800
Handle absolute pointer devices
Diffstat:
5 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/libswc/evdev_device.c b/libswc/evdev_device.c
@@ -95,8 +95,18 @@ handle_rel_event(struct evdev_device *device, struct input_event *ev)
}
static void
-handle_abs_event(struct evdev_device *device, struct input_event *input_event)
+handle_abs_event(struct evdev_device *device, struct input_event *ev)
{
+ switch (ev->code) {
+ case ABS_X:
+ device->abs.x = ev->value;
+ device->abs.pending = true;
+ break;
+ case ABS_Y:
+ device->abs.y = ev->value;
+ device->abs.pending = true;
+ break;
+ }
}
static void (*event_handlers[])(struct evdev_device *device, struct input_event *ev) = {
@@ -115,6 +125,15 @@ is_motion_event(struct input_event *ev)
static void
handle_motion_events(struct evdev_device *device, uint32_t time)
{
+ if (device->abs.pending) {
+ int32_t x = device->abs.x - device->abs.info.x->minimum;
+ int32_t max_x = device->abs.info.x->maximum - device->abs.info.x->minimum;
+ int32_t y = device->abs.y - device->abs.info.y->minimum;
+ int32_t max_y = device->abs.info.y->maximum - device->abs.info.y->minimum;
+
+ device->handler->absolute_motion(time, x, max_x, y, max_y);
+ device->abs.pending = false;
+ }
if (device->rel.pending) {
wl_fixed_t dx = wl_fixed_from_int(device->rel.dx);
wl_fixed_t dy = wl_fixed_from_int(device->rel.dy);
@@ -221,6 +240,9 @@ evdev_device_new(const char *path, const struct evdev_device_handler *handler)
device->needs_sync = false;
device->handler = handler;
device->capabilities = 0;
+ device->abs.info.x = libevdev_get_abs_info(device->dev, ABS_X);
+ device->abs.info.y = libevdev_get_abs_info(device->dev, ABS_Y);
+ device->abs.pending = false;
memset(&device->rel, 0, sizeof(device->rel));
if (libevdev_has_event_code(device->dev, EV_KEY, KEY_ENTER)) {
@@ -236,6 +258,14 @@ evdev_device_new(const char *path, const struct evdev_device_handler *handler)
DEBUG("\tThis device is a pointer\n");
}
+ if (libevdev_has_event_code(device->dev, EV_ABS, ABS_X)
+ && libevdev_has_event_code(device->dev, EV_ABS, ABS_Y)
+ && libevdev_has_event_code(device->dev, EV_KEY, BTN_MOUSE)
+ && !libevdev_has_event_code(device->dev, EV_KEY, BTN_TOOL_FINGER))
+ {
+ device->capabilities |= WL_SEAT_CAPABILITY_POINTER;
+ }
+
/* XXX: touch devices */
return device;
diff --git a/libswc/evdev_device.h b/libswc/evdev_device.h
@@ -40,6 +40,7 @@ struct evdev_device_handler {
void (*button)(uint32_t time, uint32_t key, uint32_t state);
void (*axis)(uint32_t time, uint32_t axis, wl_fixed_t amount);
void (*relative_motion)(uint32_t time, wl_fixed_t dx, wl_fixed_t dy);
+ void (*absolute_motion)(uint32_t time, int32_t x, int32_t y, int32_t max_x, int32_t max_y);
};
struct evdev_device {
@@ -52,7 +53,7 @@ struct evdev_device {
struct {
struct {
- struct input_absinfo x, y;
+ const struct input_absinfo *x, *y;
} info;
int32_t x, y;
diff --git a/libswc/pointer.c b/libswc/pointer.c
@@ -404,9 +404,15 @@ pointer_handle_axis(struct pointer *pointer, uint32_t time, uint32_t axis, wl_fi
void
pointer_handle_relative_motion(struct pointer *pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
{
+ pointer_handle_absolute_motion(pointer, time, pointer->x + dx, pointer->y + dy);
+}
+
+void
+pointer_handle_absolute_motion(struct pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
struct pointer_handler *handler;
- clip_position(pointer, pointer->x + dx, pointer->y + dy);
+ clip_position(pointer, x, y);
wl_list_for_each (handler, &pointer->handlers, link) {
if (handler->motion && handler->motion(handler, time, pointer->x, pointer->y))
diff --git a/libswc/pointer.h b/libswc/pointer.h
@@ -81,5 +81,6 @@ struct wl_resource *pointer_bind(struct pointer *pointer, struct wl_client *clie
void pointer_handle_button(struct pointer *pointer, uint32_t time, uint32_t button, uint32_t state);
void pointer_handle_axis(struct pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t amount);
void pointer_handle_relative_motion(struct pointer *pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy);
+void pointer_handle_absolute_motion(struct pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y);
#endif
diff --git a/libswc/seat.c b/libswc/seat.c
@@ -30,6 +30,7 @@
#include "keyboard.h"
#include "launch.h"
#include "pointer.h"
+#include "screen.h"
#include "surface.h"
#include "util.h"
@@ -97,6 +98,17 @@ handle_relative_motion(uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
}
static void
+handle_absolute_motion(uint32_t time, int32_t x, int32_t max_x, int32_t y, int32_t max_y)
+{
+ struct screen *screen = wl_container_of(swc.screens.next, screen, link);
+ struct swc_rectangle *rect = &screen->base.geometry;
+ wl_fixed_t fx = wl_fixed_from_int(x * rect->width / max_x + rect->x);
+ wl_fixed_t fy = wl_fixed_from_int(y * rect->height / max_y + rect->y);
+
+ pointer_handle_absolute_motion(&seat.pointer, time, fx, fy);
+}
+
+static void
handle_keyboard_focus_event(struct wl_listener *listener, void *data)
{
struct event *ev = data;
@@ -390,6 +402,7 @@ const static struct evdev_device_handler evdev_handler = {
.button = handle_button,
.axis = handle_axis,
.relative_motion = handle_relative_motion,
+ .absolute_motion = handle_absolute_motion,
};
static void