mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 03:30:05 +01:00
evdev: add a internal device notification mechanism
When a device is added or removed, notify all internal devices about the device change. This allows all devices to configure themselves depending on other devices in the system. Prime use-case here is an internal touchpad that wants to know if an external mouse is connected. On device added, notification goes both ways: existing devices are notified about the new device, and the new device is notified about existing devices. On device removed, notification only goes one way. In both cases, the internal notification is complete before the event is sent to the caller. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
195a02c7a4
commit
1c8a5ca659
3 changed files with 46 additions and 3 deletions
|
|
@ -678,7 +678,9 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
|
||||
static struct evdev_dispatch_interface tp_interface = {
|
||||
tp_process,
|
||||
tp_destroy
|
||||
tp_destroy,
|
||||
NULL, /* device_added */
|
||||
NULL, /* device_removed */
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
|||
37
src/evdev.c
37
src/evdev.c
|
|
@ -621,7 +621,9 @@ evdev_calibration_get_default_matrix(struct libinput_device *libinput_device,
|
|||
|
||||
struct evdev_dispatch_interface fallback_interface = {
|
||||
fallback_process,
|
||||
fallback_destroy
|
||||
fallback_destroy,
|
||||
NULL, /* device_added */
|
||||
NULL, /* device_removed */
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
|
|
@ -968,6 +970,26 @@ evdev_configure_device(struct evdev_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_notify_added_device(struct evdev_device *device)
|
||||
{
|
||||
struct libinput_device *dev;
|
||||
|
||||
list_for_each(dev, &device->base.seat->devices_list, link) {
|
||||
struct evdev_device *d = (struct evdev_device*)dev;
|
||||
if (dev == &device->base)
|
||||
continue;
|
||||
|
||||
if (d->dispatch->interface->device_added)
|
||||
d->dispatch->interface->device_added(d, device);
|
||||
|
||||
if (device->dispatch->interface->device_added)
|
||||
device->dispatch->interface->device_added(device, d);
|
||||
}
|
||||
|
||||
notify_added_device(&device->base);
|
||||
}
|
||||
|
||||
struct evdev_device *
|
||||
evdev_device_create(struct libinput_seat *seat,
|
||||
const char *devnode,
|
||||
|
|
@ -1042,7 +1064,7 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
goto err;
|
||||
|
||||
list_insert(seat->devices_list.prev, &device->base.link);
|
||||
notify_added_device(&device->base);
|
||||
evdev_notify_added_device(device);
|
||||
|
||||
return device;
|
||||
|
||||
|
|
@ -1341,6 +1363,17 @@ evdev_device_resume(struct evdev_device *device)
|
|||
void
|
||||
evdev_device_remove(struct evdev_device *device)
|
||||
{
|
||||
struct libinput_device *dev;
|
||||
|
||||
list_for_each(dev, &device->base.seat->devices_list, link) {
|
||||
struct evdev_device *d = (struct evdev_device*)dev;;
|
||||
if (dev == &device->base)
|
||||
continue;
|
||||
|
||||
if (d->dispatch->interface->device_removed)
|
||||
d->dispatch->interface->device_removed(d, device);
|
||||
}
|
||||
|
||||
evdev_device_suspend(device);
|
||||
|
||||
/* A device may be removed while suspended. Free the syspath to
|
||||
|
|
|
|||
|
|
@ -120,6 +120,14 @@ struct evdev_dispatch_interface {
|
|||
|
||||
/* Destroy an event dispatch handler and free all its resources. */
|
||||
void (*destroy)(struct evdev_dispatch *dispatch);
|
||||
|
||||
/* A new device was added */
|
||||
void (*device_added)(struct evdev_device *device,
|
||||
struct evdev_device *added_device);
|
||||
|
||||
/* A device was removed */
|
||||
void (*device_removed)(struct evdev_device *device,
|
||||
struct evdev_device *removed_device);
|
||||
};
|
||||
|
||||
struct evdev_dispatch {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue