X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fudev-seat.c;h=8d198947b559c3f4f99dd133af4fb43770be26bb;hb=bd8e3086939230a3501a6ee6ea3b2cdb1b2203a2;hp=b35555422b21af9c58188226bc9fc726062be6b9;hpb=ac1f1acb418f634c80f3bdea93ad7f2f7315b909;p=platform%2Fupstream%2Flibinput.git diff --git a/src/udev-seat.c b/src/udev-seat.c index b355554..8d19894 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -35,20 +35,20 @@ static const char default_seat[] = "seat0"; static const char default_seat_name[] = "default"; static struct udev_seat * -udev_seat_create(struct udev_input *input, const char *seat_name); +udev_seat_create(struct udev_input *input, + const char *device_seat, + const char *seat_name); static struct udev_seat * udev_seat_get_named(struct udev_input *input, const char *seat_name); static int device_added(struct udev_device *udev_device, struct udev_input *input) { - struct libinput *libinput = &input->base; struct evdev_device *device; const char *devnode; const char *sysname; const char *device_seat, *seat_name, *output_name; const char *calibration_values; - int fd; struct udev_seat *seat; device_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); @@ -68,26 +68,22 @@ device_added(struct udev_device *udev_device, struct udev_input *input) seat = udev_seat_get_named(input, seat_name); - if (seat == NULL) - return -1; - - /* Use non-blocking mode so that we can loop on read on - * evdev_device_data() until all events on the fd are - * read. mtdev_get() also expects this. */ - fd = open_restricted(libinput, devnode, O_RDWR | O_NONBLOCK); - if (fd < 0) { - log_info("opening input device '%s' failed (%s).\n", devnode, strerror(-fd)); - return 0; + if (seat) + libinput_seat_ref(&seat->base); + else { + seat = udev_seat_create(input, device_seat, seat_name); + if (!seat) + return -1; } - device = evdev_device_create(&seat->base, devnode, sysname, fd); + device = evdev_device_create(&seat->base, devnode, sysname); + libinput_seat_unref(&seat->base); + if (device == EVDEV_UNHANDLED_DEVICE) { - close_restricted(libinput, fd); - log_info("not using input device '%s'.\n", devnode); + log_info(&input->base, "not using input device '%s'.\n", devnode); return 0; } else if (device == NULL) { - close_restricted(libinput, fd); - log_info("failed to create input device '%s'.\n", devnode); + log_info(&input->base, "failed to create input device '%s'.\n", devnode); return 0; } @@ -104,7 +100,8 @@ device_added(struct udev_device *udev_device, struct udev_input *input) &device->abs.calibration[4], &device->abs.calibration[5]) == 6) { device->abs.apply_calibration = 1; - log_info("Applying calibration: %f %f %f %f %f %f\n", + log_info(&input->base, + "Applying calibration: %f %f %f %f %f %f\n", device->abs.calibration[0], device->abs.calibration[1], device->abs.calibration[2], @@ -120,6 +117,28 @@ device_added(struct udev_device *udev_device, struct udev_input *input) return 0; } +static void +device_removed(struct udev_device *udev_device, struct udev_input *input) +{ + const char *devnode; + struct evdev_device *device, *next; + struct udev_seat *seat; + + devnode = udev_device_get_devnode(udev_device); + list_for_each(seat, &input->base.seat_list, base.link) { + list_for_each_safe(device, next, + &seat->base.devices_list, base.link) { + if (!strcmp(device->devnode, devnode)) { + log_info(&input->base, + "input device %s, %s removed\n", + device->devname, device->devnode); + evdev_device_remove(device); + break; + } + } + } +} + static int udev_input_add_devices(struct udev_input *input, struct udev *udev) { @@ -158,12 +177,8 @@ static void evdev_udev_handler(void *data) { struct udev_input *input = data; - struct libinput *libinput = &input->base; struct udev_device *udev_device; - struct evdev_device *device, *next; const char *action; - const char *devnode; - struct udev_seat *seat; udev_device = udev_monitor_receive_device(input->udev_monitor); if (!udev_device) @@ -176,37 +191,61 @@ evdev_udev_handler(void *data) if (strncmp("event", udev_device_get_sysname(udev_device), 5) != 0) goto out; - if (!strcmp(action, "add")) { + if (!strcmp(action, "add")) device_added(udev_device, input); - } - else if (!strcmp(action, "remove")) { - devnode = udev_device_get_devnode(udev_device); - list_for_each(seat, &input->base.seat_list, base.link) { - list_for_each_safe(device, next, - &seat->base.devices_list, base.link) - if (!strcmp(device->devnode, devnode)) { - log_info("input device %s, %s removed\n", - device->devname, device->devnode); - close_restricted(libinput, device->fd); - evdev_device_remove(device); - break; - } - } - } + else if (!strcmp(action, "remove")) + device_removed(udev_device, input); out: udev_device_unref(udev_device); } -int -udev_input_enable(struct udev_input *input) +static void +udev_input_remove_devices(struct udev_input *input) { + struct evdev_device *device, *next; + struct udev_seat *seat, *tmp; + + list_for_each_safe(seat, tmp, &input->base.seat_list, base.link) { + libinput_seat_ref(&seat->base); + list_for_each_safe(device, next, + &seat->base.devices_list, base.link) { + evdev_device_remove(device); + } + libinput_seat_unref(&seat->base); + } +} + +static void +udev_input_disable(struct libinput *libinput) +{ + struct udev_input *input = (struct udev_input*)libinput; + + if (!input->udev_monitor) + return; + + udev_monitor_unref(input->udev_monitor); + input->udev_monitor = NULL; + libinput_remove_source(&input->base, input->udev_monitor_source); + input->udev_monitor_source = NULL; + + udev_input_remove_devices(input); +} + +static int +udev_input_enable(struct libinput *libinput) +{ + struct udev_input *input = (struct udev_input*)libinput; struct udev *udev = input->udev; int fd; + if (input->udev_monitor) + return 0; + input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (!input->udev_monitor) { - log_info("udev: failed to create the udev monitor\n"); + log_info(libinput, + "udev: failed to create the udev monitor\n"); return -1; } @@ -214,8 +253,9 @@ udev_input_enable(struct udev_input *input) "input", NULL); if (udev_monitor_enable_receiving(input->udev_monitor)) { - log_info("udev: failed to bind the udev monitor\n"); + log_info(libinput, "udev: failed to bind the udev monitor\n"); udev_monitor_unref(input->udev_monitor); + input->udev_monitor = NULL; return -1; } @@ -226,11 +266,12 @@ udev_input_enable(struct udev_input *input) input); if (!input->udev_monitor_source) { udev_monitor_unref(input->udev_monitor); + input->udev_monitor = NULL; return -1; } if (udev_input_add_devices(input, udev) < 0) { - udev_input_disable(input); + udev_input_disable(libinput); return -1; } @@ -238,53 +279,28 @@ udev_input_enable(struct udev_input *input) } static void -udev_input_remove_devices(struct udev_input *input) +udev_input_destroy(struct libinput *input) { - struct evdev_device *device, *next; - struct udev_seat *seat; - - list_for_each(seat, &input->base.seat_list, base.link) { - list_for_each_safe(device, next, - &seat->base.devices_list, base.link) { - close_restricted(&input->base, device->fd); - evdev_device_remove(device); - } - } -} + struct udev_input *udev_input = (struct udev_input*)input; -void -udev_input_disable(struct udev_input *input) -{ - if (!input->udev_monitor) + if (input == NULL) return; - udev_monitor_unref(input->udev_monitor); - input->udev_monitor = NULL; - libinput_remove_source(&input->base, input->udev_monitor_source); - input->udev_monitor_source = NULL; - - udev_input_remove_devices(input); + udev_unref(udev_input->udev); + free(udev_input->seat_id); } -void -udev_input_destroy(struct udev_input *input) +static void +udev_seat_destroy(struct libinput_seat *seat) { - struct libinput_seat *seat, *next; - - if (input == NULL) - return; - - udev_input_disable(input); - list_for_each_safe(seat, next, &input->base.seat_list, link) { - notify_removed_seat(seat); - libinput_seat_unref(seat); - } - udev_unref(input->udev); - free(input->seat_id); + struct udev_seat *useat = (struct udev_seat*)seat; + free(useat); } static struct udev_seat * -udev_seat_create(struct udev_input *input, const char *seat_name) +udev_seat_create(struct udev_input *input, + const char *device_seat, + const char *seat_name) { struct udev_seat *seat; @@ -292,67 +308,78 @@ udev_seat_create(struct udev_input *input, const char *seat_name) if (!seat) return NULL; - libinput_seat_init(&seat->base, &input->base, seat_name); - list_insert(&input->base.seat_list, &seat->base.link); - notify_added_seat(&seat->base); + libinput_seat_init(&seat->base, &input->base, + device_seat, seat_name, + udev_seat_destroy); return seat; } -void -udev_seat_destroy(struct udev_seat *seat) -{ - list_remove(&seat->base.link); - free(seat); -} - static struct udev_seat * udev_seat_get_named(struct udev_input *input, const char *seat_name) { struct udev_seat *seat; list_for_each(seat, &input->base.seat_list, base.link) { - if (strcmp(seat->base.name, seat_name) == 0) + if (strcmp(seat->base.logical_name, seat_name) == 0) return seat; } - seat = udev_seat_create(input, seat_name); - - if (!seat) - return NULL; - - return seat; + return NULL; } +static const struct libinput_interface_backend interface_backend = { + .resume = udev_input_enable, + .suspend = udev_input_disable, + .destroy = udev_input_destroy, +}; + LIBINPUT_EXPORT struct libinput * -libinput_create_from_udev(const struct libinput_interface *interface, - void *user_data, - struct udev *udev, - const char *seat_id) +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev) { struct udev_input *input; - if (!interface || !udev || !seat_id) + if (!interface || !udev) return NULL; input = zalloc(sizeof *input); if (!input) return NULL; - if (libinput_init(&input->base, interface, user_data) != 0) { + if (libinput_init(&input->base, interface, + &interface_backend, user_data) != 0) { + libinput_unref(&input->base); free(input); return NULL; } input->udev = udev_ref(udev); - input->seat_id = strdup(seat_id); - if (udev_input_enable(input) < 0) { - udev_unref(udev); - libinput_destroy(&input->base); - free(input); - return NULL; + return &input->base; +} + +LIBINPUT_EXPORT int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id) +{ + struct udev_input *input = (struct udev_input*)libinput; + + if (!seat_id) + return -1; + if (input->seat_id != NULL) + return -1; + + if (libinput->interface_backend != &interface_backend) { + log_bug_client(libinput, "Mismatching backends.\n"); + return -1; } - return &input->base; + input->seat_id = strdup(seat_id); + + if (udev_input_enable(&input->base) < 0) + return -1; + + return 0; }