evdev: Make evdev manage its seat reference
[platform/upstream/libinput.git] / src / udev-seat.c
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30
31 #include "evdev.h"
32 #include "udev-seat.h"
33
34 static const char default_seat[] = "seat0";
35 static const char default_seat_name[] = "default";
36
37 static struct udev_seat *
38 udev_seat_create(struct udev_input *input,
39                  const char *device_seat,
40                  const char *seat_name);
41 static struct udev_seat *
42 udev_seat_get_named(struct udev_input *input, const char *seat_name);
43
44 static int
45 device_added(struct udev_device *udev_device, struct udev_input *input)
46 {
47         struct libinput *libinput = &input->base;
48         struct evdev_device *device;
49         const char *devnode;
50         const char *sysname;
51         const char *device_seat, *seat_name, *output_name;
52         const char *calibration_values;
53         int fd;
54         struct udev_seat *seat;
55
56         device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
57         if (!device_seat)
58                 device_seat = default_seat;
59
60         if (strcmp(device_seat, input->seat_id))
61                 return 0;
62
63         devnode = udev_device_get_devnode(udev_device);
64         sysname = udev_device_get_sysname(udev_device);
65
66         /* Search for matching logical seat */
67         seat_name = udev_device_get_property_value(udev_device, "WL_SEAT");
68         if (!seat_name)
69                 seat_name = default_seat_name;
70
71         seat = udev_seat_get_named(input, seat_name);
72
73         if (seat)
74                 libinput_seat_ref(&seat->base);
75         else {
76                 seat = udev_seat_create(input, device_seat, seat_name);
77                 if (!seat)
78                         return -1;
79         }
80
81         /* Use non-blocking mode so that we can loop on read on
82          * evdev_device_data() until all events on the fd are
83          * read.  mtdev_get() also expects this. */
84         fd = open_restricted(libinput, devnode, O_RDWR | O_NONBLOCK);
85         if (fd < 0) {
86                 log_info("opening input device '%s' failed (%s).\n",
87                          devnode, strerror(-fd));
88                 libinput_seat_unref(&seat->base);
89                 return 0;
90         }
91
92         device = evdev_device_create(&seat->base, devnode, sysname, fd);
93         libinput_seat_unref(&seat->base);
94
95         if (device == EVDEV_UNHANDLED_DEVICE) {
96                 close_restricted(libinput, fd);
97                 log_info("not using input device '%s'.\n", devnode);
98                 return 0;
99         } else if (device == NULL) {
100                 close_restricted(libinput, fd);
101                 log_info("failed to create input device '%s'.\n", devnode);
102                 return 0;
103         }
104
105         calibration_values =
106                 udev_device_get_property_value(udev_device,
107                                                "WL_CALIBRATION");
108
109         if (calibration_values && sscanf(calibration_values,
110                                          "%f %f %f %f %f %f",
111                                          &device->abs.calibration[0],
112                                          &device->abs.calibration[1],
113                                          &device->abs.calibration[2],
114                                          &device->abs.calibration[3],
115                                          &device->abs.calibration[4],
116                                          &device->abs.calibration[5]) == 6) {
117                 device->abs.apply_calibration = 1;
118                 log_info("Applying calibration: %f %f %f %f %f %f\n",
119                          device->abs.calibration[0],
120                          device->abs.calibration[1],
121                          device->abs.calibration[2],
122                          device->abs.calibration[3],
123                          device->abs.calibration[4],
124                          device->abs.calibration[5]);
125         }
126
127         output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT");
128         if (output_name)
129                 device->output_name = strdup(output_name);
130
131         return 0;
132 }
133
134 static int
135 udev_input_add_devices(struct udev_input *input, struct udev *udev)
136 {
137         struct udev_enumerate *e;
138         struct udev_list_entry *entry;
139         struct udev_device *device;
140         const char *path, *sysname;
141
142         e = udev_enumerate_new(udev);
143         udev_enumerate_add_match_subsystem(e, "input");
144         udev_enumerate_scan_devices(e);
145         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
146                 path = udev_list_entry_get_name(entry);
147                 device = udev_device_new_from_syspath(udev, path);
148
149                 sysname = udev_device_get_sysname(device);
150                 if (strncmp("event", sysname, 5) != 0) {
151                         udev_device_unref(device);
152                         continue;
153                 }
154
155                 if (device_added(device, input) < 0) {
156                         udev_device_unref(device);
157                         udev_enumerate_unref(e);
158                         return -1;
159                 }
160
161                 udev_device_unref(device);
162         }
163         udev_enumerate_unref(e);
164
165         return 0;
166 }
167
168 static void
169 evdev_udev_handler(void *data)
170 {
171         struct udev_input *input = data;
172         struct libinput *libinput = &input->base;
173         struct udev_device *udev_device;
174         struct evdev_device *device, *next;
175         const char *action;
176         const char *devnode;
177         struct udev_seat *seat;
178
179         udev_device = udev_monitor_receive_device(input->udev_monitor);
180         if (!udev_device)
181                 return;
182
183         action = udev_device_get_action(udev_device);
184         if (!action)
185                 goto out;
186
187         if (strncmp("event", udev_device_get_sysname(udev_device), 5) != 0)
188                 goto out;
189
190         if (!strcmp(action, "add")) {
191                 device_added(udev_device, input);
192         }
193         else if (!strcmp(action, "remove")) {
194                 devnode = udev_device_get_devnode(udev_device);
195                 list_for_each(seat, &input->base.seat_list, base.link) {
196                         list_for_each_safe(device, next,
197                                            &seat->base.devices_list, base.link)
198                                 if (!strcmp(device->devnode, devnode)) {
199                                         log_info("input device %s, %s removed\n",
200                                                  device->devname, device->devnode);
201                                         close_restricted(libinput, device->fd);
202                                         evdev_device_remove(device);
203                                         break;
204                                 }
205                 }
206         }
207
208 out:
209         udev_device_unref(udev_device);
210 }
211
212 static void
213 udev_input_remove_devices(struct udev_input *input)
214 {
215         struct evdev_device *device, *next;
216         struct udev_seat *seat, *tmp;
217
218         list_for_each_safe(seat, tmp, &input->base.seat_list, base.link) {
219                 libinput_seat_ref(&seat->base);
220                 list_for_each_safe(device, next,
221                                    &seat->base.devices_list, base.link) {
222                         close_restricted(&input->base, device->fd);
223                         evdev_device_remove(device);
224                         if (list_empty(&seat->base.devices_list)) {
225                                 /* if the seat may be referenced by the
226                                    client, so make sure it's dropped from
227                                    the seat list now, to be freed whenever
228                                  * the device is removed */
229                                 list_remove(&seat->base.link);
230                                 list_init(&seat->base.link);
231                         }
232                 }
233                 libinput_seat_unref(&seat->base);
234         }
235 }
236
237
238 static void
239 udev_input_disable(struct libinput *libinput)
240 {
241         struct udev_input *input = (struct udev_input*)libinput;
242
243         if (!input->udev_monitor)
244                 return;
245
246         udev_monitor_unref(input->udev_monitor);
247         input->udev_monitor = NULL;
248         libinput_remove_source(&input->base, input->udev_monitor_source);
249         input->udev_monitor_source = NULL;
250
251         udev_input_remove_devices(input);
252 }
253
254 static int
255 udev_input_enable(struct libinput *libinput)
256 {
257         struct udev_input *input = (struct udev_input*)libinput;
258         struct udev *udev = input->udev;
259         int fd;
260
261         if (input->udev_monitor)
262                 return 0;
263
264         input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
265         if (!input->udev_monitor) {
266                 log_info("udev: failed to create the udev monitor\n");
267                 return -1;
268         }
269
270         udev_monitor_filter_add_match_subsystem_devtype(input->udev_monitor,
271                         "input", NULL);
272
273         if (udev_monitor_enable_receiving(input->udev_monitor)) {
274                 log_info("udev: failed to bind the udev monitor\n");
275                 udev_monitor_unref(input->udev_monitor);
276                 input->udev_monitor = NULL;
277                 return -1;
278         }
279
280         fd = udev_monitor_get_fd(input->udev_monitor);
281         input->udev_monitor_source = libinput_add_fd(&input->base,
282                                                      fd,
283                                                      evdev_udev_handler,
284                                                      input);
285         if (!input->udev_monitor_source) {
286                 udev_monitor_unref(input->udev_monitor);
287                 input->udev_monitor = NULL;
288                 return -1;
289         }
290
291         if (udev_input_add_devices(input, udev) < 0) {
292                 udev_input_disable(libinput);
293                 return -1;
294         }
295
296         return 0;
297 }
298
299 static void
300 udev_input_destroy(struct libinput *input)
301 {
302         struct udev_input *udev_input = (struct udev_input*)input;
303
304         if (input == NULL)
305                 return;
306
307         udev_unref(udev_input->udev);
308         free(udev_input->seat_id);
309 }
310
311 static void
312 udev_seat_destroy(struct libinput_seat *seat)
313 {
314         struct udev_seat *useat = (struct udev_seat*)seat;
315         free(useat);
316 }
317
318 static struct udev_seat *
319 udev_seat_create(struct udev_input *input,
320                  const char *device_seat,
321                  const char *seat_name)
322 {
323         struct udev_seat *seat;
324
325         seat = zalloc(sizeof *seat);
326         if (!seat)
327                 return NULL;
328
329         libinput_seat_init(&seat->base, &input->base,
330                            device_seat, seat_name,
331                            udev_seat_destroy);
332         list_insert(&input->base.seat_list, &seat->base.link);
333
334         return seat;
335 }
336
337 static struct udev_seat *
338 udev_seat_get_named(struct udev_input *input, const char *seat_name)
339 {
340         struct udev_seat *seat;
341
342         list_for_each(seat, &input->base.seat_list, base.link) {
343                 if (strcmp(seat->base.logical_name, seat_name) == 0)
344                         return seat;
345         }
346
347         return NULL;
348 }
349
350 static const struct libinput_interface_backend interface_backend = {
351         .resume = udev_input_enable,
352         .suspend = udev_input_disable,
353         .destroy = udev_input_destroy,
354 };
355
356 LIBINPUT_EXPORT struct libinput *
357 libinput_create_from_udev(const struct libinput_interface *interface,
358                           void *user_data,
359                           struct udev *udev,
360                           const char *seat_id)
361 {
362         struct udev_input *input;
363
364         if (!interface || !udev || !seat_id)
365                 return NULL;
366
367         input = zalloc(sizeof *input);
368         if (!input)
369                 return NULL;
370
371         if (libinput_init(&input->base, interface,
372                           &interface_backend, user_data) != 0) {
373                 free(input);
374                 return NULL;
375         }
376
377         input->udev = udev_ref(udev);
378         input->seat_id = strdup(seat_id);
379
380         if (udev_input_enable(&input->base) < 0) {
381                 udev_unref(udev);
382                 libinput_destroy(&input->base);
383                 free(input);
384                 return NULL;
385         }
386
387         return &input->base;
388 }