Use events instead of callbacks for capability registration
authorJonas Ådahl <jadahl@gmail.com>
Sun, 17 Nov 2013 15:59:09 +0000 (16:59 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Sun, 17 Nov 2013 17:32:53 +0000 (18:32 +0100)
This commit also introduces a new requirement to
libinput_device_destroy() - libinput_device_terminate() must be called
before libinput_device_destroy() in order to allow the user to dispatch
the events related to a terminating input devices while the device is
still valid.

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

index 4f107ea..0316c6f 100644 (file)
@@ -585,21 +585,18 @@ evdev_configure_device(struct evdev_device *device)
 {
        if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL)) &&
            (device->caps & EVDEV_BUTTON)) {
-               device->base.device_interface->register_capability(
-                       LIBINPUT_DEVICE_CAP_POINTER,
-                       device->base.device_interface_data);
+               device_register_capability(&device->base,
+                                          LIBINPUT_DEVICE_CAP_POINTER);
                device->seat_caps |= EVDEV_DEVICE_POINTER;
        }
        if ((device->caps & EVDEV_KEYBOARD)) {
-               device->base.device_interface->register_capability(
-                       LIBINPUT_DEVICE_CAP_KEYBOARD,
-                       device->base.device_interface_data);
+               device_register_capability(&device->base,
+                                          LIBINPUT_DEVICE_CAP_KEYBOARD);
                device->seat_caps |= EVDEV_DEVICE_KEYBOARD;
        }
        if ((device->caps & EVDEV_TOUCH)) {
-               device->base.device_interface->register_capability(
-                       LIBINPUT_DEVICE_CAP_TOUCH,
-                       device->base.device_interface_data);
+               device_register_capability(&device->base,
+                                          LIBINPUT_DEVICE_CAP_TOUCH);
                device->seat_caps |= EVDEV_DEVICE_TOUCH;
        }
 
@@ -681,25 +678,26 @@ evdev_device_calibrate(struct evdev_device *device, float calibration[6])
 }
 
 void
-evdev_device_destroy(struct evdev_device *device)
+evdev_device_terminate(struct evdev_device *device)
 {
-       struct evdev_dispatch *dispatch;
-
        if (device->seat_caps & EVDEV_DEVICE_POINTER) {
-               device->base.device_interface->unregister_capability(
-                       LIBINPUT_DEVICE_CAP_POINTER,
-                       device->base.device_interface_data);
+               device_unregister_capability(&device->base,
+                                            LIBINPUT_DEVICE_CAP_POINTER);
        }
        if (device->seat_caps & EVDEV_DEVICE_KEYBOARD) {
-               device->base.device_interface->unregister_capability(
-                       LIBINPUT_DEVICE_CAP_KEYBOARD,
-                       device->base.device_interface_data);
+               device_unregister_capability(&device->base,
+                                            LIBINPUT_DEVICE_CAP_KEYBOARD);
        }
        if (device->seat_caps & EVDEV_DEVICE_TOUCH) {
-               device->base.device_interface->unregister_capability(
-                       LIBINPUT_DEVICE_CAP_TOUCH,
-                       device->base.device_interface_data);
+               device_unregister_capability(&device->base,
+                                            LIBINPUT_DEVICE_CAP_TOUCH);
        }
+}
+
+void
+evdev_device_destroy(struct evdev_device *device)
+{
+       struct evdev_dispatch *dispatch;
 
        dispatch = device->dispatch;
        if (dispatch)
index 1b45aed..c8cb405 100644 (file)
@@ -145,6 +145,9 @@ void
 evdev_device_calibrate(struct evdev_device *device, float calibration[6]);
 
 void
+evdev_device_terminate(struct evdev_device *terminate);
+
+void
 evdev_device_destroy(struct evdev_device *device);
 
 #endif /* EVDEV_H */
index 6796ccf..e9a5aaa 100644 (file)
@@ -41,6 +41,7 @@ struct libinput_device {
        struct libinput *libinput;
        const struct libinput_device_interface *device_interface;
        void *device_interface_data;
+       int terminated;
 };
 
 typedef void (*libinput_source_dispatch_t)(void *data);
@@ -62,6 +63,14 @@ libinput_post_event(struct libinput *libinput,
                    struct libinput_event *event);
 
 void
+device_register_capability(struct libinput_device *device,
+                          enum libinput_device_capability capability);
+
+void
+device_unregister_capability(struct libinput_device *device,
+                            enum libinput_device_capability capability);
+
+void
 keyboard_notify_key(struct libinput_device *device,
                    uint32_t time,
                    uint32_t key,
index af00725..0226b81 100644 (file)
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <sys/epoll.h>
 #include <unistd.h>
+#include <assert.h>
 
 #include "libinput.h"
 #include "evdev.h"
@@ -161,6 +162,40 @@ post_device_event(struct libinput_device *device,
 }
 
 void
+device_register_capability(struct libinput_device *device,
+                          enum libinput_device_capability capability)
+{
+       struct libinput_event_device_register_capability *capability_event;
+
+       capability_event = malloc(sizeof *capability_event);
+
+       *capability_event = (struct libinput_event_device_register_capability) {
+               .capability = capability,
+       };
+
+       post_device_event(device,
+                         LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY,
+                         &capability_event->base);
+}
+
+void
+device_unregister_capability(struct libinput_device *device,
+                            enum libinput_device_capability capability)
+{
+       struct libinput_event_device_unregister_capability *capability_event;
+
+       capability_event = malloc(sizeof *capability_event);
+
+       *capability_event = (struct libinput_event_device_unregister_capability) {
+               .capability = capability,
+       };
+
+       post_device_event(device,
+                         LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY,
+                         &capability_event->base);
+}
+
+void
 keyboard_notify_key(struct libinput_device *device,
                    uint32_t time,
                    uint32_t key,
@@ -363,8 +398,16 @@ libinput_get_event(struct libinput *libinput)
 }
 
 LIBINPUT_EXPORT void
+libinput_device_terminate(struct libinput_device *device)
+{
+       evdev_device_terminate((struct evdev_device *) device);
+       device->terminated = 1;
+}
+
+LIBINPUT_EXPORT void
 libinput_device_destroy(struct libinput_device *device)
 {
+       assert(device->terminated);
        evdev_device_destroy((struct evdev_device *) device);
 }
 
index 67b7c1e..ee6b98a 100644 (file)
@@ -64,6 +64,8 @@ enum libinput_touch_type {
 };
 
 enum libinput_event_type {
+       LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY = 200,
+       LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY,
 
        LIBINPUT_EVENT_KEYBOARD_KEY = 300,
 
@@ -80,6 +82,16 @@ struct libinput_event {
        struct libinput_device *device;
 };
 
+struct libinput_event_device_register_capability {
+       struct libinput_event base;
+       enum libinput_device_capability capability;
+};
+
+struct libinput_event_device_unregister_capability {
+       struct libinput_event base;
+       enum libinput_device_capability capability;
+};
+
 struct libinput_event_keyboard_key {
        struct libinput_event base;
        uint32_t time;
@@ -129,13 +141,6 @@ struct libinput_fd_handle;
 typedef void (*libinput_fd_callback)(int fd, void *data);
 
 struct libinput_device_interface {
-       /* */
-       void (*register_capability)(enum libinput_device_capability capability,
-                                   void *data);
-       void (*unregister_capability)(enum libinput_device_capability capability,
-                                     void *data);
-
-       /* */
        void (*get_current_screen_dimensions)(int *width,
                                              int *height,
                                              void *data);
@@ -167,6 +172,9 @@ libinput_device_create_evdev(struct libinput *libinput,
                             void *user_data);
 
 void
+libinput_device_terminate(struct libinput_device *device);
+
+void
 libinput_device_destroy(struct libinput_device *device);
 
 void *