commit acec51090e74b672ed4489ad1bcaa6ba6264eae6
parent bba112e9c73e713d938cf512fa7a7232650df24a
Author: Michael Forney <mforney@mforney.org>
Date: Sat, 11 Mar 2017 14:42:29 -0800
Make libinput a hard dependency
I am not interested in maintaining the direct evdev device handling, nor
implementing touchpad support. However, libinput has a hard libudev
dependency, even with the path-seat.
To resolve this, I branched libinput to remove the libinput dependency,
and made libinput a hard dependency in swc. Now, ENABLE_LIBINPUT
controls whether or not device hotplugging should be supported,
otherwise path-seat is used.
Diffstat:
6 files changed, 95 insertions(+), 587 deletions(-)
diff --git a/README.md b/README.md
@@ -14,14 +14,14 @@ Dependencies
* wayland
* wayland-protocols
* libdrm
-* libevdev
+* libinput (see my [libinput repository](https://github.com/michaelforney/libinput)
+ if you don't want the libudev dependency)
* libxkbcommon
* pixman
* [wld](http://github.com/michaelforney/wld)
* linux\[>=3.12\] (for EVIOCREVOKE)
-For input hotplugging and touchpad support, the following is also required:
-* libinput
+For input hotplugging, the following is also required:
* libudev
For XWayland support, the following are also required:
diff --git a/config.mk b/config.mk
@@ -18,6 +18,6 @@ CFLAGS = -pipe
ENABLE_DEBUG = 1
ENABLE_STATIC = 1
ENABLE_SHARED = 1
-ENABLE_LIBINPUT = 1
+ENABLE_LIBUDEV = 1
ENABLE_XWAYLAND = 1
diff --git a/libswc/evdev_device.c b/libswc/evdev_device.c
@@ -1,355 +0,0 @@
-/* swc: libswc/evdev_device.c
- *
- * Copyright (c) 2013, 2014 Michael Forney
- *
- * Based in part upon evdev.c from weston, which is:
- *
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "evdev_device.h"
-#include "event.h"
-#include "internal.h"
-#include "launch.h"
-#include "seat.h"
-#include "util.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <libevdev/libevdev.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#define AXIS_STEP_DISTANCE 10
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-static inline uint32_t
-timeval_to_msec(struct timeval *time)
-{
- return time->tv_sec * 1000 + time->tv_usec / 1000;
-}
-
-static void
-handle_key_event(struct evdev_device *device, struct input_event *ev)
-{
- uint32_t time = timeval_to_msec(&ev->time);
- uint32_t state;
-
- if ((ev->code >= BTN_MISC && ev->code <= BTN_GEAR_UP) || ev->code >= BTN_TRIGGER_HAPPY) {
- state = ev->value ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED;
- device->handler->button(time, ev->code, state);
- if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
- /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so
- * pass those through as axis events. */
- switch (ev->code) {
- case BTN_GEAR_DOWN:
- device->handler->axis(time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(AXIS_STEP_DISTANCE));
- break;
- case BTN_GEAR_UP:
- device->handler->axis(time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-AXIS_STEP_DISTANCE));
- break;
- }
- }
- } else {
- state = ev->value ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
- device->handler->key(time, ev->code, state);
- }
-}
-
-static void
-handle_rel_event(struct evdev_device *device, struct input_event *ev)
-{
- uint32_t time = timeval_to_msec(&ev->time);
- uint32_t axis, amount;
-
- if (!(device->capabilities & WL_SEAT_CAPABILITY_POINTER))
- return;
-
- switch (ev->code) {
- case REL_X:
- device->rel.dx += ev->value;
- device->rel.pending = true;
- return;
- case REL_Y:
- device->rel.dy += ev->value;
- device->rel.pending = true;
- return;
- case REL_WHEEL:
- axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
- amount = -AXIS_STEP_DISTANCE * wl_fixed_from_int(ev->value);
- break;
- case REL_HWHEEL:
- axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
- amount = AXIS_STEP_DISTANCE * wl_fixed_from_int(ev->value);
- break;
- default:
- return;
- }
-
- device->handler->axis(time, axis, amount);
-}
-
-static void
-handle_abs_event(struct evdev_device *device, struct input_event *ev)
-{
- if (!(device->capabilities & WL_SEAT_CAPABILITY_POINTER))
- return;
-
- 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) = {
- [EV_KEY] = handle_key_event,
- [EV_REL] = handle_rel_event,
- [EV_ABS] = handle_abs_event,
-};
-
-static bool
-is_motion_event(struct input_event *ev)
-{
- return (ev->type == EV_REL && (ev->code == REL_X || ev->code == REL_Y))
- || (ev->type == EV_ABS && (ev->code == ABS_X || ev->code == ABS_Y));
-}
-
-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);
-
- device->handler->relative_motion(time, dx, dy);
- device->rel.pending = false;
- device->rel.dx = 0;
- device->rel.dy = 0;
- }
-}
-
-static void
-handle_event(struct evdev_device *device, struct input_event *ev)
-{
- if (!is_motion_event(ev))
- handle_motion_events(device, timeval_to_msec(&ev->time));
-
- if (ev->type < ARRAY_SIZE(event_handlers) && event_handlers[ev->type])
- event_handlers[ev->type](device, ev);
-}
-
-static void
-close_device(struct evdev_device *device)
-{
- wl_event_source_remove(device->source);
- close(device->fd);
- device->source = NULL;
- device->fd = -1;
-}
-
-static int
-handle_data(int fd, uint32_t mask, void *data)
-{
- struct evdev_device *device = data;
- struct input_event event;
- unsigned flags = device->needs_sync ? LIBEVDEV_READ_FLAG_FORCE_SYNC : LIBEVDEV_READ_FLAG_NORMAL;
- int ret;
-
- device->needs_sync = false;
-
- for (;;) {
- ret = libevdev_next_event(device->dev, flags, &event);
-
- switch (ret) {
- case LIBEVDEV_READ_STATUS_SUCCESS:
- handle_event(device, &event);
- break;
- case LIBEVDEV_READ_STATUS_SYNC:
- while (ret == LIBEVDEV_READ_STATUS_SYNC) {
- ret = libevdev_next_event(device->dev, LIBEVDEV_READ_FLAG_SYNC, &event);
-
- if (ret < 0)
- goto done;
-
- handle_event(device, &event);
- }
- break;
- default:
- goto done;
- }
- }
-
-done:
- if (ret == -ENODEV)
- close_device(device);
-
- handle_motion_events(device, timeval_to_msec(&event.time));
-
- return 1;
-}
-
-struct evdev_device *
-evdev_device_new(const char *path, const struct evdev_device_handler *handler)
-{
- struct evdev_device *device;
-
- if (!(device = malloc(sizeof *device)))
- goto error0;
-
- device->fd = launch_open_device(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-
- if (device->fd == -1) {
- ERROR("Failed to open input device at %s\n", path);
- goto error1;
- }
-
- if (!(device->path = strdup(path)))
- goto error2;
-
- if (libevdev_new_from_fd(device->fd, &device->dev) != 0) {
- ERROR("Failed to create libevdev device\n");
- goto error3;
- }
-
- if (libevdev_set_clock_id(device->dev, CLOCK_MONOTONIC) != 0) {
- ERROR("Failed to set libevdev device to monotonic clock\n");
- goto error4;
- }
-
- device->source = wl_event_loop_add_fd(swc.event_loop, device->fd, WL_EVENT_READABLE, handle_data, device);
-
- if (!device->source) {
- ERROR("Failed to add event source\n");
- goto error4;
- }
-
- DEBUG("Adding device %s\n", libevdev_get_name(device->dev));
-
- 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)) {
- device->capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
- DEBUG("\tThis device is a keyboard\n");
- }
-
- if (libevdev_has_event_code(device->dev, EV_REL, REL_X)
- && libevdev_has_event_code(device->dev, EV_REL, REL_Y)
- && libevdev_has_event_code(device->dev, EV_KEY, BTN_MOUSE))
- {
- device->capabilities |= WL_SEAT_CAPABILITY_POINTER;
- 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;
-
-error4:
- libevdev_free(device->dev);
-error3:
- free(device->path);
-error2:
- close(device->fd);
-error1:
- free(device);
-error0:
- return NULL;
-}
-
-void
-evdev_device_destroy(struct evdev_device *device)
-{
- if (device->source)
- close_device(device);
-
- libevdev_free(device->dev);
- free(device->path);
- free(device);
-}
-
-bool
-evdev_device_reopen(struct evdev_device *device)
-{
- if (device->source)
- close_device(device);
-
- device->fd = launch_open_device(device->path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-
- if (device->fd == -1) {
- WARNING("Failed to reopen input device at %s: %s\n", device->path, strerror(errno));
- goto error0;
- }
-
- if (libevdev_change_fd(device->dev, device->fd) == -1) {
- ERROR("Failed to update libevdev fd\n");
- goto error1;
- }
-
- /* According to libevdev documentation, after changing the fd for the device,
- * you should force a sync to bring it's state up to date. */
- device->needs_sync = true;
- device->source = wl_event_loop_add_fd(swc.event_loop, device->fd, WL_EVENT_READABLE, handle_data, device);
-
- if (!device->source) {
- ERROR("Failed to create event source\n");
- goto error1;
- }
-
- return true;
-
-error1:
- close(device->fd);
- device->fd = -1;
-error0:
- return false;
-}
diff --git a/libswc/evdev_device.h b/libswc/evdev_device.h
@@ -1,78 +0,0 @@
-/* swc: libswc/evdev_device.h
- *
- * Copyright (c) 2013 Michael Forney
- *
- * Based in part upon evdev.h from weston, which is:
- *
- * Copyright © 2011, 2012 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef SWC_EVDEV_DEVICE_H
-#define SWC_EVDEV_DEVICE_H
-
-#include <stdbool.h>
-#include <linux/input.h>
-#include <wayland-util.h>
-
-struct evdev_device;
-struct wl_event_loop;
-
-struct evdev_device_handler {
- void (*key)(uint32_t time, uint32_t key, uint32_t state);
- 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 {
- char *path;
- int fd;
- struct libevdev *dev;
- bool needs_sync;
-
- const struct evdev_device_handler *handler;
-
- struct {
- struct {
- const struct input_absinfo *x, *y;
- } info;
-
- int32_t x, y;
- bool pending;
- } abs;
-
- struct {
- int32_t dx, dy;
- bool pending;
- } rel;
-
- uint32_t capabilities;
-
- struct wl_event_source *source;
- struct wl_list link;
-};
-
-struct evdev_device *evdev_device_new(const char *path, const struct evdev_device_handler *handler);
-void evdev_device_destroy(struct evdev_device *device);
-bool evdev_device_reopen(struct evdev_device *device);
-
-#endif
diff --git a/libswc/local.mk b/libswc/local.mk
@@ -17,7 +17,7 @@ $(dir)_TARGETS += \
$(dir)/$(LIBSWC_LINK)
endif
-$(dir)_PACKAGES := libdrm libevdev pixman-1 wayland-server wld xkbcommon
+$(dir)_PACKAGES := libdrm libinput pixman-1 wayland-server wld xkbcommon
$(dir)_CFLAGS += -Iprotocol
SWC_SOURCES = \
@@ -59,11 +59,9 @@ SWC_SOURCES = \
protocol/wayland-drm-protocol.c \
protocol/xdg-shell-unstable-v5-protocol.c
-ifeq ($(ENABLE_LIBINPUT),1)
-$(dir)_CFLAGS += -DENABLE_LIBINPUT
-$(dir)_PACKAGES += libinput libudev
-else
-SWC_SOURCES += libswc/evdev_device.c
+ifeq ($(ENABLE_LIBUDEV),1)
+$(dir)_CFLAGS += -DENABLE_LIBUDEV
+$(dir)_PACKAGES += libudev
endif
ifeq ($(ENABLE_XWAYLAND),1)
@@ -121,4 +119,3 @@ install-$(dir): $($(dir)_TARGETS:$(dir)/%=install-%) | $(DESTDIR)$(INCLUDEDIR)
CLEAN_FILES += $(SWC_SHARED_OBJECTS) $(SWC_STATIC_OBJECTS)
include common.mk
-
diff --git a/libswc/seat.c b/libswc/seat.c
@@ -24,7 +24,6 @@
#include "seat.h"
#include "compositor.h"
#include "data_device.h"
-#include "evdev_device.h"
#include "event.h"
#include "internal.h"
#include "keyboard.h"
@@ -34,27 +33,28 @@
#include "surface.h"
#include "util.h"
-#include <errno.h>
#include <dirent.h>
-#include <stdlib.h>
+#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifdef ENABLE_LIBINPUT
+
+#include <libinput.h>
+#include <linux/input.h>
+#ifdef ENABLE_LIBUDEV
# include <libudev.h>
-# include <libinput.h>
#endif
static struct {
char *name;
uint32_t capabilities;
-#ifdef ENABLE_LIBINPUT
- struct udev *udev;
struct libinput *libinput;
struct wl_event_source *libinput_source;
-#else
- struct wl_list devices;
+
+#ifdef ENABLE_LIBUDEV
+ struct udev *udev;
#endif
struct wl_listener swc_listener;
@@ -74,41 +74,6 @@ const struct swc_seat swc_seat = {
};
static void
-handle_key(uint32_t time, uint32_t key, uint32_t state)
-{
- keyboard_handle_key(&seat.keyboard, time, key, state);
-}
-
-static void
-handle_button(uint32_t time, uint32_t button, uint32_t state)
-{
- pointer_handle_button(&seat.pointer, time, button, state);
-}
-
-static void
-handle_axis(uint32_t time, uint32_t axis, wl_fixed_t amount)
-{
- pointer_handle_axis(&seat.pointer, time, axis, amount);
-}
-
-static void
-handle_relative_motion(uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
-{
- pointer_handle_relative_motion(&seat.pointer, time, dx, 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;
@@ -151,30 +116,15 @@ static void
handle_swc_event(struct wl_listener *listener, void *data)
{
struct event *ev = data;
-#ifndef ENABLE_LIBINPUT
- struct evdev_device *device, *next;
-#endif
switch (ev->type) {
case SWC_EVENT_DEACTIVATED:
-#ifdef ENABLE_LIBINPUT
libinput_suspend(seat.libinput);
-#endif
keyboard_reset(&seat.keyboard);
break;
case SWC_EVENT_ACTIVATED:
-#ifdef ENABLE_LIBINPUT
if (libinput_resume(seat.libinput) != 0)
WARNING("Failed to resume libinput context\n");
-#else
- /* Re-open all input devices */
- wl_list_for_each_safe (device, next, &seat.devices, link) {
- if (!evdev_device_reopen(device)) {
- wl_list_remove(&device->link);
- evdev_device_destroy(device);
- }
- }
-#endif
break;
}
}
@@ -235,7 +185,6 @@ update_capabilities(uint32_t capabilities)
wl_seat_send_capabilities(resource, seat.capabilities);
}
-#ifdef ENABLE_LIBINPUT
static int
open_restricted(const char *path, int flags, void *user_data)
{
@@ -273,19 +222,28 @@ device_capabilities(struct libinput_device *device)
static void
handle_libinput_axis_event(struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
{
- double amount;
+ wl_fixed_t amount;
if (!libinput_event_pointer_has_axis(event, axis))
return;
- amount = libinput_event_pointer_get_axis_value(event, axis);
- handle_axis(libinput_event_pointer_get_time(event), axis, wl_fixed_from_double(amount));
+ amount = wl_fixed_from_double(libinput_event_pointer_get_axis_value(event, axis));
+ pointer_handle_axis(&seat.pointer, libinput_event_pointer_get_time(event), axis, amount);
}
static int
handle_libinput_data(int fd, uint32_t mask, void *data)
{
+ struct screen *screen;
+ struct swc_rectangle *rect;
struct libinput_event *generic_event;
+ struct libinput_device *device;
+ union {
+ struct libinput_event_keyboard *k;
+ struct libinput_event_pointer *p;
+ } event;
+ wl_fixed_t x, y;
+ uint32_t time, key, state;
if (libinput_dispatch(seat.libinput) != 0) {
WARNING("libinput_dispatch failed: %s\n", strerror(errno));
@@ -294,49 +252,57 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
while ((generic_event = libinput_get_event(seat.libinput))) {
switch (libinput_event_get_type(generic_event)) {
- case LIBINPUT_EVENT_DEVICE_ADDED: {
- struct libinput_device *device;
-
+ case LIBINPUT_EVENT_DEVICE_ADDED:
device = libinput_event_get_device(generic_event);
update_capabilities(device_capabilities(device));
break;
- }
- case LIBINPUT_EVENT_KEYBOARD_KEY: {
- struct libinput_event_keyboard *event;
-
- event = libinput_event_get_keyboard_event(generic_event);
- handle_key(libinput_event_keyboard_get_time(event),
- libinput_event_keyboard_get_key(event),
- libinput_event_keyboard_get_key_state(event));
+ case LIBINPUT_EVENT_KEYBOARD_KEY:
+ event.k = libinput_event_get_keyboard_event(generic_event);
+ time = libinput_event_keyboard_get_time(event.k);
+ key = libinput_event_keyboard_get_key(event.k);
+ state = libinput_event_keyboard_get_key_state(event.k);
+ keyboard_handle_key(&seat.keyboard, time, key, state);
break;
- }
- case LIBINPUT_EVENT_POINTER_MOTION: {
- struct libinput_event_pointer *event;
- wl_fixed_t dx, dy;
-
- event = libinput_event_get_pointer_event(generic_event);
- dx = wl_fixed_from_double(libinput_event_pointer_get_dx(event));
- dy = wl_fixed_from_double(libinput_event_pointer_get_dy(event));
- handle_relative_motion(libinput_event_pointer_get_time(event), dx, dy);
+ case LIBINPUT_EVENT_POINTER_MOTION:
+ event.p = libinput_event_get_pointer_event(generic_event);
+ time = libinput_event_pointer_get_time(event.p);
+ x = wl_fixed_from_double(libinput_event_pointer_get_dx(event.p));
+ y = wl_fixed_from_double(libinput_event_pointer_get_dy(event.p));
+ pointer_handle_relative_motion(&seat.pointer, time, x, y);
break;
- }
- case LIBINPUT_EVENT_POINTER_BUTTON: {
- struct libinput_event_pointer *event;
-
- event = libinput_event_get_pointer_event(generic_event);
- handle_button(libinput_event_pointer_get_time(event),
- libinput_event_pointer_get_button(event),
- libinput_event_pointer_get_button_state(event));
+ case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+ screen = wl_container_of(swc.screens.next, screen, link);
+ rect = &screen->base.geometry;
+ event.p = libinput_event_get_pointer_event(generic_event);
+ time = libinput_event_pointer_get_time(event.p);
+ x = wl_fixed_from_double(libinput_event_pointer_get_absolute_x_transformed(event.p, rect->width));
+ y = wl_fixed_from_double(libinput_event_pointer_get_absolute_y_transformed(event.p, rect->height));
+ pointer_handle_absolute_motion(&seat.pointer, time, x, y);
break;
- }
- case LIBINPUT_EVENT_POINTER_AXIS: {
- struct libinput_event_pointer *event;
-
- event = libinput_event_get_pointer_event(generic_event);
- handle_libinput_axis_event(event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- handle_libinput_axis_event(event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ case LIBINPUT_EVENT_POINTER_BUTTON:
+ event.p = libinput_event_get_pointer_event(generic_event);
+ time = libinput_event_pointer_get_time(event.p);
+ key = libinput_event_pointer_get_button(event.p);
+ state = libinput_event_pointer_get_button_state(event.p);
+ pointer_handle_button(&seat.pointer, time, key, state);
+ if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
+ /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so pass
+ * those through as axis events. */
+ switch (key) {
+ case BTN_GEAR_DOWN:
+ pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
+ break;
+ case BTN_GEAR_UP:
+ pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
+ break;
+ }
+ }
+ break;
+ case LIBINPUT_EVENT_POINTER_AXIS:
+ event.p = libinput_event_get_pointer_event(generic_event);
+ handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
break;
- }
default:
break;
}
@@ -350,22 +316,28 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
bool
initialize_libinput(const char *seat_name)
{
+#ifdef ENABLE_LIBUDEV
if (!(seat.udev = udev_new())) {
ERROR("Could not create udev context\n");
goto error0;
}
seat.libinput = libinput_udev_create_context(&libinput_interface, NULL, seat.udev);
+#else
+ seat.libinput = libinput_path_create_context(&libinput_interface, NULL);
+#endif
if (!seat.libinput) {
ERROR("Could not create libinput context\n");
goto error1;
}
+#ifdef ENABLE_LIBUDEV
if (libinput_udev_assign_seat(seat.libinput, seat_name) != 0) {
ERROR("Failed to assign seat to libinput context\n");
goto error2;
}
+#endif
seat.libinput_source = wl_event_loop_add_fd
(swc.event_loop, libinput_get_fd(seat.libinput), WL_EVENT_READABLE,
@@ -384,41 +356,14 @@ initialize_libinput(const char *seat_name)
error2:
libinput_unref(seat.libinput);
error1:
+#ifdef ENABLE_LIBUDEV
udev_unref(seat.udev);
error0:
+#endif
return false;
}
-void
-finalize_libinput(void)
-{
- wl_event_source_remove(seat.libinput_source);
- libinput_unref(seat.libinput);
- udev_unref(seat.udev);
-}
-#else
-const static struct evdev_device_handler evdev_handler = {
- .key = handle_key,
- .button = handle_button,
- .axis = handle_axis,
- .relative_motion = handle_relative_motion,
- .absolute_motion = handle_absolute_motion,
-};
-
-static void
-add_device(const char *path)
-{
- struct evdev_device *device;
-
- if (!(device = evdev_device_new(path, &evdev_handler))) {
- ERROR("Could not create evdev device\n");
- return;
- }
-
- update_capabilities(device->capabilities);
- wl_list_insert(&seat.devices, &device->link);
-}
-
+#ifndef ENABLE_LIBUDEV
static int
select_device(const struct dirent *entry)
{
@@ -430,20 +375,23 @@ static bool
add_devices(void)
{
struct dirent **devices;
- int i, num_devices;
+ int i, n;
char path[64];
+ struct libinput_device *device;
- num_devices = scandir("/dev/input", &devices, &select_device, &alphasort);
+ n = scandir("/dev/input", &devices, &select_device, &alphasort);
- if (num_devices == -1) {
+ if (n == -1) {
ERROR("Failed to scan /dev/input for event devices\n");
return false;
}
- for (i = 0; i < num_devices; ++i) {
+ for (i = 0; i < n; ++i) {
snprintf(path, sizeof path, "/dev/input/%s", devices[i]->d_name);
free(devices[i]);
- add_device(path);
+ device = libinput_path_add_device(seat.libinput, path);
+ if (device)
+ update_capabilities(device_capabilities(device));
}
free(devices);
@@ -489,12 +437,10 @@ seat_initialize(const char *seat_name)
goto error4;
}
-#ifdef ENABLE_LIBINPUT
if (!initialize_libinput(seat.name))
goto error5;
-#else
- wl_list_init(&seat.devices);
+#ifndef ENABLE_LIBUDEV
if (!add_devices())
goto error5;
#endif
@@ -518,12 +464,10 @@ error0:
void
seat_finalize(void)
{
-#ifdef ENABLE_LIBINPUT
- finalize_libinput();
-#else
- struct evdev_device *device, *tmp;
- wl_list_for_each_safe (device, tmp, &seat.devices, link)
- evdev_device_destroy(device);
+ wl_event_source_remove(seat.libinput_source);
+ libinput_unref(seat.libinput);
+#ifdef ENABLE_LIBUDEV
+ udev_unref(seat.udev);
#endif
pointer_finalize(&seat.pointer);