1 /*
2 * Copyright © 2013-2015 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "config.h"
25
26 #include <string.h>
27 #include <sys/stat.h>
28 #include <libudev.h>
29
30 #include "evdev.h"
31
32 struct path_input {
33 struct libinput base;
34 struct udev *udev;
35 struct list path_list;
36 };
37
38 struct path_device {
39 struct list link;
40 struct udev_device *udev_device;
41 };
42
43 struct path_seat {
44 struct libinput_seat base;
45 };
46
47
48 static const char default_seat[] = "seat0";
49 static const char default_seat_name[] = "default";
50
51 static void
path_disable_device(struct libinput * libinput,struct evdev_device * device)52 path_disable_device(struct libinput *libinput,
53 struct evdev_device *device)
54 {
55 struct libinput_seat *seat = device->base.seat;
56 struct evdev_device *dev, *next;
57
58 list_for_each_safe(dev, next,
59 &seat->devices_list, base.link) {
60 if (dev != device)
61 continue;
62
63 evdev_device_remove(device);
64 break;
65 }
66 }
67
68 static void
path_input_disable(struct libinput * libinput)69 path_input_disable(struct libinput *libinput)
70 {
71 struct path_input *input = (struct path_input*)libinput;
72 struct path_seat *seat, *tmp;
73 struct evdev_device *device, *next;
74
75 list_for_each_safe(seat, tmp, &input->base.seat_list, base.link) {
76 libinput_seat_ref(&seat->base);
77 list_for_each_safe(device, next,
78 &seat->base.devices_list, base.link)
79 path_disable_device(libinput, device);
80 libinput_seat_unref(&seat->base);
81 }
82 }
83
84 static void
path_seat_destroy(struct libinput_seat * seat)85 path_seat_destroy(struct libinput_seat *seat)
86 {
87 struct path_seat *pseat = (struct path_seat*)seat;
88 free(pseat);
89 }
90
91 static struct path_seat*
path_seat_create(struct path_input * input,const char * seat_name,const char * seat_logical_name)92 path_seat_create(struct path_input *input,
93 const char *seat_name,
94 const char *seat_logical_name)
95 {
96 struct path_seat *seat;
97
98 seat = zalloc(sizeof(*seat));
99
100 libinput_seat_init(&seat->base, &input->base, seat_name,
101 seat_logical_name, path_seat_destroy);
102
103 return seat;
104 }
105
106 static struct path_seat*
path_seat_get_named(struct path_input * input,const char * seat_name_physical,const char * seat_name_logical)107 path_seat_get_named(struct path_input *input,
108 const char *seat_name_physical,
109 const char *seat_name_logical)
110 {
111 struct path_seat *seat;
112
113 list_for_each(seat, &input->base.seat_list, base.link) {
114 if (streq(seat->base.physical_name, seat_name_physical) &&
115 streq(seat->base.logical_name, seat_name_logical))
116 return seat;
117 }
118
119 return NULL;
120 }
121
122 static struct path_seat *
path_seat_get_for_device(struct path_input * input,struct udev_device * udev_device,const char * seat_logical_name_override)123 path_seat_get_for_device(struct path_input *input,
124 struct udev_device *udev_device,
125 const char *seat_logical_name_override)
126 {
127 struct path_seat *seat = NULL;
128 char *seat_name = NULL, *seat_logical_name = NULL;
129 const char *seat_prop;
130
131 const char *devnode, *sysname;
132
133 devnode = udev_device_get_devnode(udev_device);
134 sysname = udev_device_get_sysname(udev_device);
135
136 seat_prop = udev_device_get_property_value(udev_device, "ID_SEAT");
137 seat_name = safe_strdup(seat_prop ? seat_prop : default_seat);
138
139 if (seat_logical_name_override) {
140 seat_logical_name = safe_strdup(seat_logical_name_override);
141 } else {
142 seat_prop = udev_device_get_property_value(udev_device, "WL_SEAT");
143 seat_logical_name = strdup(seat_prop ? seat_prop : default_seat_name);
144 }
145
146 if (!seat_logical_name) {
147 log_error(&input->base,
148 "%s: failed to create seat name for device '%s'.\n",
149 sysname,
150 devnode);
151 goto out;
152 }
153
154 seat = path_seat_get_named(input, seat_name, seat_logical_name);
155
156 if (!seat)
157 seat = path_seat_create(input, seat_name, seat_logical_name);
158 if (!seat) {
159 log_info(&input->base,
160 "%s: failed to create seat for device '%s'.\n",
161 sysname,
162 devnode);
163 goto out;
164 }
165
166 libinput_seat_ref(&seat->base);
167 out:
168 free(seat_name);
169 free(seat_logical_name);
170
171 return seat;
172 }
173
174 static struct libinput_device *
path_device_enable(struct path_input * input,struct udev_device * udev_device,const char * seat_logical_name_override)175 path_device_enable(struct path_input *input,
176 struct udev_device *udev_device,
177 const char *seat_logical_name_override)
178 {
179 struct path_seat *seat;
180 struct evdev_device *device = NULL;
181 const char *output_name;
182 const char *devnode, *sysname;
183
184 devnode = udev_device_get_devnode(udev_device);
185 sysname = udev_device_get_sysname(udev_device);
186
187 seat = path_seat_get_for_device(input, udev_device, seat_logical_name_override);
188 if (!seat)
189 goto out;
190
191 device = evdev_device_create(&seat->base, udev_device);
192 libinput_seat_unref(&seat->base);
193
194 if (device == EVDEV_UNHANDLED_DEVICE) {
195 device = NULL;
196 log_info(&input->base,
197 "%-7s - not using input device '%s'.\n",
198 sysname,
199 devnode);
200 goto out;
201 } else if (device == NULL) {
202 log_info(&input->base,
203 "%-7s - failed to create input device '%s'.\n",
204 sysname,
205 devnode);
206 goto out;
207 }
208
209 evdev_read_calibration_prop(device);
210 output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT");
211 device->output_name = safe_strdup(output_name);
212
213 out:
214 return device ? &device->base : NULL;
215 }
216
217 static int
path_input_enable(struct libinput * libinput)218 path_input_enable(struct libinput *libinput)
219 {
220 struct path_input *input = (struct path_input*)libinput;
221 struct path_device *dev;
222
223 list_for_each(dev, &input->path_list, link) {
224 if (path_device_enable(input, dev->udev_device, NULL) == NULL) {
225 path_input_disable(libinput);
226 return -1;
227 }
228 }
229
230 return 0;
231 }
232
233 static void
path_device_destroy(struct path_device * dev)234 path_device_destroy(struct path_device *dev)
235 {
236 list_remove(&dev->link);
237 udev_device_unref(dev->udev_device);
238 free(dev);
239 }
240
241 static void
path_input_destroy(struct libinput * input)242 path_input_destroy(struct libinput *input)
243 {
244 struct path_input *path_input = (struct path_input*)input;
245 struct path_device *dev, *tmp;
246
247 udev_unref(path_input->udev);
248
249 list_for_each_safe(dev, tmp, &path_input->path_list, link)
250 path_device_destroy(dev);
251
252 }
253
254 static struct libinput_device *
path_create_device(struct libinput * libinput,struct udev_device * udev_device,const char * seat_name)255 path_create_device(struct libinput *libinput,
256 struct udev_device *udev_device,
257 const char *seat_name)
258 {
259 struct path_input *input = (struct path_input*)libinput;
260 struct path_device *dev;
261 struct libinput_device *device;
262
263 dev = zalloc(sizeof *dev);
264 dev->udev_device = udev_device_ref(udev_device);
265
266 list_insert(&input->path_list, &dev->link);
267
268 device = path_device_enable(input, udev_device, seat_name);
269
270 if (!device)
271 path_device_destroy(dev);
272
273 return device;
274 }
275
276 static int
path_device_change_seat(struct libinput_device * device,const char * seat_name)277 path_device_change_seat(struct libinput_device *device,
278 const char *seat_name)
279 {
280 struct libinput *libinput = device->seat->libinput;
281 struct evdev_device *evdev = evdev_device(device);
282 struct udev_device *udev_device = NULL;
283 int rc = -1;
284
285 udev_device = evdev->udev_device;
286 udev_device_ref(udev_device);
287 libinput_path_remove_device(device);
288
289 if (path_create_device(libinput, udev_device, seat_name) != NULL)
290 rc = 0;
291 udev_device_unref(udev_device);
292 return rc;
293 }
294
295 static const struct libinput_interface_backend interface_backend = {
296 .resume = path_input_enable,
297 .suspend = path_input_disable,
298 .destroy = path_input_destroy,
299 .device_change_seat = path_device_change_seat,
300 };
301
302 LIBINPUT_EXPORT struct libinput *
libinput_path_create_context(const struct libinput_interface * interface,void * user_data)303 libinput_path_create_context(const struct libinput_interface *interface,
304 void *user_data)
305 {
306 struct path_input *input;
307 struct udev *udev;
308
309 if (!interface)
310 return NULL;
311
312 udev = udev_new();
313 if (!udev)
314 return NULL;
315
316 input = zalloc(sizeof *input);
317 if (libinput_init(&input->base, interface,
318 &interface_backend, user_data) != 0) {
319 udev_unref(udev);
320 free(input);
321 return NULL;
322 }
323
324 input->udev = udev;
325 list_init(&input->path_list);
326
327 return &input->base;
328 }
329
330 static inline struct udev_device *
udev_device_from_devnode(struct libinput * libinput,struct udev * udev,const char * devnode)331 udev_device_from_devnode(struct libinput *libinput,
332 struct udev *udev,
333 const char *devnode)
334 {
335 struct udev_device *dev;
336 struct stat st;
337 size_t count = 0;
338
339 if (stat(devnode, &st) < 0)
340 return NULL;
341
342 dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
343
344 while (dev && !udev_device_get_is_initialized(dev)) {
345 udev_device_unref(dev);
346 count++;
347 if (count > 200) {
348 log_bug_libinput(libinput,
349 "udev device never initialized (%s)\n",
350 devnode);
351 return NULL;
352 }
353 msleep(10);
354 dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
355 }
356
357 return dev;
358 }
359
360 LIBINPUT_EXPORT struct libinput_device *
libinput_path_add_device(struct libinput * libinput,const char * path)361 libinput_path_add_device(struct libinput *libinput,
362 const char *path)
363 {
364 struct path_input *input = (struct path_input *)libinput;
365 struct udev *udev = input->udev;
366 struct udev_device *udev_device;
367 struct libinput_device *device;
368
369 if (strlen(path) > PATH_MAX) {
370 log_bug_client(libinput,
371 "Unexpected path, limited to %d characters.\n",
372 PATH_MAX);
373 return NULL;
374 }
375
376 if (libinput->interface_backend != &interface_backend) {
377 log_bug_client(libinput, "Mismatching backends.\n");
378 return NULL;
379 }
380
381 udev_device = udev_device_from_devnode(libinput, udev, path);
382 if (!udev_device) {
383 log_bug_client(libinput, "Invalid path %s\n", path);
384 return NULL;
385 }
386
387 if (ignore_litest_test_suite_device(udev_device)) {
388 udev_device_unref(udev_device);
389 return NULL;
390 }
391
392 /* We cannot do this during path_create_context because the log
393 * handler isn't set up there but we really want to log to the right
394 * place if the quirks run into parser errors. So we have to do it
395 * on the first call to add_device.
396 */
397 libinput_init_quirks(libinput);
398
399 device = path_create_device(libinput, udev_device, NULL);
400 udev_device_unref(udev_device);
401 return device;
402 }
403
404 LIBINPUT_EXPORT void
libinput_path_remove_device(struct libinput_device * device)405 libinput_path_remove_device(struct libinput_device *device)
406 {
407 struct libinput *libinput = device->seat->libinput;
408 struct path_input *input = (struct path_input*)libinput;
409 struct libinput_seat *seat;
410 struct evdev_device *evdev = evdev_device(device);
411 struct path_device *dev;
412
413 if (libinput->interface_backend != &interface_backend) {
414 log_bug_client(libinput, "Mismatching backends.\n");
415 return;
416 }
417
418 list_for_each(dev, &input->path_list, link) {
419 if (dev->udev_device == evdev->udev_device) {
420 path_device_destroy(dev);
421 break;
422 }
423 }
424
425 seat = device->seat;
426 libinput_seat_ref(seat);
427 path_disable_device(libinput, evdev);
428 libinput_seat_unref(seat);
429 }
430