commit acec510
Michael Forney
·
2017-03-11 22:42:29 +0000 UTC
parent bba112e
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.
6 files changed,
+95,
-587
+3,
-3
1@@ -14,14 +14,14 @@ Dependencies
2 * wayland
3 * wayland-protocols
4 * libdrm
5-* libevdev
6+* libinput (see my [libinput repository](https://github.com/michaelforney/libinput)
7+ if you don't want the libudev dependency)
8 * libxkbcommon
9 * pixman
10 * [wld](http://github.com/michaelforney/wld)
11 * linux\[>=3.12\] (for EVIOCREVOKE)
12
13-For input hotplugging and touchpad support, the following is also required:
14-* libinput
15+For input hotplugging, the following is also required:
16 * libudev
17
18 For XWayland support, the following are also required:
+1,
-1
1@@ -18,6 +18,6 @@ CFLAGS = -pipe
2 ENABLE_DEBUG = 1
3 ENABLE_STATIC = 1
4 ENABLE_SHARED = 1
5-ENABLE_LIBINPUT = 1
6+ENABLE_LIBUDEV = 1
7 ENABLE_XWAYLAND = 1
8
+0,
-355
1@@ -1,355 +0,0 @@
2-/* swc: libswc/evdev_device.c
3- *
4- * Copyright (c) 2013, 2014 Michael Forney
5- *
6- * Based in part upon evdev.c from weston, which is:
7- *
8- * Copyright © 2010 Intel Corporation
9- *
10- * Permission is hereby granted, free of charge, to any person obtaining a copy
11- * of this software and associated documentation files (the "Software"), to deal
12- * in the Software without restriction, including without limitation the rights
13- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14- * copies of the Software, and to permit persons to whom the Software is
15- * furnished to do so, subject to the following conditions:
16- *
17- * The above copyright notice and this permission notice shall be included in
18- * all copies or substantial portions of the Software.
19- *
20- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26- * SOFTWARE.
27- */
28-
29-#include "evdev_device.h"
30-#include "event.h"
31-#include "internal.h"
32-#include "launch.h"
33-#include "seat.h"
34-#include "util.h"
35-
36-#include <errno.h>
37-#include <fcntl.h>
38-#include <libevdev/libevdev.h>
39-#include <stdio.h>
40-#include <stdlib.h>
41-#include <string.h>
42-#include <time.h>
43-#include <unistd.h>
44-
45-#define AXIS_STEP_DISTANCE 10
46-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
47-
48-static inline uint32_t
49-timeval_to_msec(struct timeval *time)
50-{
51- return time->tv_sec * 1000 + time->tv_usec / 1000;
52-}
53-
54-static void
55-handle_key_event(struct evdev_device *device, struct input_event *ev)
56-{
57- uint32_t time = timeval_to_msec(&ev->time);
58- uint32_t state;
59-
60- if ((ev->code >= BTN_MISC && ev->code <= BTN_GEAR_UP) || ev->code >= BTN_TRIGGER_HAPPY) {
61- state = ev->value ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED;
62- device->handler->button(time, ev->code, state);
63- if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
64- /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so
65- * pass those through as axis events. */
66- switch (ev->code) {
67- case BTN_GEAR_DOWN:
68- device->handler->axis(time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(AXIS_STEP_DISTANCE));
69- break;
70- case BTN_GEAR_UP:
71- device->handler->axis(time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-AXIS_STEP_DISTANCE));
72- break;
73- }
74- }
75- } else {
76- state = ev->value ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
77- device->handler->key(time, ev->code, state);
78- }
79-}
80-
81-static void
82-handle_rel_event(struct evdev_device *device, struct input_event *ev)
83-{
84- uint32_t time = timeval_to_msec(&ev->time);
85- uint32_t axis, amount;
86-
87- if (!(device->capabilities & WL_SEAT_CAPABILITY_POINTER))
88- return;
89-
90- switch (ev->code) {
91- case REL_X:
92- device->rel.dx += ev->value;
93- device->rel.pending = true;
94- return;
95- case REL_Y:
96- device->rel.dy += ev->value;
97- device->rel.pending = true;
98- return;
99- case REL_WHEEL:
100- axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
101- amount = -AXIS_STEP_DISTANCE * wl_fixed_from_int(ev->value);
102- break;
103- case REL_HWHEEL:
104- axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
105- amount = AXIS_STEP_DISTANCE * wl_fixed_from_int(ev->value);
106- break;
107- default:
108- return;
109- }
110-
111- device->handler->axis(time, axis, amount);
112-}
113-
114-static void
115-handle_abs_event(struct evdev_device *device, struct input_event *ev)
116-{
117- if (!(device->capabilities & WL_SEAT_CAPABILITY_POINTER))
118- return;
119-
120- switch (ev->code) {
121- case ABS_X:
122- device->abs.x = ev->value;
123- device->abs.pending = true;
124- break;
125- case ABS_Y:
126- device->abs.y = ev->value;
127- device->abs.pending = true;
128- break;
129- }
130-}
131-
132-static void (*event_handlers[])(struct evdev_device *device, struct input_event *ev) = {
133- [EV_KEY] = handle_key_event,
134- [EV_REL] = handle_rel_event,
135- [EV_ABS] = handle_abs_event,
136-};
137-
138-static bool
139-is_motion_event(struct input_event *ev)
140-{
141- return (ev->type == EV_REL && (ev->code == REL_X || ev->code == REL_Y))
142- || (ev->type == EV_ABS && (ev->code == ABS_X || ev->code == ABS_Y));
143-}
144-
145-static void
146-handle_motion_events(struct evdev_device *device, uint32_t time)
147-{
148- if (device->abs.pending) {
149- int32_t x = device->abs.x - device->abs.info.x->minimum;
150- int32_t max_x = device->abs.info.x->maximum - device->abs.info.x->minimum;
151- int32_t y = device->abs.y - device->abs.info.y->minimum;
152- int32_t max_y = device->abs.info.y->maximum - device->abs.info.y->minimum;
153-
154- device->handler->absolute_motion(time, x, max_x, y, max_y);
155- device->abs.pending = false;
156- }
157- if (device->rel.pending) {
158- wl_fixed_t dx = wl_fixed_from_int(device->rel.dx);
159- wl_fixed_t dy = wl_fixed_from_int(device->rel.dy);
160-
161- device->handler->relative_motion(time, dx, dy);
162- device->rel.pending = false;
163- device->rel.dx = 0;
164- device->rel.dy = 0;
165- }
166-}
167-
168-static void
169-handle_event(struct evdev_device *device, struct input_event *ev)
170-{
171- if (!is_motion_event(ev))
172- handle_motion_events(device, timeval_to_msec(&ev->time));
173-
174- if (ev->type < ARRAY_SIZE(event_handlers) && event_handlers[ev->type])
175- event_handlers[ev->type](device, ev);
176-}
177-
178-static void
179-close_device(struct evdev_device *device)
180-{
181- wl_event_source_remove(device->source);
182- close(device->fd);
183- device->source = NULL;
184- device->fd = -1;
185-}
186-
187-static int
188-handle_data(int fd, uint32_t mask, void *data)
189-{
190- struct evdev_device *device = data;
191- struct input_event event;
192- unsigned flags = device->needs_sync ? LIBEVDEV_READ_FLAG_FORCE_SYNC : LIBEVDEV_READ_FLAG_NORMAL;
193- int ret;
194-
195- device->needs_sync = false;
196-
197- for (;;) {
198- ret = libevdev_next_event(device->dev, flags, &event);
199-
200- switch (ret) {
201- case LIBEVDEV_READ_STATUS_SUCCESS:
202- handle_event(device, &event);
203- break;
204- case LIBEVDEV_READ_STATUS_SYNC:
205- while (ret == LIBEVDEV_READ_STATUS_SYNC) {
206- ret = libevdev_next_event(device->dev, LIBEVDEV_READ_FLAG_SYNC, &event);
207-
208- if (ret < 0)
209- goto done;
210-
211- handle_event(device, &event);
212- }
213- break;
214- default:
215- goto done;
216- }
217- }
218-
219-done:
220- if (ret == -ENODEV)
221- close_device(device);
222-
223- handle_motion_events(device, timeval_to_msec(&event.time));
224-
225- return 1;
226-}
227-
228-struct evdev_device *
229-evdev_device_new(const char *path, const struct evdev_device_handler *handler)
230-{
231- struct evdev_device *device;
232-
233- if (!(device = malloc(sizeof *device)))
234- goto error0;
235-
236- device->fd = launch_open_device(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
237-
238- if (device->fd == -1) {
239- ERROR("Failed to open input device at %s\n", path);
240- goto error1;
241- }
242-
243- if (!(device->path = strdup(path)))
244- goto error2;
245-
246- if (libevdev_new_from_fd(device->fd, &device->dev) != 0) {
247- ERROR("Failed to create libevdev device\n");
248- goto error3;
249- }
250-
251- if (libevdev_set_clock_id(device->dev, CLOCK_MONOTONIC) != 0) {
252- ERROR("Failed to set libevdev device to monotonic clock\n");
253- goto error4;
254- }
255-
256- device->source = wl_event_loop_add_fd(swc.event_loop, device->fd, WL_EVENT_READABLE, handle_data, device);
257-
258- if (!device->source) {
259- ERROR("Failed to add event source\n");
260- goto error4;
261- }
262-
263- DEBUG("Adding device %s\n", libevdev_get_name(device->dev));
264-
265- device->needs_sync = false;
266- device->handler = handler;
267- device->capabilities = 0;
268- device->abs.info.x = libevdev_get_abs_info(device->dev, ABS_X);
269- device->abs.info.y = libevdev_get_abs_info(device->dev, ABS_Y);
270- device->abs.pending = false;
271- memset(&device->rel, 0, sizeof(device->rel));
272-
273- if (libevdev_has_event_code(device->dev, EV_KEY, KEY_ENTER)) {
274- device->capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
275- DEBUG("\tThis device is a keyboard\n");
276- }
277-
278- if (libevdev_has_event_code(device->dev, EV_REL, REL_X)
279- && libevdev_has_event_code(device->dev, EV_REL, REL_Y)
280- && libevdev_has_event_code(device->dev, EV_KEY, BTN_MOUSE))
281- {
282- device->capabilities |= WL_SEAT_CAPABILITY_POINTER;
283- DEBUG("\tThis device is a pointer\n");
284- }
285-
286- if (libevdev_has_event_code(device->dev, EV_ABS, ABS_X)
287- && libevdev_has_event_code(device->dev, EV_ABS, ABS_Y)
288- && libevdev_has_event_code(device->dev, EV_KEY, BTN_MOUSE)
289- && !libevdev_has_event_code(device->dev, EV_KEY, BTN_TOOL_FINGER))
290- {
291- device->capabilities |= WL_SEAT_CAPABILITY_POINTER;
292- }
293-
294- /* XXX: touch devices */
295-
296- return device;
297-
298-error4:
299- libevdev_free(device->dev);
300-error3:
301- free(device->path);
302-error2:
303- close(device->fd);
304-error1:
305- free(device);
306-error0:
307- return NULL;
308-}
309-
310-void
311-evdev_device_destroy(struct evdev_device *device)
312-{
313- if (device->source)
314- close_device(device);
315-
316- libevdev_free(device->dev);
317- free(device->path);
318- free(device);
319-}
320-
321-bool
322-evdev_device_reopen(struct evdev_device *device)
323-{
324- if (device->source)
325- close_device(device);
326-
327- device->fd = launch_open_device(device->path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
328-
329- if (device->fd == -1) {
330- WARNING("Failed to reopen input device at %s: %s\n", device->path, strerror(errno));
331- goto error0;
332- }
333-
334- if (libevdev_change_fd(device->dev, device->fd) == -1) {
335- ERROR("Failed to update libevdev fd\n");
336- goto error1;
337- }
338-
339- /* According to libevdev documentation, after changing the fd for the device,
340- * you should force a sync to bring it's state up to date. */
341- device->needs_sync = true;
342- device->source = wl_event_loop_add_fd(swc.event_loop, device->fd, WL_EVENT_READABLE, handle_data, device);
343-
344- if (!device->source) {
345- ERROR("Failed to create event source\n");
346- goto error1;
347- }
348-
349- return true;
350-
351-error1:
352- close(device->fd);
353- device->fd = -1;
354-error0:
355- return false;
356-}
+0,
-78
1@@ -1,78 +0,0 @@
2-/* swc: libswc/evdev_device.h
3- *
4- * Copyright (c) 2013 Michael Forney
5- *
6- * Based in part upon evdev.h from weston, which is:
7- *
8- * Copyright © 2011, 2012 Intel Corporation
9- *
10- * Permission is hereby granted, free of charge, to any person obtaining a copy
11- * of this software and associated documentation files (the "Software"), to deal
12- * in the Software without restriction, including without limitation the rights
13- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14- * copies of the Software, and to permit persons to whom the Software is
15- * furnished to do so, subject to the following conditions:
16- *
17- * The above copyright notice and this permission notice shall be included in
18- * all copies or substantial portions of the Software.
19- *
20- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26- * SOFTWARE.
27- */
28-
29-#ifndef SWC_EVDEV_DEVICE_H
30-#define SWC_EVDEV_DEVICE_H
31-
32-#include <stdbool.h>
33-#include <linux/input.h>
34-#include <wayland-util.h>
35-
36-struct evdev_device;
37-struct wl_event_loop;
38-
39-struct evdev_device_handler {
40- void (*key)(uint32_t time, uint32_t key, uint32_t state);
41- void (*button)(uint32_t time, uint32_t key, uint32_t state);
42- void (*axis)(uint32_t time, uint32_t axis, wl_fixed_t amount);
43- void (*relative_motion)(uint32_t time, wl_fixed_t dx, wl_fixed_t dy);
44- void (*absolute_motion)(uint32_t time, int32_t x, int32_t y, int32_t max_x, int32_t max_y);
45-};
46-
47-struct evdev_device {
48- char *path;
49- int fd;
50- struct libevdev *dev;
51- bool needs_sync;
52-
53- const struct evdev_device_handler *handler;
54-
55- struct {
56- struct {
57- const struct input_absinfo *x, *y;
58- } info;
59-
60- int32_t x, y;
61- bool pending;
62- } abs;
63-
64- struct {
65- int32_t dx, dy;
66- bool pending;
67- } rel;
68-
69- uint32_t capabilities;
70-
71- struct wl_event_source *source;
72- struct wl_list link;
73-};
74-
75-struct evdev_device *evdev_device_new(const char *path, const struct evdev_device_handler *handler);
76-void evdev_device_destroy(struct evdev_device *device);
77-bool evdev_device_reopen(struct evdev_device *device);
78-
79-#endif
+4,
-7
1@@ -17,7 +17,7 @@ $(dir)_TARGETS += \
2 $(dir)/$(LIBSWC_LINK)
3 endif
4
5-$(dir)_PACKAGES := libdrm libevdev pixman-1 wayland-server wld xkbcommon
6+$(dir)_PACKAGES := libdrm libinput pixman-1 wayland-server wld xkbcommon
7 $(dir)_CFLAGS += -Iprotocol
8
9 SWC_SOURCES = \
10@@ -59,11 +59,9 @@ SWC_SOURCES = \
11 protocol/wayland-drm-protocol.c \
12 protocol/xdg-shell-unstable-v5-protocol.c
13
14-ifeq ($(ENABLE_LIBINPUT),1)
15-$(dir)_CFLAGS += -DENABLE_LIBINPUT
16-$(dir)_PACKAGES += libinput libudev
17-else
18-SWC_SOURCES += libswc/evdev_device.c
19+ifeq ($(ENABLE_LIBUDEV),1)
20+$(dir)_CFLAGS += -DENABLE_LIBUDEV
21+$(dir)_PACKAGES += libudev
22 endif
23
24 ifeq ($(ENABLE_XWAYLAND),1)
25@@ -121,4 +119,3 @@ install-$(dir): $($(dir)_TARGETS:$(dir)/%=install-%) | $(DESTDIR)$(INCLUDEDIR)
26 CLEAN_FILES += $(SWC_SHARED_OBJECTS) $(SWC_STATIC_OBJECTS)
27
28 include common.mk
29-
+87,
-143
1@@ -24,7 +24,6 @@
2 #include "seat.h"
3 #include "compositor.h"
4 #include "data_device.h"
5-#include "evdev_device.h"
6 #include "event.h"
7 #include "internal.h"
8 #include "keyboard.h"
9@@ -34,27 +33,28 @@
10 #include "surface.h"
11 #include "util.h"
12
13-#include <errno.h>
14 #include <dirent.h>
15-#include <stdlib.h>
16+#include <errno.h>
17 #include <stdio.h>
18+#include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21-#ifdef ENABLE_LIBINPUT
22+
23+#include <libinput.h>
24+#include <linux/input.h>
25+#ifdef ENABLE_LIBUDEV
26 # include <libudev.h>
27-# include <libinput.h>
28 #endif
29
30 static struct {
31 char *name;
32 uint32_t capabilities;
33
34-#ifdef ENABLE_LIBINPUT
35- struct udev *udev;
36 struct libinput *libinput;
37 struct wl_event_source *libinput_source;
38-#else
39- struct wl_list devices;
40+
41+#ifdef ENABLE_LIBUDEV
42+ struct udev *udev;
43 #endif
44
45 struct wl_listener swc_listener;
46@@ -73,41 +73,6 @@ const struct swc_seat swc_seat = {
47 .data_device = &seat.data_device,
48 };
49
50-static void
51-handle_key(uint32_t time, uint32_t key, uint32_t state)
52-{
53- keyboard_handle_key(&seat.keyboard, time, key, state);
54-}
55-
56-static void
57-handle_button(uint32_t time, uint32_t button, uint32_t state)
58-{
59- pointer_handle_button(&seat.pointer, time, button, state);
60-}
61-
62-static void
63-handle_axis(uint32_t time, uint32_t axis, wl_fixed_t amount)
64-{
65- pointer_handle_axis(&seat.pointer, time, axis, amount);
66-}
67-
68-static void
69-handle_relative_motion(uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
70-{
71- pointer_handle_relative_motion(&seat.pointer, time, dx, dy);
72-}
73-
74-static void
75-handle_absolute_motion(uint32_t time, int32_t x, int32_t max_x, int32_t y, int32_t max_y)
76-{
77- struct screen *screen = wl_container_of(swc.screens.next, screen, link);
78- struct swc_rectangle *rect = &screen->base.geometry;
79- wl_fixed_t fx = wl_fixed_from_int(x * rect->width / max_x + rect->x);
80- wl_fixed_t fy = wl_fixed_from_int(y * rect->height / max_y + rect->y);
81-
82- pointer_handle_absolute_motion(&seat.pointer, time, fx, fy);
83-}
84-
85 static void
86 handle_keyboard_focus_event(struct wl_listener *listener, void *data)
87 {
88@@ -151,30 +116,15 @@ static void
89 handle_swc_event(struct wl_listener *listener, void *data)
90 {
91 struct event *ev = data;
92-#ifndef ENABLE_LIBINPUT
93- struct evdev_device *device, *next;
94-#endif
95
96 switch (ev->type) {
97 case SWC_EVENT_DEACTIVATED:
98-#ifdef ENABLE_LIBINPUT
99 libinput_suspend(seat.libinput);
100-#endif
101 keyboard_reset(&seat.keyboard);
102 break;
103 case SWC_EVENT_ACTIVATED:
104-#ifdef ENABLE_LIBINPUT
105 if (libinput_resume(seat.libinput) != 0)
106 WARNING("Failed to resume libinput context\n");
107-#else
108- /* Re-open all input devices */
109- wl_list_for_each_safe (device, next, &seat.devices, link) {
110- if (!evdev_device_reopen(device)) {
111- wl_list_remove(&device->link);
112- evdev_device_destroy(device);
113- }
114- }
115-#endif
116 break;
117 }
118 }
119@@ -235,7 +185,6 @@ update_capabilities(uint32_t capabilities)
120 wl_seat_send_capabilities(resource, seat.capabilities);
121 }
122
123-#ifdef ENABLE_LIBINPUT
124 static int
125 open_restricted(const char *path, int flags, void *user_data)
126 {
127@@ -273,19 +222,28 @@ device_capabilities(struct libinput_device *device)
128 static void
129 handle_libinput_axis_event(struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
130 {
131- double amount;
132+ wl_fixed_t amount;
133
134 if (!libinput_event_pointer_has_axis(event, axis))
135 return;
136
137- amount = libinput_event_pointer_get_axis_value(event, axis);
138- handle_axis(libinput_event_pointer_get_time(event), axis, wl_fixed_from_double(amount));
139+ amount = wl_fixed_from_double(libinput_event_pointer_get_axis_value(event, axis));
140+ pointer_handle_axis(&seat.pointer, libinput_event_pointer_get_time(event), axis, amount);
141 }
142
143 static int
144 handle_libinput_data(int fd, uint32_t mask, void *data)
145 {
146+ struct screen *screen;
147+ struct swc_rectangle *rect;
148 struct libinput_event *generic_event;
149+ struct libinput_device *device;
150+ union {
151+ struct libinput_event_keyboard *k;
152+ struct libinput_event_pointer *p;
153+ } event;
154+ wl_fixed_t x, y;
155+ uint32_t time, key, state;
156
157 if (libinput_dispatch(seat.libinput) != 0) {
158 WARNING("libinput_dispatch failed: %s\n", strerror(errno));
159@@ -294,49 +252,57 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
160
161 while ((generic_event = libinput_get_event(seat.libinput))) {
162 switch (libinput_event_get_type(generic_event)) {
163- case LIBINPUT_EVENT_DEVICE_ADDED: {
164- struct libinput_device *device;
165-
166+ case LIBINPUT_EVENT_DEVICE_ADDED:
167 device = libinput_event_get_device(generic_event);
168 update_capabilities(device_capabilities(device));
169 break;
170- }
171- case LIBINPUT_EVENT_KEYBOARD_KEY: {
172- struct libinput_event_keyboard *event;
173-
174- event = libinput_event_get_keyboard_event(generic_event);
175- handle_key(libinput_event_keyboard_get_time(event),
176- libinput_event_keyboard_get_key(event),
177- libinput_event_keyboard_get_key_state(event));
178+ case LIBINPUT_EVENT_KEYBOARD_KEY:
179+ event.k = libinput_event_get_keyboard_event(generic_event);
180+ time = libinput_event_keyboard_get_time(event.k);
181+ key = libinput_event_keyboard_get_key(event.k);
182+ state = libinput_event_keyboard_get_key_state(event.k);
183+ keyboard_handle_key(&seat.keyboard, time, key, state);
184 break;
185- }
186- case LIBINPUT_EVENT_POINTER_MOTION: {
187- struct libinput_event_pointer *event;
188- wl_fixed_t dx, dy;
189-
190- event = libinput_event_get_pointer_event(generic_event);
191- dx = wl_fixed_from_double(libinput_event_pointer_get_dx(event));
192- dy = wl_fixed_from_double(libinput_event_pointer_get_dy(event));
193- handle_relative_motion(libinput_event_pointer_get_time(event), dx, dy);
194+ case LIBINPUT_EVENT_POINTER_MOTION:
195+ event.p = libinput_event_get_pointer_event(generic_event);
196+ time = libinput_event_pointer_get_time(event.p);
197+ x = wl_fixed_from_double(libinput_event_pointer_get_dx(event.p));
198+ y = wl_fixed_from_double(libinput_event_pointer_get_dy(event.p));
199+ pointer_handle_relative_motion(&seat.pointer, time, x, y);
200 break;
201- }
202- case LIBINPUT_EVENT_POINTER_BUTTON: {
203- struct libinput_event_pointer *event;
204-
205- event = libinput_event_get_pointer_event(generic_event);
206- handle_button(libinput_event_pointer_get_time(event),
207- libinput_event_pointer_get_button(event),
208- libinput_event_pointer_get_button_state(event));
209+ case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
210+ screen = wl_container_of(swc.screens.next, screen, link);
211+ rect = &screen->base.geometry;
212+ event.p = libinput_event_get_pointer_event(generic_event);
213+ time = libinput_event_pointer_get_time(event.p);
214+ x = wl_fixed_from_double(libinput_event_pointer_get_absolute_x_transformed(event.p, rect->width));
215+ y = wl_fixed_from_double(libinput_event_pointer_get_absolute_y_transformed(event.p, rect->height));
216+ pointer_handle_absolute_motion(&seat.pointer, time, x, y);
217 break;
218- }
219- case LIBINPUT_EVENT_POINTER_AXIS: {
220- struct libinput_event_pointer *event;
221-
222- event = libinput_event_get_pointer_event(generic_event);
223- handle_libinput_axis_event(event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
224- handle_libinput_axis_event(event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
225+ case LIBINPUT_EVENT_POINTER_BUTTON:
226+ event.p = libinput_event_get_pointer_event(generic_event);
227+ time = libinput_event_pointer_get_time(event.p);
228+ key = libinput_event_pointer_get_button(event.p);
229+ state = libinput_event_pointer_get_button_state(event.p);
230+ pointer_handle_button(&seat.pointer, time, key, state);
231+ if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
232+ /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so pass
233+ * those through as axis events. */
234+ switch (key) {
235+ case BTN_GEAR_DOWN:
236+ pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
237+ break;
238+ case BTN_GEAR_UP:
239+ pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
240+ break;
241+ }
242+ }
243+ break;
244+ case LIBINPUT_EVENT_POINTER_AXIS:
245+ event.p = libinput_event_get_pointer_event(generic_event);
246+ handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
247+ handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
248 break;
249- }
250 default:
251 break;
252 }
253@@ -350,22 +316,28 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
254 bool
255 initialize_libinput(const char *seat_name)
256 {
257+#ifdef ENABLE_LIBUDEV
258 if (!(seat.udev = udev_new())) {
259 ERROR("Could not create udev context\n");
260 goto error0;
261 }
262
263 seat.libinput = libinput_udev_create_context(&libinput_interface, NULL, seat.udev);
264+#else
265+ seat.libinput = libinput_path_create_context(&libinput_interface, NULL);
266+#endif
267
268 if (!seat.libinput) {
269 ERROR("Could not create libinput context\n");
270 goto error1;
271 }
272
273+#ifdef ENABLE_LIBUDEV
274 if (libinput_udev_assign_seat(seat.libinput, seat_name) != 0) {
275 ERROR("Failed to assign seat to libinput context\n");
276 goto error2;
277 }
278+#endif
279
280 seat.libinput_source = wl_event_loop_add_fd
281 (swc.event_loop, libinput_get_fd(seat.libinput), WL_EVENT_READABLE,
282@@ -384,41 +356,14 @@ initialize_libinput(const char *seat_name)
283 error2:
284 libinput_unref(seat.libinput);
285 error1:
286+#ifdef ENABLE_LIBUDEV
287 udev_unref(seat.udev);
288 error0:
289+#endif
290 return false;
291 }
292
293-void
294-finalize_libinput(void)
295-{
296- wl_event_source_remove(seat.libinput_source);
297- libinput_unref(seat.libinput);
298- udev_unref(seat.udev);
299-}
300-#else
301-const static struct evdev_device_handler evdev_handler = {
302- .key = handle_key,
303- .button = handle_button,
304- .axis = handle_axis,
305- .relative_motion = handle_relative_motion,
306- .absolute_motion = handle_absolute_motion,
307-};
308-
309-static void
310-add_device(const char *path)
311-{
312- struct evdev_device *device;
313-
314- if (!(device = evdev_device_new(path, &evdev_handler))) {
315- ERROR("Could not create evdev device\n");
316- return;
317- }
318-
319- update_capabilities(device->capabilities);
320- wl_list_insert(&seat.devices, &device->link);
321-}
322-
323+#ifndef ENABLE_LIBUDEV
324 static int
325 select_device(const struct dirent *entry)
326 {
327@@ -430,20 +375,23 @@ static bool
328 add_devices(void)
329 {
330 struct dirent **devices;
331- int i, num_devices;
332+ int i, n;
333 char path[64];
334+ struct libinput_device *device;
335
336- num_devices = scandir("/dev/input", &devices, &select_device, &alphasort);
337+ n = scandir("/dev/input", &devices, &select_device, &alphasort);
338
339- if (num_devices == -1) {
340+ if (n == -1) {
341 ERROR("Failed to scan /dev/input for event devices\n");
342 return false;
343 }
344
345- for (i = 0; i < num_devices; ++i) {
346+ for (i = 0; i < n; ++i) {
347 snprintf(path, sizeof path, "/dev/input/%s", devices[i]->d_name);
348 free(devices[i]);
349- add_device(path);
350+ device = libinput_path_add_device(seat.libinput, path);
351+ if (device)
352+ update_capabilities(device_capabilities(device));
353 }
354
355 free(devices);
356@@ -489,12 +437,10 @@ seat_initialize(const char *seat_name)
357 goto error4;
358 }
359
360-#ifdef ENABLE_LIBINPUT
361 if (!initialize_libinput(seat.name))
362 goto error5;
363-#else
364- wl_list_init(&seat.devices);
365
366+#ifndef ENABLE_LIBUDEV
367 if (!add_devices())
368 goto error5;
369 #endif
370@@ -518,12 +464,10 @@ error0:
371 void
372 seat_finalize(void)
373 {
374-#ifdef ENABLE_LIBINPUT
375- finalize_libinput();
376-#else
377- struct evdev_device *device, *tmp;
378- wl_list_for_each_safe (device, tmp, &seat.devices, link)
379- evdev_device_destroy(device);
380+ wl_event_source_remove(seat.libinput_source);
381+ libinput_unref(seat.libinput);
382+#ifdef ENABLE_LIBUDEV
383+ udev_unref(seat.udev);
384 #endif
385
386 pointer_finalize(&seat.pointer);