Hi,

On 11/24/2014 01:46 AM, Peter Hutterer wrote:
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.hutte...@who-t.net>

Looks good:

Reviewed-by: Hans de Goede <hdego...@redhat.com>

Regards,

Hans

---
  src/libinput-private.h |  2 ++
  src/libinput.c         | 13 +++++++++++++
  src/libinput.h         | 26 ++++++++++++++++++++++++++
  src/path.c             | 20 ++++++++++++++++++++
  src/udev-seat.c        | 19 +++++++++++++++++++
  5 files changed, 80 insertions(+)

diff --git a/src/libinput-private.h b/src/libinput-private.h
index 8c75d1f..07db7fd 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -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 {
diff --git a/src/libinput.c b/src/libinput.c
index 3f5370f..7b94320 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -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)
diff --git a/src/libinput.h b/src/libinput.h
index 092b0e7..9c9a313 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1373,6 +1373,32 @@ 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
+ *
   * Update the LEDs on the device, if any. If the device does not have
   * LEDs, or does not have one or more of the LEDs given in the mask, this
   * function does nothing.
diff --git a/src/path.c b/src/path.c
index fef1d46..57f4cc6 100644
--- a/src/path.c
+++ b/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 *
diff --git a/src/udev-seat.c b/src/udev-seat.c
index c69d175..f7a3df3 100644
--- a/src/udev-seat.c
+++ b/src/udev-seat.c
@@ -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 *

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to