summaryrefslogtreecommitdiff
path: root/src/udev-seat.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2014-01-15 16:31:29 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2014-01-17 18:17:11 +1000
commit5b5b6bca06562a3f558d8d582fbc90129f1f5d17 (patch)
tree2c0fedb282108efb7f360cc6da419f5460732e1d /src/udev-seat.c
parent06453ba7a533b919460d78de0edf1cd980bc638a (diff)
Drop seat events
seats are more a compositor concept than a concept of the input library. All devices in a libinput context are associated with the seat given on creation of the seat (maps to ID_SEAT in udev for the udev backend). A logical seat may be assigned to a device (e.g. WL_SEAT) but this does not necessarily map to the creation of the seat in the compositor. Drop the seat events but keep seat objects around so that the caller can still identify which seat a device belongs to. If the libinput_seat_unref() in the udev backend destroys the seat, the device list of that seat is invalid and we'd be accessing already freed bytes. To avoid this, ref the seat before the device removal loop, then unref it once we're done - that unref then may trigger the actual removal of the seat. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/udev-seat.c')
-rw-r--r--src/udev-seat.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/src/udev-seat.c b/src/udev-seat.c
index 610b45d3..1522c30f 100644
--- a/src/udev-seat.c
+++ b/src/udev-seat.c
@@ -198,8 +198,6 @@ evdev_udev_handler(void *data)
device->devname, device->devnode);
close_restricted(libinput, device->fd);
evdev_device_remove(device);
- if (list_empty(&seat->base.devices_list))
- notify_removed_seat(&seat->base);
libinput_seat_unref(&seat->base);
break;
}
@@ -217,21 +215,22 @@ udev_input_remove_devices(struct udev_input *input)
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) {
close_restricted(&input->base, device->fd);
evdev_device_remove(device);
if (list_empty(&seat->base.devices_list)) {
- notify_removed_seat(&seat->base);
- /* seat is referenced by the event, so make
- sure it's dropped from the seat list now,
- to be freed whenever the device is
- removed */
+ /* if the seat may be referenced by the
+ client, so make sure it's dropped from
+ the seat list now, to be freed whenever
+ the device is removed */
list_remove(&seat->base.link);
list_init(&seat->base.link);
}
libinput_seat_unref(&seat->base);
}
+ libinput_seat_unref(&seat->base);
}
}
@@ -327,7 +326,6 @@ udev_seat_create(struct udev_input *input, const char *seat_name)
libinput_seat_init(&seat->base, &input->base, seat_name, udev_seat_destroy);
list_insert(&input->base.seat_list, &seat->base.link);
- notify_added_seat(&seat->base);
return seat;
}