mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-06 01:20:17 +01:00
Add libinput_device_set_seat_logical_name() to change seats at runtime
The seat of a device is currently immutable, but a device may (in a multi-pointer case) move between different logical seats. Moving it between seats is akin to removing it and re-plugging it, so let's do exactly that. The physical seat name stays immutable. Pro: - device handling after changing a seat remains identical as handling any other device. Con: - tracking a device across seat changes is difficult - this is not an atomic operation, if re-adding the device fails it stays removed from the original seat and is now dead Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
ff2b0cb84b
commit
d546c284c8
5 changed files with 80 additions and 0 deletions
|
|
@ -36,6 +36,8 @@ struct libinput_interface_backend {
|
|||
int (*resume)(struct libinput *libinput);
|
||||
void (*suspend)(struct libinput *libinput);
|
||||
void (*destroy)(struct libinput *libinput);
|
||||
int (*device_change_seat)(struct libinput_device *device,
|
||||
const char *seat_name);
|
||||
};
|
||||
|
||||
struct libinput {
|
||||
|
|
|
|||
|
|
@ -1213,6 +1213,19 @@ libinput_device_get_seat(struct libinput_device *device)
|
|||
return device->seat;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_device_set_seat_logical_name(struct libinput_device *device,
|
||||
const char *name)
|
||||
{
|
||||
struct libinput *libinput = device->seat->libinput;
|
||||
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
|
||||
return libinput->interface_backend->device_change_seat(device,
|
||||
name);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT void
|
||||
libinput_device_led_update(struct libinput_device *device,
|
||||
enum libinput_led leds)
|
||||
|
|
|
|||
|
|
@ -1370,6 +1370,32 @@ libinput_device_get_output_name(struct libinput_device *device);
|
|||
struct libinput_seat *
|
||||
libinput_device_get_seat(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Change the logical seat associated with this device by removing the
|
||||
* device and adding it to the new seat.
|
||||
*
|
||||
* This command is identical to physically unplugging the device, then
|
||||
* re-plugging it as member of the new seat,
|
||||
* @ref LIBINPUT_EVENT_DEVICE_REMOVED and @ref LIBINPUT_EVENT_DEVICE_ADDED
|
||||
* events are sent accordingly. Those events mark the end of the lifetime
|
||||
* of this device and the start of a new device.
|
||||
*
|
||||
* If the logical seat name already exists in the device's physical seat,
|
||||
* the device is added to this seat. Otherwise, a new seat is created.
|
||||
*
|
||||
* @note This change applies to this device until removal or @ref
|
||||
* libinput_suspend(), whichever happens earlier.
|
||||
*
|
||||
* @param device A previously obtained device
|
||||
* @param name The new logical seat name
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
int
|
||||
libinput_device_set_seat_logical_name(struct libinput_device *device,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
|
|
|
|||
20
src/path.c
20
src/path.c
|
|
@ -235,10 +235,30 @@ path_create_device(struct libinput *libinput,
|
|||
return device;
|
||||
}
|
||||
|
||||
static int
|
||||
path_device_change_seat(struct libinput_device *device,
|
||||
const char *seat_name)
|
||||
{
|
||||
struct libinput *libinput = device->seat->libinput;
|
||||
struct evdev_device *evdev_device = (struct evdev_device *)device;
|
||||
struct udev_device *udev_device = NULL;
|
||||
int rc = -1;
|
||||
|
||||
udev_device = evdev_device->udev_device;
|
||||
udev_device_ref(udev_device);
|
||||
libinput_path_remove_device(device);
|
||||
|
||||
if (path_create_device(libinput, udev_device, seat_name) != NULL)
|
||||
rc = 0;
|
||||
udev_device_unref(udev_device);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct libinput_interface_backend interface_backend = {
|
||||
.resume = path_input_enable,
|
||||
.suspend = path_input_disable,
|
||||
.destroy = path_input_destroy,
|
||||
.device_change_seat = path_device_change_seat,
|
||||
};
|
||||
|
||||
LIBINPUT_EXPORT struct libinput *
|
||||
|
|
|
|||
|
|
@ -332,10 +332,29 @@ udev_seat_get_named(struct udev_input *input, const char *seat_name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
udev_device_change_seat(struct libinput_device *device,
|
||||
const char *seat_name)
|
||||
{
|
||||
struct libinput *libinput = device->seat->libinput;
|
||||
struct udev_input *input = (struct udev_input *)libinput;
|
||||
struct evdev_device *evdev_device = (struct evdev_device *)device;
|
||||
struct udev_device *udev_device = evdev_device->udev_device;
|
||||
int rc;
|
||||
|
||||
udev_device_ref(udev_device);
|
||||
device_removed(udev_device, input);
|
||||
rc = device_added(udev_device, input, seat_name);
|
||||
udev_device_unref(udev_device);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct libinput_interface_backend interface_backend = {
|
||||
.resume = udev_input_enable,
|
||||
.suspend = udev_input_disable,
|
||||
.destroy = udev_input_destroy,
|
||||
.device_change_seat = udev_device_change_seat,
|
||||
};
|
||||
|
||||
LIBINPUT_EXPORT struct libinput *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue