commit 1c1c5a8
Michael Forney
·
2014-07-16 01:40:39 +0000 UTC
parent a77e11d
Add optional support for libinput Fixes #5.
3 files changed,
+178,
-136
+5,
-5
1@@ -14,9 +14,9 @@ CFLAGS = -pipe
2 # PKG_CONFIG = pkg-config
3 # WAYLAND_SCANNER = wayland-scanner
4
5-ENABLE_DEBUG = 1
6-ENABLE_STATIC = 1
7-ENABLE_SHARED = 1
8-ENABLE_HOTPLUGGING = 1
9-ENABLE_XWAYLAND = 1
10+ENABLE_DEBUG = 1
11+ENABLE_STATIC = 1
12+ENABLE_SHARED = 1
13+ENABLE_LIBINPUT = 1
14+ENABLE_XWAYLAND = 1
15
+5,
-4
1@@ -35,7 +35,6 @@ SWC_SOURCES = \
2 libswc/data_device.c \
3 libswc/data_device_manager.c \
4 libswc/drm.c \
5- libswc/evdev_device.c \
6 libswc/framebuffer_plane.c \
7 libswc/input.c \
8 libswc/keyboard.c \
9@@ -61,9 +60,11 @@ SWC_SOURCES = \
10 protocol/swc-protocol.c \
11 protocol/wayland-drm-protocol.c
12
13-ifeq ($(ENABLE_HOTPLUGGING),1)
14-$(dir)_CFLAGS += -DENABLE_HOTPLUGGING
15-$(dir)_PACKAGES += libudev
16+ifeq ($(ENABLE_LIBINPUT),1)
17+$(dir)_CFLAGS += -DENABLE_LIBINPUT
18+$(dir)_PACKAGES += libinput libudev
19+else
20+SWC_SOURCES += libswc/evdev_device.c
21 endif
22
23 ifeq ($(ENABLE_XWAYLAND),1)
+168,
-127
1@@ -32,12 +32,15 @@
2 #include "pointer.h"
3 #include "util.h"
4
5+#include <errno.h>
6 #include <dirent.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10-#ifdef ENABLE_HOTPLUGGING
11+#include <unistd.h>
12+#ifdef ENABLE_LIBINPUT
13 # include <libudev.h>
14+# include <libinput.h>
15 #endif
16
17 static struct
18@@ -45,10 +48,12 @@ static struct
19 char * name;
20 uint32_t capabilities;
21
22-#ifdef ENABLE_HOTPLUGGING
23+#ifdef ENABLE_LIBINPUT
24 struct udev * udev;
25- struct udev_monitor * monitor;
26- struct wl_event_source * monitor_source;
27+ struct libinput * libinput;
28+ struct wl_event_source * libinput_source;
29+#else
30+ struct wl_list devices;
31 #endif
32
33 struct keyboard keyboard;
34@@ -57,7 +62,6 @@ static struct
35
36 struct wl_global * global;
37 struct wl_list resources;
38- struct wl_list devices;
39 } seat;
40
41 const struct swc_seat swc_seat = {
42@@ -86,13 +90,6 @@ static void handle_relative_motion(uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
43 pointer_handle_relative_motion(&seat.pointer, time, dx, dy);
44 }
45
46-const static struct swc_evdev_device_handler evdev_handler = {
47- .key = &handle_key,
48- .button = &handle_button,
49- .axis = &handle_axis,
50- .relative_motion = &handle_relative_motion
51-};
52-
53 static void handle_keyboard_focus_event(struct wl_listener * listener,
54 void * data)
55 {
56@@ -142,11 +139,22 @@ static struct wl_listener data_device_listener = {
57 static void handle_launch_event(struct wl_listener * listener, void * data)
58 {
59 struct swc_event * event = data;
60- struct swc_evdev_device * device, * next;
61
62 switch (event->type)
63 {
64+ case SWC_LAUNCH_EVENT_DEACTIVATED:
65+#ifdef ENABLE_LIBINPUT
66+ libinput_suspend(seat.libinput);
67+#endif
68+ break;
69 case SWC_LAUNCH_EVENT_ACTIVATED:
70+ {
71+#ifdef ENABLE_LIBINPUT
72+ if (libinput_resume(seat.libinput) != 0)
73+ WARNING("Failed to resume libinput context\n");
74+#else
75+ struct swc_evdev_device * device, * next;
76+
77 /* Re-open all input devices */
78 wl_list_for_each_safe(device, next, &seat.devices, link)
79 {
80@@ -156,8 +164,9 @@ static void handle_launch_event(struct wl_listener * listener, void * data)
81 swc_evdev_device_destroy(device);
82 }
83 }
84-
85+#endif
86 break;
87+ }
88 }
89 }
90
91@@ -209,159 +218,194 @@ static void bind_seat(struct wl_client * client, void * data, uint32_t version,
92 wl_seat_send_capabilities(resource, seat.capabilities);
93 }
94
95-static void add_device(const char * path)
96+#ifdef ENABLE_LIBINPUT
97+static int open_restricted(const char * path, int flags, void * user_data)
98 {
99- struct swc_evdev_device * device;
100-
101- if (!(device = swc_evdev_device_new(path, &evdev_handler)))
102- {
103- ERROR("Could not create evdev device\n");
104- return;
105- }
106-
107- if (~seat.capabilities & device->capabilities)
108- {
109- struct wl_resource * resource;
110-
111- seat.capabilities |= device->capabilities;
112- wl_list_for_each(resource, &seat.resources, link)
113- wl_seat_send_capabilities(resource, seat.capabilities);
114- }
115-
116- wl_list_insert(&seat.devices, &device->link);
117+ return swc_launch_open_device(path, flags);
118 }
119
120-static int select_device(const struct dirent * entry)
121+static void close_restricted(int fd, void * user_data)
122 {
123- unsigned num;
124-
125- return sscanf(entry->d_name, "event%u", &num) == 1;
126+ close(fd);
127 }
128
129-static bool add_devices()
130-{
131- struct dirent ** devices;
132- int num_devices;
133- char path[64];
134- unsigned index;
135+const struct libinput_interface libinput_interface = {
136+ .open_restricted = &open_restricted,
137+ .close_restricted = &close_restricted,
138+};
139
140- num_devices = scandir("/dev/input", &devices, &select_device, &alphasort);
141+static int handle_libinput_data(int fd, uint32_t mask, void * data)
142+{
143+ struct libinput_event * generic_event;
144
145- if (num_devices == -1)
146+ if (libinput_dispatch(seat.libinput) != 0)
147 {
148- ERROR("Failed to scan /dev/input for event devices\n");
149- return false;
150+ WARNING("libinput_dispatch failed: %s\n", strerror(errno));
151+ return 0;
152 }
153
154- for (index = 0; index < num_devices; ++index)
155+ while ((generic_event = libinput_get_event(seat.libinput)))
156 {
157- snprintf(path, sizeof path, "/dev/input/%s", devices[index]->d_name);
158- free(devices[index]);
159- add_device(path);
160- }
161-
162- free(devices);
163-
164- return true;
165-}
166-
167-#ifdef ENABLE_HOTPLUGGING
168-static int handle_monitor_data(int fd, uint32_t mask, void * data)
169-{
170- struct udev_device * udev_device;
171- const char * path, * action, * sysname;
172- unsigned num;
173-
174- if (!(udev_device = udev_monitor_receive_device(seat.monitor)))
175- return 0;
176-
177- if (!(action = udev_device_get_action(udev_device)))
178- goto done;
179-
180- sysname = udev_device_get_sysname(udev_device);
181-
182- if (sscanf(sysname, "event%u", &num) != 1)
183- goto done;
184-
185- path = udev_device_get_devnode(udev_device);
186+ switch (libinput_event_get_type(generic_event))
187+ {
188+ case LIBINPUT_EVENT_KEYBOARD_KEY:
189+ {
190+ struct libinput_event_keyboard * event;
191
192- if (strcmp(action, "add") == 0)
193- add_device(path);
194- else if (strcmp(action, "remove") == 0)
195- {
196- struct swc_evdev_device * device, * next;
197+ event = libinput_event_get_keyboard_event(generic_event);
198+ handle_key(libinput_event_keyboard_get_time(event),
199+ libinput_event_keyboard_get_key(event),
200+ libinput_event_keyboard_get_key_state(event));
201+ break;
202+ }
203+ case LIBINPUT_EVENT_POINTER_MOTION:
204+ {
205+ struct libinput_event_pointer * event;
206+ wl_fixed_t dx, dy;
207+
208+ event = libinput_event_get_pointer_event(generic_event);
209+ dx = wl_fixed_from_double(libinput_event_pointer_get_dx(event));
210+ dy = wl_fixed_from_double(libinput_event_pointer_get_dy(event));
211+ handle_relative_motion(libinput_event_pointer_get_time(event),
212+ dx, dy);
213+ break;
214+ }
215+ case LIBINPUT_EVENT_POINTER_BUTTON:
216+ {
217+ struct libinput_event_pointer * event;
218
219- wl_list_for_each_safe(device, next, &seat.devices, link)
220- {
221- if (strcmp(device->path, path) == 0)
222+ event = libinput_event_get_pointer_event(generic_event);
223+ handle_button(libinput_event_pointer_get_time(event),
224+ libinput_event_pointer_get_button(event),
225+ libinput_event_pointer_get_button_state(event));
226+ break;
227+ }
228+ case LIBINPUT_EVENT_POINTER_AXIS:
229 {
230- wl_list_remove(&device->link);
231- swc_evdev_device_destroy(device);
232+ struct libinput_event_pointer * event;
233+ wl_fixed_t amount;
234+
235+ event = libinput_event_get_pointer_event(generic_event);
236+ amount = wl_fixed_from_double
237+ (libinput_event_pointer_get_axis_value(event));
238+ handle_axis(libinput_event_pointer_get_time(event),
239+ libinput_event_pointer_get_axis(event), amount);
240 break;
241 }
242+ default:
243+ break;
244 }
245+
246+ libinput_event_destroy(generic_event);
247 }
248
249- done:
250- udev_device_unref(udev_device);
251 return 0;
252 }
253
254-bool initialize_monitor()
255+bool initialize_libinput(const char * seat_name)
256 {
257- int fd;
258-
259 if (!(seat.udev = udev_new()))
260 {
261 ERROR("Could not create udev context\n");
262 goto error0;
263 }
264
265- if (!(seat.monitor = udev_monitor_new_from_netlink(seat.udev, "udev")))
266- {
267- ERROR("Could not create udev monitor\n");
268- goto error1;
269- }
270+ seat.libinput = libinput_udev_create_context(&libinput_interface, NULL,
271+ seat.udev);
272
273- if (udev_monitor_filter_add_match_subsystem_devtype(seat.monitor,
274- "input", NULL) != 0)
275+ if (!seat.libinput)
276 {
277- ERROR("Could not set up udev monitor filter\n");
278- goto error2;
279+ ERROR("Could not create libinput context\n");
280+ goto error1;
281 }
282
283- if (udev_monitor_enable_receiving(seat.monitor) != 0)
284+ if (libinput_udev_assign_seat(seat.libinput, seat_name) != 0)
285 {
286- ERROR("Could not enable receiving for udev monitor\n");
287+ ERROR("Failed to assign seat to libinput context\n");
288 goto error2;
289 }
290
291- fd = udev_monitor_get_fd(seat.monitor);
292- seat.monitor_source = wl_event_loop_add_fd
293- (swc.event_loop, fd, WL_EVENT_READABLE, &handle_monitor_data, NULL);
294+ seat.libinput_source = wl_event_loop_add_fd
295+ (swc.event_loop, libinput_get_fd(seat.libinput), WL_EVENT_READABLE,
296+ &handle_libinput_data, NULL);
297
298- if (!seat.monitor_source)
299+ if (!seat.libinput_source)
300 {
301- ERROR("Could not create event source for udev monitor\n");
302+ ERROR("Could not create event source for libinput\n");
303 goto error2;
304 }
305
306 return true;
307
308 error2:
309- udev_monitor_unref(seat.monitor);
310+ libinput_unref(seat.libinput);
311 error1:
312 udev_unref(seat.udev);
313 error0:
314 return false;
315 }
316
317-void finalize_monitor()
318+void finalize_libinput()
319 {
320- wl_event_source_remove(seat.monitor_source);
321- udev_monitor_unref(seat.monitor);
322+ wl_event_source_remove(seat.libinput_source);
323+ libinput_unref(seat.libinput);
324 udev_unref(seat.udev);
325 }
326+#else
327+const static struct swc_evdev_device_handler evdev_handler = {
328+ .key = &handle_key,
329+ .button = &handle_button,
330+ .axis = &handle_axis,
331+ .relative_motion = &handle_relative_motion,
332+};
333+
334+static void add_device(const char * path)
335+{
336+ struct swc_evdev_device * device;
337+
338+ if (!(device = swc_evdev_device_new(path, &evdev_handler)))
339+ {
340+ ERROR("Could not create evdev device\n");
341+ return;
342+ }
343+
344+ update_capabilities(device->capabilities);
345+ wl_list_insert(&seat.devices, &device->link);
346+}
347+
348+static int select_device(const struct dirent * entry)
349+{
350+ unsigned num;
351+
352+ return sscanf(entry->d_name, "event%u", &num) == 1;
353+}
354+
355+static bool add_devices()
356+{
357+ struct dirent ** devices;
358+ int num_devices;
359+ char path[64];
360+ unsigned index;
361+
362+ num_devices = scandir("/dev/input", &devices, &select_device, &alphasort);
363+
364+ if (num_devices == -1)
365+ {
366+ ERROR("Failed to scan /dev/input for event devices\n");
367+ return false;
368+ }
369+
370+ for (index = 0; index < num_devices; ++index)
371+ {
372+ snprintf(path, sizeof path, "/dev/input/%s", devices[index]->d_name);
373+ free(devices[index]);
374+ add_device(path);
375+ }
376+
377+ free(devices);
378+
379+ return true;
380+}
381 #endif
382
383 bool swc_seat_initialize(const char * seat_name)
384@@ -380,7 +424,6 @@ bool swc_seat_initialize(const char * seat_name)
385
386 seat.capabilities = 0;
387 wl_list_init(&seat.resources);
388- wl_list_init(&seat.devices);
389 wl_signal_add(&swc.launch->event_signal, &launch_listener);
390
391 if (!swc_data_device_initialize(&seat.data_device))
392@@ -405,21 +448,19 @@ bool swc_seat_initialize(const char * seat_name)
393 goto error4;
394 }
395
396-#ifdef ENABLE_HOTPLUGGING
397- if (!initialize_monitor())
398+#ifdef ENABLE_LIBINPUT
399+ if (!initialize_libinput(seat.name))
400 goto error5;
401-#endif
402+#else
403+ wl_list_init(&seat.devices);
404
405 if (!add_devices())
406- goto error6;
407+ goto error5;
408+#endif
409
410 return true;
411
412- error6:
413-#ifdef ENABLE_HOTPLUGGING
414- finalize_monitor();
415 error5:
416-#endif
417 pointer_finalize(&seat.pointer);
418 error4:
419 keyboard_finalize(&seat.keyboard);
420@@ -435,17 +476,17 @@ bool swc_seat_initialize(const char * seat_name)
421
422 void swc_seat_finalize()
423 {
424+#ifdef ENABLE_LIBINPUT
425+ finalize_libinput();
426+#else
427 struct swc_evdev_device * device, * tmp;
428-
429-#ifdef ENABLE_HOTPLUGGING
430- finalize_monitor();
431+ wl_list_for_each_safe(device, tmp, &seat.devices, link)
432+ swc_evdev_device_destroy(device);
433 #endif
434+
435 pointer_finalize(&seat.pointer);
436 keyboard_finalize(&seat.keyboard);
437
438- wl_list_for_each_safe(device, tmp, &seat.devices, link)
439- swc_evdev_device_destroy(device);
440-
441 wl_global_destroy(seat.global);
442 free(seat.name);
443 }