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 32struct path_input { 33 struct libinput base; 34 struct udev *udev; 35 struct list path_list; 36}; 37 38struct path_device { 39 struct list link; 40 struct udev_device *udev_device; 41}; 42 43struct path_seat { 44 struct libinput_seat base; 45}; 46 47static const char default_seat[] = "seat0"; 48static const char default_seat_name[] = "default"; 49 50static void 51path_disable_device(struct evdev_device *device) 52{ 53 struct libinput_seat *seat = device->base.seat; 54 struct evdev_device *dev; 55 56 list_for_each_safe(dev, 57 &seat->devices_list, base.link) { 58 if (dev != device) 59 continue; 60 61 evdev_device_remove(device); 62 break; 63 } 64} 65 66static void 67path_input_disable(struct libinput *libinput) 68{ 69 struct path_input *input = (struct path_input*)libinput; 70 struct path_seat *seat; 71 struct evdev_device *device; 72 73 list_for_each_safe(seat, &input->base.seat_list, base.link) { 74 libinput_seat_ref(&seat->base); 75 list_for_each_safe(device, 76 &seat->base.devices_list, base.link) 77 path_disable_device(device); 78 libinput_seat_unref(&seat->base); 79 } 80} 81 82static void 83path_seat_destroy(struct libinput_seat *seat) 84{ 85 struct path_seat *pseat = (struct path_seat*)seat; 86 free(pseat); 87} 88 89static struct path_seat* 90path_seat_create(struct path_input *input, 91 const char *seat_name, 92 const char *seat_logical_name) 93{ 94 struct path_seat *seat; 95 96 seat = zalloc(sizeof(*seat)); 97 98 libinput_seat_init(&seat->base, &input->base, seat_name, 99 seat_logical_name, path_seat_destroy); 100 101 return seat; 102} 103 104static struct path_seat* 105path_seat_get_named(struct path_input *input, 106 const char *seat_name_physical, 107 const char *seat_name_logical) 108{ 109 struct path_seat *seat; 110 111 list_for_each(seat, &input->base.seat_list, base.link) { 112 if (streq(seat->base.physical_name, seat_name_physical) && 113 streq(seat->base.logical_name, seat_name_logical)) 114 return seat; 115 } 116 117 return NULL; 118} 119 120static struct path_seat * 121path_seat_get_for_device(struct path_input *input, 122 struct udev_device *udev_device, 123 const char *seat_logical_name_override) 124{ 125 struct path_seat *seat = NULL; 126 char *seat_name = NULL, *seat_logical_name = NULL; 127 const char *seat_prop; 128 129 const char *devnode, *sysname; 130 131 devnode = udev_device_get_devnode(udev_device); 132 sysname = udev_device_get_sysname(udev_device); 133 134 seat_prop = udev_device_get_property_value(udev_device, "ID_SEAT"); 135 seat_name = safe_strdup(seat_prop ? seat_prop : default_seat); 136 137 if (seat_logical_name_override) { 138 seat_logical_name = safe_strdup(seat_logical_name_override); 139 } else { 140 seat_prop = udev_device_get_property_value(udev_device, "WL_SEAT"); 141 seat_logical_name = safe_strdup(seat_prop ? seat_prop : default_seat_name); 142 } 143 144 if (!seat_logical_name) { 145 log_error(&input->base, 146 "%s: failed to create seat name for device '%s'.\n", 147 sysname, 148 devnode); 149 goto out; 150 } 151 152 seat = path_seat_get_named(input, seat_name, seat_logical_name); 153 154 if (!seat) 155 seat = path_seat_create(input, seat_name, seat_logical_name); 156 if (!seat) { 157 log_info(&input->base, 158 "%s: failed to create seat for device '%s'.\n", 159 sysname, 160 devnode); 161 goto out; 162 } 163 164 libinput_seat_ref(&seat->base); 165out: 166 free(seat_name); 167 free(seat_logical_name); 168 169 return seat; 170} 171 172static struct libinput_device * 173path_device_enable(struct path_input *input, 174 struct udev_device *udev_device, 175 const char *seat_logical_name_override) 176{ 177 struct path_seat *seat; 178 struct evdev_device *device = NULL; 179 const char *output_name; 180 const char *devnode, *sysname; 181 182 devnode = udev_device_get_devnode(udev_device); 183 sysname = udev_device_get_sysname(udev_device); 184 185 seat = path_seat_get_for_device(input, udev_device, seat_logical_name_override); 186 if (!seat) 187 goto out; 188 189 device = evdev_device_create(&seat->base, udev_device); 190 libinput_seat_unref(&seat->base); 191 192 if (device == EVDEV_UNHANDLED_DEVICE) { 193 device = NULL; 194 log_info(&input->base, 195 "%-7s - not using input device '%s'.\n", 196 sysname, 197 devnode); 198 goto out; 199 } else if (device == NULL) { 200 log_info(&input->base, 201 "%-7s - failed to create input device '%s'.\n", 202 sysname, 203 devnode); 204 goto out; 205 } 206 207 evdev_read_calibration_prop(device); 208 output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT"); 209 device->output_name = safe_strdup(output_name); 210 211out: 212 return device ? &device->base : NULL; 213} 214 215static int 216path_input_enable(struct libinput *libinput) 217{ 218 struct path_input *input = (struct path_input*)libinput; 219 struct path_device *dev; 220 221 list_for_each(dev, &input->path_list, link) { 222 if (path_device_enable(input, dev->udev_device, NULL) == NULL) { 223 path_input_disable(libinput); 224 return -1; 225 } 226 } 227 228 return 0; 229} 230 231static void 232path_device_destroy(struct path_device *dev) 233{ 234 list_remove(&dev->link); 235 udev_device_unref(dev->udev_device); 236 free(dev); 237} 238 239static void 240path_input_destroy(struct libinput *input) 241{ 242 struct path_input *path_input = (struct path_input*)input; 243 struct path_device *dev; 244 245 udev_unref(path_input->udev); 246 247 list_for_each_safe(dev, &path_input->path_list, link) 248 path_device_destroy(dev); 249 250} 251 252static struct libinput_device * 253path_create_device(struct libinput *libinput, 254 struct udev_device *udev_device, 255 const char *seat_name) 256{ 257 struct path_input *input = (struct path_input*)libinput; 258 struct path_device *dev; 259 struct libinput_device *device; 260 261 dev = zalloc(sizeof *dev); 262 dev->udev_device = udev_device_ref(udev_device); 263 264 list_insert(&input->path_list, &dev->link); 265 266 device = path_device_enable(input, udev_device, seat_name); 267 268 if (!device) 269 path_device_destroy(dev); 270 271 return device; 272} 273 274static int 275path_device_change_seat(struct libinput_device *device, 276 const char *seat_name) 277{ 278 struct libinput *libinput = device->seat->libinput; 279 struct evdev_device *evdev = evdev_device(device); 280 struct udev_device *udev_device = NULL; 281 int rc = -1; 282 283 udev_device = evdev->udev_device; 284 udev_device_ref(udev_device); 285 libinput_path_remove_device(device); 286 287 if (path_create_device(libinput, udev_device, seat_name) != NULL) 288 rc = 0; 289 udev_device_unref(udev_device); 290 return rc; 291} 292 293static const struct libinput_interface_backend interface_backend = { 294 .resume = path_input_enable, 295 .suspend = path_input_disable, 296 .destroy = path_input_destroy, 297 .device_change_seat = path_device_change_seat, 298}; 299 300LIBINPUT_EXPORT struct libinput * 301libinput_path_create_context(const struct libinput_interface *interface, 302 void *user_data) 303{ 304 struct path_input *input; 305 struct udev *udev; 306 307 if (!interface) 308 return NULL; 309 310 udev = udev_new(); 311 if (!udev) 312 return NULL; 313 314 input = zalloc(sizeof *input); 315 if (libinput_init(&input->base, interface, 316 &interface_backend, user_data) != 0) { 317 udev_unref(udev); 318 free(input); 319 return NULL; 320 } 321 322 input->udev = udev; 323 list_init(&input->path_list); 324 325 return &input->base; 326} 327 328static inline struct udev_device * 329udev_device_from_devnode(struct libinput *libinput, 330 struct udev *udev, 331 const char *devnode) 332{ 333 struct udev_device *dev; 334 struct stat st; 335 size_t count = 0; 336 337 if (stat(devnode, &st) < 0) 338 return NULL; 339 340 dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev); 341 342 while (dev && !udev_device_get_is_initialized(dev)) { 343 udev_device_unref(dev); 344 count++; 345 if (count > 200) { 346 log_bug_libinput(libinput, 347 "udev device never initialized (%s)\n", 348 devnode); 349 return NULL; 350 } 351 msleep(10); 352 dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev); 353 } 354 355 return dev; 356} 357 358LIBINPUT_EXPORT struct libinput_device * 359libinput_path_add_device(struct libinput *libinput, 360 const char *path) 361{ 362 struct path_input *input = (struct path_input *)libinput; 363 struct udev *udev = input->udev; 364 struct udev_device *udev_device; 365 struct libinput_device *device; 366 367 if (strlen(path) > PATH_MAX) { 368 log_bug_client(libinput, 369 "Unexpected path, limited to %d characters.\n", 370 PATH_MAX); 371 return NULL; 372 } 373 374 if (libinput->interface_backend != &interface_backend) { 375 log_bug_client(libinput, "Mismatching backends.\n"); 376 return NULL; 377 } 378 379 udev_device = udev_device_from_devnode(libinput, udev, path); 380 if (!udev_device) { 381 log_bug_client(libinput, "Invalid path %s\n", path); 382 return NULL; 383 } 384 385 if (ignore_litest_test_suite_device(udev_device)) { 386 udev_device_unref(udev_device); 387 return NULL; 388 } 389 390 /* We cannot do this during path_create_context because the log 391 * handler isn't set up there but we really want to log to the right 392 * place if the quirks run into parser errors. So we have to do it 393 * on the first call to add_device. 394 */ 395 libinput_init_quirks(libinput); 396 397 device = path_create_device(libinput, udev_device, NULL); 398 udev_device_unref(udev_device); 399 return device; 400} 401 402LIBINPUT_EXPORT void 403libinput_path_remove_device(struct libinput_device *device) 404{ 405 struct libinput *libinput = device->seat->libinput; 406 struct path_input *input = (struct path_input*)libinput; 407 struct libinput_seat *seat; 408 struct evdev_device *evdev = evdev_device(device); 409 struct path_device *dev; 410 411 if (libinput->interface_backend != &interface_backend) { 412 log_bug_client(libinput, "Mismatching backends.\n"); 413 return; 414 } 415 416 list_for_each_safe(dev, &input->path_list, link) { 417 if (dev->udev_device == evdev->udev_device) { 418 path_device_destroy(dev); 419 break; 420 } 421 } 422 423 seat = device->seat; 424 libinput_seat_ref(seat); 425 path_disable_device(evdev); 426 libinput_seat_unref(seat); 427} 428