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