evdev: Reference count input device's seat capabilities
authorJonas Ådahl <jadahl@gmail.com>
Thu, 17 Oct 2013 21:04:05 +0000 (23:04 +0200)
committerJonas Ådahl <jadahl@gmail.com>
Sun, 10 Nov 2013 16:51:34 +0000 (17:51 +0100)
When the only input device of a certain seat capability is unplugged,
stop advertising the capability.

Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
src/evdev.c
src/evdev.h

index 7397ea1..eb7631a 100644 (file)
@@ -565,6 +565,7 @@ evdev_configure_device(struct evdev_device *device)
        if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL)) &&
            (device->caps & EVDEV_BUTTON)) {
                weston_seat_init_pointer(device->seat);
+               device->seat_caps |= EVDEV_SEAT_POINTER;
                weston_log("input device %s, %s is a pointer caps =%s%s%s\n",
                           device->devname, device->devnode,
                           device->caps & EVDEV_MOTION_ABS ? " absolute-motion" : "",
@@ -574,11 +575,13 @@ evdev_configure_device(struct evdev_device *device)
        if ((device->caps & EVDEV_KEYBOARD)) {
                if (weston_seat_init_keyboard(device->seat, NULL) < 0)
                        return -1;
+               device->seat_caps |= EVDEV_SEAT_KEYBOARD;
                weston_log("input device %s, %s is a keyboard\n",
                           device->devname, device->devnode);
        }
        if ((device->caps & EVDEV_TOUCH)) {
                weston_seat_init_touch(device->seat);
+               device->seat_caps |= EVDEV_SEAT_TOUCH;
                weston_log("input device %s, %s is a touch device\n",
                           device->devname, device->devnode);
        }
@@ -602,6 +605,7 @@ evdev_device_create(struct weston_seat *seat, const char *path, int device_fd)
                container_of(ec->output_list.next, struct weston_output, link);
 
        device->seat = seat;
+       device->seat_caps = 0;
        device->is_mt = 0;
        device->mtdev = NULL;
        device->devnode = strdup(path);
@@ -649,6 +653,13 @@ evdev_device_destroy(struct evdev_device *device)
 {
        struct evdev_dispatch *dispatch;
 
+       if (device->seat_caps & EVDEV_SEAT_POINTER)
+               weston_seat_release_pointer(device->seat);
+       if (device->seat_caps & EVDEV_SEAT_KEYBOARD)
+               weston_seat_release_keyboard(device->seat);
+       if (device->seat_caps & EVDEV_SEAT_TOUCH)
+               weston_seat_release_touch(device->seat);
+
        dispatch = device->dispatch;
        if (dispatch)
                dispatch->interface->destroy(dispatch);
index 5e4d11a..e146d1a 100644 (file)
@@ -49,6 +49,12 @@ enum evdev_device_capability {
        EVDEV_TOUCH = (1 << 4),
 };
 
+enum evdev_device_seat_capability {
+       EVDEV_SEAT_POINTER = (1 << 0),
+       EVDEV_SEAT_KEYBOARD = (1 << 1),
+       EVDEV_SEAT_TOUCH = (1 << 2)
+};
+
 struct evdev_device {
        struct weston_seat *seat;
        struct wl_list link;
@@ -80,6 +86,7 @@ struct evdev_device {
 
        enum evdev_event_type pending_event;
        enum evdev_device_capability caps;
+       enum evdev_device_seat_capability seat_caps;
 
        int is_mt;
 };