commit f8e4d3d
Michael Forney
·
2014-01-20 23:33:31 +0000 UTC
parent 21b4199
evdev_device: Fix reopen
2 files changed,
+33,
-7
+32,
-7
1@@ -145,16 +145,27 @@ static void handle_event(struct swc_evdev_device * device,
2 }
3 }
4
5+static void close_device(struct swc_evdev_device * device)
6+{
7+ wl_event_source_remove(device->source);
8+ close(device->fd);
9+ device->source = NULL;
10+ device->fd = -1;
11+}
12+
13 static int handle_data(int fd, uint32_t mask, void * data)
14 {
15 struct swc_evdev_device * device = data;
16 struct input_event event;
17+ unsigned flags = device->needs_sync ? LIBEVDEV_READ_FLAG_FORCE_SYNC
18+ : LIBEVDEV_READ_FLAG_NORMAL;
19 int ret;
20
21+ device->needs_sync = false;
22+
23 while (true)
24 {
25- ret = libevdev_next_event(device->dev, LIBEVDEV_READ_FLAG_NORMAL,
26- &event);
27+ ret = libevdev_next_event(device->dev, flags, &event);
28
29 if (ret < 0)
30 goto done;
31@@ -177,10 +188,7 @@ static int handle_data(int fd, uint32_t mask, void * data)
32
33 done:
34 if (ret == -ENODEV)
35- {
36- wl_event_source_remove(device->source);
37- device->source = NULL;
38- }
39+ close_device(device);
40
41 handle_motion_events(device, timeval_to_msec(&event.time));
42
43@@ -223,6 +231,7 @@ struct swc_evdev_device * swc_evdev_device_new
44
45 DEBUG("Adding device %s\n", libevdev_get_name(device->dev));
46
47+ device->needs_sync = false;
48 device->handler = handler;
49 device->capabilities = 0;
50 memset(&device->motion, 0, sizeof device->motion);
51@@ -268,7 +277,8 @@ void swc_evdev_device_destroy(struct swc_evdev_device * device)
52
53 bool swc_evdev_device_reopen(struct swc_evdev_device * device)
54 {
55- close(device->fd);
56+ if (device->source)
57+ close_device(device);
58
59 device->fd = swc_launch_open_device(device->path,
60 O_RDWR | O_NONBLOCK | O_CLOEXEC);
61@@ -285,8 +295,23 @@ bool swc_evdev_device_reopen(struct swc_evdev_device * device)
62 goto error1;
63 }
64
65+ /* According to libevdev documentation, after changing the fd for the
66+ * device, you should force a sync to bring it's state up to date. */
67+ device->needs_sync = true;
68+ device->source = wl_event_loop_add_fd
69+ (swc.event_loop, device->fd, WL_EVENT_READABLE, handle_data, device);
70+
71+ if (!device->source)
72+ {
73+ ERROR("Failed to create event source\n");
74+ goto error1;
75+ }
76+
77+ return true;
78+
79 error1:
80 close(device->fd);
81+ device->fd = -1;
82 error0:
83 return false;
84 }
+1,
-0
1@@ -48,6 +48,7 @@ struct swc_evdev_device
2 char * path;
3 int fd;
4 struct libevdev * dev;
5+ bool needs_sync;
6
7 const struct swc_evdev_device_handler * handler;
8